From 099c9a47c9dec8fde66c253fd8e1eca6c1e33a9e Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 13 Mar 2021 09:46:32 -0600 Subject: [PATCH 01/14] configs: omap35_logic_somlv: Fix MMC booting A previous patch had removed the GPIO nodes from being built into the SPL Device tree, but CONFIG_SPL_GPIO_SUPPORT remained which makes the MMC card detect fail and the board does not boot. Fix this by disabling CONFIG_SPL_GPIO_SUPPORT. Fixes: 6f1efe81aa84 ("configs: omap3/35_logic and omap3/35_logic_somlv: Reduce SPL size") Signed-off-by: Adam Ford --- configs/omap35_logic_somlv_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/omap35_logic_somlv_defconfig b/configs/omap35_logic_somlv_defconfig index e6655c7828d..a8eab408f6e 100644 --- a/configs/omap35_logic_somlv_defconfig +++ b/configs/omap35_logic_somlv_defconfig @@ -4,6 +4,7 @@ CONFIG_ARM=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_TEXT_BASE=0x80100000 CONFIG_TI_COMMON_CMD_OPTIONS=y +# CONFIG_SPL_GPIO_SUPPORT is not set CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_NR_DRAM_BANKS=2 CONFIG_SPL_TEXT_BASE=0x40200000 From 4ace4fa697a84a18fc1c414842fd100e4d3690ae Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:39 +0200 Subject: [PATCH 02/14] pinctrl: single: fix format of structure documentation U-Boot adopted the kernel-doc annotation style. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-single.c | 45 +++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 20c3c82aa98..c9a6c272bff 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -10,23 +10,50 @@ #include #include +/** + * struct single_pdata - platform data + * @base: first configuration register + * @offset: index of last configuration register + * @mask: configuration-value mask bits + * @width: configuration register bit width + * @bits_per_mux: true if one register controls more than one pin + */ struct single_pdata { - fdt_addr_t base; /* first configuration register */ - int offset; /* index of last configuration register */ - u32 mask; /* configuration-value mask bits */ - int width; /* configuration register bit width */ + fdt_addr_t base; + int offset; + u32 mask; + int width; bool bits_per_mux; }; +/** + * struct single_fdt_pin_cfg - pin configuration + * + * This structure is used for the pin configuration parameters in case + * the register controls only one pin. + * + * @reg: configuration register offset + * @val: configuration register value + */ struct single_fdt_pin_cfg { - fdt32_t reg; /* configuration register offset */ - fdt32_t val; /* configuration register value */ + fdt32_t reg; + fdt32_t val; }; +/** + * struct single_fdt_bits_cfg - pin configuration + * + * This structure is used for the pin configuration parameters in case + * the register controls more than one pin. + * + * @reg: configuration register offset + * @val: configuration register value + * @mask: configuration register mask + */ struct single_fdt_bits_cfg { - fdt32_t reg; /* configuration register offset */ - fdt32_t val; /* configuration register value */ - fdt32_t mask; /* configuration register mask */ + fdt32_t reg; + fdt32_t val; + fdt32_t mask; }; /** From 6719294694bf65c1ec9b0ccd15e204f46eb0d6b0 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:40 +0200 Subject: [PATCH 03/14] pinctrl: single: fix the loop counter variable type The 'n' variable is used as a loop counter, not as a physical address, and is used in a comparison with an int. So it makes sense to change its type from phys_addr_t to int. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass Reviewed-by: Pratyush Yadav --- drivers/pinctrl/pinctrl-single.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index c9a6c272bff..49ed15211d4 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -75,8 +75,8 @@ static int single_configure_pins(struct udevice *dev, int size) { struct single_pdata *pdata = dev_get_plat(dev); - int count = size / sizeof(struct single_fdt_pin_cfg); - phys_addr_t n, reg; + int n, count = size / sizeof(struct single_fdt_pin_cfg); + phys_addr_t reg; u32 val; for (n = 0; n < count; n++, pins++) { @@ -109,8 +109,8 @@ static int single_configure_bits(struct udevice *dev, int size) { struct single_pdata *pdata = dev_get_plat(dev); - int count = size / sizeof(struct single_fdt_bits_cfg); - phys_addr_t n, reg; + int n, count = size / sizeof(struct single_fdt_bits_cfg); + phys_addr_t reg; u32 val, mask; for (n = 0; n < count; n++, pins++) { From 9b884e79a6ac8cededabc3eced318d212a9c8fc3 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:41 +0200 Subject: [PATCH 04/14] pinctrl: single: fix offset management The pinmux configuration DT node of a peripheral does not define a physical address but an offset. Only by adding it to the base address of the controller it is possible to calculate the physical address of the register to be configured. Printing an offset also requires a different formatting option than a physical address. Signed-off-by: Dario Binacchi Reviewed-by: Pratyush Yadav --- drivers/pinctrl/pinctrl-single.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 49ed15211d4..935b5e920d7 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -77,15 +77,17 @@ static int single_configure_pins(struct udevice *dev, struct single_pdata *pdata = dev_get_plat(dev); int n, count = size / sizeof(struct single_fdt_pin_cfg); phys_addr_t reg; - u32 val; + u32 offset, val; for (n = 0; n < count; n++, pins++) { - reg = fdt32_to_cpu(pins->reg); - if ((reg < 0) || (reg > pdata->offset)) { - dev_dbg(dev, " invalid register offset 0x%pa\n", ®); + offset = fdt32_to_cpu(pins->reg); + if (offset < 0 || offset > pdata->offset) { + dev_dbg(dev, " invalid register offset 0x%x\n", + offset); continue; } - reg += pdata->base; + + reg = pdata->base + offset; val = fdt32_to_cpu(pins->val) & pdata->mask; switch (pdata->width) { case 16: @@ -111,15 +113,17 @@ static int single_configure_bits(struct udevice *dev, struct single_pdata *pdata = dev_get_plat(dev); int n, count = size / sizeof(struct single_fdt_bits_cfg); phys_addr_t reg; - u32 val, mask; + u32 offset, val, mask; for (n = 0; n < count; n++, pins++) { - reg = fdt32_to_cpu(pins->reg); - if ((reg < 0) || (reg > pdata->offset)) { - dev_dbg(dev, " invalid register offset 0x%pa\n", ®); + offset = fdt32_to_cpu(pins->reg); + if (offset < 0 || offset > pdata->offset) { + dev_dbg(dev, " invalid register offset 0x%x\n", + offset); continue; } - reg += pdata->base; + + reg = pdata->base + offset; mask = fdt32_to_cpu(pins->mask); val = fdt32_to_cpu(pins->val) & mask; From fcf6a2b30a23a77323b11dedf31526f66b9ea2f2 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:42 +0200 Subject: [PATCH 05/14] pinctrl: single: fix debug messages formatting The dev_dbg(dev, " reg/val 0x%pa/0x%08x\n", ®, val); prints the 'reg' address preceded by the prefix 0x0x instead of 0x. This because the printf '%pa' format specifier already prepends the prefix '0x' to the address displayed. Signed-off-by: Dario Binacchi Reviewed-by: Pratyush Yadav --- drivers/pinctrl/pinctrl-single.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 935b5e920d7..cec00e289c3 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -101,7 +101,7 @@ static int single_configure_pins(struct udevice *dev, pdata->width); continue; } - dev_dbg(dev, " reg/val 0x%pa/0x%08x\n", ®, val); + dev_dbg(dev, " reg/val %pa/0x%08x\n", ®, val); } return 0; } @@ -140,7 +140,7 @@ static int single_configure_bits(struct udevice *dev, pdata->width); continue; } - dev_dbg(dev, " reg/val 0x%pa/0x%08x\n", ®, val); + dev_dbg(dev, " reg/val %pa/0x%08x\n", ®, val); } return 0; } From 9fd8a430f33f1a412a43c12a8b83e19ed91a16fd Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:43 +0200 Subject: [PATCH 06/14] pinctrl: single: get register area size by device API Use dev_read_addr_size to get size of the controller's register area. Signed-off-by: Dario Binacchi Reviewed-by: Pratyush Yadav --- drivers/pinctrl/pinctrl-single.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index cec00e289c3..d5656de8e8a 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -182,17 +182,19 @@ static int single_set_state(struct udevice *dev, static int single_of_to_plat(struct udevice *dev) { fdt_addr_t addr; - u32 of_reg[2]; - int res; + fdt_size_t size; struct single_pdata *pdata = dev_get_plat(dev); pdata->width = dev_read_u32_default(dev, "pinctrl-single,register-width", 0); - res = dev_read_u32_array(dev, "reg", of_reg, 2); - if (res) - return res; - pdata->offset = of_reg[1] - pdata->width / 8; + addr = dev_read_addr_size(dev, "reg", &size); + if (addr == FDT_ADDR_T_NONE) { + dev_err(dev, "failed to get base register size\n"); + return -EINVAL; + } + + pdata->offset = size - pdata->width / BITS_PER_BYTE; addr = dev_read_addr(dev); if (addr == FDT_ADDR_T_NONE) { From 971c64a452f6220f3a9c5f9fc77c4cb1928c38e4 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:44 +0200 Subject: [PATCH 07/14] pinctrl: single: check "register-width" DT property In more recent versions of the Linux kernel the driver's probe function returns an error if the "pinctrl-single,register-width" DT property is missing. The lack of this information, in fact, does not allow to know whether to access the registers of the controller at 8, 16, ... bits. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-single.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index d5656de8e8a..5ade1088755 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -22,7 +22,7 @@ struct single_pdata { fdt_addr_t base; int offset; u32 mask; - int width; + u32 width; bool bits_per_mux; }; @@ -184,9 +184,13 @@ static int single_of_to_plat(struct udevice *dev) fdt_addr_t addr; fdt_size_t size; struct single_pdata *pdata = dev_get_plat(dev); + int ret; - pdata->width = - dev_read_u32_default(dev, "pinctrl-single,register-width", 0); + ret = dev_read_u32(dev, "pinctrl-single,register-width", &pdata->width); + if (ret) { + dev_err(dev, "missing register width\n"); + return ret; + } addr = dev_read_addr_size(dev, "reg", &size); if (addr == FDT_ADDR_T_NONE) { From d85b93e80bb285fd380a8bcb4c4b118d4b5f7b77 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:45 +0200 Subject: [PATCH 08/14] pinctrl: single: change function mask default value The patch is inspired by more recent versions of the Linux driver. Replacing the default value 0xffffffff of the function mask with 0 is certainly more conservative in case the "pinctrl-single,function-mask" DT property is missing. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-single.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 5ade1088755..630a6c08b8d 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -79,6 +79,10 @@ static int single_configure_pins(struct udevice *dev, phys_addr_t reg; u32 offset, val; + /* If function mask is null, needn't enable it. */ + if (!pdata->mask) + return 0; + for (n = 0; n < count; n++, pins++) { offset = fdt32_to_cpu(pins->reg); if (offset < 0 || offset > pdata->offset) { @@ -207,8 +211,12 @@ static int single_of_to_plat(struct udevice *dev) } pdata->base = addr; - pdata->mask = dev_read_u32_default(dev, "pinctrl-single,function-mask", - 0xffffffff); + ret = dev_read_u32(dev, "pinctrl-single,function-mask", &pdata->mask); + if (ret) { + pdata->mask = 0; + dev_warn(dev, "missing function register mask\n"); + } + pdata->bits_per_mux = dev_read_bool(dev, "pinctrl-single,bit-per-mux"); return 0; From 180531fc2f95ea6801cb7248853b9c3d0d0fafe3 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:46 +0200 Subject: [PATCH 09/14] pinctrl: single: add register access functions The configuration of pinmux registers was implemented with duplicate code which can be removed by adding two functions for read/write access. Access to 8-bit registers has also been added. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-single.c | 71 +++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 630a6c08b8d..5b3ccc22812 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -56,6 +56,38 @@ struct single_fdt_bits_cfg { fdt32_t mask; }; +static unsigned int single_read(struct udevice *dev, fdt_addr_t reg) +{ + struct single_pdata *pdata = dev_get_plat(dev); + + switch (pdata->width) { + case 8: + return readb(reg); + case 16: + return readw(reg); + default: /* 32 bits */ + return readl(reg); + } + + return readb(reg); +} + +static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg) +{ + struct single_pdata *pdata = dev_get_plat(dev); + + switch (pdata->width) { + case 8: + writeb(val, reg); + break; + case 16: + writew(val, reg); + break; + default: /* 32 bits */ + writel(val, reg); + } +} + /** * single_configure_pins() - Configure pins based on FDT data * @@ -93,19 +125,10 @@ static int single_configure_pins(struct udevice *dev, reg = pdata->base + offset; val = fdt32_to_cpu(pins->val) & pdata->mask; - switch (pdata->width) { - case 16: - writew((readw(reg) & ~pdata->mask) | val, reg); - break; - case 32: - writel((readl(reg) & ~pdata->mask) | val, reg); - break; - default: - dev_warn(dev, "unsupported register width %i\n", - pdata->width); - continue; - } + single_write(dev, (single_read(dev, reg) & ~pdata->mask) | val, + reg); dev_dbg(dev, " reg/val %pa/0x%08x\n", ®, val); + } return 0; } @@ -131,19 +154,7 @@ static int single_configure_bits(struct udevice *dev, mask = fdt32_to_cpu(pins->mask); val = fdt32_to_cpu(pins->val) & mask; - - switch (pdata->width) { - case 16: - writew((readw(reg) & ~mask) | val, reg); - break; - case 32: - writel((readl(reg) & ~mask) | val, reg); - break; - default: - dev_warn(dev, "unsupported register width %i\n", - pdata->width); - continue; - } + single_write(dev, (single_read(dev, reg) & ~mask) | val, reg); dev_dbg(dev, " reg/val %pa/0x%08x\n", ®, val); } return 0; @@ -196,6 +207,16 @@ static int single_of_to_plat(struct udevice *dev) return ret; } + switch (pdata->width) { + case 8: + case 16: + case 32: + break; + default: + dev_err(dev, "wrong register width\n"); + return -EINVAL; + } + addr = dev_read_addr_size(dev, "reg", &size); if (addr == FDT_ADDR_T_NONE) { dev_err(dev, "failed to get base register size\n"); From 1dd7ae20debc5043a3395d1d1aedc39e7511bb63 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:47 +0200 Subject: [PATCH 10/14] pinctrl: single: add get_pins_count operation It returns the number of selectable pins. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-single.c | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 5b3ccc22812..e99eb552f5b 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -26,6 +26,16 @@ struct single_pdata { bool bits_per_mux; }; +/** + * struct single_priv - private data + * @bits_per_pin: number of bits per pin + * @npins: number of selectable pins + */ +struct single_priv { + unsigned int bits_per_pin; + unsigned int npins; +}; + /** * struct single_fdt_pin_cfg - pin configuration * @@ -194,6 +204,30 @@ static int single_set_state(struct udevice *dev, return len; } +static int single_get_pins_count(struct udevice *dev) +{ + struct single_priv *priv = dev_get_priv(dev); + + return priv->npins; +} + +static int single_probe(struct udevice *dev) +{ + struct single_pdata *pdata = dev_get_plat(dev); + struct single_priv *priv = dev_get_priv(dev); + u32 size; + + size = pdata->offset + pdata->width / BITS_PER_BYTE; + priv->npins = size / (pdata->width / BITS_PER_BYTE); + if (pdata->bits_per_mux) { + priv->bits_per_pin = fls(pdata->mask); + priv->npins *= (pdata->width / priv->bits_per_pin); + } + + dev_dbg(dev, "%d pins\n", priv->npins); + return 0; +} + static int single_of_to_plat(struct udevice *dev) { fdt_addr_t addr; @@ -244,6 +278,7 @@ static int single_of_to_plat(struct udevice *dev) } const struct pinctrl_ops single_pinctrl_ops = { + .get_pins_count = single_get_pins_count, .set_state = single_set_state, }; @@ -258,5 +293,7 @@ U_BOOT_DRIVER(single_pinctrl) = { .of_match = single_pinctrl_match, .ops = &single_pinctrl_ops, .plat_auto = sizeof(struct single_pdata), + .priv_auto = sizeof(struct single_priv), .of_to_plat = single_of_to_plat, + .probe = single_probe, }; From 0b12162910ddcb2debe3f953e8993354afba45d7 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:48 +0200 Subject: [PATCH 11/14] pinctrl: single: add get_pin_name operation It returns the name of the requested pin. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-single.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index e99eb552f5b..cdb5040852f 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -30,10 +30,12 @@ struct single_pdata { * struct single_priv - private data * @bits_per_pin: number of bits per pin * @npins: number of selectable pins + * @pin_name: temporary buffer to store the pin name */ struct single_priv { unsigned int bits_per_pin; unsigned int npins; + char pin_name[PINNAME_SIZE]; }; /** @@ -204,6 +206,19 @@ static int single_set_state(struct udevice *dev, return len; } +static const char *single_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + struct single_priv *priv = dev_get_priv(dev); + + if (selector >= priv->npins) + snprintf(priv->pin_name, PINNAME_SIZE, "Error"); + else + snprintf(priv->pin_name, PINNAME_SIZE, "PIN%u", selector); + + return priv->pin_name; +} + static int single_get_pins_count(struct udevice *dev) { struct single_priv *priv = dev_get_priv(dev); @@ -279,6 +294,7 @@ static int single_of_to_plat(struct udevice *dev) const struct pinctrl_ops single_pinctrl_ops = { .get_pins_count = single_get_pins_count, + .get_pin_name = single_get_pin_name, .set_state = single_set_state, }; From 76d470de1a3c323823f5c4096a797e366cd225b0 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:49 +0200 Subject: [PATCH 12/14] pinctrl: single: add get_pin_muxing operation It allows to display the muxing of a given pin. Inspired by more recent versions of the Linux driver, in addition to the address and the value of the configuration register I added the pin function retrieved from the DT. In doing so, the information displayed does not depend on the platform, being a generic type driver, and it can be useful for debug purposes. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- drivers/pinctrl/pinctrl-single.c | 222 +++++++++++++++++++++++++++++-- 1 file changed, 213 insertions(+), 9 deletions(-) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index cdb5040852f..3ddb637ab77 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1,14 +1,18 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) EETS GmbH, 2017, Felix Brack + * Copyright (C) 2021 Dario Binacchi */ #include #include #include +#include #include #include +#include #include +#include /** * struct single_pdata - platform data @@ -26,6 +30,20 @@ struct single_pdata { bool bits_per_mux; }; +/** + * struct single_func - pinctrl function + * @node: list node + * @name: pinctrl function name + * @npins: number of entries in pins array + * @pins: pins array + */ +struct single_func { + struct list_head node; + const char *name; + unsigned int npins; + unsigned int *pins; +}; + /** * struct single_priv - private data * @bits_per_pin: number of bits per pin @@ -36,6 +54,7 @@ struct single_priv { unsigned int bits_per_pin; unsigned int npins; char pin_name[PINNAME_SIZE]; + struct list_head functions; }; /** @@ -100,6 +119,121 @@ static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg) } } +/** + * single_get_pin_by_offset() - get a pin based on the register offset + * @dev: single driver instance + * @offset: register offset from the base + */ +static int single_get_pin_by_offset(struct udevice *dev, unsigned int offset) +{ + struct single_pdata *pdata = dev_get_plat(dev); + struct single_priv *priv = dev_get_priv(dev); + + if (offset > pdata->offset) { + dev_err(dev, "mux offset out of range: 0x%x (0x%x)\n", + offset, pdata->offset); + return -EINVAL; + } + + if (pdata->bits_per_mux) + return (offset * BITS_PER_BYTE) / priv->bits_per_pin; + + return offset / (pdata->width / BITS_PER_BYTE); +} + +static int single_get_offset_by_pin(struct udevice *dev, unsigned int pin) +{ + struct single_pdata *pdata = dev_get_plat(dev); + struct single_priv *priv = dev_get_priv(dev); + unsigned int mux_bytes; + + if (pin >= priv->npins) + return -EINVAL; + + mux_bytes = pdata->width / BITS_PER_BYTE; + if (pdata->bits_per_mux) { + int byte_num; + + byte_num = (priv->bits_per_pin * pin) / BITS_PER_BYTE; + return (byte_num / mux_bytes) * mux_bytes; + } + + return pin * mux_bytes; +} + +static const char *single_get_pin_function(struct udevice *dev, + unsigned int pin) +{ + struct single_priv *priv = dev_get_priv(dev); + struct single_func *func; + int i; + + list_for_each_entry(func, &priv->functions, node) { + for (i = 0; i < func->npins; i++) { + if (pin == func->pins[i]) + return func->name; + + if (pin < func->pins[i]) + break; + } + } + + return NULL; +} + +static int single_get_pin_muxing(struct udevice *dev, unsigned int pin, + char *buf, int size) +{ + struct single_pdata *pdata = dev_get_plat(dev); + struct single_priv *priv = dev_get_priv(dev); + fdt_addr_t reg; + const char *fname; + unsigned int val; + int offset, pin_shift = 0; + + offset = single_get_offset_by_pin(dev, pin); + if (offset < 0) + return offset; + + reg = pdata->base + offset; + val = single_read(dev, reg); + + if (pdata->bits_per_mux) + pin_shift = pin % (pdata->width / priv->bits_per_pin) * + priv->bits_per_pin; + + val &= (pdata->mask << pin_shift); + fname = single_get_pin_function(dev, pin); + snprintf(buf, size, "%pa 0x%08x %s", ®, val, + fname ? fname : "UNCLAIMED"); + return 0; +} + +static struct single_func *single_allocate_function(struct udevice *dev, + unsigned int group_pins) +{ + struct single_func *func; + + func = devm_kmalloc(dev, sizeof(*func), GFP_KERNEL); + if (!func) + return ERR_PTR(-ENOMEM); + + func->pins = devm_kmalloc(dev, sizeof(unsigned int) * group_pins, + GFP_KERNEL); + if (!func->pins) + return ERR_PTR(-ENOMEM); + + return func; +} + +static int single_pin_compare(const void *s1, const void *s2) +{ + int pin1 = *(const unsigned int *)s1; + int pin2 = *(const unsigned int *)s2; + + return pin1 - pin2; +} + /** * single_configure_pins() - Configure pins based on FDT data * @@ -113,13 +247,16 @@ static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg) * @size: Size of the 'pins' array in bytes. * The number of register/value pairs in the 'pins' array therefore * equals to 'size / sizeof(struct single_fdt_pin_cfg)'. + * @fname: Function name. */ static int single_configure_pins(struct udevice *dev, const struct single_fdt_pin_cfg *pins, - int size) + int size, const char *fname) { struct single_pdata *pdata = dev_get_plat(dev); - int n, count = size / sizeof(struct single_fdt_pin_cfg); + struct single_priv *priv = dev_get_priv(dev); + int n, pin, count = size / sizeof(struct single_fdt_pin_cfg); + struct single_func *func; phys_addr_t reg; u32 offset, val; @@ -127,33 +264,61 @@ static int single_configure_pins(struct udevice *dev, if (!pdata->mask) return 0; + func = single_allocate_function(dev, count); + if (IS_ERR(func)) + return PTR_ERR(func); + + func->name = fname; + func->npins = 0; for (n = 0; n < count; n++, pins++) { offset = fdt32_to_cpu(pins->reg); if (offset < 0 || offset > pdata->offset) { - dev_dbg(dev, " invalid register offset 0x%x\n", + dev_err(dev, " invalid register offset 0x%x\n", offset); continue; } reg = pdata->base + offset; val = fdt32_to_cpu(pins->val) & pdata->mask; + pin = single_get_pin_by_offset(dev, offset); + if (pin < 0) { + dev_err(dev, " failed to get pin by offset %x\n", + offset); + continue; + } + single_write(dev, (single_read(dev, reg) & ~pdata->mask) | val, reg); dev_dbg(dev, " reg/val %pa/0x%08x\n", ®, val); - + func->pins[func->npins] = pin; + func->npins++; } + + qsort(func->pins, func->npins, sizeof(func->pins[0]), + single_pin_compare); + list_add(&func->node, &priv->functions); return 0; } static int single_configure_bits(struct udevice *dev, const struct single_fdt_bits_cfg *pins, - int size) + int size, const char *fname) { struct single_pdata *pdata = dev_get_plat(dev); - int n, count = size / sizeof(struct single_fdt_bits_cfg); + struct single_priv *priv = dev_get_priv(dev); + int n, pin, count = size / sizeof(struct single_fdt_bits_cfg); + int npins_in_reg, pin_num_from_lsb; + struct single_func *func; phys_addr_t reg; - u32 offset, val, mask; + u32 offset, val, mask, bit_pos, val_pos, mask_pos, submask; + npins_in_reg = pdata->width / priv->bits_per_pin; + func = single_allocate_function(dev, count * npins_in_reg); + if (IS_ERR(func)) + return PTR_ERR(func); + + func->name = fname; + func->npins = 0; for (n = 0; n < count; n++, pins++) { offset = fdt32_to_cpu(pins->reg); if (offset < 0 || offset > pdata->offset) { @@ -164,11 +329,47 @@ static int single_configure_bits(struct udevice *dev, reg = pdata->base + offset; + pin = single_get_pin_by_offset(dev, offset); + if (pin < 0) { + dev_err(dev, " failed to get pin by offset 0x%pa\n", + ®); + continue; + } + mask = fdt32_to_cpu(pins->mask); val = fdt32_to_cpu(pins->val) & mask; single_write(dev, (single_read(dev, reg) & ~mask) | val, reg); dev_dbg(dev, " reg/val %pa/0x%08x\n", ®, val); + + while (mask) { + bit_pos = __ffs(mask); + pin_num_from_lsb = bit_pos / priv->bits_per_pin; + mask_pos = pdata->mask << bit_pos; + val_pos = val & mask_pos; + submask = mask & mask_pos; + + if ((mask & mask_pos) == 0) { + dev_err(dev, "Invalid mask at 0x%x\n", offset); + break; + } + + mask &= ~mask_pos; + + if (submask != mask_pos) { + dev_warn(dev, + "Invalid submask 0x%x at 0x%x\n", + submask, offset); + continue; + } + + func->pins[func->npins] = pin + pin_num_from_lsb; + func->npins++; + } } + + qsort(func->pins, func->npins, sizeof(func->pins[0]), + single_pin_compare); + list_add(&func->node, &priv->functions); return 0; } static int single_set_state(struct udevice *dev, @@ -186,7 +387,7 @@ static int single_set_state(struct udevice *dev, dev_dbg(dev, " invalid pin configuration in fdt\n"); return -FDT_ERR_BADSTRUCTURE; } - single_configure_pins(dev, prop, len); + single_configure_pins(dev, prop, len, config->name); return 0; } @@ -198,7 +399,7 @@ static int single_set_state(struct udevice *dev, dev_dbg(dev, " invalid bits configuration in fdt\n"); return -FDT_ERR_BADSTRUCTURE; } - single_configure_bits(dev, prop_bits, len); + single_configure_bits(dev, prop_bits, len, config->name); return 0; } @@ -232,6 +433,8 @@ static int single_probe(struct udevice *dev) struct single_priv *priv = dev_get_priv(dev); u32 size; + INIT_LIST_HEAD(&priv->functions); + size = pdata->offset + pdata->width / BITS_PER_BYTE; priv->npins = size / (pdata->width / BITS_PER_BYTE); if (pdata->bits_per_mux) { @@ -296,6 +499,7 @@ const struct pinctrl_ops single_pinctrl_ops = { .get_pins_count = single_get_pins_count, .get_pin_name = single_get_pin_name, .set_state = single_set_state, + .get_pin_muxing = single_get_pin_muxing, }; static const struct udevice_id single_pinctrl_match[] = { From 5532262d46a38dc5b973d7ac0977241b4c850e71 Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Sun, 11 Apr 2021 09:39:50 +0200 Subject: [PATCH 13/14] test: pinmux: add test for 'pinctrl-single' driver The test adds two pinmux nodes to the device tree, one to test when a register changes only one pin's mux (pinctrl-single,pins), and the other to test when more than one pin's mux is changed (pinctrl-single,bits). This required replacing the controller's register access functions when the driver is used on sandbox. Signed-off-by: Dario Binacchi Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 72 +++++++++++++++++++++++ configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + drivers/pinctrl/pinctrl-single.c | 31 ++++++++++ test/dm/pinmux.c | 91 ++++++++++++++++++++++++++++-- 5 files changed, 191 insertions(+), 5 deletions(-) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 26003602249..b09342ed2cb 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -569,6 +569,9 @@ reg = <0 1>; compatible = "sandbox,i2c"; clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_i2c0_pins>; + eeprom@2c { reg = <0x2c>; compatible = "i2c-eeprom"; @@ -649,6 +652,8 @@ lcd { u-boot,dm-pre-reloc; compatible = "sandbox,lcd-sdl"; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_lcd_pins>; xres = <1366>; yres = <768>; }; @@ -899,6 +904,8 @@ pwm: pwm { compatible = "sandbox,pwm"; #pwm-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_pwm_pins>; }; pwm2 { @@ -970,6 +977,9 @@ reg = <0 1>; compatible = "sandbox,spi"; cs-gpios = <0>, <0>, <&gpio_a 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_spi0_pins>; + spi.bin@0 { reg = <0>; compatible = "spansion,m25p16", "jedec,spi-nor"; @@ -1059,6 +1069,8 @@ uart0: serial { compatible = "sandbox,serial"; u-boot,dm-pre-reloc; + pinctrl-names = "default"; + pinctrl-0 = <&pinmux_uart0_pins>; }; usb_0: usb@0 { @@ -1325,6 +1337,66 @@ }; }; + pinctrl-single-no-width { + compatible = "pinctrl-single"; + reg = <0x0000 0x238>; + #pinctrl-cells = <1>; + pinctrl-single,function-mask = <0x7f>; + }; + + pinctrl-single-pins { + compatible = "pinctrl-single"; + reg = <0x0000 0x238>; + #pinctrl-cells = <1>; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0x7f>; + + pinmux_pwm_pins: pinmux_pwm_pins { + pinctrl-single,pins = < 0x48 0x06 >; + }; + + pinmux_spi0_pins: pinmux_spi0_pins { + pinctrl-single,pins = < + 0x190 0x0c + 0x194 0x0c + 0x198 0x23 + 0x19c 0x0c + >; + }; + + pinmux_uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x70 0x30 + 0x74 0x00 + >; + }; + }; + + pinctrl-single-bits { + compatible = "pinctrl-single"; + reg = <0x0000 0x50>; + #pinctrl-cells = <2>; + pinctrl-single,bit-per-mux; + pinctrl-single,register-width = <32>; + pinctrl-single,function-mask = <0xf>; + + pinmux_i2c0_pins: pinmux_i2c0_pins { + pinctrl-single,bits = < + 0x10 0x00002200 0x0000ff00 + >; + }; + + pinmux_lcd_pins: pinmux_lcd_pins { + pinctrl-single,bits = < + 0x40 0x22222200 0xffffff00 + 0x44 0x22222222 0xffffffff + 0x48 0x00000022 0x000000ff + 0x48 0x02000000 0x0f000000 + 0x4c 0x02000022 0x0f0000ff + >; + }; + }; + hwspinlock@0 { compatible = "sandbox,hwspinlock"; }; diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 5bc90d09a8f..3a09f378045 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -197,6 +197,7 @@ CONFIG_PHY_SANDBOX=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_PINCTRL_SANDBOX=y +CONFIG_PINCTRL_SINGLE=y CONFIG_POWER_DOMAIN=y CONFIG_SANDBOX_POWER_DOMAIN=y CONFIG_DM_PMIC=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 4401f33f0ba..03a1881f6de 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -142,6 +142,7 @@ CONFIG_PHY_SANDBOX=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_PINCTRL_SANDBOX=y +CONFIG_PINCTRL_SINGLE=y CONFIG_POWER_DOMAIN=y CONFIG_SANDBOX_POWER_DOMAIN=y CONFIG_DM_PMIC=y diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 3ddb637ab77..48bdd0f6f5b 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -51,6 +51,9 @@ struct single_func { * @pin_name: temporary buffer to store the pin name */ struct single_priv { +#if (IS_ENABLED(CONFIG_SANDBOX)) + u32 *sandbox_regs; +#endif unsigned int bits_per_pin; unsigned int npins; char pin_name[PINNAME_SIZE]; @@ -87,6 +90,8 @@ struct single_fdt_bits_cfg { fdt32_t mask; }; +#if (!IS_ENABLED(CONFIG_SANDBOX)) + static unsigned int single_read(struct udevice *dev, fdt_addr_t reg) { struct single_pdata *pdata = dev_get_plat(dev); @@ -119,6 +124,24 @@ static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg) } } +#else /* CONFIG_SANDBOX */ + +static unsigned int single_read(struct udevice *dev, fdt_addr_t reg) +{ + struct single_priv *priv = dev_get_priv(dev); + + return priv->sandbox_regs[reg]; +} + +static void single_write(struct udevice *dev, unsigned int val, fdt_addr_t reg) +{ + struct single_priv *priv = dev_get_priv(dev); + + priv->sandbox_regs[reg] = val; +} + +#endif /* CONFIG_SANDBOX */ + /** * single_get_pin_by_offset() - get a pin based on the register offset * @dev: single driver instance @@ -436,6 +459,14 @@ static int single_probe(struct udevice *dev) INIT_LIST_HEAD(&priv->functions); size = pdata->offset + pdata->width / BITS_PER_BYTE; + #if (CONFIG_IS_ENABLED(SANDBOX)) + priv->sandbox_regs = + devm_kzalloc(dev, size * sizeof(*priv->sandbox_regs), + GFP_KERNEL); + if (!priv->sandbox_regs) + return -ENOMEM; + #endif + priv->npins = size / (pdata->width / BITS_PER_BYTE); if (pdata->bits_per_mux) { priv->bits_per_pin = fls(pdata->mask); diff --git a/test/dm/pinmux.c b/test/dm/pinmux.c index 047184d4bcb..265df4ccb97 100644 --- a/test/dm/pinmux.c +++ b/test/dm/pinmux.c @@ -9,16 +9,21 @@ #include #include -static int dm_test_pinmux(struct unit_test_state *uts) -{ - char buf[64]; - struct udevice *dev; - +static char buf[64]; #define test_muxing(selector, expected) do { \ ut_assertok(pinctrl_get_pin_muxing(dev, selector, buf, sizeof(buf))); \ ut_asserteq_str(expected, (char *)&buf); \ } while (0) +#define test_name(selector, expected) do { \ + ut_assertok(pinctrl_get_pin_name(dev, selector, buf, sizeof(buf))); \ + ut_asserteq_str(expected, (char *)&buf); \ +} while (0) + +static int dm_test_pinmux(struct unit_test_state *uts) +{ + struct udevice *dev; + ut_assertok(uclass_get_device_by_name(UCLASS_PINCTRL, "pinctrl", &dev)); test_muxing(0, "UART TX."); test_muxing(1, "UART RX."); @@ -54,4 +59,80 @@ static int dm_test_pinmux(struct unit_test_state *uts) return 0; } + DM_TEST(dm_test_pinmux, UT_TESTF_SCAN_FDT); + +static int dm_test_pinctrl_single(struct unit_test_state *uts) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_name(UCLASS_PINCTRL, + "pinctrl-single-no-width", &dev); + ut_asserteq(-EINVAL, ret); + ut_assertok(uclass_get_device_by_name(UCLASS_PWM, "pwm", &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_SERIAL, "serial", &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_SPI, "spi@0", &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_PINCTRL, + "pinctrl-single-pins", &dev)); + ut_asserteq(142, pinctrl_get_pins_count(dev)); + test_name(0, "PIN0"); + test_name(141, "PIN141"); + test_name(142, "Error"); + test_muxing(0, "0x00000000 0x00000000 UNCLAIMED"); + test_muxing(18, "0x00000048 0x00000006 pinmux_pwm_pins"); + test_muxing(28, "0x00000070 0x00000030 pinmux_uart0_pins"); + test_muxing(29, "0x00000074 0x00000000 pinmux_uart0_pins"); + test_muxing(100, "0x00000190 0x0000000c pinmux_spi0_pins"); + test_muxing(101, "0x00000194 0x0000000c pinmux_spi0_pins"); + test_muxing(102, "0x00000198 0x00000023 pinmux_spi0_pins"); + test_muxing(103, "0x0000019c 0x0000000c pinmux_spi0_pins"); + ret = pinctrl_get_pin_muxing(dev, 142, buf, sizeof(buf)); + ut_asserteq(-EINVAL, ret); + ut_assertok(uclass_get_device_by_name(UCLASS_I2C, "i2c@0", &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_VIDEO, "lcd", &dev)); + ut_assertok(uclass_get_device_by_name(UCLASS_PINCTRL, + "pinctrl-single-bits", &dev)); + ut_asserteq(160, pinctrl_get_pins_count(dev)); + test_name(0, "PIN0"); + test_name(159, "PIN159"); + test_name(160, "Error"); + test_muxing(0, "0x00000000 0x00000000 UNCLAIMED"); + test_muxing(34, "0x00000010 0x00000200 pinmux_i2c0_pins"); + test_muxing(35, "0x00000010 0x00002000 pinmux_i2c0_pins"); + test_muxing(130, "0x00000040 0x00000200 pinmux_lcd_pins"); + test_muxing(131, "0x00000040 0x00002000 pinmux_lcd_pins"); + test_muxing(132, "0x00000040 0x00020000 pinmux_lcd_pins"); + test_muxing(133, "0x00000040 0x00200000 pinmux_lcd_pins"); + test_muxing(134, "0x00000040 0x02000000 pinmux_lcd_pins"); + test_muxing(135, "0x00000040 0x20000000 pinmux_lcd_pins"); + test_muxing(136, "0x00000044 0x00000002 pinmux_lcd_pins"); + test_muxing(137, "0x00000044 0x00000020 pinmux_lcd_pins"); + test_muxing(138, "0x00000044 0x00000200 pinmux_lcd_pins"); + test_muxing(139, "0x00000044 0x00002000 pinmux_lcd_pins"); + test_muxing(140, "0x00000044 0x00020000 pinmux_lcd_pins"); + test_muxing(141, "0x00000044 0x00200000 pinmux_lcd_pins"); + test_muxing(142, "0x00000044 0x02000000 pinmux_lcd_pins"); + test_muxing(143, "0x00000044 0x20000000 pinmux_lcd_pins"); + test_muxing(144, "0x00000048 0x00000002 pinmux_lcd_pins"); + test_muxing(145, "0x00000048 0x00000020 pinmux_lcd_pins"); + test_muxing(146, "0x00000048 0x00000000 UNCLAIMED"); + test_muxing(147, "0x00000048 0x00000000 UNCLAIMED"); + test_muxing(148, "0x00000048 0x00000000 UNCLAIMED"); + test_muxing(149, "0x00000048 0x00000000 UNCLAIMED"); + test_muxing(150, "0x00000048 0x02000000 pinmux_lcd_pins"); + test_muxing(151, "0x00000048 0x00000000 UNCLAIMED"); + test_muxing(152, "0x0000004c 0x00000002 pinmux_lcd_pins"); + test_muxing(153, "0x0000004c 0x00000020 pinmux_lcd_pins"); + test_muxing(154, "0x0000004c 0x00000000 UNCLAIMED"); + test_muxing(155, "0x0000004c 0x00000000 UNCLAIMED"); + test_muxing(156, "0x0000004c 0x00000000 UNCLAIMED"); + test_muxing(157, "0x0000004c 0x00000000 UNCLAIMED"); + test_muxing(158, "0x0000004c 0x02000000 pinmux_lcd_pins"); + test_muxing(159, "0x0000004c 0x00000000 UNCLAIMED"); + ret = pinctrl_get_pin_muxing(dev, 160, buf, sizeof(buf)); + ut_asserteq(-EINVAL, ret); + return 0; +} + +DM_TEST(dm_test_pinctrl_single, UT_TESTF_SCAN_FDT); From e64665fa727eeecd04446551cee25b43f355c69e Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Mon, 12 Apr 2021 21:10:55 +0530 Subject: [PATCH 14/14] arm: dts: k3-j721e-main: Update the speed modes supported and their itap delay values for MMCSD subsystems According to latest errata of J721e [1], HS400 mode is not supported in MMCSD0 subsystem (i2024) and SDR104 mode is not supported in MMCSD1/2 subsystems (i2090). Therefore, replace mmc-hs400-1_8v with mmc-hs200-1_8v in MMCSD0 subsystem and add a sdhci mask to disable SDR104 speed mode. Also, update the itap delay values for all the MMCSD subsystems according the latest J721e data sheet[2] [1] - https://www.ti.com/lit/er/sprz455/sprz455.pdf [2] - https://www.ti.com/lit/ds/symlink/tda4vm.pdf Fixes: 70e167495ab2 ("arm: dts: k3-j721e: Sync Linux v5.11-rc6 dts into U-Boot") Signed-off-by: Aswath Govindraju --- arch/arm/dts/k3-j721e-main.dtsi | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/arch/arm/dts/k3-j721e-main.dtsi b/arch/arm/dts/k3-j721e-main.dtsi index e47b6c0eb70..07b489679ed 100644 --- a/arch/arm/dts/k3-j721e-main.dtsi +++ b/arch/arm/dts/k3-j721e-main.dtsi @@ -1078,13 +1078,12 @@ assigned-clocks = <&k3_clks 91 1>; assigned-clock-parents = <&k3_clks 91 2>; bus-width = <8>; - mmc-hs400-1_8v; + mmc-hs200-1_8v; mmc-ddr-1_8v; ti,otap-del-sel-legacy = <0xf>; ti,otap-del-sel-mmc-hs = <0xf>; ti,otap-del-sel-ddr52 = <0x5>; ti,otap-del-sel-hs200 = <0x6>; - ti,otap-del-sel-hs400 = <0x0>; ti,itap-del-sel-legacy = <0x10>; ti,itap-del-sel-mmc-hs = <0xa>; ti,itap-del-sel-ddr52 = <0x3>; @@ -1102,14 +1101,20 @@ assigned-clocks = <&k3_clks 92 0>; assigned-clock-parents = <&k3_clks 92 1>; ti,otap-del-sel-legacy = <0x0>; - ti,otap-del-sel-sd-hs = <0xf>; + ti,otap-del-sel-sd-hs = <0x0>; ti,otap-del-sel-sdr12 = <0xf>; ti,otap-del-sel-sdr25 = <0xf>; ti,otap-del-sel-sdr50 = <0xc>; ti,otap-del-sel-ddr50 = <0xc>; + ti,itap-del-sel-legacy = <0x0>; + ti,itap-del-sel-sd-hs = <0x0>; + ti,itap-del-sel-sdr12 = <0x0>; + ti,itap-del-sel-sdr25 = <0x0>; + ti,itap-del-sel-ddr50 = <0x2>; ti,trm-icp = <0x8>; ti,clkbuf-sel = <0x7>; dma-coherent; + sdhci-caps-mask = <0x2 0x0>; }; main_sdhci2: sdhci@4f98000 { @@ -1122,14 +1127,20 @@ assigned-clocks = <&k3_clks 93 0>; assigned-clock-parents = <&k3_clks 93 1>; ti,otap-del-sel-legacy = <0x0>; - ti,otap-del-sel-sd-hs = <0xf>; + ti,otap-del-sel-sd-hs = <0x0>; ti,otap-del-sel-sdr12 = <0xf>; ti,otap-del-sel-sdr25 = <0xf>; ti,otap-del-sel-sdr50 = <0xc>; ti,otap-del-sel-ddr50 = <0xc>; + ti,itap-del-sel-legacy = <0x0>; + ti,itap-del-sel-sd-hs = <0x0>; + ti,itap-del-sel-sdr12 = <0x0>; + ti,itap-del-sel-sdr25 = <0x0>; + ti,itap-del-sel-ddr50 = <0x2>; ti,trm-icp = <0x8>; ti,clkbuf-sel = <0x7>; dma-coherent; + sdhci-caps-mask = <0x2 0x0>; }; usbss0: cdns-usb@4104000 {