mbox series

[v2,00/40] mmc: dw_mmc: Enable eMMC on E850-96 board

Message ID 20240610011226.4050-1-semen.protsenko@linaro.org
Headers show
Series mmc: dw_mmc: Enable eMMC on E850-96 board | expand

Message

Sam Protsenko June 10, 2024, 1:11 a.m. UTC
Bring 64-bit support to dw_mmc core and Exynos dw_mmc drivers, and
enable it on E850-96 board. Additionally do some related cleanups and
device tree updates.

64-bit version of DesignWare MMC can be often found on modern ARM64
chips. It's different from its older 32-bit version (which is already
implemented in U-Boot): some new registers were added, existing
register addresses are changed, DMA descriptor table is different, etc.
Next Exynos chips are known to have 64-bit DW MMC block:

  - Exynos3475
  - Exynos5433
  - Exynos7420
  - Exynos7570
  - Exynos7580
  - Exynos7870
  - Exynos7872
  - Exynos7880
  - Exynos7885
  - Exynos7890
  - Exynos850 (Exynos3830)

Exynos DW MMC driver was updated too: ARM64 Exynos chips implement their
clock drivers using CCF framework, pinmux configuration is done at
startup in DM capable pinctrl drivers, device tree properties were
changed w.r.t. their upstream (Linux kernel) counterparts. CLKSEL
register address is also different on 64-bit Exynos platforms.

The patch series was tested on E850-96 board by running mainline Linux
kernel with Debian rootfs from eMMC ("boot" partition) with these
commands:

8<-------------------------------------------------------------------->8
env set fdtaddr 0x8a000000
env set bootaddr 0x94000000
env set boot_kerneladdr 0x94000800
part start mmc 0 boot boot_start
part size mmc 0 boot boot_size
mmc read $bootaddr $boot_start $boot_size
abootimg addr $bootaddr
abootimg get dtb --index=0 dtb_start dtb_size
cp.b $dtb_start $fdtaddr $dtb_size
fdt addr $fdtaddr 0x100000
cp.b $boot_kerneladdr $loadaddr 2aaaa00
env set bootargs console=ttySAC0,115200n8 printk.devkmsg=on \
                 root=/dev/mmcblk0p12 rootwait rw
booti $loadaddr - $fdtaddr
8<-------------------------------------------------------------------->8

For E850-96 eMMC to function properly in DDR mode, the pending patch [1]
has to be applied. Otherwise it won't be possible for exynos_dw_mmc
driver to change CIU clock rate from 200 MHz up to 400 MHz, and MMC will
fall back to SDR mode, which makes eMMC throughput twice as slower. With
patch [1] applied, 'mmc info' reports this:

    Bus Speed: 52000000
    Mode: MMC DDR52 (52MHz)

and 'clk dump' shows CIU clock rate to be ~400 MHz (after first mmc
operation, e.g. 'part start' or 'mmc read'):

    399750000    gout_mmc_embd_sdclkin

Which makes sense, because dw_mmc requests to set CCLKIN = 52 MHz (with
DDR/8-bit mode), and exynos_dw_mmc tries to set CIU clock rate to:

    SDCLKIN = 2 * ciu_div * CCLKIN = 2 * 4 * 52 MHz = 416 MHz,

and the closest possible value the clock driver can set is 399.75 MHz,
which works just fine.

For Exynos4 and Exynos5 (ARM32) boards, this patch series was only build
tested (manually and with buildman). The build is clean (no errors or
warnings), but I don't have any Exynos4/Exynos5 boards at my disposal,
so I can't actually verify MMC operation there.

