From 92d5f99633e4d0a33ea1f22e28674440ddcd7072 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 14 Aug 2023 01:51:27 +0200 Subject: [PATCH 1/4] clk: Add GPIO-controlled clock gate driver Add driver which implements GPIO-controlled clock. The GPIO is used as a gate to enable/disable the clock. This matches linux clk-gpio.c driver, however this does not implement the GPIO mux part, which in U-Boot DM would be better fit in separate driver. Signed-off-by: Marek Vasut Reviewed-by: Sean Anderson --- drivers/clk/Kconfig | 13 +++++++++ drivers/clk/Makefile | 1 + drivers/clk/clk-gpio.c | 66 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 drivers/clk/clk-gpio.c diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 29859cdfa15..bfd23a99046 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -83,6 +83,19 @@ config CLK_COMPOSITE_CCF Enable this option if you want to (re-)use the Linux kernel's Common Clock Framework [CCF] composite code in U-Boot's clock driver. +config CLK_GPIO + bool "GPIO-controlled clock gate driver" + depends on CLK + help + Enable this option to add GPIO-controlled clock gate driver. + +config SPL_CLK_GPIO + bool "GPIO-controlled clock gate driver in SPL" + depends on SPL_CLK + help + Enable this option to add GPIO-controlled clock gate driver + in U-Boot SPL. + config CLK_BCM6345 bool "Clock controller driver for BCM6345" depends on CLK && ARCH_BMIPS diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index e22c8cf291f..26bf429acbc 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk_fixed_factor.o obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk.o clk-divider.o clk-mux.o clk-gate.o obj-$(CONFIG_$(SPL_TPL_)CLK_CCF) += clk-fixed-factor.o obj-$(CONFIG_$(SPL_TPL_)CLK_COMPOSITE_CCF) += clk-composite.o +obj-$(CONFIG_$(SPL_TPL_)CLK_GPIO) += clk-gpio.o obj-y += analogbits/ obj-y += imx/ diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c new file mode 100644 index 00000000000..26d795b9783 --- /dev/null +++ b/drivers/clk/clk-gpio.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Marek Vasut + */ + +#include +#include +#include +#include + +struct clk_gpio_priv { + struct gpio_desc enable; +}; + +static int clk_gpio_enable(struct clk *clk) +{ + struct clk_gpio_priv *priv = dev_get_priv(clk->dev); + + dm_gpio_set_value(&priv->enable, 1); + + return 0; +} + +static int clk_gpio_disable(struct clk *clk) +{ + struct clk_gpio_priv *priv = dev_get_priv(clk->dev); + + dm_gpio_set_value(&priv->enable, 0); + + return 0; +} + +const struct clk_ops clk_gpio_ops = { + .enable = clk_gpio_enable, + .disable = clk_gpio_disable, +}; + +static int clk_gpio_probe(struct udevice *dev) +{ + struct clk_gpio_priv *priv = dev_get_priv(dev); + + return gpio_request_by_name(dev, "enable-gpios", 0, + &priv->enable, GPIOD_IS_OUT); +} + +/* + * When implementing clk-mux-clock, use gpio_request_list_by_name + * and implement get_rate/set_rate/set_parent ops. This should be + * in a separate driver and with separate Kconfig option to enable + * that driver, since unlike Linux implementation, the U-Boot DM + * integration would be orthogonal to this driver. + */ +static const struct udevice_id clk_gpio_match[] = { + { .compatible = "gpio-gate-clock" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(gpio_gate_clock) = { + .name = "gpio_clock", + .id = UCLASS_CLK, + .of_match = clk_gpio_match, + .probe = clk_gpio_probe, + .priv_auto = sizeof(struct clk_gpio_priv), + .ops = &clk_gpio_ops, + .flags = DM_FLAG_PRE_RELOC, +}; From 19f627eceaf80f048dad93c5e132787b46faa17a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 22 Aug 2023 03:47:13 +0200 Subject: [PATCH 2/4] ufs: ufs-renesas: Add support for Renesas R-Car UFS controller Add support for Renesas R-Car UFS controller which needs vendor-specific initialization. Ported from Linux kernel as of commit c2ab666072bc ("scsi: ufs: Explicitly include correct DT includes") Signed-off-by: Marek Vasut Reviewed-by: Tom Rini --- drivers/ufs/Kconfig | 9 + drivers/ufs/Makefile | 1 + drivers/ufs/ufs-renesas.c | 413 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 423 insertions(+) create mode 100644 drivers/ufs/ufs-renesas.c diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig index 69ea18edf8d..0e0cc58e3d6 100644 --- a/drivers/ufs/Kconfig +++ b/drivers/ufs/Kconfig @@ -21,4 +21,13 @@ config TI_J721E_UFS This selects the glue layer driver for Cadence controller present on TI's J721E devices. +config UFS_RENESAS + bool "Renesas specific hooks to UFS controller platform driver" + depends on UFS + select BOUNCE_BUFFER + help + This selects the Renesas specific additions to UFSHCD platform driver. + UFS host on Renesas needs some vendor specific configuration before + accessing the hardware. + endmenu diff --git a/drivers/ufs/Makefile b/drivers/ufs/Makefile index 62ed0166084..4f3344fd4e4 100644 --- a/drivers/ufs/Makefile +++ b/drivers/ufs/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_UFS) += ufs.o ufs-uclass.o obj-$(CONFIG_CADENCE_UFS) += cdns-platform.o obj-$(CONFIG_TI_J721E_UFS) += ti-j721e-ufs.o +obj-$(CONFIG_UFS_RENESAS) += ufs-renesas.o diff --git a/drivers/ufs/ufs-renesas.c b/drivers/ufs/ufs-renesas.c new file mode 100644 index 00000000000..f6086050cde --- /dev/null +++ b/drivers/ufs/ufs-renesas.c @@ -0,0 +1,413 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Renesas UFS host controller driver + * + * Copyright (C) 2022 Renesas Electronics Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ufs.h" + +struct ufs_renesas_priv { + struct clk_bulk clks; + bool initialized; /* The hardware needs initialization once */ +}; + +enum { + SET_PHY_INDEX_LO = 0, + SET_PHY_INDEX_HI, + TIMER_INDEX, + MAX_INDEX +}; + +enum ufs_renesas_init_param_mode { + MODE_RESTORE, + MODE_SET, + MODE_SAVE, + MODE_POLL, + MODE_WAIT, + MODE_WRITE, +}; + +#define PARAM_RESTORE(_reg, _index) \ + { .mode = MODE_RESTORE, .reg = _reg, .index = _index } +#define PARAM_SET(_index, _set) \ + { .mode = MODE_SET, .index = _index, .u.set = _set } +#define PARAM_SAVE(_reg, _mask, _index) \ + { .mode = MODE_SAVE, .reg = _reg, .mask = (u32)(_mask), \ + .index = _index } +#define PARAM_POLL(_reg, _expected, _mask) \ + { .mode = MODE_POLL, .reg = _reg, .u.expected = _expected, \ + .mask = (u32)(_mask) } +#define PARAM_WAIT(_delay_us) \ + { .mode = MODE_WAIT, .u.delay_us = _delay_us } + +#define PARAM_WRITE(_reg, _val) \ + { .mode = MODE_WRITE, .reg = _reg, .u.val = _val } + +#define PARAM_WRITE_D0_D4(_d0, _d4) \ + PARAM_WRITE(0xd0, _d0), PARAM_WRITE(0xd4, _d4) + +#define PARAM_WRITE_800_80C_POLL(_addr, _data_800) \ + PARAM_WRITE_D0_D4(0x0000080c, 0x00000100), \ + PARAM_WRITE_D0_D4(0x00000800, ((_data_800) << 16) | BIT(8) | (_addr)), \ + PARAM_WRITE(0xd0, 0x0000080c), \ + PARAM_POLL(0xd4, BIT(8), BIT(8)) + +#define PARAM_RESTORE_800_80C_POLL(_index) \ + PARAM_WRITE_D0_D4(0x0000080c, 0x00000100), \ + PARAM_WRITE(0xd0, 0x00000800), \ + PARAM_RESTORE(0xd4, (_index)), \ + PARAM_WRITE(0xd0, 0x0000080c), \ + PARAM_POLL(0xd4, BIT(8), BIT(8)) + +#define PARAM_WRITE_804_80C_POLL(_addr, _data_804) \ + PARAM_WRITE_D0_D4(0x0000080c, 0x00000100), \ + PARAM_WRITE_D0_D4(0x00000804, ((_data_804) << 16) | BIT(8) | (_addr)), \ + PARAM_WRITE(0xd0, 0x0000080c), \ + PARAM_POLL(0xd4, BIT(8), BIT(8)) + +#define PARAM_WRITE_828_82C_POLL(_data_828) \ + PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000), \ + PARAM_WRITE_D0_D4(0x00000828, _data_828), \ + PARAM_WRITE(0xd0, 0x0000082c), \ + PARAM_POLL(0xd4, _data_828, _data_828) + +#define PARAM_WRITE_PHY(_addr16, _data16) \ + PARAM_WRITE(0xf0, 1), \ + PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \ + PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \ + PARAM_WRITE_800_80C_POLL(0x18, (_data16) & 0xff), \ + PARAM_WRITE_800_80C_POLL(0x19, ((_data16) >> 8) & 0xff), \ + PARAM_WRITE_800_80C_POLL(0x1c, 0x01), \ + PARAM_WRITE_828_82C_POLL(0x0f000000), \ + PARAM_WRITE(0xf0, 0) + +#define PARAM_SET_PHY(_addr16, _data16) \ + PARAM_WRITE(0xf0, 1), \ + PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \ + PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \ + PARAM_WRITE_800_80C_POLL(0x1c, 0x01), \ + PARAM_WRITE_828_82C_POLL(0x0f000000), \ + PARAM_WRITE_804_80C_POLL(0x1a, 0), \ + PARAM_WRITE(0xd0, 0x00000808), \ + PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_LO), \ + PARAM_WRITE_804_80C_POLL(0x1b, 0), \ + PARAM_WRITE(0xd0, 0x00000808), \ + PARAM_SAVE(0xd4, 0xff, SET_PHY_INDEX_HI), \ + PARAM_WRITE_828_82C_POLL(0x0f000000), \ + PARAM_WRITE(0xf0, 0), \ + PARAM_WRITE(0xf0, 1), \ + PARAM_WRITE_800_80C_POLL(0x16, (_addr16) & 0xff), \ + PARAM_WRITE_800_80C_POLL(0x17, ((_addr16) >> 8) & 0xff), \ + PARAM_SET(SET_PHY_INDEX_LO, (((_data16) & 0xff) << 16) | BIT(8) | 0x18), \ + PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_LO), \ + PARAM_SET(SET_PHY_INDEX_HI, ((((_data16) >> 8) & 0xff) << 16) | BIT(8) | 0x19), \ + PARAM_RESTORE_800_80C_POLL(SET_PHY_INDEX_HI), \ + PARAM_WRITE_800_80C_POLL(0x1c, 0x01), \ + PARAM_WRITE_828_82C_POLL(0x0f000000), \ + PARAM_WRITE(0xf0, 0) + +#define PARAM_INDIRECT_WRITE(_gpio, _addr, _data_800) \ + PARAM_WRITE(0xf0, _gpio), \ + PARAM_WRITE_800_80C_POLL((_addr), _data_800), \ + PARAM_WRITE_828_82C_POLL(0x0f000000), \ + PARAM_WRITE(0xf0, 0) + +#define PARAM_INDIRECT_POLL(_gpio, _addr, _expected, _mask) \ + PARAM_WRITE(0xf0, _gpio), \ + PARAM_WRITE_800_80C_POLL((_addr), 0), \ + PARAM_WRITE(0xd0, 0x00000808), \ + PARAM_POLL(0xd4, (_expected), (_mask)), \ + PARAM_WRITE(0xf0, 0) + +struct ufs_renesas_init_param { + enum ufs_renesas_init_param_mode mode; + u32 reg; + union { + u32 expected; + u32 delay_us; + u32 set; + u32 val; + } u; + u32 mask; + u32 index; +}; + +/* This setting is for SERIES B */ +static const struct ufs_renesas_init_param ufs_param[] = { + PARAM_WRITE(0xc0, 0x49425308), + PARAM_WRITE_D0_D4(0x00000104, 0x00000002), + PARAM_WAIT(1), + PARAM_WRITE_D0_D4(0x00000828, 0x00000200), + PARAM_WAIT(1), + PARAM_WRITE_D0_D4(0x00000828, 0x00000000), + PARAM_WRITE_D0_D4(0x00000104, 0x00000001), + PARAM_WRITE_D0_D4(0x00000940, 0x00000001), + PARAM_WAIT(1), + PARAM_WRITE_D0_D4(0x00000940, 0x00000000), + + PARAM_WRITE(0xc0, 0x49425308), + PARAM_WRITE(0xc0, 0x41584901), + + PARAM_WRITE_D0_D4(0x0000080c, 0x00000100), + PARAM_WRITE_D0_D4(0x00000804, 0x00000000), + PARAM_WRITE(0xd0, 0x0000080c), + PARAM_POLL(0xd4, BIT(8), BIT(8)), + + PARAM_WRITE(REG_CONTROLLER_ENABLE, 0x00000001), + + PARAM_WRITE(0xd0, 0x00000804), + PARAM_POLL(0xd4, BIT(8) | BIT(6) | BIT(0), BIT(8) | BIT(6) | BIT(0)), + + PARAM_WRITE(0xd0, 0x00000d00), + PARAM_SAVE(0xd4, 0x0000ffff, TIMER_INDEX), + PARAM_WRITE(0xd4, 0x00000000), + PARAM_WRITE_D0_D4(0x0000082c, 0x0f000000), + PARAM_WRITE_D0_D4(0x00000828, 0x08000000), + PARAM_WRITE(0xd0, 0x0000082c), + PARAM_POLL(0xd4, BIT(27), BIT(27)), + PARAM_WRITE(0xd0, 0x00000d2c), + PARAM_POLL(0xd4, BIT(0), BIT(0)), + + /* phy setup */ + PARAM_INDIRECT_WRITE(1, 0x01, 0x001f), + PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014), + PARAM_INDIRECT_WRITE(7, 0x5e, 0x0014), + PARAM_INDIRECT_WRITE(7, 0x0d, 0x0003), + PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007), + PARAM_INDIRECT_WRITE(7, 0x5f, 0x0003), + PARAM_INDIRECT_WRITE(7, 0x60, 0x0003), + PARAM_INDIRECT_WRITE(7, 0x5b, 0x00a6), + PARAM_INDIRECT_WRITE(7, 0x5c, 0x0003), + + PARAM_INDIRECT_POLL(7, 0x3c, 0, BIT(7)), + PARAM_INDIRECT_POLL(7, 0x4c, 0, BIT(4)), + + PARAM_INDIRECT_WRITE(1, 0x32, 0x0080), + PARAM_INDIRECT_WRITE(1, 0x1f, 0x0001), + PARAM_INDIRECT_WRITE(0, 0x2c, 0x0001), + PARAM_INDIRECT_WRITE(0, 0x32, 0x0087), + + PARAM_INDIRECT_WRITE(1, 0x4d, 0x0061), + PARAM_INDIRECT_WRITE(4, 0x9b, 0x0009), + PARAM_INDIRECT_WRITE(4, 0xa6, 0x0005), + PARAM_INDIRECT_WRITE(4, 0xa5, 0x0058), + PARAM_INDIRECT_WRITE(1, 0x39, 0x0027), + PARAM_INDIRECT_WRITE(1, 0x47, 0x004c), + + PARAM_INDIRECT_WRITE(7, 0x0d, 0x0002), + PARAM_INDIRECT_WRITE(7, 0x0e, 0x0007), + + PARAM_WRITE_PHY(0x0028, 0x0061), + PARAM_WRITE_PHY(0x4014, 0x0061), + PARAM_SET_PHY(0x401c, BIT(2)), + PARAM_WRITE_PHY(0x4000, 0x0000), + PARAM_WRITE_PHY(0x4001, 0x0000), + + PARAM_WRITE_PHY(0x10ae, 0x0001), + PARAM_WRITE_PHY(0x10ad, 0x0000), + PARAM_WRITE_PHY(0x10af, 0x0001), + PARAM_WRITE_PHY(0x10b6, 0x0001), + PARAM_WRITE_PHY(0x10ae, 0x0000), + + PARAM_WRITE_PHY(0x10ae, 0x0001), + PARAM_WRITE_PHY(0x10ad, 0x0000), + PARAM_WRITE_PHY(0x10af, 0x0002), + PARAM_WRITE_PHY(0x10b6, 0x0001), + PARAM_WRITE_PHY(0x10ae, 0x0000), + + PARAM_WRITE_PHY(0x10ae, 0x0001), + PARAM_WRITE_PHY(0x10ad, 0x0080), + PARAM_WRITE_PHY(0x10af, 0x0000), + PARAM_WRITE_PHY(0x10b6, 0x0001), + PARAM_WRITE_PHY(0x10ae, 0x0000), + + PARAM_WRITE_PHY(0x10ae, 0x0001), + PARAM_WRITE_PHY(0x10ad, 0x0080), + PARAM_WRITE_PHY(0x10af, 0x001a), + PARAM_WRITE_PHY(0x10b6, 0x0001), + PARAM_WRITE_PHY(0x10ae, 0x0000), + + PARAM_INDIRECT_WRITE(7, 0x70, 0x0016), + PARAM_INDIRECT_WRITE(7, 0x71, 0x0016), + PARAM_INDIRECT_WRITE(7, 0x72, 0x0014), + PARAM_INDIRECT_WRITE(7, 0x73, 0x0014), + PARAM_INDIRECT_WRITE(7, 0x74, 0x0000), + PARAM_INDIRECT_WRITE(7, 0x75, 0x0000), + PARAM_INDIRECT_WRITE(7, 0x76, 0x0010), + PARAM_INDIRECT_WRITE(7, 0x77, 0x0010), + PARAM_INDIRECT_WRITE(7, 0x78, 0x00ff), + PARAM_INDIRECT_WRITE(7, 0x79, 0x0000), + + PARAM_INDIRECT_WRITE(7, 0x19, 0x0007), + + PARAM_INDIRECT_WRITE(7, 0x1a, 0x0007), + + PARAM_INDIRECT_WRITE(7, 0x24, 0x000c), + + PARAM_INDIRECT_WRITE(7, 0x25, 0x000c), + + PARAM_INDIRECT_WRITE(7, 0x62, 0x0000), + PARAM_INDIRECT_WRITE(7, 0x63, 0x0000), + PARAM_INDIRECT_WRITE(7, 0x5d, 0x0014), + PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017), + PARAM_INDIRECT_WRITE(7, 0x5d, 0x0004), + PARAM_INDIRECT_WRITE(7, 0x5e, 0x0017), + PARAM_INDIRECT_POLL(7, 0x55, 0, BIT(6)), + PARAM_INDIRECT_POLL(7, 0x41, 0, BIT(7)), + /* end of phy setup */ + + PARAM_WRITE(0xf0, 0), + PARAM_WRITE(0xd0, 0x00000d00), + PARAM_RESTORE(0xd4, TIMER_INDEX), +}; + +static void ufs_renesas_reg_control(struct ufs_hba *hba, + const struct ufs_renesas_init_param *p) +{ + static u32 save[MAX_INDEX]; + int ret; + u32 val; + + WARN_ON(p->index >= MAX_INDEX); + + switch (p->mode) { + case MODE_RESTORE: + ufshcd_writel(hba, save[p->index], p->reg); + break; + case MODE_SET: + save[p->index] |= p->u.set; + break; + case MODE_SAVE: + save[p->index] = ufshcd_readl(hba, p->reg) & p->mask; + break; + case MODE_POLL: + ret = readl_poll_timeout(hba->mmio_base + p->reg, val, + (val & p->mask) == p->u.expected, + 10000); + if (ret) + dev_err(hba->dev, "%s: poll failed %d (%08x, %08x, %08x)\n", + __func__, ret, val, p->mask, p->u.expected); + break; + case MODE_WAIT: + if (p->u.delay_us > 1000) + mdelay(DIV_ROUND_UP(p->u.delay_us, 1000)); + else + udelay(p->u.delay_us); + break; + case MODE_WRITE: + ufshcd_writel(hba, p->u.val, p->reg); + break; + default: + break; + } +} + +static void ufs_renesas_pre_init(struct ufs_hba *hba) +{ + const struct ufs_renesas_init_param *p = ufs_param; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(ufs_param); i++) + ufs_renesas_reg_control(hba, &p[i]); +} + +static int ufs_renesas_hce_enable_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status) +{ + struct ufs_renesas_priv *priv = dev_get_priv(hba->dev); + + if (priv->initialized) + return 0; + + if (status == PRE_CHANGE) + ufs_renesas_pre_init(hba); + + priv->initialized = true; + + return 0; +} + +static int ufs_renesas_init(struct ufs_hba *hba) +{ + hba->quirks |= UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS | UFSHCD_QUIRK_HIBERN_FASTAUTO; + + return 0; +} + +static struct ufs_hba_ops ufs_renesas_vops = { + .init = ufs_renesas_init, + .hce_enable_notify = ufs_renesas_hce_enable_notify, +}; + +static int ufs_renesas_pltfm_bind(struct udevice *dev) +{ + struct udevice *scsi_dev; + + return ufs_scsi_bind(dev, &scsi_dev); +} + +static int ufs_renesas_pltfm_probe(struct udevice *dev) +{ + struct ufs_renesas_priv *priv = dev_get_priv(dev); + int err; + + err = clk_get_bulk(dev, &priv->clks); + if (err < 0) + return err; + + err = clk_enable_bulk(&priv->clks); + if (err) + goto err_clk_enable; + + err = ufshcd_probe(dev, &ufs_renesas_vops); + if (err) { + dev_err(dev, "ufshcd_probe() failed %d\n", err); + goto err_ufshcd_probe; + } + + return 0; + +err_ufshcd_probe: + clk_disable_bulk(&priv->clks); +err_clk_enable: + clk_release_bulk(&priv->clks); + return err; +} + +static int ufs_renesas_pltfm_remove(struct udevice *dev) +{ + struct ufs_renesas_priv *priv = dev_get_priv(dev); + + clk_disable_bulk(&priv->clks); + clk_release_bulk(&priv->clks); + + return 0; +} + +static const struct udevice_id ufs_renesas_pltfm_ids[] = { + { .compatible = "renesas,r8a779f0-ufs" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(ufs_renesas) = { + .name = "ufs-renesas", + .id = UCLASS_UFS, + .of_match = ufs_renesas_pltfm_ids, + .bind = ufs_renesas_pltfm_bind, + .probe = ufs_renesas_pltfm_probe, + .remove = ufs_renesas_pltfm_remove, + .priv_auto = sizeof(struct ufs_renesas_priv), +}; From 9a059a3af59cfffe7f1a6f025391c3fe0a5a0abf Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Tue, 22 Aug 2023 03:47:56 +0200 Subject: [PATCH 3/4] ARM: renesas: Enable UFS on R8A779F0 S4 Spider Enable UFS controller driver and matching UFS and SCSI commands. The former is used to initialize the device, the later is used to perform low level access to the SCSI interface of the UFS device. Enable R8A779F0 S4 Spider specific dependencies, the PCA953x driver and GPIO clock gate driver. This setup is used to toggle 38.4 MHz clock for the UFS controller. Enable support for 48bit LBA in block layer to address disks larger than 512*2^32 ~= 144 PiB. Enable use of 64bit LBA variables in the rest of U-Boot, instead of the default 32bit ones. Increase FAT cluster size to 128k as that is what is used by the filesystem that is populated on the UFS device. Use 'ufs init && scsi scan' to start the UFS device from U-Boot prompt. Signed-off-by: Marek Vasut --- configs/r8a779f0_spider_defconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/configs/r8a779f0_spider_defconfig b/configs/r8a779f0_spider_defconfig index 0edacc4d569..f250d1a13c1 100644 --- a/configs/r8a779f0_spider_defconfig +++ b/configs/r8a779f0_spider_defconfig @@ -31,7 +31,9 @@ CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y CONFIG_CMD_SPI=y +CONFIG_CMD_UFS=y CONFIG_CMD_DHCP=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y @@ -46,9 +48,13 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_VERSION_VARIABLE=y CONFIG_REGMAP=y CONFIG_SYSCON=y +CONFIG_LBA48=y +CONFIG_SYS_64BIT_LBA=y CONFIG_CLK=y +CONFIG_CLK_GPIO=y CONFIG_CLK_RENESAS=y CONFIG_RCAR_GPIO=y +CONFIG_DM_PCA953X=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_RCAR_I2C=y CONFIG_MMC_IO_VOLTAGE=y @@ -67,8 +73,13 @@ CONFIG_PHY_R8A779F0_ETHERNET_SERDES=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y CONFIG_BAUDRATE=1843200 CONFIG_SCIF_CONSOLE=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_RENESAS_RPC_SPI=y +CONFIG_UFS=y +CONFIG_UFS_RENESAS=y +CONFIG_FS_FAT_MAX_CLUSTSIZE=131072 From cad6abff2937b8f4e14c40fe82c36804e01ca38b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 Sep 2023 04:54:35 +0200 Subject: [PATCH 4/4] ufs: ufs-renesas: Drop include common.h The "#include " is being phased out in favor of more fine grained header management, i.e. ideally include a subset of headers that are really needed. Remove it from this driver. Signed-off-by: Marek Vasut Reviewed-by: Tom Rini --- drivers/ufs/ufs-renesas.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ufs/ufs-renesas.c b/drivers/ufs/ufs-renesas.c index f6086050cde..ae05bdc8102 100644 --- a/drivers/ufs/ufs-renesas.c +++ b/drivers/ufs/ufs-renesas.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include