Hi Werner,

Sorry if you think https://review.coreboot.org/c/coreboot/+/34385 could
break things for you. Feel free to push
somewhat of a revert (if you can think of a better message than "bad
counts" :) )

-Tim

On Thu, Apr 29, 2021 at 8:55 AM Zeh, Werner <werner....@siemens.com> wrote:

> In the meantime Kyösti provided a patch [1] where the clock timing is
> computed based on rise and fall times in the default case.
> This results in a much more accurate timings which I was able to measure
> on mb/siemens/mc_apl6
>
> Nevertheless, looking closer to the driver implementation, a few odds are
> in there.
> First, the values 7 and 1 [2] (which actually should be 8 and 1 according
> to the Synopsis specification) are completely uncommented and therefore
> hard to understand from somebody without the specification in mind.
> In addition, I still have not fully understood why the spike rejection
> counter value is subtracted from the count value for the high period as it
> is not described that way in the specification.
>
> Further on, we easily can run into issues if the OS decides to switch the
> bus frequency from <= FULL_SPEED_PLUS to HIGH_SPEED on some platforms as
> e.g. on Apollo Lake there is a stronger output driver enabled internally
> for HIGH_SPEED mode which significantly changes the rise and fall times. So
> maybe the earlier implementation, where we had a set of parameters reported
> in ACPI for every implemented bus speed (removed with [3]), was not so bad
> in this regard.
>
> Werner
>
> [1] https://review.coreboot.org/c/coreboot/+/52723
> [2]
> https://review.coreboot.org/plugins/gitiles/coreboot/+/refs/heads/master/src/drivers/i2c/designware/dw_i2c.c#579
> [3] https://review.coreboot.org/c/coreboot/+/34385
>
>
> Von: Tim Wawrzynczak <twawrzync...@google.com>
> Gesendet: Dienstag, 27. April 2021 23:01
> An: werner....@siemens.com
> Cc: coreboot <coreboot@coreboot.org>
> Betreff: Re: [coreboot] Default-timings in Designware I2C driver
>
> Hi Werner,
>
> I agree we could probably do a little better than we do today (feel free
> to submit a patch ;)),
> but speaking for what I have seen on bringing up Chrome OS devices, the
> ODMs ultimately
> end up having to tweak these values depending on the board design (bus
> load, etc.); e.g.
>
> ```
> $
>  git grep 'scl_lcnt' -- src/mainboard/google/*.cb | wc -l
> 72
> ```
>
> One idea we've had is to implement a sysfs interface in the Linux kernel
> to expose
> a way to change these registers at runtime, so they can be tuned, or add a
> custom
> module to our payload (depthcharge) to allow tuning these values in the
> CLI.
>
> -Tim
>
> On Tue, Apr 27, 2021 at 3:01 AM Zeh, Werner <mailto:werner....@siemens.com>
> wrote:
> Hi everybody.
>
> We do have a driver for a widely used I2C-controller from Designware in
> src/drivers/i2c/designware.
> It is used across multiple platforms and has a quite good configurability
> from mainboard side. One can tweak everything needed and make it work with
> the needed timing easily.
> Though I stumbled lately across a thing I wouldn't expect the way it is.
>
> It is possible to define the speed one needs to operate the I2C bus on in
> devicetree by setting the .speed-value to one of the supported defines
> (I2C_SPEED_STANDARD, I2C_SPEED_FAST, I2C_SPEED_FAST_PLUS, I2C_SPEED_HIGH or
> I2C_SPEED_FAST_ULTRA), e.g.:
>
> register "common_soc_config" = "{
>         .i2c[0] = {
>                 .speed = I2C_SPEED_STANDARD
>                  }
>         }"
>
> If one just sets the .speed value, the driver will take care about the
> needed SCL clock rate and set it up to a default value. Yes, these values
> might be not the best for the current bus load but should at least provide
> a clock that matches the requested speed.
> This default values are defined in src/drivers/i2c/designware/dw_i2c.c as
> follows:
> /* High and low times in different speed modes (in ns) */
> enum {
>         /* SDA Hold Time */
>         DEFAULT_SDA_HOLD_TIME   = 300,
>         /* Standard Speed */
>         MIN_SS_SCL_HIGHTIME     = 4000,
>         MIN_SS_SCL_LOWTIME              = 4700,
>         /* Fast Speed */
>         MIN_FS_SCL_HIGHTIME     = 600,
>         MIN_FS_SCL_LOWTIME              = 1300,
>         /* Fast Plus Speed */
>         MIN_FP_SCL_HIGHTIME     = 260,
>         MIN_FP_SCL_LOWTIME      = 500,
>         /* High Speed */
>         MIN_HS_SCL_HIGHTIME     = 60,
>         MIN_HS_SCL_LOWTIME      = 160,
> };
>
> While these values do match the needed _minimum_ durations for the high
> and low period of the SCL signal according to the I2C-specification [1],
> they are not enough for the overall clock cycle to match the requested
> speed. Let's take standard speed for example:
>
> MIN_SS_SCL_HIGHTIME = 4,0 us, MIN_SS_SCL_LOWTIME = 4,7 µs
>         ==> MIN_SS_SCL_HIGHTIME + MIN_SS_SCL_LOWTIME = 8,7 µs which equals
> to 114,943 kHz instead of 100 kHz
> The same applies to the other speeds as well.
>
> As the driver is aware of the clock the IP is clocked with inside the
> Chipset/SoC (CONFIG_DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ), it can be done
> right. There is code already which computes the needed counter values for
> high and low period from the provided IP-clock, *LOWTIME and *HIGHTIME in
> dw_i2c_gen_speed_config():
> ...
> if (speed >= I2C_SPEED_HIGH) {
>         /* High speed */
>         hcnt_min = MIN_HS_SCL_HIGHTIME;
>         lcnt_min = MIN_HS_SCL_LOWTIME;
> } else if (speed >= I2C_SPEED_FAST_PLUS) {
>         /* Fast-Plus speed */
>         hcnt_min = MIN_FP_SCL_HIGHTIME;
>         lcnt_min = MIN_FP_SCL_LOWTIME;
> } else if (speed >= I2C_SPEED_FAST) {
>         /* Fast speed */
>         hcnt_min = MIN_FS_SCL_HIGHTIME;
>         lcnt_min = MIN_FS_SCL_LOWTIME;
> } else {
>         /* Standard speed */
>         hcnt_min = MIN_SS_SCL_HIGHTIME;
>         lcnt_min = MIN_SS_SCL_LOWTIME;
> }
> config->speed = speed;
> config->scl_hcnt = ic_clk * hcnt_min / KHz;
> config->scl_lcnt = ic_clk * lcnt_min / KHz;
> config->sda_hold = ic_clk * DEFAULT_SDA_HOLD_TIME / KHz;
> ...
>
> I tend to change the high and low values
> (MIN_{SS,FS,FPHS}_SCL_{HIGH,LOW}TIME) to match the needed minimum
> constraints while still fulfilling the overall clock cycle, e.g. by
> increasing the HIGHTIME.
> But I would like to hear other opinions on that. Surely I am not aware of
> all the use cases out there.
>
> And again: These default values can easily be overridden in the devicetree
> with something like this:
> register "common_soc_config" = "{
>         .i2c[0] = {
>                 .speed = I2C_SPEED_STANDARD,
>                 .speed_config[0] = {
>                         .speed = I2C_SPEED_STANDARD,
>                         .scl_lcnt = 664,
>                         .scl_hcnt = 657, /*This value is smaller due to
> the IP adding a count of 8 internally, see [2]*/
>                         .sda_hold = 39
>                 }
>         },
> }"
>
> But I would expect the driver to do it right in the default configuration.
>
> Any input is highly welcome.
>
> Werner
>
> [1]
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.nxp.com%2Fdocs%2Fen%2Fuser-guide%2FUM10204.pdf&data=04%7C01%7Cwerner.zeh%40siemens.com%7C826e4a3f0e4648bc46e008d909bf86b6%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637551541076454574%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=vM3723zODxZlpcifKoNrOhepB5lFgbFb8RI6GoXkj4w%3D&reserved=0
> [2]
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdokumen.tips%2Fdocuments%2Fdesignware-dw-apb-i2c-databook-pudn-designware-dwapbi2c-databook-preface-preface.html&data=04%7C01%7Cwerner.zeh%40siemens.com%7C826e4a3f0e4648bc46e008d909bf86b6%7C38ae3bcd95794fd4addab42e1495d55a%7C1%7C0%7C637551541076464568%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=qOQuy%2BUJ%2FAckoG2l4Ysn5lg4em2jt4Wsy5vTdo6moJg%3D&reserved=0
> _______________________________________________
> coreboot mailing list -- mailto:coreboot@coreboot.org
> To unsubscribe send an email to mailto:coreboot-le...@coreboot.org
>
_______________________________________________
coreboot mailing list -- coreboot@coreboot.org
To unsubscribe send an email to coreboot-le...@coreboot.org

Reply via email to