All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: Sean Anderson <sean.anderson@seco.com>
Cc: U-Boot Mailing List <u-boot@lists.denx.de>,
	Mario Six <mario.six@gdsys.cc>,
	Ramon Fried <rfried.dev@gmail.com>,
	Heinrich Schuchardt <xypron.glpk@gmx.de>,
	Tom Rini <trini@konsulko.com>,
	Joe Hershberger <joe.hershberger@ni.com>
Subject: Re: [PATCH v3 08/13] misc: Add support for nvmem cells
Date: Tue, 3 May 2022 02:50:52 -0600	[thread overview]
Message-ID: <CAPnjgZ1cwKhnnrB-j+Y2jo4VcnoTduC211DTE5JB6xWQFvJ5Ew@mail.gmail.com> (raw)
In-Reply-To: <86ab39e4-f463-418e-a337-3173d019f624@seco.com>

Hi Sean,

On Fri, 29 Apr 2022 at 13:40, Sean Anderson <sean.anderson@seco.com> wrote:
>
> Hi Simon,
>
> On 4/25/22 11:24 AM, Sean Anderson wrote:
> >
> >
> > On 4/25/22 1:48 AM, Simon Glass wrote:
> >> Hi Sean,
> >>
> >> On Mon, 18 Apr 2022 at 13:37, Sean Anderson <sean.anderson@seco.com> wrote:
> >>>
> >>> This adds support for "nvmem cells" as seen in Linux. The nvmem device
> >>> class in Linux is used for various assorted ROMs and EEPROMs. In this
> >>> sense, it is similar to UCLASS_MISC, but also includes
> >>> UCLASS_I2C_EEPROM, UCLASS_RTC, and UCLASS_MTD. New drivers corresponding
> >>> to a Linux-style nvmem device should be implemented as one of the
> >>> previously-mentioned uclasses. The nvmem API acts as a compatibility
> >>> layer to adapt the (slightly different) APIs of these uclasses. It also
> >>> handles the lookup of nvmem cells.
> >>>
> >>> While nvmem devices can be accessed directly, they are most often used
> >>> by reading/writing contiguous values called "cells". Cells typically
> >>> hold information like calibration, versions, or configuration (such as
> >>> mac addresses).
> >>>
> >>> nvmem devices can specify "cells" in their device tree:
> >>>
> >>>         qfprom: eeprom@700000 {
> >>>                 #address-cells = <1>;
> >>>                 #size-cells = <1>;
> >>>                 reg = <0x00700000 0x100000>;
> >>>
> >>>                 /* ... */
> >>>
> >>>                 tsens_calibration: calib@404 {
> >>>                         reg = <0x404 0x10>;
> >>>                 };
> >>>         };
> >>>
> >>> which can then be referenced like:
> >>>
> >>>         tsens {
> >>>                 /* ... */
> >>>                 nvmem-cells = <&tsens_calibration>;
> >>>                 nvmem-cell-names = "calibration";
> >>>         };
> >>>
> >>> The tsens driver could then read the calibration value like:
> >>>
> >>>         struct nvmem_cell cal_cell;
> >>>         u8 cal[16];
> >>>         nvmem_cell_get_by_name(dev, "calibration", &cal_cell);
> >>>         nvmem_cell_read(&cal_cell, cal, sizeof(cal));
> >>>
> >>> Because nvmem devices are not all of the same uclass, supported uclasses
> >>> must register a nvmem_interface struct. This allows CONFIG_NVMEM to be
> >>> enabled without depending on specific uclasses. At the moment,
> >>> nvmem_interface is very bare-bones, and assumes that no initialization
> >>> is necessary. However, this could be amended in the future.
> >>>
> >>> Although I2C_EEPROM and MISC are quite similar (and could likely be
> >>> unified), they present different read/write function signatures. To
> >>> abstract over this, NVMEM uses the same read/write signature as Linux.
> >>> In particular, short read/writes are not allowed, which is allowed by
> >>> MISC.
> >>>
> >>> The functionality implemented by nvmem cells is very similar to that
> >>> provided by i2c_eeprom_partition. "fixed-partition"s for eeproms does
> >>> not seem to have made its way into Linux or into any device tree other
> >>> than sandbox. It is possible that with the introduction of this API it
> >>> would be possible to remove it.
> >>
> >> I still think this would be better as a separate uclass, with child
> >> devices created at bind time in each of the respective uclasses, like
> >> mmc_bind() does. Then you will see the nvmem devices in the DM tree.
> >> Wouldn't we want to add a command to access the nvmem devices?
> >
> > We already do. E.g. the misc/rtc/eeprom commands. The problem is that
> > for software to access them, they would have to use misc_read/dm_rtc_read/
> > i2c_eeprom_read.
> >
> >> This patch feels like a shortcut to me and I'm not sure of the
> >> benefit of that shortcut.
> > Well, I suppose it's because "nvmem" devices are strict subsets of
> > existing devices. There is no new functionality here (except adapting
> > between semantics like for misc). We should always be able to use the
> > existing API to implement support for a new underlying uclass. There
> > should never be device-specific read/write methods, because we can
> > use the existing read/write uclass methods.
> >
> > What I'm trying to get at is that we sort of already have an nvmem
> > uclass with nvmem devices, they're just not accessible in a uniform
> > way. This series is trying to address the uniformity aspect. But I
> > don't think we need new devices for each nvmem interface, because
> > all they would do would take up ram/rom.
> >
> > --Sean
> >
> > PS. In an ideal world we'd have something like
> >
> > struct nvmem_ops {
> >       read();
> >       write();
> > };
> >
> > struct dm_rtc_ops {
> >       nvmem_ops nvmem;
> >       /* the other ops minus read/write */
> > };
> >
> > int nvmem_read (...) {
> >       struct nvmem_ops *ops = cell->nvmem->ops;
> >       /* ... */
> >
> >       return ops->read(...);
> > }
> >
> > but unfortunately, we already have fragmented implementations.

