On Mon, Oct 29, 2018 at 11:04:39AM +0000, Lee Jones wrote:
On Fri, 26 Oct 2018, Mark Brown wrote:
On Fri, Oct 26, 2018 at 09:00:51AM +0100, Lee Jones wrote:
On Thu, 25 Oct 2018, Richard Fitzgerald wrote:
Precisely my point. Lochnagar is a small device yet it's required to
submit hundreds of lines of Regmap tables. Imagine what that would
look like for a large device.
There's no *requirement* to provide the data even if you're using the
cache (and the cache support is entirely optional), there's just costs
to not providing it in terms of what features you can get from the
regmap API and the performance of the system. Not every device is going
to be bothered by those costs, many devices don't provide all of the
data they could.
So what do we do in the case where, due to the size of the device, the
amount of lines required by these tables go from crazy to grotesque?
Ultimately, I guess I have always just viewed it as just data
tables. Its a lot of lines of source but its not complicated,
and complexity has really always been the thing I try to avoid.
Even if it is absolutely critical that you have to supply these to
Regmap up-front, instead of on first use/read, why can't you just
supply the oddball non-zero ones?
That doesn't work, we need to know both if the register has a default
value and what that value is - there's no great value in only supplying
the defaults for registers with non-zero values.
All registers have a default value. Why can't we assume that if a
register is writable and a default value was omitted then the default
is zero?
Defaults basically serve two purposes in regmap:
1) Initialise the register cache.
There are basically three ways you could handle this
(at least that I can think of) and regmap supports all
three. Obviously each with their own pros and cons:
1.1) Table of default values
+ Fast boot time
- Uses some additional memory
1.2) Read all the registers from the device on boot
+ Uses less memory
- Potentially very slow boot time
1.3) Only read values as you touch registers
+ Uses less memory
+ Usually no significant impact on boot time
- Can't do read or read/write/modify operations on
previously untouched registers whilst chip is off
1.3 does probably make sense here for Lochnagar since we
don't currently power things down. However, it is worth
noting that such an approach is extremely challenging for many
devices. For example the CODECs generally have all sorts of
actual user-facing interface that needs to be accessible
regardless of if the CODEC is powered up or down and powering it
up to access registers would end up being either horrific on
power consumption and/or horrific in terms of code complexity.
1.1 and 1.2 are basically a straight trade off. Generally
for our devices we talking loads of registers and
potentially connected over I2C. Our customers care deeply
about device boot time, Android has specs for such things
and often it is tight for a system to make those specs.
Conversly, generally the products we integrate into have
a fairly large amount of memory. As such this is a no
brainer of a choice for most of our devices.
2) Determine what registers should be synchronised on a cache
sync.
A cache sync is usually done when pulling a device out of
low power mode to reapply the currently desired register
settings. As discussed in 1) we don't currently do cache
syncs on Lochnagar, but this would affect most of our
parts. Again I can see three approaches to synchronising
the cache:
2.1) Sync out registers that arn't at their default value
+ Only syncs register that are actually needed
- Requires a table of defaults to work
2.2) Store a per register dirty flag in the cache
+ No up front table required in the driver
+ Potentially less memory as only a single bit required
per register, although realising that saving might be
very hard on some cache types
- May sync registers that arn't required
2.3) Sync all registers from the cache
+ No memory usage
- Potentially large penalty for cache sync
Regmap has options to do 2.3, however for most of our
devices that would be totally unacceptable. Our parts have
a lot of registers most of which are cacheable and for
power reasons cache syncs happen as the audio path is being
brought up. Again Android has targets here and they are
in low 10's of millseconds so bus accesses really do matter.
2.1 is the normal proceedure in regmap, although this
is defined on a per cache implementation basis, with the
core providing 2.1 as a default.
Again it's a bit of a trade off between 2.1 and 2.2, but
given 1 pretty much requires us to know the defaults
anyway, 2.1 will in general make the most sense, at least
for Cirrus parts.
So I would conclude, certainly for most Cirrus devices, we
do need to know the defaults at least for the vast majority
of registers. I guess the next question would be could we
generate some of the defaults table to reduce the table size
in the driver. I would agree with you that the only sensible
approach to reducing the defaults table size I can see would be
to not have to specify defaults for registers with a default
of zero. As an example to set expectations cs47l90, probably
the largest CODEC we have made, has 1357 defaults of which
693 are zero so ~50%.
The issue really boils down to how do we tell the difference
between a register that has no default, and one that has a default
of zero? There are a few problems I can foresee on this front:
1) There are occasions where people use a readable,
non-volatile register with no default for things like
device ID or revision. The idea being it can be read once
which will populate it into the cache then it never needs
to be read from the hardware again. Especially useful if
this information might be required whilst the hardware
is powered down.
We could potentially update such drivers to mark the
register as volatile and then store the value explicitly
in the drivers data structures?
2) There are occasions where a readable, writeable,
non-volatile register cannot be given a fixed default.
Usually this will be registers that are configured by
firmware or hardware during boot but then have control
passed to the kernel.
For example a couple of registers on Lochnagar will be
configured by the board controller itself depending on
the CODEC that is attached, mostly regulators that are
enabled during boot being set to appropriate voltages to
avoid hardware damage. To handle these we don't give them
defaults which forces a read from the device but then after
that we can use the cache.
For this one would probably have to add a new register
property (in addition to the existing readable, writeable,
volatile, and precious) for no default. Which would require
an additional callback. Although I guess that would cover 1
as well, and normally there would be very few registers in
this catagory.
3) Rather nervous there are other issues I am not currently
thinking of this is a widely used API and I am mostly
familiar only with the style of devices I work with.
We could potentially add an assume zero defaults flag,
that would at least then only apply the change to devices
that opt in?
One other related thing that rests on my mind is that creating
the defaults table is going to be a little intensive. I guess
it is not so bad if using the ranges API, so perhaps we would
need to tie it in with that. Although it is still a little
fiddly as you need to work out overlaps between the ranges for
different properties to be more efficient than just checking
each register. For the callback based systems though you
would have to check each register and for example coming
back to cs47l90, the highest register address is 0x3FFE7C
which means you would need to call over 4 million callbacks
probably multiple times whilst constructing your defaults table.