Changes in v2:
  - Rebased on top of the most recent U-Boot/master
  - Added pending R-b tags from the mailing list
  - Addressed the comment from Quentin about CONFIG_IS_ENABLED() not
    playing nice in SPL case:
    1. Dropped [PATCH 35/42]
       ("mmc: exynos_dw_mmc: Use CONFIG_IS_ENABLED() to check config
        options")
    2. Dropped [PATCH 14/42]
       ("mmc: dw_mmc: Use CONFIG_IS_ENABLED() to check config options")
    3. Got rid of all other CONFIG_IS_ENABLED() changes (used #ifdef for
       now)
  - Addressed the comment from Quentin about incorrect logic for divider
    update in [PATCH 06/40]
  - Guarded exynos_dwmmc_of_to_plat() with #ifded CONFIG_DM_MMC in
    [PATCH 22/40]
  - Added list of Exynos chips implementing 64-bit IDMAC descriptor (in
    [PATCH 00/40])

[1] https://lists.denx.de/pipermail/u-boot/2024-March/547719.html

Sam Protsenko (40):
  mmc: dw_mmc: Remove common.h
  mmc: dw_mmc: Remove unused version field from struct dwmci_host
  mmc: dw_mmc: Move struct idmac to dw_mmc.c
  mmc: dw_mmc: Extract waiting for data busy into a separate routine
  mmc: dw_mmc: Extract FIFO init into a separate routine
  mmc: dw_mmc: Extract divider update to a separate function
  mmc: dw_mmc: Extract FIFO data transfer into a separate routine
  mmc: dw_mmc: Extract DMA transfer handling code into a separate
    routine
  mmc: dw_mmc: Extract setting the DMA descriptor into a separate
    routine
  mmc: dw_mmc: Improve 32-bit IDMAC descriptor namings
  mmc: dw_mmc: Add support for 64-bit IDMAC
  mmc: dw_mmc: Replace fifoth_val property with fifo-depth
  mmc: dw_mmc: Fix kernel-doc comments in dwmmc.h
  mmc: dw_mmc: Improve coding style
  arm: dts: exynos: Add upstream DW MMC properties to all Exynos dts
  dt-bindings: exynos: Update bindings doc for DW MMC controller
  arm: exynos: Add header guard for dwmmc.h
  mmc: exynos_dw_mmc: Fix obtaining the base address of controller
  mmc: exynos_dw_mmc: Fix getting private data in
    exynos_dwmci_board_init()
  mmc: exynos_dw_mmc: Don't call pinmux functions on ARM64 chips
  mmc: exynos_dw_mmc: Obtain and use CIU clock via CCF API
  mmc: exynos_dw_mmc: Use .of_to_plat for device tree parsing
  mmc: exynos_dw_mmc: Convert to use livetree API
  mmc: exynos_dw_mmc: Read upstream SDR timing properties
  mmc: exynos_dw_mmc: Abstract CLKSEL register
  mmc: exynos_dw_mmc: Refactor fixed CIU clock divider
  mmc: exynos_dw_mmc: Read common bus-width property
  mmc: exynos_dw_mmc: Read common clock-frequency property
  mmc: exynos_dw_mmc: Move quirks from struct dwmci_host to chip data
  mmc: exynos_dw_mmc: Read and use DDR timing when available
  mmc: exynos_dw_mmc: Set requested freq in get_mmc_clk() callback
  mmc: exynos_dw_mmc: Add support for ARM64 Exynos chips
  mmc: exynos_dw_mmc: Remove common.h
  mmc: exynos_dw_mmc: Pull all init code into probe function
  mmc: exynos_dw_mmc: Don't call dwmci_setup_cfg() after add_dwmci()
  mmc: exynos_dw_mmc: Use dev->name as driver's displayed name
  mmc: exynos_dw_mmc: Improve coding style
  arm: dts: exynos: Remove outdated DW MMC properties in all Exynos dts
  configs: e850-96: Enable MMC
  doc: samsung: Mention enabled eMMC in E850-96 board doc

 arch/arm/dts/exynos4210-origen.dts         |   3 +-
 arch/arm/dts/exynos4210-trats.dts          |   6 +-
 arch/arm/dts/exynos4210-universal_c210.dts |   6 +-
 arch/arm/dts/exynos4412-odroid.dts         |  14 +-
 arch/arm/dts/exynos4412-trats2.dts         |  20 +-
 arch/arm/dts/exynos5250-arndale.dts        |  10 +-
 arch/arm/dts/exynos5250-smdk5250.dts       |  13 +-
 arch/arm/dts/exynos5250-snow.dts           |  13 +-
 arch/arm/dts/exynos5250-spring.dts         |   7 +-
 arch/arm/dts/exynos5420-smdk5420.dts       |  13 +-
 arch/arm/dts/exynos5422-odroidxu3.dts      |   4 +-
 arch/arm/dts/exynos54xx.dtsi               |  13 +-
 arch/arm/mach-exynos/include/mach/dwmmc.h  |  40 +-
 configs/e850-96_defconfig                  |  10 +-
 doc/board/samsung/e850-96.rst              |   5 +-
 doc/device-tree-bindings/exynos/dwmmc.txt  |  46 +-
 drivers/mmc/ca_dw_mmc.c                    |   2 +-
 drivers/mmc/dw_mmc.c                       | 550 +++++++++++++--------
 drivers/mmc/exynos_dw_mmc.c                | 358 +++++++++-----
 drivers/mmc/ftsdc010_mci.h                 |   1 -
 drivers/mmc/hi6220_dw_mmc.c                |   7 +-
 drivers/mmc/nexell_dw_mmc.c                |   5 +-
 drivers/mmc/rockchip_dw_mmc.c              |   5 +-
 drivers/mmc/s5p_sdhci.c                    |   2 +-
 drivers/mmc/snps_dw_mmc.c                  |   6 +-
 drivers/mmc/socfpga_dw_mmc.c               |   4 +-
 include/dwmmc.h                            | 242 +++++----
 27 files changed, 868 insertions(+), 537 deletions(-)

Comments

Sam Protsenko June 18, 2024, 8:56 p.m. UTC | #1
If there are no new comments on this series, can you please apply it?

Thanks!

On Sun, Jun 9, 2024 at 8:12 PM Sam Protsenko <semen.protsenko@linaro.org> wrote:
>
> Bring 64-bit support to dw_mmc core and Exynos dw_mmc drivers, and
> enable it on E850-96 board. Additionally do some related cleanups and
> device tree updates.
>
> 64-bit version of DesignWare MMC can be often found on modern ARM64
> chips. It's different from its older 32-bit version (which is already
> implemented in U-Boot): some new registers were added, existing
> register addresses are changed, DMA descriptor table is different, etc.
> Next Exynos chips are known to have 64-bit DW MMC block:
>
>   - Exynos3475
>   - Exynos5433
>   - Exynos7420
>   - Exynos7570
>   - Exynos7580
>   - Exynos7870
>   - Exynos7872
>   - Exynos7880
>   - Exynos7885
>   - Exynos7890
>   - Exynos850 (Exynos3830)
>
> Exynos DW MMC driver was updated too: ARM64 Exynos chips implement their
> clock drivers using CCF framework, pinmux configuration is done at
> startup in DM capable pinctrl drivers, device tree properties were
> changed w.r.t. their upstream (Linux kernel) counterparts. CLKSEL
> register address is also different on 64-bit Exynos platforms.
>
> The patch series was tested on E850-96 board by running mainline Linux
> kernel with Debian rootfs from eMMC ("boot" partition) with these
> commands:
>
> 8<-------------------------------------------------------------------->8
> env set fdtaddr 0x8a000000
> env set bootaddr 0x94000000
> env set boot_kerneladdr 0x94000800
> part start mmc 0 boot boot_start
> part size mmc 0 boot boot_size
> mmc read $bootaddr $boot_start $boot_size
> abootimg addr $bootaddr
> abootimg get dtb --index=0 dtb_start dtb_size
> cp.b $dtb_start $fdtaddr $dtb_size
> fdt addr $fdtaddr 0x100000
> cp.b $boot_kerneladdr $loadaddr 2aaaa00
> env set bootargs console=ttySAC0,115200n8 printk.devkmsg=on \
>                  root=/dev/mmcblk0p12 rootwait rw
> booti $loadaddr - $fdtaddr
> 8<-------------------------------------------------------------------->8
>
> For E850-96 eMMC to function properly in DDR mode, the pending patch [1]
> has to be applied. Otherwise it won't be possible for exynos_dw_mmc
> driver to change CIU clock rate from 200 MHz up to 400 MHz, and MMC will
> fall back to SDR mode, which makes eMMC throughput twice as slower. With
> patch [1] applied, 'mmc info' reports this:
>
>     Bus Speed: 52000000
>     Mode: MMC DDR52 (52MHz)
>
> and 'clk dump' shows CIU clock rate to be ~400 MHz (after first mmc
> operation, e.g. 'part start' or 'mmc read'):
>
>     399750000    gout_mmc_embd_sdclkin
>
> Which makes sense, because dw_mmc requests to set CCLKIN = 52 MHz (with
> DDR/8-bit mode), and exynos_dw_mmc tries to set CIU clock rate to:
>
>     SDCLKIN = 2 * ciu_div * CCLKIN = 2 * 4 * 52 MHz = 416 MHz,
>
> and the closest possible value the clock driver can set is 399.75 MHz,
> which works just fine.
>
> For Exynos4 and Exynos5 (ARM32) boards, this patch series was only build
> tested (manually and with buildman). The build is clean (no errors or
> warnings), but I don't have any Exynos4/Exynos5 boards at my disposal,
> so I can't actually verify MMC operation there.
>
> Changes in v2:
>   - Rebased on top of the most recent U-Boot/master
>   - Added pending R-b tags from the mailing list
>   - Addressed the comment from Quentin about CONFIG_IS_ENABLED() not
>     playing nice in SPL case:
>     1. Dropped [PATCH 35/42]
>        ("mmc: exynos_dw_mmc: Use CONFIG_IS_ENABLED() to check config
>         options")
>     2. Dropped [PATCH 14/42]
>        ("mmc: dw_mmc: Use CONFIG_IS_ENABLED() to check config options")
>     3. Got rid of all other CONFIG_IS_ENABLED() changes (used #ifdef for
>        now)
>   - Addressed the comment from Quentin about incorrect logic for divider
>     update in [PATCH 06/40]
>   - Guarded exynos_dwmmc_of_to_plat() with #ifded CONFIG_DM_MMC in
>     [PATCH 22/40]
>   - Added list of Exynos chips implementing 64-bit IDMAC descriptor (in
>     [PATCH 00/40])
>
> [1] https://lists.denx.de/pipermail/u-boot/2024-March/547719.html
>
> Sam Protsenko (40):
>   mmc: dw_mmc: Remove common.h
>   mmc: dw_mmc: Remove unused version field from struct dwmci_host
>   mmc: dw_mmc: Move struct idmac to dw_mmc.c
>   mmc: dw_mmc: Extract waiting for data busy into a separate routine
>   mmc: dw_mmc: Extract FIFO init into a separate routine
>   mmc: dw_mmc: Extract divider update to a separate function
>   mmc: dw_mmc: Extract FIFO data transfer into a separate routine
>   mmc: dw_mmc: Extract DMA transfer handling code into a separate
>     routine
>   mmc: dw_mmc: Extract setting the DMA descriptor into a separate
>     routine
>   mmc: dw_mmc: Improve 32-bit IDMAC descriptor namings
>   mmc: dw_mmc: Add support for 64-bit IDMAC
>   mmc: dw_mmc: Replace fifoth_val property with fifo-depth
>   mmc: dw_mmc: Fix kernel-doc comments in dwmmc.h
>   mmc: dw_mmc: Improve coding style
>   arm: dts: exynos: Add upstream DW MMC properties to all Exynos dts
>   dt-bindings: exynos: Update bindings doc for DW MMC controller
>   arm: exynos: Add header guard for dwmmc.h
>   mmc: exynos_dw_mmc: Fix obtaining the base address of controller
>   mmc: exynos_dw_mmc: Fix getting private data in
>     exynos_dwmci_board_init()
>   mmc: exynos_dw_mmc: Don't call pinmux functions on ARM64 chips
>   mmc: exynos_dw_mmc: Obtain and use CIU clock via CCF API
>   mmc: exynos_dw_mmc: Use .of_to_plat for device tree parsing
>   mmc: exynos_dw_mmc: Convert to use livetree API
>   mmc: exynos_dw_mmc: Read upstream SDR timing properties
>   mmc: exynos_dw_mmc: Abstract CLKSEL register
>   mmc: exynos_dw_mmc: Refactor fixed CIU clock divider
>   mmc: exynos_dw_mmc: Read common bus-width property
>   mmc: exynos_dw_mmc: Read common clock-frequency property
>   mmc: exynos_dw_mmc: Move quirks from struct dwmci_host to chip data
>   mmc: exynos_dw_mmc: Read and use DDR timing when available
>   mmc: exynos_dw_mmc: Set requested freq in get_mmc_clk() callback
>   mmc: exynos_dw_mmc: Add support for ARM64 Exynos chips
>   mmc: exynos_dw_mmc: Remove common.h
>   mmc: exynos_dw_mmc: Pull all init code into probe function
>   mmc: exynos_dw_mmc: Don't call dwmci_setup_cfg() after add_dwmci()
>   mmc: exynos_dw_mmc: Use dev->name as driver's displayed name
>   mmc: exynos_dw_mmc: Improve coding style
>   arm: dts: exynos: Remove outdated DW MMC properties in all Exynos dts
>   configs: e850-96: Enable MMC
>   doc: samsung: Mention enabled eMMC in E850-96 board doc
>
>  arch/arm/dts/exynos4210-origen.dts         |   3 +-
>  arch/arm/dts/exynos4210-trats.dts          |   6 +-
>  arch/arm/dts/exynos4210-universal_c210.dts |   6 +-
>  arch/arm/dts/exynos4412-odroid.dts         |  14 +-
>  arch/arm/dts/exynos4412-trats2.dts         |  20 +-
>  arch/arm/dts/exynos5250-arndale.dts        |  10 +-
>  arch/arm/dts/exynos5250-smdk5250.dts       |  13 +-
>  arch/arm/dts/exynos5250-snow.dts           |  13 +-
>  arch/arm/dts/exynos5250-spring.dts         |   7 +-
>  arch/arm/dts/exynos5420-smdk5420.dts       |  13 +-
>  arch/arm/dts/exynos5422-odroidxu3.dts      |   4 +-
>  arch/arm/dts/exynos54xx.dtsi               |  13 +-
>  arch/arm/mach-exynos/include/mach/dwmmc.h  |  40 +-
>  configs/e850-96_defconfig                  |  10 +-
>  doc/board/samsung/e850-96.rst              |   5 +-
>  doc/device-tree-bindings/exynos/dwmmc.txt  |  46 +-
>  drivers/mmc/ca_dw_mmc.c                    |   2 +-
>  drivers/mmc/dw_mmc.c                       | 550 +++++++++++++--------
>  drivers/mmc/exynos_dw_mmc.c                | 358 +++++++++-----
>  drivers/mmc/ftsdc010_mci.h                 |   1 -
>  drivers/mmc/hi6220_dw_mmc.c                |   7 +-
>  drivers/mmc/nexell_dw_mmc.c                |   5 +-
>  drivers/mmc/rockchip_dw_mmc.c              |   5 +-
>  drivers/mmc/s5p_sdhci.c                    |   2 +-
>  drivers/mmc/snps_dw_mmc.c                  |   6 +-
>  drivers/mmc/socfpga_dw_mmc.c               |   4 +-
>  include/dwmmc.h                            | 242 +++++----
>  27 files changed, 868 insertions(+), 537 deletions(-)
>
> --
> 2.39.2
>
Anand Moon June 26, 2024, 4:42 p.m. UTC | #2
Hi Sam,

On Wed, 19 Jun 2024 at 02:26, Sam Protsenko <semen.protsenko@linaro.org> wrote:
>
> If there are no new comments on this series, can you please apply it?
>
> Thanks!

Tested on Odroid XU4 and Odrroid U3 boards

Please add my

Reviewed-by: Anand Moon <linux.amoon@gmail.com>
Tested-by: Anand Moon <linux.amoon@gmail.com>

Thanks
-Anand