I don't see that as ideal as it involves a 'nested' API, something we
have avoided so far.

> >
>
> To follow up on this, I've conducted some size experiments. The
> following is the bloat caused by applying the current series on
> sandbox64_defconfig:
>
> add/remove: 8/0 grow/shrink: 7/2 up/down: 1069/-170 (899)
> Function                                     old     new   delta
> nvmem_cell_get_by_index                        -     216    +216
> dm_test_ethaddr                                -     192    +192
> nvmem_cell_write                               -     125    +125
> nvmem_cell_read                                -     125    +125
> nvmem_cell_get_by_name                         -      65     +65
> addr                                           -      64     +64
> sandbox_i2c_rtc_probe                          -      54     +54
> sb_eth_write_hwaddr                           14      57     +43
> sandbox_i2c_eeprom_probe                      70     112     +42
> misc_sandbox_probe                            21      61     +40
> eth_post_probe                               444     484     +40
> _u_boot_list_2_ut_dm_test_2_dm_test_ethaddr       -      32     +32
> __func__                                   15147   15163     +16
> data_gz                                    18327   18338     +11
> dsa_pre_probe                                181     185      +4
> sb_eth_of_to_plat                            126      64     -62
> default_environment                          553     445    -108
> Total: Before=1765267, After=1766166, chg +0.05%
>
> And here is the difference (from baseline) when using your
> suggested approach:
>
> add/remove: 26/0 grow/shrink: 8/2 up/down: 2030/-170 (1860)
> Function                                     old     new   delta
> dm_test_ethaddr                                -     192    +192
> nvmem_cell_get_by_index                        -     152    +152
> nvmem_register                                 -     137    +137
> _u_boot_list_2_driver_2_rtc_nvmem              -     128    +128
> _u_boot_list_2_driver_2_misc_nvmem             -     128    +128
> _u_boot_list_2_driver_2_i2c_eeprom_nvmem       -     128    +128
> _u_boot_list_2_uclass_driver_2_nvmem           -     120    +120
> misc_nvmem_write                               -      68     +68
> misc_nvmem_read                                -      68     +68
> nvmem_cell_write                               -      66     +66
> nvmem_cell_read                                -      65     +65
> nvmem_cell_get_by_name                         -      65     +65
> addr                                           -      64     +64
> sandbox_i2c_rtc_probe                          -      54     +54
> rtc_post_bind                                  -      48     +48
> nvmem_rtc_write                                -      48     +48
> nvmem_rtc_read                                 -      48     +48
> misc_post_bind                                 -      48     +48
> i2c_eeprom_nvmem_write                         -      48     +48
> i2c_eeprom_nvmem_read                          -      48     +48
> sb_eth_write_hwaddr                           14      57     +43
> sandbox_i2c_eeprom_probe                      70     112     +42
> misc_sandbox_probe                            21      61     +40
> eth_post_probe                               444     484     +40
> _u_boot_list_2_ut_dm_test_2_dm_test_ethaddr       -      32     +32
> rtc_nvmem_ops                                  -      16     +16
> misc_nvmem_ops                                 -      16     +16
> i2c_eeprom_post_bind                           -      16     +16
> i2c_eeprom_nvmem_ops                           -      16     +16
> __func__                                   15147   15163     +16
> data_gz                                    18327   18338     +11
> fmt                                            -       9      +9
> version_string                                68      74      +6
> dsa_pre_probe                                181     185      +4
> sb_eth_of_to_plat                            126      64     -62
> default_environment                          553     445    -108
> Total: Before=1765267, After=1767127, chg +0.11%
>
> As you can see, adding a second driver for each nvmem device
> doubles the size of this feature. The patch I used for this follows
> (it does not apply cleanly to v3 because the base contains some
> changes fixing bugs pointed out by Tom).

Thanks for the analysis and patch. This is what buildman reports for me:

01: test: Load mac address using misc device
   sandbox:  w+   sandbox
02: misc: nvmem: Convert to using udevices
   sandbox: (for 1/1 boards) all +1584.0 data +576.0 rodata +32.0 text +976.0
[..]

So we have text growth of about 1KB on 64-bit x86. The data size is
not that important IMO since this is most likely to be used in U-Boot
proper which doesn't have tight constraints. For that we should
instead focus on reducing the cost of driver model overall, e.g. with
the ideas mentioned at [1].

I didn't try on Thumb2 but I suppose it would be about 0.5KB.

It seems OK to pay this cost to keep things clean.

If we do go ahead with this series (i.e. without the last patch), I
don't think it should be a model for how to add new APIs in future.
E.g. we could save space by making a special case for PMICs which
support GPIOs, so that GPIO operations could accept a PMIC device or a
GPIO device, but it would be quite confusing, We could make the
random-number device disappear and just 'know' that a TPM and a MISC
device can produce random numbers, but I have the same feeling about
that.

Given that you have done the analysis and you are still pretty keen on
this, I am OK with it going in. I don't like it very much. but we can
always review things later. Perhaps add a comment in the nvmem header
files about how it works and why it doesn't use driver model in the
normal way?

Regards,
Simon

[1] https://lore.kernel.org/all/20220327202622.3438333-1-sjg@chromium.org/

  reply	other threads:[~2022-05-03  8:51 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-18 19:36 [PATCH v3 00/13] Add support for NVMEM API Sean Anderson
2022-04-18 19:36 ` [PATCH v3 01/13] sandbox: net: Add aliases for ethernet devices Sean Anderson
2022-04-29 14:48   ` Tom Rini
2022-04-18 19:36 ` [PATCH v3 02/13] sandbox: net: Add mac address for eth8 to environment Sean Anderson
2022-04-18 19:36 ` [PATCH v3 03/13] test: eth: Add test for ethernet addresses Sean Anderson
2022-04-18 19:36 ` [PATCH v3 04/13] sandbox: net: Remove fake-host-hwaddr Sean Anderson
2022-04-18 19:36 ` [PATCH v3 05/13] sandbox: Remove eth2addr from environment Sean Anderson
2022-04-18 19:36 ` [PATCH v3 06/13] sandbox: Move some mac addresses to device tree Sean Anderson
2022-04-18 19:36 ` [PATCH v3 07/13] misc: i2c_eeprom: Make i2c_eeprom_write use a const buf Sean Anderson
2022-04-18 19:36 ` [PATCH v3 08/13] misc: Add support for nvmem cells Sean Anderson
2022-04-25  5:48   ` Simon Glass
2022-04-25 15:24     ` Sean Anderson
2022-04-29 19:40       ` Sean Anderson
2022-05-03  8:50         ` Simon Glass [this message]
2022-05-05 15:26           ` Sean Anderson
2022-04-18 19:36 ` [PATCH v3 09/13] sandbox: Enable NVMEM Sean Anderson
2022-04-18 19:36 ` [PATCH v3 10/13] net: Add support for reading mac addresses from nvmem cells Sean Anderson
2022-04-29 14:48   ` Tom Rini
2022-04-18 19:36 ` [PATCH v3 11/13] test: Load mac address with i2c eeprom Sean Anderson
2022-04-18 19:36 ` [PATCH v3 12/13] test: Load mac address using RTC Sean Anderson
2022-04-29 14:48   ` Tom Rini
2022-04-18 19:36 ` [PATCH v3 13/13] test: Load mac address using misc device Sean Anderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAPnjgZ1cwKhnnrB-j+Y2jo4VcnoTduC211DTE5JB6xWQFvJ5Ew@mail.gmail.com \
    --to=sjg@chromium.org \
    --cc=joe.hershberger@ni.com \
    --cc=mario.six@gdsys.cc \
    --cc=rfried.dev@gmail.com \
    --cc=sean.anderson@seco.com \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.