Re: [PATCH 4/7] net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568
Hi Jonas, Thank you for your help. 在 2023/8/7 08:08, Jonas Karlman 写道: Add a new glue driver for Rockchip SoCs, i.e RK3568, with a GMAC based on Synopsys DWC Ethernet QoS IP. rk_gmac_ops was ported from linux commit: 3bb3d6b1c195 ("net: stmmac: Add RK3566/RK3568 SoC support") Signed-off-by: Jonas Karlman --- Cc: David Wu Cc: Ezequiel Garcia --- drivers/net/Kconfig| 8 + drivers/net/Makefile | 1 + drivers/net/dwc_eth_qos.c | 8 +- drivers/net/dwc_eth_qos.h | 2 + drivers/net/dwc_eth_qos_rockchip.c | 348 + 5 files changed, 365 insertions(+), 2 deletions(-) create mode 100644 drivers/net/dwc_eth_qos_rockchip.c diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 0ed39a61e4de..29304fd77759 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -225,6 +225,14 @@ config DWC_ETH_QOS_IMX The Synopsys Designware Ethernet QOS IP block with the specific configuration used in IMX soc. +config DWC_ETH_QOS_ROCKCHIP + bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs" + depends on DWC_ETH_QOS + select DM_ETH_PHY + help + The Synopsys Designware Ethernet QOS IP block with specific + configuration used in Rockchip SoCs. + config DWC_ETH_QOS_STM32 bool "Synopsys DWC Ethernet QOS device support for STM32" depends on DWC_ETH_QOS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index d4af253b6f28..1d444f5b4a69 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o +obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o obj-$(CONFIG_E1000) += e1000.o diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 24fb3fac1f12..9fb98a2c3c74 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1707,7 +1707,12 @@ static const struct udevice_id eqos_ids[] = { .data = (ulong)_imx_config }, #endif - +#if IS_ENABLED(CONFIG_DWC_ETH_QOS_ROCKCHIP) + { + .compatible = "rockchip,rk3568-gmac", + .data = (ulong)_rockchip_config + }, +#endif If this compatible could move to dwc_eth_qos_rockchip.c, it is better, we have other SoCs that also use this driver in the feature, and it must increase this array all the time for new SoCs later, it will be better only change dwc_eth_qos_rockchip.c, we don't need to change the current file. #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM) { .compatible = "qcom,qcs404-ethqos", @@ -1720,7 +1725,6 @@ static const struct udevice_id eqos_ids[] = { .data = (ulong)_jh7110_config }, #endif - { } }; diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 06a082da72ef..e3222e1e17e5 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -82,6 +82,7 @@ struct eqos_mac_regs { #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT8 +#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1 #define EQOS_MAC_MDIO_ADDRESS_CR_20_352 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 #define EQOS_MAC_MDIO_ADDRESS_SKAPBIT(4) @@ -287,5 +288,6 @@ void eqos_flush_buffer_generic(void *buf, size_t size); int eqos_null_ops(struct udevice *dev); extern struct eqos_config eqos_imx_config; +extern struct eqos_config eqos_rockchip_config; extern struct eqos_config eqos_qcom_config; extern struct eqos_config eqos_jh7110_config; diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c new file mode 100644 index ..c8abe351fc3e --- /dev/null +++ b/drivers/net/dwc_eth_qos_rockchip.c @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dwc_eth_qos.h" + +struct rk_gmac_ops { + const char *compatible; + int (*set_to_rgmii)(struct udevice *dev, + int tx_delay, int rx_delay); + int (*set_to_rmii)(struct udevice *dev); + int (*set_gmac_speed)(struct udevice *dev); + u32 regs[3]; +}; + +struct rockchip_platform_data { + struct reset_ctl_bulk resets; + const struct rk_gmac_ops *ops; + int id; + struct regmap *grf; +}; + +#define HIWORD_UPDATE(val, mask, shift) \ + ((va
Re: [PATCH 1/9] net: gmac_rockchip: Fix misuse of GENMASK macro
Hi Pierre-Clément, Thanks for your correction, there was wrong mask here. Reviewed-by: David Wu 在 2022/4/6 23:08, Kever Yang 写道: Add David, Hi David, Could you help to check this patch? Thanks, - Kever On 2022/3/16 23:39, Pierre-Clément Tosi wrote: Swap the arguments as that seems to have been the author's intention. Note: This fix wasn't tested on hardware and will result in more bits being set by the underlying writel() in rk_clrsetreg(), which might bring unexpected behavioural changes. Fixes: b07911840025 ("net: gmac_rockchip: add support for px30") Signed-off-by: Pierre-Clément Tosi Cc: Joe Hershberger Cc: Heiko Stuebner Cc: Kever Yang Cc: Tom Rini --- drivers/net/gmac_rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index 04008d2b19..0ecbcdf641 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -350,7 +350,7 @@ static void px30_gmac_set_to_rmii(struct gmac_rockchip_plat *pdata) struct px30_grf *grf; enum { PX30_GMAC_PHY_INTF_SEL_SHIFT = 4, - PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 6), + PX30_GMAC_PHY_INTF_SEL_MASK = GENMASK(6, 4), PX30_GMAC_PHY_INTF_SEL_RMII = BIT(6), };
Re: [PATCH] net: use the same alias stem for ethernet as linux
Hi Michael, Thank you for your patch, good complement. 在 2021/2/25 下午11:51, Michael Walle 写道: Linux uses the prefix "ethernet" whereas u-boot uses "eth". This is from the linux tree: $ grep "eth[0-9].*=.*&" arch/**/*dts{,i}|wc -l 0 $ grep "ethernet[0-9].*=.*&" arch/**/*dts{,i}|wc -l 633 In u-boot device trees both prefixes are used. Until recently the only user of the ethernet alias was the sandbox test device tree. This changed with commit fc054d563bfb ("net: Introduce DSA class for Ethernet switches"). There, the MAC addresses are inherited based on the devices sequence IDs which is in turn given by the device tree. Before there are more users in u-boot and both worlds will differ even more, rename the alias prefix to "ethernet" to match the linux ones. Also adapt the test cases and rename any old aliases in the u-boot device trees. Cc: David Wu Signed-off-by: Michael Walle --- Vladimir, I didn't do another patch to rename any ethernet aliases to "eth". Though kontron boards contain "ethernetN" aliases, all in tree variants don't make use of it. So there is nothing to be fixed. arch/arm/dts/fsl-ls1028a-rdb.dts | 12 ++-- arch/sandbox/dts/test.dts| 10 +- net/eth-uclass.c | 4 ++-- test/dm/ofnode.c | 2 +- test/dm/test-fdt.c | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm/dts/fsl-ls1028a-rdb.dts b/arch/arm/dts/fsl-ls1028a-rdb.dts index 3432fca352..82a8c0a0cd 100644 --- a/arch/arm/dts/fsl-ls1028a-rdb.dts +++ b/arch/arm/dts/fsl-ls1028a-rdb.dts @@ -15,12 +15,12 @@ compatible = "fsl,ls1028a-rdb", "fsl,ls1028a"; aliases { spi0 = - eth0 = - eth1 = - eth2 = _felix_port0; - eth3 = _felix_port1; - eth4 = _felix_port2; - eth5 = _felix_port3; + ethernet0 = + ethernet1 = + ethernet2 = _felix_port0; + ethernet3 = _felix_port1; + ethernet4 = _felix_port2; + ethernet5 = _felix_port3; }; }; diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 3ef3ba0b17..7a5d4aa71d 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -14,11 +14,11 @@ aliases { console = - eth0 = "/eth@10002000"; - eth2 = _0; - eth3 = _3; - eth4 = _eth0; - eth5 = _5; + ethernet0 = "/eth@10002000"; + ethernet2 = _0; + ethernet3 = _3; + ethernet4 = _eth0; + ethernet5 = _5; gpio1 = _a; gpio2 = _b; gpio3 = _c; diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 0b4260dc5b..5146bd 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -605,8 +605,8 @@ static int eth_pre_remove(struct udevice *dev) return 0; } -UCLASS_DRIVER(eth) = { - .name = "eth", +UCLASS_DRIVER(ethernet) = { + .name = "ethernet", .id = UCLASS_ETH, .post_bind = eth_post_bind, .pre_unbind = eth_pre_unbind, diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index c539134296..3b708b63eb 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -213,7 +213,7 @@ static int dm_test_ofnode_read_aliases(struct unit_test_state *uts) ofnode node; int size; - node = ofnode_get_aliases_node("eth3"); + node = ofnode_get_aliases_node("ethernet3"); ut_assert(ofnode_valid(node)); ut_asserteq_str("sbe5", ofnode_get_name(node)); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 6e83aeecd9..98972665f2 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -183,7 +183,7 @@ static int dm_test_alias_highest_id(struct unit_test_state *uts) { int ret; - ret = dev_read_alias_highest_id("eth"); + ret = dev_read_alias_highest_id("ethernet"); ut_asserteq(5, ret); ret = dev_read_alias_highest_id("gpio");
[PATCH v1] net: eth-uclass: Change uclass driver name to ethernet
dev_read_alias_seq() used uc_drv->name compared to alias stem string, Ethernet's alias stem uses "ethernet", which does not match the eth-uclass driver name "eth", can not get the correct index of ethernet alias namer. So it seems change uclass driver name to match the alias stem is a more reasonable way. Signed-off-by: David Wu --- net/eth-uclass.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/eth-uclass.c b/net/eth-uclass.c index e14695c0f1..3497a17db6 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -593,8 +593,8 @@ static int eth_pre_remove(struct udevice *dev) return 0; } -UCLASS_DRIVER(eth) = { - .name = "eth", +UCLASS_DRIVER(ethernet) = { + .name = "ethernet", .id = UCLASS_ETH, .post_bind = eth_post_bind, .pre_unbind = eth_pre_unbind, -- 2.19.1
[PATCH] net: eth-uclass: Change uclass driver name to ethernet
dev_read_alias_seq() used uc_drv->name compared to alias stem string, Ethernet's alias stem uses "ethernet", which does not match the eth-uclass driver name "eth", can not get the correct index of ethernet alias namer. So it seems change uclass driver name to match the alias stem is a more reasonable way. Signed-off-by: David Wu --- net/eth-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/eth-uclass.c b/net/eth-uclass.c index e14695c0f1..7dd962db64 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -594,7 +594,7 @@ static int eth_pre_remove(struct udevice *dev) } UCLASS_DRIVER(eth) = { - .name = "eth", + .name = "ethernet", .id = UCLASS_ETH, .post_bind = eth_post_bind, .pre_unbind = eth_pre_unbind, -- 2.19.1
Re: [PATCH] rockchip: i2c: fix switch to new implementation for rk3188
Hi Alexander, Thank you for your patch, the grf header file is missing for rk3066, the GRF_SOC_CON1 offset of 3066 is 0x154, the corresponding bit of i2c0~i2c4 is also bit11 ~ bit15. There is currently no support for rk3066 at mainline, rk3066 is not handled here, I think it’s okay, so, Reviewed-by: David Wu 在 2020/6/27 下午11:03, Alexander Kochetkov 写道: To make clear, there is kernel driver i2c-rk3x.c. For rk3066 it write bits in the GRF word at offset 0x154. See [1] and [2]. [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/i2c/busses/i2c-rk3x.c#n1236 [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/i2c/busses/i2c-rk3x.c#n1137 In u-boot there is include file cru_rk3036.h [3]. If this include file valid for rk3066, than offset 0x154 correspond to soc_con3 register. But all documentation I found for 30xx SoC clarify that I2C switch bits located in the soc_con1 registers. So I don’t know correct location for I2C switch bits. [3] https://github.com/u-boot/u-boot/blob/master/arch/arm/include/asm/arch-rockchip/cru_rk3036.h 27 июня 2020 г., в 17:17, Kever Yang написал(а): +David, Hi David, Could you help to commend on this? Hi Alex, Thanks for your patch. On 2020/6/22 下午9:06, Alexander Kochetkov wrote: The commit e7ae4cf27a6d 'pinctrl: rockchip: Add common rockchip pinctrl driver' dropped rk3188_pinctrl_request operation, that did switching to new implementation. This commit implement switching to new implementation using writing bits to GRF. I don't have rk3060 rk3066 board to test, so switching implemented as a stub returning -ENOSYS. Signed-off-by: Alexander Kochetkov --- drivers/i2c/rk_i2c.c | 42 +++--- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/rk_i2c.c b/drivers/i2c/rk_i2c.c index 32b2ee8578..ad3c66843b 100644 --- a/drivers/i2c/rk_i2c.c +++ b/drivers/i2c/rk_i2c.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,7 @@ enum { */ struct rk_i2c_soc_data { int controller_type; + int (*switch_to_new_type)(int bus_nr); }; static inline void rk_i2c_get_div(int div, int *divh, int *divl) @@ -388,11 +391,33 @@ static int rockchip_i2c_ofdata_to_platdata(struct udevice *bus) return 0; } +static int rockchip_i2c_switch_to_new_type_rk3066(int bus_nr) +{ + return -ENOSYS; +} + +static int rockchip_i2c_switch_to_new_type_rk3188(int bus_nr) +{ + struct rk3188_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + + if (grf == NULL) + return -ENOSYS; + + if (bus_nr < 0 || bus_nr > (RKI2C4_SEL_SHIFT - RKI2C0_SEL_SHIFT)) + return -EINVAL; + + /* enable new i2c controller */ + rk_clrsetreg(>soc_con1, +1 << (RKI2C0_SEL_SHIFT + bus_nr), +1 << (RKI2C0_SEL_SHIFT + bus_nr)); + + return 0; +} + static int rockchip_i2c_probe(struct udevice *bus) { struct rk_i2c *priv = dev_get_priv(bus); struct rk_i2c_soc_data *soc_data; - struct udevice *pinctrl; int bus_nr; int ret; @@ -408,17 +433,10 @@ static int rockchip_i2c_probe(struct udevice *bus) return ret; } - ret = uclass_get_device(UCLASS_PINCTRL, 0, ); - if (ret) { - debug("%s: Cannot find pinctrl device\n", __func__); - return ret; - } - - /* pinctrl will switch I2C to new type */ - ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_I2C0 + bus_nr); - if (ret) { + ret = soc_data->switch_to_new_type(bus_nr); + if (ret < 0) { debug("%s: Failed to switch I2C to new type %s: %d\n", - __func__, bus->name, ret); +__func__, bus->name, ret); return ret; } } @@ -433,10 +451,12 @@ static const struct dm_i2c_ops rockchip_i2c_ops = { static const struct rk_i2c_soc_data rk3066_soc_data = { .controller_type = RK_I2C_LEGACY, + .switch_to_new_type = rockchip_i2c_switch_to_new_type_rk3066, }; static const struct rk_i2c_soc_data rk3188_soc_data = { .controller_type = RK_I2C_LEGACY, + .switch_to_new_type = rockchip_i2c_switch_to_new_type_rk3188, }; static const struct rk_i2c_soc_data rk3228_soc_data = {
Re: [RESEND PATCH v2 02/11] net: dwc_eth_qos: Add option "snps, reset-gpio" phy-rst gpio for stm32
Hi Tom, 在 2020/6/12 下午10:48, Tom Rini 写道: On Tue, May 12, 2020 at 05:56:01PM +0800, David Wu wrote: It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general. Signed-off-by: David Wu Reviewed-by: Patrice Chotard --- Changes in v2: - Remove the code is not related (Patrice) Please note that based on Patrick's feedback I am expecting a v3 of this patch or further answers about the obsolete binding being used. Thanks! I think I will submit v3 after the following two patches, it looks like I need to add a rockchip config. [1] net: dwc_eth_qos: update the compatible supported for STM32 http://patchwork.ozlabs.org/project/uboot/patch/20200514130023.15030-1-patrick.delau...@st.com/ [2] net: dwc_eth_qos: add Kconfig option to select supported configuration http://patchwork.ozlabs.org/project/uboot/list/?series=181931
Re: [RESEND PATCH v2 02/11] net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32
Hi Patrick, Yes, this is the case, it should be add at PHY node, and I also used the original writing "snps,reset*" at MAC node. Anyway, I will try to put the reset gpio in the PHY node. 在 2020/5/13 下午8:55, Patrick DELAUNAY 写道: Hi David From: David Wu Sent: mardi 12 mai 2020 11:56 It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general. Signed-off-by: David Wu --- Changes in v2: - Remove the code is not related (Patrice) drivers/net/dwc_eth_qos.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 66a02aa80b..92dab678c7 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -314,6 +314,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio; + u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref; @@ -739,6 +740,15 @@ static int eqos_start_resets_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(>phy_reset_gpio)) { + ret = dm_gpio_set_value(>phy_reset_gpio, 0); + if (ret < 0) { + pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", + ret); + return ret; + } + + udelay(eqos->reset_delays[0]); + ret = dm_gpio_set_value(>phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", @@ -746,7 +756,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; } - udelay(2); + udelay(eqos->reset_delays[1]); ret = dm_gpio_set_value(>phy_reset_gpio, 0); if (ret < 0) { @@ -754,6 +764,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; } + + udelay(eqos->reset_delays[2]); } debug("%s: OK\n", __func__); @@ -1864,11 +1876,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret); + else + eqos->reset_delays[1] = 2; eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); } + if (!dm_gpio_is_valid(>phy_reset_gpio)) { + int reset_flags = GPIOD_IS_OUT; + + if (dev_read_bool(dev, "snps,reset-active-low")) + reset_flags |= GPIOD_ACTIVE_LOW; + + ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, + >phy_reset_gpio, reset_flags); + if (ret == 0) + ret = dev_read_u32_array(dev, "snps,reset-delays-us", +eqos->reset_delays, 3); + else + pr_warn("gpio_request_by_name(snps,reset-gpio) failed: %d", + ret); + } + debug("%s: OK\n", __func__); return 0; -- 2.19.1 This obsolete binding isn't expected to be supported in stm32 glue for dwmac (and it tis the purpose of eqos_stm32_config) Reference in linux binding ./Documentation/devicetree/bindings/net/stm32-dwmac.txt (the glue) ./Documentation/devicetree/bindings/net/snps,dwmac.yaml snps,reset-gpio: deprecated: true snps,reset-active-low: deprecated: true snps,reset-delays-us: deprecated: true I expected that gpio reset in future device tree should be managed by only by PHY generic binding (upstream in progress on Linux side for STM32MP15x), as described in: Documentation/devicetree/bindings/net/ethernet-phy.yaml reset-gpios: maxItems: 1 description: The GPIO phandle and specifier for the PHY reset signal. reset-assert-us: description: Delay after the reset was asserted in microseconds. If this property is missing the delay will be skipped. reset-deassert-us: description: Delay after the reset was deasserted in microseconds. If this property is missing the delay will be skipped. See alsoU-Boot: doc/device-tree-bindings/net/phy.txt Something as { status = "okay"; pinctrl-0 = <_mii>; pinctrl-names = "defaul
Re: [PATCH v2 00/11] Add dwc_eth_qos support for rockchip
Hi Patrice, Thanks for your remind, i resend this series base on last v2020.07-rc2. 在 2020/5/12 下午4:17, Patrice CHOTARD 写道: Hi David IN order to test it on STM32, can you rebase this series on last master branch, there was some update already merged that avoid to apply smoothly this series. Thanks Patrice On 5/11/20 9:00 AM, David Wu wrote: Rockchip Socs can support two controllers "snps, dwmac-4.20a" and "snps, dwmac-3.50". In order to support two at gmac-rockchip.c, export public interface functions and struct data, it will be more general for others. Changes in v2: - None - Remove the code is not related (Patrice) - None - Don't change the Rx and Tx clock names. (Patrice, Stephen) - None - None - Add the lost head file. (Patrice) - None - None - None - None David Wu (11): net: dwc_eth_qos: Use dev_ functions calls to get FDT data net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32 net: dwc_eth_qos: Move interface() to eqos_ops structure net: dwc_eth_qos: Make clk_rx and clk_tx optional net: dwc_eth_qos: Split eqos_start() to get link speed net: dwc_eth_qos: make eqos_start_clks and eqos_stop_clks optional net: dwc_eth_qos: Export common struct and interface at head file net: gmac_rockchip: Add dwc_eth_qos support net: dwc_eth_qos: Add eqos_rockchip_ops net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip net: gmac_rockchip: Add RV1126 gmac support drivers/net/Kconfig | 2 +- drivers/net/dwc_eth_qos.c | 273 ++-- drivers/net/dwc_eth_qos.h | 89 drivers/net/gmac_rockchip.c | 188 + 4 files changed, 390 insertions(+), 162 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h
[RESEND PATCH v2 11/11] net: gmac_rockchip: Add RV1126 gmac support
This Soc is different from the previous Socs, need to define eqos_config, and follow the dwc_eth_qos driver process. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/gmac_rockchip.c | 28 1 file changed, 28 insertions(+) diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index aa2bab4203..d48a0f516b 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -368,6 +368,13 @@ static int rv1108_set_rmii_speed(struct rockchip_eth_dev *dev) return 0; } +static int rv1126_set_rgmii_speed(struct rockchip_eth_dev *dev) +{ + /* TO DO... */ + + return 0; +} + static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) { struct px30_grf *grf; @@ -577,6 +584,11 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) RV1108_GMAC_PHY_INTF_SEL_RMII); } +static void rv1126_set_to_rgmii(struct gmac_rockchip_platdata *pdata) +{ + /* TO DO... */ +} + static int gmac_rockchip_probe(struct udevice *dev) { struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); @@ -837,6 +849,20 @@ const struct rk_gmac_ops rv1108_gmac_ops = { .set_to_rmii = rv1108_gmac_set_to_rmii, }; +const struct rk_gmac_ops rv1126_gmac_ops = { + .config = { + .reg_access_always_ok = false, + .mdio_wait = 1, + .swr_wait = 200, + .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED, + .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150, + .ops = _rockchip_ops + }, + + .fix_mac_speed = rv1126_set_rgmii_speed, + .set_to_rgmii = rv1126_set_to_rgmii, +}; + static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,px30-gmac", .data = (ulong)_gmac_ops }, @@ -854,6 +880,8 @@ static const struct udevice_id rockchip_gmac_ids[] = { .data = (ulong)_gmac_ops }, { .compatible = "rockchip,rv1108-gmac", .data = (ulong)_gmac_ops }, + { .compatible = "rockchip,rv1126-gmac", + .data = (ulong)_gmac_ops }, { } }; -- 2.19.1
[RESEND PATCH v2 10/11] net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip
The Rockchip CSR clock range is from 100M to 150M, add EQOS_MAC_MDIO_ADDRESS_CR_100_150. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index def2706271..39f8452c17 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -12,10 +12,10 @@ #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 +#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1 #define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 - struct eqos_config { bool reg_access_always_ok; int mdio_wait; -- 2.19.1
[RESEND PATCH v2 09/11] net: dwc_eth_qos: Add eqos_rockchip_ops
The eqos_rockchip_ops is simillar to eqos_stm32_ops, and export the eqos_rockchip_ops to use. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 16 drivers/net/dwc_eth_qos.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b3195d484e..f4f6f73849 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -2147,6 +2147,22 @@ struct eqos_config eqos_imx_config = { .ops = _imx_ops }; +struct eqos_ops eqos_rockchip_ops = { + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, + .eqos_inval_buffer = eqos_inval_buffer_generic, + .eqos_flush_buffer = eqos_flush_buffer_generic, + .eqos_probe_resources = eqos_probe_resources_stm32, + .eqos_remove_resources = eqos_remove_resources_stm32, + .eqos_stop_resets = eqos_stop_resets_stm32, + .eqos_start_resets = eqos_start_resets_stm32, + .eqos_calibrate_pads = eqos_calibrate_pads_stm32, + .eqos_disable_calibration = eqos_disable_calibration_stm32, + .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32, + .eqos_get_interface = eqos_get_interface_stm32 +}; + static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 3125a301f0..def2706271 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -84,4 +84,6 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp); int eqos_free_pkt(struct udevice *dev, uchar *packet, int length); int eqos_write_hwaddr(struct udevice *dev); +extern struct eqos_ops eqos_rockchip_ops; + #endif -- 2.19.1
[RESEND PATCH v2 08/11] net: gmac_rockchip: Add dwc_eth_qos support
Change the original data structure so that Rockchip's Soc gmac controller can support the designware.c and dwc_eth_qos.c drivers, a Soc can only support one. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/Kconfig | 2 +- drivers/net/gmac_rockchip.c | 160 ++-- 2 files changed, 135 insertions(+), 27 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 38f2bd6637..d29adebee0 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -490,7 +490,7 @@ config PIC32_ETH config GMAC_ROCKCHIP bool "Rockchip Synopsys Designware Ethernet MAC" - depends on DM_ETH && ETH_DESIGNWARE + depends on DM_ETH && (ETH_DESIGNWARE || DWC_ETH_QOS) help This driver provides Rockchip SoCs network support based on the Synopsys Designware driver. diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index e152faf083..aa2bab4203 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -25,26 +25,39 @@ #include #include #include "designware.h" +#include "dwc_eth_qos.h" DECLARE_GLOBAL_DATA_PTR; #define DELAY_ENABLE(soc, tx, rx) \ (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \ ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE)) +struct rockchip_eth_dev { + union { + struct eqos_priv eqos; + struct dw_eth_dev dw; + }; +}; + /* * Platform data for the gmac * * dw_eth_pdata: Required platform data for designware driver (must be first) */ struct gmac_rockchip_platdata { - struct dw_eth_pdata dw_eth_pdata; + union { + struct dw_eth_pdata dw_eth_pdata; + struct eth_pdata eth_pdata; + }; + bool has_gmac4; bool clock_input; int tx_delay; int rx_delay; }; struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); + const struct eqos_config config; + int (*fix_mac_speed)(struct rockchip_eth_dev *dev); void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); }; @@ -55,6 +68,9 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); const char *string; + if (device_is_compatible(dev, "snps,dwmac-4.20a")) + pdata->has_gmac4 = true; + string = dev_read_string(dev, "clock_in_out"); if (!strcmp(string, "input")) pdata->clock_input = true; @@ -71,11 +87,15 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) if (pdata->rx_delay == -ENOENT) pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10); - return designware_eth_ofdata_to_platdata(dev); + if (!pdata->has_gmac4) + return designware_eth_ofdata_to_platdata(dev); + + return 0; } -static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int px30_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct px30_grf *grf; struct clk clk_speed; int speed, ret; @@ -115,8 +135,9 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3228_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk322x_grf *grf; int clk; enum { @@ -148,8 +169,9 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3288_grf *grf; int clk; @@ -174,8 +196,9 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3308_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3308_grf *grf; struct clk clk_speed; int speed, ret; @@ -215,8 +238,9 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3328_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3328_grf_regs *grf; int clk; enum { @@ -248,8 +272,9 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_
[RESEND PATCH v2 07/11] net: dwc_eth_qos: Export common struct and interface at head file
Open structure data and interface, so that Soc using dw_eth_qos controller can reference. Signed-off-by: David Wu --- Changes in v2: - Add the lost head file. (Patrice) drivers/net/dwc_eth_qos.c | 81 drivers/net/dwc_eth_qos.h | 87 +++ 2 files changed, 96 insertions(+), 72 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 295707cbb0..b3195d484e 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -46,6 +46,7 @@ #include #include #endif +#include "dwc_eth_qos.h" /* Core registers */ @@ -100,9 +101,6 @@ struct eqos_mac_regs { #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT0 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff @@ -123,8 +121,6 @@ struct eqos_mac_regs { #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 -#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 -#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 #define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4) #define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT2 #define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3 @@ -277,65 +273,6 @@ struct eqos_desc { #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24) -struct eqos_config { - bool reg_access_always_ok; - int mdio_wait; - int swr_wait; - int config_mac; - int config_mac_mdio; - struct eqos_ops *ops; -}; - -struct eqos_ops { - void (*eqos_inval_desc)(void *desc); - void (*eqos_flush_desc)(void *desc); - void (*eqos_inval_buffer)(void *buf, size_t size); - void (*eqos_flush_buffer)(void *buf, size_t size); - int (*eqos_probe_resources)(struct udevice *dev); - int (*eqos_remove_resources)(struct udevice *dev); - int (*eqos_stop_resets)(struct udevice *dev); - int (*eqos_start_resets)(struct udevice *dev); - void (*eqos_stop_clks)(struct udevice *dev); - int (*eqos_start_clks)(struct udevice *dev); - int (*eqos_calibrate_pads)(struct udevice *dev); - int (*eqos_disable_calibration)(struct udevice *dev); - int (*eqos_set_tx_clk_speed)(struct udevice *dev); - ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); - phy_interface_t (*eqos_get_interface)(struct udevice *dev); -}; - -struct eqos_priv { - struct udevice *dev; - const struct eqos_config *config; - fdt_addr_t regs; - struct eqos_mac_regs *mac_regs; - struct eqos_mtl_regs *mtl_regs; - struct eqos_dma_regs *dma_regs; - struct eqos_tegra186_regs *tegra186_regs; - struct reset_ctl reset_ctl; - struct gpio_desc phy_reset_gpio; - u32 reset_delays[3]; - struct clk clk_master_bus; - struct clk clk_rx; - struct clk clk_ptp_ref; - struct clk clk_tx; - struct clk clk_ck; - struct clk clk_slave_bus; - struct mii_dev *mii; - struct phy_device *phy; - int phyaddr; - u32 max_speed; - void *descs; - struct eqos_desc *tx_descs; - struct eqos_desc *rx_descs; - int tx_desc_idx, rx_desc_idx; - void *tx_dma_buf; - void *rx_dma_buf; - void *rx_pkt; - bool started; - bool reg_access_ok; -}; - /* * TX and RX descriptors are 16 bytes. This causes problems with the cache * maintenance on CPUs where the cache-line size exceeds the size of these @@ -1121,7 +1058,7 @@ static int eqos_adjust_link(struct udevice *dev) return 0; } -static int eqos_write_hwaddr(struct udevice *dev) +int eqos_write_hwaddr(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct eqos_priv *eqos = dev_get_priv(dev); @@ -1175,7 +1112,7 @@ static int eqos_read_rom_hwaddr(struct udevice *dev) return !is_valid_ethaddr(pdata->enetaddr); } -static int eqos_init(struct udevice *dev) +int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -1286,7 +1223,7 @@ err: return ret; } -static void eqos_enable(struct udevice *dev) +void eqos_enable(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; @@ -1530,7 +1467,7 @@ static int eqos_start(struct udevice *dev) return 0; } -static void eqos_stop(struct udevice *dev) +void eqos_stop(struct udevice *dev) { struct eq
[RESEND PATCH v2 05/11] net: dwc_eth_qos: Split eqos_start() to get link speed
For Rockchip, need to obtain the current link speed to configure the tx clocks, (for example, in rgmii mode, 1000M link: 125M, 100M link: 25M, 10M link is 2.5M rate) and then enable gmac. So after the adjust_link(), before the start gamc, this intermediate stage needs to configure the clock according to the current link speed. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 56 ++- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index bec9bf556b..e503be5b4b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1175,19 +1175,15 @@ static int eqos_read_rom_hwaddr(struct udevice *dev) return !is_valid_ethaddr(pdata->enetaddr); } -static int eqos_start(struct udevice *dev) +static int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); - int ret, i; + int ret; ulong rate; - u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; - ulong last_rx_desc; + u32 val; debug("%s(dev=%p):\n", __func__, dev); - eqos->tx_desc_idx = 0; - eqos->rx_desc_idx = 0; - ret = eqos->config->ops->eqos_start_clks(dev); if (ret < 0) { pr_err("eqos_start_clks() failed: %d", ret); @@ -1273,6 +1269,30 @@ static int eqos_start(struct udevice *dev) goto err_shutdown_phy; } + debug("%s: OK\n", __func__); + return 0; + +err_shutdown_phy: + phy_shutdown(eqos->phy); +err_stop_resets: + eqos->config->ops->eqos_stop_resets(dev); +err_stop_clks: + eqos->config->ops->eqos_stop_clks(dev); +err: + pr_err("FAILED: %d", ret); + return ret; +} + +static void eqos_enable(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; + ulong last_rx_desc; + int i; + + eqos->tx_desc_idx = 0; + eqos->rx_desc_idx = 0; + /* Configure MTL */ writel(0x60, >mtl_regs->txq0_quantum_weight - 0x100); @@ -1492,19 +1512,19 @@ static int eqos_start(struct udevice *dev) writel(last_rx_desc, >dma_regs->ch0_rxdesc_tail_pointer); eqos->started = true; +} - debug("%s: OK\n", __func__); - return 0; +static int eqos_start(struct udevice *dev) +{ + int ret; -err_shutdown_phy: - phy_shutdown(eqos->phy); -err_stop_resets: - eqos->config->ops->eqos_stop_resets(dev); -err_stop_clks: - eqos->config->ops->eqos_stop_clks(dev); -err: - pr_err("FAILED: %d", ret); - return ret; + ret = eqos_init(dev); + if (ret) + return ret; + + eqos_enable(dev); + + return 0; } static void eqos_stop(struct udevice *dev) -- 2.19.1
[RESEND PATCH v2 03/11] net: dwc_eth_qos: Move interface() to eqos_ops structure
After moving to eqos_ops, if eqos_config is defined outside file, can not export interface() definition, only export eqos_ops struct defined in dwc_eth_qos.c. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 92dab678c7..ae2167637f 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -283,7 +283,6 @@ struct eqos_config { int swr_wait; int config_mac; int config_mac_mdio; - phy_interface_t (*interface)(struct udevice *dev); struct eqos_ops *ops; }; @@ -302,6 +301,7 @@ struct eqos_ops { int (*eqos_disable_calibration)(struct udevice *dev); int (*eqos_set_tx_clk_speed)(struct udevice *dev); ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); + phy_interface_t (*eqos_get_interface)(struct udevice *dev); }; struct eqos_priv { @@ -1227,7 +1227,7 @@ static int eqos_start(struct udevice *dev) addr = DWC_NET_PHYADDR; #endif eqos->phy = phy_connect(eqos->mii, addr, dev, - eqos->config->interface(dev)); +eqos->config->ops->eqos_get_interface(dev)); if (!eqos->phy) { pr_err("phy_connect() failed"); goto err_stop_resets; @@ -1827,7 +1827,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - interface = eqos->config->interface(dev); + interface = eqos->config->ops->eqos_get_interface(dev); if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n"); @@ -1938,7 +1938,7 @@ static int eqos_probe_resources_imx(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - interface = eqos->config->interface(dev); + interface = eqos->config->ops->eqos_get_interface(dev); if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n"); @@ -2122,7 +2122,8 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_tegra186, .eqos_disable_calibration = eqos_disable_calibration_tegra186, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186, + .eqos_get_interface = eqos_get_interface_tegra186 }; static const struct eqos_config eqos_tegra186_config = { @@ -2131,7 +2132,6 @@ static const struct eqos_config eqos_tegra186_config = { .swr_wait = 10, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, - .interface = eqos_get_interface_tegra186, .ops = _tegra186_ops }; @@ -2149,7 +2149,8 @@ static struct eqos_ops eqos_stm32_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_stm32, .eqos_disable_calibration = eqos_disable_calibration_stm32, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32, + .eqos_get_interface = eqos_get_interface_stm32 }; static const struct eqos_config eqos_stm32_config = { @@ -2158,7 +2159,6 @@ static const struct eqos_config eqos_stm32_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, - .interface = eqos_get_interface_stm32, .ops = _stm32_ops }; @@ -2176,7 +2176,8 @@ static struct eqos_ops eqos_imx_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_imx, .eqos_disable_calibration = eqos_disable_calibration_imx, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx, + .eqos_get_interface = eqos_get_interface_imx }; struct eqos_config eqos_imx_config = { @@ -2185,7 +2186,6 @@ struct eqos_config eqos_imx_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, - .interface = eqos_get_interface_imx, .ops = _imx_ops }; -- 2.19.1
[RESEND PATCH v2 06/11] net: dwc_eth_qos: make eqos_start_clks and eqos_stop_clks optional
If there are definitions for eqos_start_clks and eqos_stop_clks, then call these callback function. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e503be5b4b..295707cbb0 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1184,10 +1184,12 @@ static int eqos_init(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - ret = eqos->config->ops->eqos_start_clks(dev); - if (ret < 0) { - pr_err("eqos_start_clks() failed: %d", ret); - goto err; + if (eqos->config->ops->eqos_start_clks) { + ret = eqos->config->ops->eqos_start_clks(dev); + if (ret < 0) { + pr_err("eqos_start_clks() failed: %d", ret); + goto err; + } } ret = eqos->config->ops->eqos_start_resets(dev); @@ -1277,7 +1279,8 @@ err_shutdown_phy: err_stop_resets: eqos->config->ops->eqos_stop_resets(dev); err_stop_clks: - eqos->config->ops->eqos_stop_clks(dev); + if (eqos->config->ops->eqos_stop_clks) + eqos->config->ops->eqos_stop_clks(dev); err: pr_err("FAILED: %d", ret); return ret; @@ -1576,7 +1579,8 @@ static void eqos_stop(struct udevice *dev) phy_shutdown(eqos->phy); } eqos->config->ops->eqos_stop_resets(dev); - eqos->config->ops->eqos_stop_clks(dev); + if (eqos->config->ops->eqos_stop_clks) + eqos->config->ops->eqos_stop_clks(dev); debug("%s: OK\n", __func__); } -- 2.19.1
[RESEND PATCH v2 00/11] Add dwc_eth_qos support for rockchip
Rockchip Socs can support two controllers "snps, dwmac-4.20a" and "snps, dwmac-3.50". In order to support two at gmac-rockchip.c, export public interface functions and struct data, it will be more general for others. Changes in v2: - None - Remove the code is not related (Patrice) - None - Don't change the Rx and Tx clock names. (Patrice, Stephen) - None - None - Add the lost head file. (Patrice) - None - None - None - None David Wu (11): net: dwc_eth_qos: Use dev_ functions calls to get FDT data net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32 net: dwc_eth_qos: Move interface() to eqos_ops structure net: dwc_eth_qos: Make clk_rx and clk_tx optional net: dwc_eth_qos: Split eqos_start() to get link speed net: dwc_eth_qos: make eqos_start_clks and eqos_stop_clks optional net: dwc_eth_qos: Export common struct and interface at head file net: gmac_rockchip: Add dwc_eth_qos support net: dwc_eth_qos: Add eqos_rockchip_ops net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip net: gmac_rockchip: Add RV1126 gmac support drivers/net/Kconfig | 2 +- drivers/net/dwc_eth_qos.c | 279 ++-- drivers/net/dwc_eth_qos.h | 89 drivers/net/gmac_rockchip.c | 188 4 files changed, 393 insertions(+), 165 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h -- 2.19.1
[RESEND PATCH v2 01/11] net: dwc_eth_qos: Use dev_ functions calls to get FDT data
It seems dev_ functions are more general than fdt_ functions. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index f67c5f4570..66a02aa80b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1889,8 +1889,7 @@ static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", - NULL); + phy_mode = dev_read_string(dev, "phy-mode"); if (phy_mode) interface = phy_get_interface_by_name(phy_mode); @@ -1991,9 +1990,9 @@ static int eqos_probe(struct udevice *dev) eqos->dev = dev; eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = devfdt_get_addr(dev); + eqos->regs = dev_read_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("devfdt_get_addr() failed"); + pr_err("dev_read_addr() failed"); return -ENODEV; } eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); -- 2.19.1
[RESEND PATCH v2 02/11] net: dwc_eth_qos: Add option "snps, reset-gpio" phy-rst gpio for stm32
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general. Signed-off-by: David Wu --- Changes in v2: - Remove the code is not related (Patrice) drivers/net/dwc_eth_qos.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 66a02aa80b..92dab678c7 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -314,6 +314,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio; + u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref; @@ -739,6 +740,15 @@ static int eqos_start_resets_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(>phy_reset_gpio)) { + ret = dm_gpio_set_value(>phy_reset_gpio, 0); + if (ret < 0) { + pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", + ret); + return ret; + } + + udelay(eqos->reset_delays[0]); + ret = dm_gpio_set_value(>phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", @@ -746,7 +756,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; } - udelay(2); + udelay(eqos->reset_delays[1]); ret = dm_gpio_set_value(>phy_reset_gpio, 0); if (ret < 0) { @@ -754,6 +764,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; } + + udelay(eqos->reset_delays[2]); } debug("%s: OK\n", __func__); @@ -1864,11 +1876,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret); + else + eqos->reset_delays[1] = 2; eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); } + if (!dm_gpio_is_valid(>phy_reset_gpio)) { + int reset_flags = GPIOD_IS_OUT; + + if (dev_read_bool(dev, "snps,reset-active-low")) + reset_flags |= GPIOD_ACTIVE_LOW; + + ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, + >phy_reset_gpio, reset_flags); + if (ret == 0) + ret = dev_read_u32_array(dev, "snps,reset-delays-us", +eqos->reset_delays, 3); + else + pr_warn("gpio_request_by_name(snps,reset-gpio) failed: %d", + ret); + } + debug("%s: OK\n", __func__); return 0; -- 2.19.1
[RESEND PATCH v2 04/11] net: dwc_eth_qos: Make clk_rx and clk_tx optional
For others using, clk_rx and clk_tx may not be necessary, and their clock names are different. Signed-off-by: David Wu --- Changes in v2: - Don't change the Rx and Tx clock names. (Patrice, Stephen) drivers/net/dwc_eth_qos.c | 61 +++ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index ae2167637f..bec9bf556b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -613,16 +613,20 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err; } - ret = clk_enable(>clk_rx); - if (ret < 0) { - pr_err("clk_enable(clk_rx) failed: %d", ret); - goto err_disable_clk_master_bus; + if (clk_valid(>clk_rx)) { + ret = clk_enable(>clk_rx); + if (ret < 0) { + pr_err("clk_enable(clk_rx) failed: %d", ret); + goto err_disable_clk_master_bus; + } } - ret = clk_enable(>clk_tx); - if (ret < 0) { - pr_err("clk_enable(clk_tx) failed: %d", ret); - goto err_disable_clk_rx; + if (clk_valid(>clk_tx)) { + ret = clk_enable(>clk_tx); + if (ret < 0) { + pr_err("clk_enable(clk_tx) failed: %d", ret); + goto err_disable_clk_rx; + } } if (clk_valid(>clk_ck)) { @@ -639,9 +643,11 @@ static int eqos_start_clks_stm32(struct udevice *dev) #ifdef CONFIG_CLK err_disable_clk_tx: - clk_disable(>clk_tx); + if (clk_valid(>clk_tx)) + clk_disable(>clk_tx); err_disable_clk_rx: - clk_disable(>clk_rx); + if (clk_valid(>clk_rx)) + clk_disable(>clk_rx); err_disable_clk_master_bus: clk_disable(>clk_master_bus); err: @@ -679,8 +685,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_disable(>clk_tx); - clk_disable(>clk_rx); + if (clk_valid(>clk_tx)) + clk_disable(>clk_tx); + if (clk_valid(>clk_rx)) + clk_disable(>clk_rx); clk_disable(>clk_master_bus); if (clk_valid(>clk_ck)) clk_disable(>clk_ck); @@ -1843,20 +1851,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", >clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret); - goto err_probe; + return ret; } ret = clk_get_by_name(dev, "mac-clk-rx", >clk_rx); - if (ret) { - pr_err("clk_get_by_name(rx) failed: %d", ret); - goto err_free_clk_master_bus; - } + if (ret) + pr_warn("clk_get_by_name(rx) failed: %d", ret); ret = clk_get_by_name(dev, "mac-clk-tx", >clk_tx); - if (ret) { - pr_err("clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_rx; - } + if (ret) + pr_warn("clk_get_by_name(tx) failed: %d", ret); /* Get ETH_CLK clocks (optional) */ ret = clk_get_by_name(dev, "eth-ck", >clk_ck); @@ -1901,15 +1905,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev) debug("%s: OK\n", __func__); return 0; - -err_free_clk_rx: - clk_free(>clk_rx); -err_free_clk_master_bus: - clk_free(>clk_master_bus); -err_probe: - - debug("%s: returns %d\n", __func__, ret); - return ret; } static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) @@ -1991,8 +1986,10 @@ static int eqos_remove_resources_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_free(>clk_tx); - clk_free(>clk_rx); + if (clk_valid(>clk_tx)) + clk_free(>clk_tx); + if (clk_valid(>clk_rx)) + clk_free(>clk_rx); clk_free(>clk_master_bus); if (clk_valid(>clk_ck)) clk_free(>clk_ck); -- 2.19.1
Re: [PATCH 6/8] net: dwc_eth_qos: Split eqos_start() to get link speed
Hi Patrice, 在 2020/5/11 下午8:48, Patrice CHOTARD 写道: Hi David On 5/9/20 8:42 AM, David Wu wrote: Hi Patrice, 在 2020/4/30 下午11:33, Patrice CHOTARD 写道: Can you explain why you are splitting this function in 2 parts and calling these parts sequentially ? For rockchip, need to obtain the current link speed to configure the tx clocks, (for example, in rgmii mode, 1000M link: 125M, 100M link: 25M, 10M link is 2.5M rate) and then enable gmac. So after the adjust_link(), before the start gamc, this intermediate stage needs to configure the clock according to the current link speed. Please, add these informations in the commit message I will add it at the next version, Thanks. Thanks Patrice
[PATCH v2 07/11] net: dwc_eth_qos: Export common struct and interface at head file
Open structure data and interface, so that Soc using dw_eth_qos controller can reference. Signed-off-by: David Wu --- Changes in v2: - Add the lost head file. (Patrice) drivers/net/dwc_eth_qos.c | 81 drivers/net/dwc_eth_qos.h | 87 +++ 2 files changed, 96 insertions(+), 72 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 86e5a01d44..d6c0622de6 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -41,6 +41,7 @@ #include #include #include +#include "dwc_eth_qos.h" /* Core registers */ @@ -94,9 +95,6 @@ struct eqos_mac_regs { #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT0 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff @@ -109,8 +107,6 @@ struct eqos_mac_regs { #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 -#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 -#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 #define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4) #define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT2 #define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3 @@ -261,65 +257,6 @@ struct eqos_desc { #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24) -struct eqos_config { - bool reg_access_always_ok; - int mdio_wait; - int swr_wait; - int config_mac; - int config_mac_mdio; - struct eqos_ops *ops; -}; - -struct eqos_ops { - void (*eqos_inval_desc)(void *desc); - void (*eqos_flush_desc)(void *desc); - void (*eqos_inval_buffer)(void *buf, size_t size); - void (*eqos_flush_buffer)(void *buf, size_t size); - int (*eqos_probe_resources)(struct udevice *dev); - int (*eqos_remove_resources)(struct udevice *dev); - int (*eqos_stop_resets)(struct udevice *dev); - int (*eqos_start_resets)(struct udevice *dev); - void (*eqos_stop_clks)(struct udevice *dev); - int (*eqos_start_clks)(struct udevice *dev); - int (*eqos_calibrate_pads)(struct udevice *dev); - int (*eqos_disable_calibration)(struct udevice *dev); - int (*eqos_set_tx_clk_speed)(struct udevice *dev); - ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); - phy_interface_t (*eqos_get_interface)(struct udevice *dev); -}; - -struct eqos_priv { - struct udevice *dev; - const struct eqos_config *config; - fdt_addr_t regs; - struct eqos_mac_regs *mac_regs; - struct eqos_mtl_regs *mtl_regs; - struct eqos_dma_regs *dma_regs; - struct eqos_tegra186_regs *tegra186_regs; - struct reset_ctl reset_ctl; - struct gpio_desc phy_reset_gpio; - u32 reset_delays[3]; - struct clk clk_master_bus; - struct clk clk_rx; - struct clk clk_ptp_ref; - struct clk clk_tx; - struct clk clk_ck; - struct clk clk_slave_bus; - struct mii_dev *mii; - struct phy_device *phy; - int phyaddr; - u32 max_speed; - void *descs; - struct eqos_desc *tx_descs; - struct eqos_desc *rx_descs; - int tx_desc_idx, rx_desc_idx; - void *tx_dma_buf; - void *rx_dma_buf; - void *rx_pkt; - bool started; - bool reg_access_ok; -}; - /* * TX and RX descriptors are 16 bytes. This causes problems with the cache * maintenance on CPUs where the cache-line size exceeds the size of these @@ -1007,7 +944,7 @@ static int eqos_adjust_link(struct udevice *dev) return 0; } -static int eqos_write_hwaddr(struct udevice *dev) +int eqos_write_hwaddr(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct eqos_priv *eqos = dev_get_priv(dev); @@ -1051,7 +988,7 @@ static int eqos_write_hwaddr(struct udevice *dev) return 0; } -static int eqos_init(struct udevice *dev) +int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -1155,7 +1092,7 @@ err: return ret; } -static void eqos_enable(struct udevice *dev) +void eqos_enable(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; @@ -1381,7 +1318,7 @@ static int eqos_start(struct udevice *dev) return 0; } -static void eqos_stop(struct udevice *dev) +void eqos_stop(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int i;
[PATCH v2 10/11] net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip
The Rockchip CSR clock range is from 100M to 150M, add EQOS_MAC_MDIO_ADDRESS_CR_100_150. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index def2706271..39f8452c17 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -12,10 +12,10 @@ #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 +#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1 #define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 - struct eqos_config { bool reg_access_always_ok; int mdio_wait; -- 2.19.1
Re: [PATCH v2 10/11] net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip
Discard this duplicate patch. 在 2020/5/11 下午3:08, David Wu 写道: The Rockchip CSR clock range is from 100M to 150M, add EQOS_MAC_MDIO_ADDRESS_CR_100_150. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index def2706271..39f8452c17 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -12,10 +12,10 @@ #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 +#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1 #define EQOS_MAC_MDIO_ADDRESS_CR_20_352 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 - struct eqos_config { bool reg_access_always_ok; int mdio_wait;
[PATCH v2 11/11] net: gmac_rockchip: Add RV1126 gmac support
This Soc is different from the previous Socs, need to define eqos_config, and follow the dwc_eth_qos driver process. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/gmac_rockchip.c | 28 1 file changed, 28 insertions(+) diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index aa2bab4203..d48a0f516b 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -368,6 +368,13 @@ static int rv1108_set_rmii_speed(struct rockchip_eth_dev *dev) return 0; } +static int rv1126_set_rgmii_speed(struct rockchip_eth_dev *dev) +{ + /* TO DO... */ + + return 0; +} + static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) { struct px30_grf *grf; @@ -577,6 +584,11 @@ static void rv1108_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) RV1108_GMAC_PHY_INTF_SEL_RMII); } +static void rv1126_set_to_rgmii(struct gmac_rockchip_platdata *pdata) +{ + /* TO DO... */ +} + static int gmac_rockchip_probe(struct udevice *dev) { struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); @@ -837,6 +849,20 @@ const struct rk_gmac_ops rv1108_gmac_ops = { .set_to_rmii = rv1108_gmac_set_to_rmii, }; +const struct rk_gmac_ops rv1126_gmac_ops = { + .config = { + .reg_access_always_ok = false, + .mdio_wait = 1, + .swr_wait = 200, + .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED, + .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150, + .ops = _rockchip_ops + }, + + .fix_mac_speed = rv1126_set_rgmii_speed, + .set_to_rgmii = rv1126_set_to_rgmii, +}; + static const struct udevice_id rockchip_gmac_ids[] = { { .compatible = "rockchip,px30-gmac", .data = (ulong)_gmac_ops }, @@ -854,6 +880,8 @@ static const struct udevice_id rockchip_gmac_ids[] = { .data = (ulong)_gmac_ops }, { .compatible = "rockchip,rv1108-gmac", .data = (ulong)_gmac_ops }, + { .compatible = "rockchip,rv1126-gmac", + .data = (ulong)_gmac_ops }, { } }; -- 2.19.1
[PATCH v2 10/11] net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip
The Rockchip CSR clock range is from 100M to 150M, add EQOS_MAC_MDIO_ADDRESS_CR_100_150. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index def2706271..39f8452c17 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -12,10 +12,10 @@ #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 +#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1 #define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 #define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 - struct eqos_config { bool reg_access_always_ok; int mdio_wait; -- 2.19.1
[PATCH v2 09/11] net: dwc_eth_qos: Add eqos_rockchip_ops
The eqos_rockchip_ops is simillar to eqos_stm32_ops, and export the eqos_rockchip_ops to use. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 16 drivers/net/dwc_eth_qos.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index d6c0622de6..7453b92f40 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1907,6 +1907,22 @@ static const struct eqos_config eqos_stm32_config = { .ops = _stm32_ops }; +struct eqos_ops eqos_rockchip_ops = { + .eqos_inval_desc = eqos_inval_desc_stm32, + .eqos_flush_desc = eqos_flush_desc_stm32, + .eqos_inval_buffer = eqos_inval_buffer_stm32, + .eqos_flush_buffer = eqos_flush_buffer_stm32, + .eqos_probe_resources = eqos_probe_resources_stm32, + .eqos_remove_resources = eqos_remove_resources_stm32, + .eqos_stop_resets = eqos_stop_resets_stm32, + .eqos_start_resets = eqos_start_resets_stm32, + .eqos_calibrate_pads = eqos_calibrate_pads_stm32, + .eqos_disable_calibration = eqos_disable_calibration_stm32, + .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32, + .eqos_get_interface = eqos_get_interface_stm32 +}; + static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 3125a301f0..def2706271 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -84,4 +84,6 @@ int eqos_recv(struct udevice *dev, int flags, uchar **packetp); int eqos_free_pkt(struct udevice *dev, uchar *packet, int length); int eqos_write_hwaddr(struct udevice *dev); +extern struct eqos_ops eqos_rockchip_ops; + #endif -- 2.19.1
[PATCH v2 08/11] net: gmac_rockchip: Add dwc_eth_qos support
Change the original data structure so that Rockchip's Soc gmac controller can support the designware.c and dwc_eth_qos.c drivers, a Soc can only support one. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/Kconfig | 2 +- drivers/net/gmac_rockchip.c | 160 ++-- 2 files changed, 135 insertions(+), 27 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4d1013c984..07d2b0787c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -482,7 +482,7 @@ config PIC32_ETH config GMAC_ROCKCHIP bool "Rockchip Synopsys Designware Ethernet MAC" - depends on DM_ETH && ETH_DESIGNWARE + depends on DM_ETH && (ETH_DESIGNWARE || DWC_ETH_QOS) help This driver provides Rockchip SoCs network support based on the Synopsys Designware driver. diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index e152faf083..aa2bab4203 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -25,26 +25,39 @@ #include #include #include "designware.h" +#include "dwc_eth_qos.h" DECLARE_GLOBAL_DATA_PTR; #define DELAY_ENABLE(soc, tx, rx) \ (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \ ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE)) +struct rockchip_eth_dev { + union { + struct eqos_priv eqos; + struct dw_eth_dev dw; + }; +}; + /* * Platform data for the gmac * * dw_eth_pdata: Required platform data for designware driver (must be first) */ struct gmac_rockchip_platdata { - struct dw_eth_pdata dw_eth_pdata; + union { + struct dw_eth_pdata dw_eth_pdata; + struct eth_pdata eth_pdata; + }; + bool has_gmac4; bool clock_input; int tx_delay; int rx_delay; }; struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); + const struct eqos_config config; + int (*fix_mac_speed)(struct rockchip_eth_dev *dev); void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); }; @@ -55,6 +68,9 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); const char *string; + if (device_is_compatible(dev, "snps,dwmac-4.20a")) + pdata->has_gmac4 = true; + string = dev_read_string(dev, "clock_in_out"); if (!strcmp(string, "input")) pdata->clock_input = true; @@ -71,11 +87,15 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) if (pdata->rx_delay == -ENOENT) pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10); - return designware_eth_ofdata_to_platdata(dev); + if (!pdata->has_gmac4) + return designware_eth_ofdata_to_platdata(dev); + + return 0; } -static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int px30_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct px30_grf *grf; struct clk clk_speed; int speed, ret; @@ -115,8 +135,9 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3228_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk322x_grf *grf; int clk; enum { @@ -148,8 +169,9 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3288_grf *grf; int clk; @@ -174,8 +196,9 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3308_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3308_grf *grf; struct clk clk_speed; int speed, ret; @@ -215,8 +238,9 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3328_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3328_grf_regs *grf; int clk; enum { @@ -248,8 +272,9 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_
[PATCH v2 06/11] net: dwc_eth_qos: make eqos_start_clks and eqos_stop_clks optional
If there are definitions for eqos_start_clks and eqos_stop_clks, then call these callback function. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index c6a1eed7de..86e5a01d44 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1060,10 +1060,12 @@ static int eqos_init(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - ret = eqos->config->ops->eqos_start_clks(dev); - if (ret < 0) { - pr_err("eqos_start_clks() failed: %d", ret); - goto err; + if (eqos->config->ops->eqos_start_clks) { + ret = eqos->config->ops->eqos_start_clks(dev); + if (ret < 0) { + pr_err("eqos_start_clks() failed: %d", ret); + goto err; + } } ret = eqos->config->ops->eqos_start_resets(dev); @@ -1146,7 +1148,8 @@ err_shutdown_phy: err_stop_resets: eqos->config->ops->eqos_stop_resets(dev); err_stop_clks: - eqos->config->ops->eqos_stop_clks(dev); + if (eqos->config->ops->eqos_stop_clks) + eqos->config->ops->eqos_stop_clks(dev); err: pr_err("FAILED: %d", ret); return ret; @@ -1427,7 +1430,8 @@ static void eqos_stop(struct udevice *dev) phy_shutdown(eqos->phy); } eqos->config->ops->eqos_stop_resets(dev); - eqos->config->ops->eqos_stop_clks(dev); + if (eqos->config->ops->eqos_stop_clks) + eqos->config->ops->eqos_stop_clks(dev); debug("%s: OK\n", __func__); } -- 2.19.1
[PATCH v2 05/11] net: dwc_eth_qos: Split eqos_start() to get link speed
For Rockchip, before enabling mac and mac working, we need to obtain the current link speed to configure the TX/RX clocks, so split eqos_start into two functions. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 56 ++- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 30e72a9d7d..c6a1eed7de 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1051,19 +1051,15 @@ static int eqos_write_hwaddr(struct udevice *dev) return 0; } -static int eqos_start(struct udevice *dev) +static int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); - int ret, i; + int ret; ulong rate; - u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; - ulong last_rx_desc; + u32 val; debug("%s(dev=%p):\n", __func__, dev); - eqos->tx_desc_idx = 0; - eqos->rx_desc_idx = 0; - ret = eqos->config->ops->eqos_start_clks(dev); if (ret < 0) { pr_err("eqos_start_clks() failed: %d", ret); @@ -1142,6 +1138,30 @@ static int eqos_start(struct udevice *dev) goto err_shutdown_phy; } + debug("%s: OK\n", __func__); + return 0; + +err_shutdown_phy: + phy_shutdown(eqos->phy); +err_stop_resets: + eqos->config->ops->eqos_stop_resets(dev); +err_stop_clks: + eqos->config->ops->eqos_stop_clks(dev); +err: + pr_err("FAILED: %d", ret); + return ret; +} + +static void eqos_enable(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; + ulong last_rx_desc; + int i; + + eqos->tx_desc_idx = 0; + eqos->rx_desc_idx = 0; + /* Configure MTL */ /* Enable Store and Forward mode for TX */ @@ -1343,19 +1363,19 @@ static int eqos_start(struct udevice *dev) writel(last_rx_desc, >dma_regs->ch0_rxdesc_tail_pointer); eqos->started = true; +} - debug("%s: OK\n", __func__); - return 0; +static int eqos_start(struct udevice *dev) +{ + int ret; -err_shutdown_phy: - phy_shutdown(eqos->phy); -err_stop_resets: - eqos->config->ops->eqos_stop_resets(dev); -err_stop_clks: - eqos->config->ops->eqos_stop_clks(dev); -err: - pr_err("FAILED: %d", ret); - return ret; + ret = eqos_init(dev); + if (ret) + return ret; + + eqos_enable(dev); + + return 0; } static void eqos_stop(struct udevice *dev) -- 2.19.1
[PATCH v2 01/11] net: dwc_eth_qos: Use dev_ functions calls to get FDT data
It seems dev_ functions are more general than fdt_ functions. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 63f2086dec..a72132cacf 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1728,8 +1728,7 @@ static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", - NULL); + phy_mode = dev_read_string(dev, "phy-mode"); if (phy_mode) interface = phy_get_interface_by_name(phy_mode); @@ -1788,9 +1787,9 @@ static int eqos_probe(struct udevice *dev) eqos->dev = dev; eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = devfdt_get_addr(dev); + eqos->regs = dev_read_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("devfdt_get_addr() failed"); + pr_err("dev_read_addr() failed"); return -ENODEV; } eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); -- 2.19.1
[PATCH v2 04/11] net: dwc_eth_qos: Make clk_rx and clk_tx optional
For others using, clk_rx and clk_tx may not be necessary, and their clock names are different. Signed-off-by: David Wu --- Changes in v2: - Don't change the Rx and Tx clock names. (Patrice, Stephen) drivers/net/dwc_eth_qos.c | 61 +++ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 613cfb48ea..30e72a9d7d 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -592,16 +592,20 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err; } - ret = clk_enable(>clk_rx); - if (ret < 0) { - pr_err("clk_enable(clk_rx) failed: %d", ret); - goto err_disable_clk_master_bus; + if (clk_valid(>clk_rx)) { + ret = clk_enable(>clk_rx); + if (ret < 0) { + pr_err("clk_enable(clk_rx) failed: %d", ret); + goto err_disable_clk_master_bus; + } } - ret = clk_enable(>clk_tx); - if (ret < 0) { - pr_err("clk_enable(clk_tx) failed: %d", ret); - goto err_disable_clk_rx; + if (clk_valid(>clk_tx)) { + ret = clk_enable(>clk_tx); + if (ret < 0) { + pr_err("clk_enable(clk_tx) failed: %d", ret); + goto err_disable_clk_rx; + } } if (clk_valid(>clk_ck)) { @@ -616,9 +620,11 @@ static int eqos_start_clks_stm32(struct udevice *dev) return 0; err_disable_clk_tx: - clk_disable(>clk_tx); + if (clk_valid(>clk_tx)) + clk_disable(>clk_tx); err_disable_clk_rx: - clk_disable(>clk_rx); + if (clk_valid(>clk_rx)) + clk_disable(>clk_rx); err_disable_clk_master_bus: clk_disable(>clk_master_bus); err: @@ -647,8 +653,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_disable(>clk_tx); - clk_disable(>clk_rx); + if (clk_valid(>clk_tx)) + clk_disable(>clk_tx); + if (clk_valid(>clk_rx)) + clk_disable(>clk_rx); clk_disable(>clk_master_bus); if (clk_valid(>clk_ck)) clk_disable(>clk_ck); @@ -1682,20 +1690,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", >clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret); - goto err_probe; + return ret; } ret = clk_get_by_name(dev, "mac-clk-rx", >clk_rx); - if (ret) { - pr_err("clk_get_by_name(rx) failed: %d", ret); - goto err_free_clk_master_bus; - } + if (ret) + pr_warn("clk_get_by_name(rx) failed: %d", ret); ret = clk_get_by_name(dev, "mac-clk-tx", >clk_tx); - if (ret) { - pr_err("clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_rx; - } + if (ret) + pr_warn("clk_get_by_name(tx) failed: %d", ret); /* Get ETH_CLK clocks (optional) */ ret = clk_get_by_name(dev, "eth-ck", >clk_ck); @@ -1740,15 +1744,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev) debug("%s: OK\n", __func__); return 0; - -err_free_clk_rx: - clk_free(>clk_rx); -err_free_clk_master_bus: - clk_free(>clk_master_bus); -err_probe: - - debug("%s: returns %d\n", __func__, ret); - return ret; } static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) @@ -1794,8 +1789,10 @@ static int eqos_remove_resources_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_free(>clk_tx); - clk_free(>clk_rx); + if (clk_valid(>clk_tx)) + clk_free(>clk_tx); + if (clk_valid(>clk_rx)) + clk_free(>clk_rx); clk_free(>clk_master_bus); if (clk_valid(>clk_ck)) clk_free(>clk_ck); -- 2.19.1
[PATCH v2 03/11] net: dwc_eth_qos: Move interface() to eqos_ops structure
After moving to eqos_ops, if eqos_config is defined outside file, can not export interface() definition, only export eqos_ops struct defined in dwc_eth_qos.c. Signed-off-by: David Wu --- Changes in v2: - None drivers/net/dwc_eth_qos.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 54866aff6b..613cfb48ea 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -267,7 +267,6 @@ struct eqos_config { int swr_wait; int config_mac; int config_mac_mdio; - phy_interface_t (*interface)(struct udevice *dev); struct eqos_ops *ops; }; @@ -286,6 +285,7 @@ struct eqos_ops { int (*eqos_disable_calibration)(struct udevice *dev); int (*eqos_set_tx_clk_speed)(struct udevice *dev); ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); + phy_interface_t (*eqos_get_interface)(struct udevice *dev); }; struct eqos_priv { @@ -1096,7 +1096,7 @@ static int eqos_start(struct udevice *dev) */ if (!eqos->phy) { eqos->phy = phy_connect(eqos->mii, eqos->phyaddr, dev, - eqos->config->interface(dev)); + eqos->config->ops->eqos_get_interface(dev)); if (!eqos->phy) { pr_err("phy_connect() failed"); goto err_stop_resets; @@ -1666,7 +1666,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - interface = eqos->config->interface(dev); + interface = eqos->config->ops->eqos_get_interface(dev); if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n"); @@ -1909,7 +1909,8 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_tegra186, .eqos_disable_calibration = eqos_disable_calibration_tegra186, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186, + .eqos_get_interface = eqos_get_interface_tegra186 }; static const struct eqos_config eqos_tegra186_config = { @@ -1918,7 +1919,6 @@ static const struct eqos_config eqos_tegra186_config = { .swr_wait = 10, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, - .interface = eqos_get_interface_tegra186, .ops = _tegra186_ops }; @@ -1936,7 +1936,8 @@ static struct eqos_ops eqos_stm32_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_stm32, .eqos_disable_calibration = eqos_disable_calibration_stm32, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32, + .eqos_get_interface = eqos_get_interface_stm32 }; static const struct eqos_config eqos_stm32_config = { @@ -1945,7 +1946,6 @@ static const struct eqos_config eqos_stm32_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, - .interface = eqos_get_interface_stm32, .ops = _stm32_ops }; -- 2.19.1
[PATCH v2 02/11] net: dwc_eth_qos: Add option "snps, reset-gpio" phy-rst gpio for stm32
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general. Signed-off-by: David Wu --- Changes in v2: - Remove the code is not related (Patrice) drivers/net/dwc_eth_qos.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index a72132cacf..54866aff6b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -298,6 +298,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio; + u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref; @@ -701,6 +702,15 @@ static int eqos_start_resets_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(>phy_reset_gpio)) { + ret = dm_gpio_set_value(>phy_reset_gpio, 0); + if (ret < 0) { + pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", + ret); + return ret; + } + + udelay(eqos->reset_delays[0]); + ret = dm_gpio_set_value(>phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", @@ -708,7 +718,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; } - udelay(2); + udelay(eqos->reset_delays[1]); ret = dm_gpio_set_value(>phy_reset_gpio, 0); if (ret < 0) { @@ -716,6 +726,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; } + + udelay(eqos->reset_delays[2]); } debug("%s: OK\n", __func__); @@ -1703,11 +1715,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret); + else + eqos->reset_delays[1] = 2; eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); } + if (!dm_gpio_is_valid(>phy_reset_gpio)) { + int reset_flags = GPIOD_IS_OUT; + + if (dev_read_bool(dev, "snps,reset-active-low")) + reset_flags |= GPIOD_ACTIVE_LOW; + + ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, + >phy_reset_gpio, reset_flags); + if (ret == 0) + ret = dev_read_u32_array(dev, "snps,reset-delays-us", +eqos->reset_delays, 3); + else + pr_warn("gpio_request_by_name(snps,reset-gpio) failed: %d", + ret); + } + debug("%s: OK\n", __func__); return 0; -- 2.19.1
[PATCH v2 00/11] Add dwc_eth_qos support for rockchip
Rockchip Socs can support two controllers "snps, dwmac-4.20a" and "snps, dwmac-3.50". In order to support two at gmac-rockchip.c, export public interface functions and struct data, it will be more general for others. Changes in v2: - None - Remove the code is not related (Patrice) - None - Don't change the Rx and Tx clock names. (Patrice, Stephen) - None - None - Add the lost head file. (Patrice) - None - None - None - None David Wu (11): net: dwc_eth_qos: Use dev_ functions calls to get FDT data net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32 net: dwc_eth_qos: Move interface() to eqos_ops structure net: dwc_eth_qos: Make clk_rx and clk_tx optional net: dwc_eth_qos: Split eqos_start() to get link speed net: dwc_eth_qos: make eqos_start_clks and eqos_stop_clks optional net: dwc_eth_qos: Export common struct and interface at head file net: gmac_rockchip: Add dwc_eth_qos support net: dwc_eth_qos: Add eqos_rockchip_ops net: dwc_eth_qos: Add EQOS_MAC_MDIO_ADDRESS_CR_100_150 for Rockchip net: gmac_rockchip: Add RV1126 gmac support drivers/net/Kconfig | 2 +- drivers/net/dwc_eth_qos.c | 273 ++-- drivers/net/dwc_eth_qos.h | 89 drivers/net/gmac_rockchip.c | 188 + 4 files changed, 390 insertions(+), 162 deletions(-) create mode 100644 drivers/net/dwc_eth_qos.h -- 2.19.1
Re: [PATCH 8/8] net: gmac_rockchip: Add dwc_eth_qos support
Hi Stephen, 在 2020/5/1 上午6:52, Stephen Warren 写道: I'm really confused; with a filename like gmac_rockchip.c that sounds like it's driver for a MAC device. DWC EQoS is also a MAC device. The two shouldn't be related or coupled in any way. I think what you need is to completely drop this patch (and the patch which creates dwc_eth_qos.h), and instead make the DWC EQoS driver itself directly support the Rockchip SoC by adding RK's compatible value to the list of compatible values that the EQoS driver supports, along with new probe functions etc. Maybe this requires splitting some PHY code out of gmac_rockchip into a common/separate PHY driver? I haven't looked at the code to know if that's required. I think this relationship is like the current designware.c and gmac_rockchip.c, except that the designware driver becomes DWC EQoS. In fact, most of the code is the same, because it is the same controller, and there are a few differences related to Soc implemented in gmac_rockchip.c, this is the purpose of my series of patches, and the code must be compatible with the previous Rockchip Socs.
Re: [PATCH 6/8] net: dwc_eth_qos: Split eqos_start() to get link speed
Hi Patrice, 在 2020/4/30 下午11:33, Patrice CHOTARD 写道: Can you explain why you are splitting this function in 2 parts and calling these parts sequentially ? For rockchip, need to obtain the current link speed to configure the tx clocks, (for example, in rgmii mode, 1000M link: 125M, 100M link: 25M, 10M link is 2.5M rate) and then enable gmac. So after the adjust_link(), before the start gamc, this intermediate stage needs to configure the clock according to the current link speed.
Re: [PATCH 5/8] net: dwc_eth_qos: Make clk_rx and clk_tx optional
Hi Stephen, 在 2020/5/1 上午6:45, Stephen Warren 写道: Oh... Judging by your email, you're trying to make this driver work on a Rockchip system. However, you're editing an STM32-specific probe function. You should introduce a new probe function for Rockchip if it needs to work differently to the existing STM32 code. Also, mac_clk_rx isn't a valid DT property name; they aren't supposed to have _ in them. I don't see mac_clk_rx or mac-clk-rx in the DT binding file in Documentation/bindings/net/rockchip-dwmac.txt the kernel. That should probably be submitted/reviewed/applied before using the binding... If necessary, I can rewrite a function to obtain resources, but I think the function of rockchip and stm should be very similar, and can be shared.
Re: [PATCH 5/8] net: dwc_eth_qos: Make clk_rx and clk_tx optional
Hi Patrice, 在 2020/4/30 下午10:00, Patrice CHOTARD 写道: @@ -647,8 +653,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_disable(>clk_tx); - clk_disable(>clk_rx); + if (clk_valid(>clk_tx)) + clk_disable(>clk_tx); + if (clk_valid(>clk_rx)) + clk_disable(>clk_rx); clk_disable(>clk_master_bus); if (clk_valid(>clk_ck)) clk_disable(>clk_ck); @@ -1691,20 +1699,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", >clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret); - goto err_probe; + return ret; } why are you changing the error path here ? The following code has not returned, so for the sake of simpler code, return directly. - ret = clk_get_by_name(dev, "mac-clk-rx", >clk_rx); - if (ret) { - pr_err("clk_get_by_name(rx) failed: %d", ret); - goto err_free_clk_master_bus; - } + ret = clk_get_by_name(dev, "mac_clk_rx", >clk_rx); + if (ret) + pr_warn("clk_get_by_name(rx) failed: %d", ret); - ret = clk_get_by_name(dev, "mac-clk-tx", >clk_tx); - if (ret) { - pr_err("clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_rx; - } + ret = clk_get_by_name(dev, "mac_clk_tx", >clk_tx); + if (ret) + pr_warn("clk_get_by_name(tx) failed: %d", ret); Nak Why are you changing the Rx and Tx clock names ? for information, check with the kernel dt bindings regarding this driver: Documentation/devicetree/bindings/net/stm32-dwmac.txt This patch is breaking ethernet on STM32MP1 boards I should have made a mistake here. In fact, for Rockchip, there is no need to obtain this two clock. My intention is to make these two clocks optional.
Re: [PATCH 3/8] net: dwc_eth_qos: Add option "snps, reset-gpio" phy-rst gpio for stm32
Hi Stephen, 在 2020/5/9 上午10:41, David Wu 写道: The kernel's ./Documentation/devicetree/bindings/net/stmmac.txt mentions that Required properties: - phy-mode: See ethernet.txt file in the same directory. - snps,reset-gpio gpio number for phy reset. - snps,reset-active-low boolean flag to indicate if phy reset is active low. - snps,reset-delays-us is triplet of delays The 1st cell is reset pre-delay in micro seconds. The 2nd cell is reset pulse in micro seconds. The 3rd cell is reset post-delay in micro seconds. Sorry, I just saw you replying again before, stmmac.txt was found, this reply email please discard.
Re: [PATCH 4/8] net: dwc_eth_qos: Move interface() to eqos_ops struct
Hi Stephen, 在 2020/5/1 上午6:39, Stephen Warren 写道: On 4/30/20 4:36 AM, David Wu wrote: After moving to eqos_ops, if eqos_config is defined outside, can not export interface() definition. Looking at the patch itself, I think this patch just moves a function pointer from the config to the ops structure which makes sense. However, I can't understand the patch description at all, so I worry there's intended to be some other justification/implication for this patch, and that may not be correct... In particular, defined outside of what, and what does this have to do with exporting things Yes, if define eqos_config structure in gmac_rockchip.c, need to export an eqos_get_interface function, or redefine a similar function in gmac_rockchip.c, but this function is the same implementation as eqos_get_interface_stm32(), so we can share this function. Move interface() to eqos_ops structure, no need to export interface() in the head file. I lost a patch to define eqos_ops structure at curent file, then only exprot eqos_rockchip_ops, so it would be simpler?
Re: [PATCH 3/8] net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32
Hi Patrice, 在 2020/4/30 下午11:47, Patrice CHOTARD 写道: @@ -701,6 +702,15 @@ static int eqos_start_resets_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(>phy_reset_gpio)) { + ret = dm_gpio_set_value(>phy_reset_gpio, 0); + if (ret < 0) { + pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", + ret); + return ret; + } + + udelay(eqos->reset_delays[0]); + not related to this patch subject ret = dm_gpio_set_value(>phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", @@ -708,7 +718,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; } - udelay(2); + udelay(eqos->reset_delays[1]); ret = dm_gpio_set_value(>phy_reset_gpio, 0); if (ret < 0) { @@ -1712,11 +1724,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret); + else + eqos->reset_delays[1] = 2; this is not the correct place to set default value. It must be set in case we can't get value from DT below No, three cases below, it is second case, and we can see udelay(2) in eqos_start_resets_stm32(), here we are to be compatible with the original. - If there is not phy rst, reset_delays is 0; - If "reset-gpios exists in phy node, reset_delays [1] = 2; - "snps, reset-gpio" exists in DT, reset_delays is obtained from DT eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); } + if (!dm_gpio_is_valid(>phy_reset_gpio)) { + int reset_flags = GPIOD_IS_OUT; + + if (dev_read_bool(dev, "snps,reset-active-low")) + reset_flags |= GPIOD_ACTIVE_LOW; + + ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, + >phy_reset_gpio, reset_flags); + if (ret == 0) + ret = dev_read_u32_array(dev, "snps,reset-delays-us", +eqos->reset_delays, 3); in case "snps,reset-delays-us" is not in present DT, all resets-delays are set to 0, see my remark above + else + pr_warn("gpio_request_by_name(snps,reset-gpio) failed: %d", + ret); + } + debug("%s: OK\n", __func__); return 0;
Re: [PATCH 3/8] net: dwc_eth_qos: Add option "snps, reset-gpio" phy-rst gpio for stm32
Hi Stephen, 在 2020/5/1 上午6:36, Stephen Warren 写道: The kernel's bindings/net/snps,dwmac.yaml does not mention any reset-gpios property (which is what the existing code parses just above the portion that is quoted by this patch as context). I suspect that this patch should simply change the name of the property that this function parses to align with the binding, and fix any DTs in U-Boot that also don't match the binding? The kernel's ./Documentation/devicetree/bindings/net/stmmac.txt mentions that Required properties: - phy-mode: See ethernet.txt file in the same directory. - snps,reset-gpio gpio number for phy reset. - snps,reset-active-low boolean flag to indicate if phy reset is active low. - snps,reset-delays-us is triplet of delays The 1st cell is reset pre-delay in micro seconds. The 2nd cell is reset pulse in micro seconds. The 3rd cell is reset post-delay in micro seconds.
[PATCH 5/8] net: dwc_eth_qos: Make clk_rx and clk_tx optional
For others using, clk_rx and clk_tx may not be necessary, and their clock names are different. Signed-off-by: David Wu --- drivers/net/dwc_eth_qos.c | 65 +++ 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index fbd6caf85b..b5d5156292 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -592,16 +592,20 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err; } - ret = clk_enable(>clk_rx); - if (ret < 0) { - pr_err("clk_enable(clk_rx) failed: %d", ret); - goto err_disable_clk_master_bus; + if (clk_valid(>clk_rx)) { + ret = clk_enable(>clk_rx); + if (ret < 0) { + pr_err("clk_enable(clk_rx) failed: %d", ret); + goto err_disable_clk_master_bus; + } } - ret = clk_enable(>clk_tx); - if (ret < 0) { - pr_err("clk_enable(clk_tx) failed: %d", ret); - goto err_disable_clk_rx; + if (clk_valid(>clk_tx)) { + ret = clk_enable(>clk_tx); + if (ret < 0) { + pr_err("clk_enable(clk_tx) failed: %d", ret); + goto err_disable_clk_rx; + } } if (clk_valid(>clk_ck)) { @@ -616,9 +620,11 @@ static int eqos_start_clks_stm32(struct udevice *dev) return 0; err_disable_clk_tx: - clk_disable(>clk_tx); + if (clk_valid(>clk_tx)) + clk_disable(>clk_tx); err_disable_clk_rx: - clk_disable(>clk_rx); + if (clk_valid(>clk_rx)) + clk_disable(>clk_rx); err_disable_clk_master_bus: clk_disable(>clk_master_bus); err: @@ -647,8 +653,10 @@ static void eqos_stop_clks_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_disable(>clk_tx); - clk_disable(>clk_rx); + if (clk_valid(>clk_tx)) + clk_disable(>clk_tx); + if (clk_valid(>clk_rx)) + clk_disable(>clk_rx); clk_disable(>clk_master_bus); if (clk_valid(>clk_ck)) clk_disable(>clk_ck); @@ -1691,20 +1699,16 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "stmmaceth", >clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret); - goto err_probe; + return ret; } - ret = clk_get_by_name(dev, "mac-clk-rx", >clk_rx); - if (ret) { - pr_err("clk_get_by_name(rx) failed: %d", ret); - goto err_free_clk_master_bus; - } + ret = clk_get_by_name(dev, "mac_clk_rx", >clk_rx); + if (ret) + pr_warn("clk_get_by_name(rx) failed: %d", ret); - ret = clk_get_by_name(dev, "mac-clk-tx", >clk_tx); - if (ret) { - pr_err("clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_rx; - } + ret = clk_get_by_name(dev, "mac_clk_tx", >clk_tx); + if (ret) + pr_warn("clk_get_by_name(tx) failed: %d", ret); /* Get ETH_CLK clocks (optional) */ ret = clk_get_by_name(dev, "eth-ck", >clk_ck); @@ -1749,15 +1753,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev) debug("%s: OK\n", __func__); return 0; - -err_free_clk_rx: - clk_free(>clk_rx); -err_free_clk_master_bus: - clk_free(>clk_master_bus); -err_probe: - - debug("%s: returns %d\n", __func__, ret); - return ret; } static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) @@ -1803,8 +1798,10 @@ static int eqos_remove_resources_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_free(>clk_tx); - clk_free(>clk_rx); + if (clk_valid(>clk_tx)) + clk_free(>clk_tx); + if (clk_valid(>clk_rx)) + clk_free(>clk_rx); clk_free(>clk_master_bus); if (clk_valid(>clk_ck)) clk_free(>clk_ck); -- 2.19.1
[PATCH 8/8] net: gmac_rockchip: Add dwc_eth_qos support
Change the original data structure so that Rockchip's Soc gmac controller can support the designware.c and dwc_eth_qos.c drivers, a Soc can only support one. Signed-off-by: David Wu --- drivers/net/Kconfig | 2 +- drivers/net/gmac_rockchip.c | 160 ++-- 2 files changed, 135 insertions(+), 27 deletions(-) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 4d1013c984..07d2b0787c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -482,7 +482,7 @@ config PIC32_ETH config GMAC_ROCKCHIP bool "Rockchip Synopsys Designware Ethernet MAC" - depends on DM_ETH && ETH_DESIGNWARE + depends on DM_ETH && (ETH_DESIGNWARE || DWC_ETH_QOS) help This driver provides Rockchip SoCs network support based on the Synopsys Designware driver. diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index e152faf083..aa2bab4203 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -25,26 +25,39 @@ #include #include #include "designware.h" +#include "dwc_eth_qos.h" DECLARE_GLOBAL_DATA_PTR; #define DELAY_ENABLE(soc, tx, rx) \ (((tx) ? soc##_TXCLK_DLY_ENA_GMAC_ENABLE : soc##_TXCLK_DLY_ENA_GMAC_DISABLE) | \ ((rx) ? soc##_RXCLK_DLY_ENA_GMAC_ENABLE : soc##_RXCLK_DLY_ENA_GMAC_DISABLE)) +struct rockchip_eth_dev { + union { + struct eqos_priv eqos; + struct dw_eth_dev dw; + }; +}; + /* * Platform data for the gmac * * dw_eth_pdata: Required platform data for designware driver (must be first) */ struct gmac_rockchip_platdata { - struct dw_eth_pdata dw_eth_pdata; + union { + struct dw_eth_pdata dw_eth_pdata; + struct eth_pdata eth_pdata; + }; + bool has_gmac4; bool clock_input; int tx_delay; int rx_delay; }; struct rk_gmac_ops { - int (*fix_mac_speed)(struct dw_eth_dev *priv); + const struct eqos_config config; + int (*fix_mac_speed)(struct rockchip_eth_dev *dev); void (*set_to_rmii)(struct gmac_rockchip_platdata *pdata); void (*set_to_rgmii)(struct gmac_rockchip_platdata *pdata); }; @@ -55,6 +68,9 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); const char *string; + if (device_is_compatible(dev, "snps,dwmac-4.20a")) + pdata->has_gmac4 = true; + string = dev_read_string(dev, "clock_in_out"); if (!strcmp(string, "input")) pdata->clock_input = true; @@ -71,11 +87,15 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) if (pdata->rx_delay == -ENOENT) pdata->rx_delay = dev_read_u32_default(dev, "rx-delay", 0x10); - return designware_eth_ofdata_to_platdata(dev); + if (!pdata->has_gmac4) + return designware_eth_ofdata_to_platdata(dev); + + return 0; } -static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int px30_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct px30_grf *grf; struct clk clk_speed; int speed, ret; @@ -115,8 +135,9 @@ static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3228_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk322x_grf *grf; int clk; enum { @@ -148,8 +169,9 @@ static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3288_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3288_grf *grf; int clk; @@ -174,8 +196,9 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3308_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3308_grf *grf; struct clk clk_speed; int speed, ret; @@ -215,8 +238,9 @@ static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3328_gmac_fix_mac_speed(struct rockchip_eth_dev *dev) { + struct dw_eth_dev *priv = >dw; struct rk3328_grf_regs *grf; int clk; enum { @@ -248,8 +272,9 @@ static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } -static int rk3368_gmac_fix_mac_speed(struct dw_eth_dev *priv) +static int rk3368_gmac_fix_mac_speed(str
[PATCH 7/8] net: dwc_eth_qos: Export common struct and interface at head file
Open structure data and interface, so that Soc using dw_eth_qos controller can reference. Signed-off-by: David Wu --- drivers/net/dwc_eth_qos.c | 81 +-- 1 file changed, 9 insertions(+), 72 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 25b3449047..7f47e5f505 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -41,6 +41,7 @@ #include #include #include +#include "dwc_eth_qos.h" /* Core registers */ @@ -94,9 +95,6 @@ struct eqos_mac_regs { #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT0 #define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2 -#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff @@ -109,8 +107,6 @@ struct eqos_mac_regs { #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 -#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2 -#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5 #define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4) #define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT2 #define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3 @@ -261,65 +257,6 @@ struct eqos_desc { #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24) -struct eqos_config { - bool reg_access_always_ok; - int mdio_wait; - int swr_wait; - int config_mac; - int config_mac_mdio; - struct eqos_ops *ops; -}; - -struct eqos_ops { - void (*eqos_inval_desc)(void *desc); - void (*eqos_flush_desc)(void *desc); - void (*eqos_inval_buffer)(void *buf, size_t size); - void (*eqos_flush_buffer)(void *buf, size_t size); - int (*eqos_probe_resources)(struct udevice *dev); - int (*eqos_remove_resources)(struct udevice *dev); - int (*eqos_stop_resets)(struct udevice *dev); - int (*eqos_start_resets)(struct udevice *dev); - void (*eqos_stop_clks)(struct udevice *dev); - int (*eqos_start_clks)(struct udevice *dev); - int (*eqos_calibrate_pads)(struct udevice *dev); - int (*eqos_disable_calibration)(struct udevice *dev); - int (*eqos_set_tx_clk_speed)(struct udevice *dev); - ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); - phy_interface_t (*eqos_get_interface)(struct udevice *dev); -}; - -struct eqos_priv { - struct udevice *dev; - const struct eqos_config *config; - fdt_addr_t regs; - struct eqos_mac_regs *mac_regs; - struct eqos_mtl_regs *mtl_regs; - struct eqos_dma_regs *dma_regs; - struct eqos_tegra186_regs *tegra186_regs; - struct reset_ctl reset_ctl; - struct gpio_desc phy_reset_gpio; - u32 reset_delays[3]; - struct clk clk_master_bus; - struct clk clk_rx; - struct clk clk_ptp_ref; - struct clk clk_tx; - struct clk clk_ck; - struct clk clk_slave_bus; - struct mii_dev *mii; - struct phy_device *phy; - int phyaddr; - u32 max_speed; - void *descs; - struct eqos_desc *tx_descs; - struct eqos_desc *rx_descs; - int tx_desc_idx, rx_desc_idx; - void *tx_dma_buf; - void *rx_dma_buf; - void *rx_pkt; - bool started; - bool reg_access_ok; -}; - /* * TX and RX descriptors are 16 bytes. This causes problems with the cache * maintenance on CPUs where the cache-line size exceeds the size of these @@ -1007,7 +944,7 @@ static int eqos_adjust_link(struct udevice *dev) return 0; } -static int eqos_write_hwaddr(struct udevice *dev) +int eqos_write_hwaddr(struct udevice *dev) { struct eth_pdata *plat = dev_get_platdata(dev); struct eqos_priv *eqos = dev_get_priv(dev); @@ -1051,7 +988,7 @@ static int eqos_write_hwaddr(struct udevice *dev) return 0; } -static int eqos_init(struct udevice *dev) +int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int ret, limit; @@ -1161,7 +1098,7 @@ err: return ret; } -static void eqos_enable(struct udevice *dev) +void eqos_enable(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; @@ -1387,7 +1324,7 @@ static int eqos_start(struct udevice *dev) return 0; } -static void eqos_stop(struct udevice *dev) +void eqos_stop(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); int i; @@ -1441,7 +1378,7 @@ static void eqos_stop(struct udevice *dev) debug("%s: OK\n", __func__); } -static int eqos_send(struct udevice *de
[PATCH 6/8] net: dwc_eth_qos: Split eqos_start() to get link speed
Before enabling mac and mac working, we need to obtain the current link speed to configure the clock, so split eqos_start into two functions. Signed-off-by: David Wu --- drivers/net/dwc_eth_qos.c | 56 ++- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b5d5156292..25b3449047 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1051,19 +1051,15 @@ static int eqos_write_hwaddr(struct udevice *dev) return 0; } -static int eqos_start(struct udevice *dev) +static int eqos_init(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); - int ret, i, limit; + int ret, limit; ulong rate; - u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; - ulong last_rx_desc; + u32 val; debug("%s(dev=%p):\n", __func__, dev); - eqos->tx_desc_idx = 0; - eqos->rx_desc_idx = 0; - ret = eqos->config->ops->eqos_start_clks(dev); if (ret < 0) { pr_err("eqos_start_clks() failed: %d", ret); @@ -1151,6 +1147,30 @@ static int eqos_start(struct udevice *dev) goto err_shutdown_phy; } + debug("%s: OK\n", __func__); + return 0; + +err_shutdown_phy: + phy_shutdown(eqos->phy); +err_stop_resets: + eqos->config->ops->eqos_stop_resets(dev); +err_stop_clks: + eqos->config->ops->eqos_stop_clks(dev); +err: + pr_err("FAILED: %d", ret); + return ret; +} + +static void eqos_enable(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; + ulong last_rx_desc; + int i; + + eqos->tx_desc_idx = 0; + eqos->rx_desc_idx = 0; + /* Configure MTL */ /* Enable Store and Forward mode for TX */ @@ -1352,19 +1372,19 @@ static int eqos_start(struct udevice *dev) writel(last_rx_desc, >dma_regs->ch0_rxdesc_tail_pointer); eqos->started = true; +} - debug("%s: OK\n", __func__); - return 0; +static int eqos_start(struct udevice *dev) +{ + int ret; -err_shutdown_phy: - phy_shutdown(eqos->phy); -err_stop_resets: - eqos->config->ops->eqos_stop_resets(dev); -err_stop_clks: - eqos->config->ops->eqos_stop_clks(dev); -err: - pr_err("FAILED: %d", ret); - return ret; + ret = eqos_init(dev); + if (ret) + return ret; + + eqos_enable(dev); + + return 0; } static void eqos_stop(struct udevice *dev) -- 2.19.1
[PATCH 4/8] net: dwc_eth_qos: Move interface() to eqos_ops struct
After moving to eqos_ops, if eqos_config is defined outside, can not export interface() definition. Signed-off-by: David Wu --- drivers/net/dwc_eth_qos.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 06a8d924a7..fbd6caf85b 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -267,7 +267,6 @@ struct eqos_config { int swr_wait; int config_mac; int config_mac_mdio; - phy_interface_t (*interface)(struct udevice *dev); struct eqos_ops *ops; }; @@ -286,6 +285,7 @@ struct eqos_ops { int (*eqos_disable_calibration)(struct udevice *dev); int (*eqos_set_tx_clk_speed)(struct udevice *dev); ulong (*eqos_get_tick_clk_rate)(struct udevice *dev); + phy_interface_t (*eqos_get_interface)(struct udevice *dev); }; struct eqos_priv { @@ -1105,7 +1105,7 @@ static int eqos_start(struct udevice *dev) */ if (!eqos->phy) { eqos->phy = phy_connect(eqos->mii, eqos->phyaddr, dev, - eqos->config->interface(dev)); + eqos->config->ops->eqos_get_interface(dev)); if (!eqos->phy) { pr_err("phy_connect() failed"); goto err_stop_resets; @@ -1675,7 +1675,7 @@ static int eqos_probe_resources_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - interface = eqos->config->interface(dev); + interface = eqos->config->ops->eqos_get_interface(dev); if (interface == PHY_INTERFACE_MODE_NONE) { pr_err("Invalid PHY interface\n"); @@ -1918,7 +1918,8 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_tegra186, .eqos_disable_calibration = eqos_disable_calibration_tegra186, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186, + .eqos_get_interface = eqos_get_interface_tegra186 }; static const struct eqos_config eqos_tegra186_config = { @@ -1927,7 +1928,6 @@ static const struct eqos_config eqos_tegra186_config = { .swr_wait = 10, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35, - .interface = eqos_get_interface_tegra186, .ops = _tegra186_ops }; @@ -1945,7 +1945,8 @@ static struct eqos_ops eqos_stm32_ops = { .eqos_calibrate_pads = eqos_calibrate_pads_stm32, .eqos_disable_calibration = eqos_disable_calibration_stm32, .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32, - .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32 + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32, + .eqos_get_interface = eqos_get_interface_stm32 }; static const struct eqos_config eqos_stm32_config = { @@ -1954,7 +1955,6 @@ static const struct eqos_config eqos_stm32_config = { .swr_wait = 50, .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV, .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, - .interface = eqos_get_interface_stm32, .ops = _stm32_ops }; -- 2.19.1
[PATCH 2/8] net: dwc_eth_qos: Fix the software reset
When using rgmii Gigabit mode, the wait_for_bit_le32() reset method resulting in RX can not receive data, after this patch, works well. Signed-off-by: David Wu --- drivers/net/dwc_eth_qos.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index a72132cacf..16988f6bdc 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1034,7 +1034,7 @@ static int eqos_write_hwaddr(struct udevice *dev) static int eqos_start(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); - int ret, i; + int ret, i, limit; ulong rate; u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl; ulong last_rx_desc; @@ -1060,12 +1060,21 @@ static int eqos_start(struct udevice *dev) eqos->reg_access_ok = true; - ret = wait_for_bit_le32(>dma_regs->mode, - EQOS_DMA_MODE_SWR, false, - eqos->config->swr_wait, false); - if (ret) { + /* DMA SW reset */ + val = readl(>dma_regs->mode); + val |= EQOS_DMA_MODE_SWR; + writel(val, >dma_regs->mode); + limit = eqos->config->swr_wait / 10; + while (limit--) { + if (!(readl(>dma_regs->mode) & EQOS_DMA_MODE_SWR)) + break; + mdelay(1); + } + + if (limit < 0) { pr_err("EQOS_DMA_MODE_SWR stuck"); - goto err_stop_resets; + goto err_stop_clks; + return -ETIMEDOUT; } ret = eqos->config->ops->eqos_calibrate_pads(dev); -- 2.19.1
[PATCH 3/8] net: dwc_eth_qos: Add option "snps, reset-gpio" phy-rst gpio for stm32
It can be seen that most of the Socs using STM mac, "snps,reset-gpio" gpio is used, adding this option makes reset function more general. Signed-off-by: David Wu --- drivers/net/dwc_eth_qos.c | 40 ++- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 16988f6bdc..06a8d924a7 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -298,6 +298,7 @@ struct eqos_priv { struct eqos_tegra186_regs *tegra186_regs; struct reset_ctl reset_ctl; struct gpio_desc phy_reset_gpio; + u32 reset_delays[3]; struct clk clk_master_bus; struct clk clk_rx; struct clk clk_ptp_ref; @@ -701,6 +702,15 @@ static int eqos_start_resets_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); if (dm_gpio_is_valid(>phy_reset_gpio)) { + ret = dm_gpio_set_value(>phy_reset_gpio, 0); + if (ret < 0) { + pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", + ret); + return ret; + } + + udelay(eqos->reset_delays[0]); + ret = dm_gpio_set_value(>phy_reset_gpio, 1); if (ret < 0) { pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", @@ -708,7 +718,7 @@ static int eqos_start_resets_stm32(struct udevice *dev) return ret; } - udelay(2); + udelay(eqos->reset_delays[1]); ret = dm_gpio_set_value(>phy_reset_gpio, 0); if (ret < 0) { @@ -716,6 +726,8 @@ static int eqos_start_resets_stm32(struct udevice *dev) ret); return ret; } + + udelay(eqos->reset_delays[2]); } debug("%s: OK\n", __func__); @@ -1065,16 +1077,16 @@ static int eqos_start(struct udevice *dev) val |= EQOS_DMA_MODE_SWR; writel(val, >dma_regs->mode); limit = eqos->config->swr_wait / 10; - while (limit--) { + do { if (!(readl(>dma_regs->mode) & EQOS_DMA_MODE_SWR)) break; mdelay(1); - } + } while (limit--); if (limit < 0) { pr_err("EQOS_DMA_MODE_SWR stuck"); - goto err_stop_clks; - return -ETIMEDOUT; + ret = -ETIMEDOUT; + goto err_stop_resets; } ret = eqos->config->ops->eqos_calibrate_pads(dev); @@ -1712,11 +1724,29 @@ static int eqos_probe_resources_stm32(struct udevice *dev) if (ret) pr_warn("gpio_request_by_name(phy reset) not provided %d", ret); + else + eqos->reset_delays[1] = 2; eqos->phyaddr = ofnode_read_u32_default(phandle_args.node, "reg", -1); } + if (!dm_gpio_is_valid(>phy_reset_gpio)) { + int reset_flags = GPIOD_IS_OUT; + + if (dev_read_bool(dev, "snps,reset-active-low")) + reset_flags |= GPIOD_ACTIVE_LOW; + + ret = gpio_request_by_name(dev, "snps,reset-gpio", 0, + >phy_reset_gpio, reset_flags); + if (ret == 0) + ret = dev_read_u32_array(dev, "snps,reset-delays-us", +eqos->reset_delays, 3); + else + pr_warn("gpio_request_by_name(snps,reset-gpio) failed: %d", + ret); + } + debug("%s: OK\n", __func__); return 0; -- 2.19.1
[PATCH 1/8] net: dwc_eth_qos: Use dev_ functions calls to get FDT data
It seems dev_ functions are more general than fdt_ functions. Signed-off-by: David Wu --- drivers/net/dwc_eth_qos.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 63f2086dec..a72132cacf 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1728,8 +1728,7 @@ static phy_interface_t eqos_get_interface_stm32(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode", - NULL); + phy_mode = dev_read_string(dev, "phy-mode"); if (phy_mode) interface = phy_get_interface_by_name(phy_mode); @@ -1788,9 +1787,9 @@ static int eqos_probe(struct udevice *dev) eqos->dev = dev; eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = devfdt_get_addr(dev); + eqos->regs = dev_read_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("devfdt_get_addr() failed"); + pr_err("dev_read_addr() failed"); return -ENODEV; } eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); -- 2.19.1
[PATCH 0/8] Add dwc_eth_qos support for rockchip
Rockchip Socs can support two controllers "snps, dwmac-4.20a" and "snps, dwmac-3.50". In order to support two at gmac-rockchip.c, export public interface functions and struct data, it will be more general for others. David Wu (8): net: dwc_eth_qos: Use dev_ functions calls to get FDT data net: dwc_eth_qos: Fix the software reset net: dwc_eth_qos: Add option "snps,reset-gpio" phy-rst gpio for stm32 net: dwc_eth_qos: Move interface() to eqos_ops struct net: dwc_eth_qos: Make clk_rx and clk_tx optional net: dwc_eth_qos: Split eqos_start() to get link speed net: dwc_eth_qos: Export common struct and interface at head file net: gmac_rockchip: Add dwc_eth_qos support drivers/net/Kconfig | 2 +- drivers/net/dwc_eth_qos.c | 264 +--- drivers/net/gmac_rockchip.c | 160 ++ 3 files changed, 263 insertions(+), 163 deletions(-) -- 2.19.1
[U-Boot] [PATCH v2] pinctrl: rockchip: Add pinctrl support for rk3308
An iomux register contains 8 pins, each of which is represented by 2 bits, but the register offset is 0x8. For example, GRF_GPIO0A_IOMUX offset is 0x0, but GRF_GPIO0B_IOMUX offset is 0x8, the offset 0x4 is reserved. So add a type IOMUX_8WIDTH_2BIT to calculate offset. Signed-off-by: David Wu --- Change in v2: - None drivers/pinctrl/rockchip/Makefile | 1 + drivers/pinctrl/rockchip/pinctrl-rk3308.c | 464 ++ .../pinctrl/rockchip/pinctrl-rockchip-core.c | 3 +- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 1 + 4 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3308.c diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index 83913f668f..fcf19f877a 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o obj-$(CONFIG_ROCKCHIP_RK322X) += pinctrl-rk322x.o obj-$(CONFIG_ROCKCHIP_RK3288) += pinctrl-rk3288.o +obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3308.c b/drivers/pinctrl/rockchip/pinctrl-rk3308.c new file mode 100644 index 00..abd57e54a5 --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl-rk3308.c @@ -0,0 +1,464 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 Rockchip Electronics Co., Ltd + */ + +#include +#include +#include +#include +#include + +#include "pinctrl-rockchip.h" + +static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { + { + .num = 1, + .pin = 14, + .reg = 0x28, + .bit = 12, + .mask = 0xf + }, { + .num = 1, + .pin = 15, + .reg = 0x2c, + .bit = 0, + .mask = 0x3 + }, { + .num = 1, + .pin = 18, + .reg = 0x30, + .bit = 4, + .mask = 0xf + }, { + .num = 1, + .pin = 19, + .reg = 0x30, + .bit = 8, + .mask = 0xf + }, { + .num = 1, + .pin = 20, + .reg = 0x30, + .bit = 12, + .mask = 0xf + }, { + .num = 1, + .pin = 21, + .reg = 0x34, + .bit = 0, + .mask = 0xf + }, { + .num = 1, + .pin = 22, + .reg = 0x34, + .bit = 4, + .mask = 0xf + }, { + .num = 1, + .pin = 23, + .reg = 0x34, + .bit = 8, + .mask = 0xf + }, { + .num = 3, + .pin = 12, + .reg = 0x68, + .bit = 8, + .mask = 0xf + }, { + .num = 3, + .pin = 13, + .reg = 0x68, + .bit = 12, + .mask = 0xf + }, { + .num = 2, + .pin = 2, + .reg = 0x608, + .bit = 0, + .mask = 0x7 + }, { + .num = 2, + .pin = 3, + .reg = 0x608, + .bit = 4, + .mask = 0x7 + }, { + .num = 2, + .pin = 16, + .reg = 0x610, + .bit = 8, + .mask = 0x7 + }, { + .num = 3, + .pin = 10, + .reg = 0x610, + .bit = 0, + .mask = 0x7 + }, { + .num = 3, + .pin = 11, + .reg = 0x610, + .bit = 4, + .mask = 0x7 + }, +}; + +static struct rockchip_mux_route_data rk3308_mux_route_data[] = { + { + /* rtc_clk */ + .bank_num = 0, + .pin = 19, + .func = 1, + .route_offset = 0x314, + .route_val = BIT(16 + 0) | BIT(0), + }, { + /* uart2_rxm0 */ + .bank_num = 1, + .pin = 22, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 2) | BIT(16 + 3), + }, { + /* uart2_rxm1 */ + .bank_num = 4, + .pin = 26, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), + }, { + /* i2c3_sdam0 */ + .bank_num = 0, + .pin = 15, + .func = 2, + .route_offset = 0x608, + .route_va
[U-Boot] [PATCH v2] pwm: rk_pwm: Make PWM driver to support all Rockchip Socs
This PWM driver can be used to support pwm functions for on all Rockchip Socs. The previous chips than RK3288 did not support polarity, and register layout was different from the RK3288 PWM. The RK3288 keep the current functions. RK3308 and the chips after it, which can support hardware lock, configure duty, period and polarity at next same period, to prevent the intermediate temporary state. Signed-off-by: David Wu --- Change in v2: None - Remove RK3399 compatible arch/arm/include/asm/arch-rockchip/pwm.h | 17 ++- drivers/pwm/rk_pwm.c | 138 +++ 2 files changed, 130 insertions(+), 25 deletions(-) diff --git a/arch/arm/include/asm/arch-rockchip/pwm.h b/arch/arm/include/asm/arch-rockchip/pwm.h index b5178db394..e8594055cd 100644 --- a/arch/arm/include/asm/arch-rockchip/pwm.h +++ b/arch/arm/include/asm/arch-rockchip/pwm.h @@ -7,13 +7,15 @@ #ifndef _ASM_ARCH_PWM_H #define _ASM_ARCH_PWM_H -struct rk3288_pwm { - u32 cnt; - u32 period_hpr; - u32 duty_lpr; - u32 ctrl; +struct rockchip_pwm_regs { + unsigned long duty; + unsigned long period; + unsigned long cntr; + unsigned long ctrl; }; -check_member(rk3288_pwm, ctrl, 0xc); + +#define PWM_CTRL_TIMER_EN (1 << 0) +#define PWM_CTRL_OUTPUT_EN (1 << 3) #define RK_PWM_DISABLE (0 << 0) #define RK_PWM_ENABLE (1 << 0) @@ -33,6 +35,9 @@ check_member(rk3288_pwm, ctrl, 0xc); #define PWM_OUTPUT_LEFT (0 << 5) #define PWM_OUTPUT_CENTER (1 << 5) +#define PWM_LOCK (1 << 6) +#define PWM_UNLOCK (0 << 6) + #define PWM_LP_ENABLE (1 << 8) #define PWM_LP_DISABLE (0 << 8) diff --git a/drivers/pwm/rk_pwm.c b/drivers/pwm/rk_pwm.c index 88db294cf1..46888e9077 100644 --- a/drivers/pwm/rk_pwm.c +++ b/drivers/pwm/rk_pwm.c @@ -15,22 +15,38 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + +struct rockchip_pwm_data { + struct rockchip_pwm_regs regs; + unsigned int prescaler; + bool supports_polarity; + bool supports_lock; + u32 enable_conf; + u32 enable_conf_mask; +}; + struct rk_pwm_priv { - struct rk3288_pwm *regs; + fdt_addr_t base; ulong freq; - uint enable_conf; + u32 conf_polarity; + const struct rockchip_pwm_data *data; }; static int rk_pwm_set_invert(struct udevice *dev, uint channel, bool polarity) { struct rk_pwm_priv *priv = dev_get_priv(dev); + if (!priv->data->supports_polarity) { + debug("%s: Do not support polarity\n", __func__); + return 0; + } + debug("%s: polarity=%u\n", __func__, polarity); - priv->enable_conf &= ~(PWM_DUTY_MASK | PWM_INACTIVE_MASK); if (polarity) - priv->enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSTIVE; + priv->conf_polarity = PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSTIVE; else - priv->enable_conf |= PWM_DUTY_POSTIVE | PWM_INACTIVE_NEGATIVE; + priv->conf_polarity = PWM_DUTY_POSTIVE | PWM_INACTIVE_NEGATIVE; return 0; } @@ -39,20 +55,44 @@ static int rk_pwm_set_config(struct udevice *dev, uint channel, uint period_ns, uint duty_ns) { struct rk_pwm_priv *priv = dev_get_priv(dev); - struct rk3288_pwm *regs = priv->regs; + const struct rockchip_pwm_regs *regs = >data->regs; unsigned long period, duty; + u32 ctrl; debug("%s: period_ns=%u, duty_ns=%u\n", __func__, period_ns, duty_ns); - writel(PWM_SEL_SRC_CLK | PWM_OUTPUT_LEFT | PWM_LP_DISABLE | - PWM_CONTINUOUS | priv->enable_conf | - RK_PWM_DISABLE, - >ctrl); - period = lldiv((uint64_t)(priv->freq / 1000) * period_ns, 100); - duty = lldiv((uint64_t)(priv->freq / 1000) * duty_ns, 100); + ctrl = readl(priv->base + regs->ctrl); + /* +* Lock the period and duty of previous configuration, then +* change the duty and period, that would not be effective. +*/ + if (priv->data->supports_lock) { + ctrl |= PWM_LOCK; + writel(ctrl, priv->base + regs->ctrl); + } + + period = lldiv((uint64_t)priv->freq * period_ns, + priv->data->prescaler * 10); + duty = lldiv((uint64_t)priv->freq * duty_ns, +priv->data->prescaler * 10); + + writel(period, priv->base + regs->period); + writel(duty, priv->base + regs->duty); + + if (priv->data->supports_polarity) { + ctrl &= ~(PWM_DUTY_MASK | PWM_INACTIVE_MASK); +
Re: [U-Boot] [PATCH 2/3] arm: dts: Add mac node for rk3308 at dtsi level
Hi Kever, 在 2019/11/27 下午2:23, Kever Yang 写道: David, On 2019/11/26 上午9:39, David Wu wrote: The rk3308 only support RMII mode, and if it is output clock mode, better to use ref_clk pin with drive strength 12ma. Signed-off-by: David Wu Did you send this to kernel list at the same time? I will send it later. Thanks, - Kever --- arch/arm/dts/rk3308.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/dts/rk3308.dtsi b/arch/arm/dts/rk3308.dtsi index 0eeec165d4..a5c0b72ae0 100644 --- a/arch/arm/dts/rk3308.dtsi +++ b/arch/arm/dts/rk3308.dtsi @@ -627,6 +627,28 @@ status = "disabled"; }; + mac: ethernet@ff4e { + compatible = "rockchip,rk3308-mac"; + reg = <0x0 0xff4e 0x0 0x1>; + rockchip,grf = <>; + interrupts = ; + interrupt-names = "macirq"; + clocks = < SCLK_MAC>, < SCLK_MAC_RX_TX>, + < SCLK_MAC_RX_TX>, < SCLK_MAC_REF>, + < SCLK_MAC>, < ACLK_MAC>, + < PCLK_MAC>, < SCLK_MAC_RMII>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "clk_mac_refout", "aclk_mac", + "pclk_mac", "clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <_pins _refclk_12ma>; + resets = < SRST_MAC_A>; + reset-names = "stmmaceth"; + status = "disabled"; + }; + cru: clock-controller@ff50 { compatible = "rockchip,rk3308-cru"; reg = <0x0 0xff50 0x0 0x1000>; ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH 3/3] dts: rk3308: Enable ethernet function supported for Firefly ROC_RK3308_CC
The Firefly ROC_RK3308_CC use ref_clock of input mode, and rmii pins of m1 group. Signed-off-by: David Wu --- arch/arm/dts/rk3308-roc-cc.dts | 9 + 1 file changed, 9 insertions(+) diff --git a/arch/arm/dts/rk3308-roc-cc.dts b/arch/arm/dts/rk3308-roc-cc.dts index e10aa638a3..b4a54a852c 100644 --- a/arch/arm/dts/rk3308-roc-cc.dts +++ b/arch/arm/dts/rk3308-roc-cc.dts @@ -143,6 +143,15 @@ }; }; + { + assigned-clocks = < SCLK_MAC>; + assigned-clock-parents = <_clkin>; + clock_in_out = "input"; + pinctrl-names = "default"; + pinctrl-0 = <_pins _refclk>; + status = "okay"; +}; + { status = "okay"; pinctrl-names = "active"; -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH 2/3] arm: dts: Add mac node for rk3308 at dtsi level
The rk3308 only support RMII mode, and if it is output clock mode, better to use ref_clk pin with drive strength 12ma. Signed-off-by: David Wu --- arch/arm/dts/rk3308.dtsi | 22 ++ 1 file changed, 22 insertions(+) diff --git a/arch/arm/dts/rk3308.dtsi b/arch/arm/dts/rk3308.dtsi index 0eeec165d4..a5c0b72ae0 100644 --- a/arch/arm/dts/rk3308.dtsi +++ b/arch/arm/dts/rk3308.dtsi @@ -627,6 +627,28 @@ status = "disabled"; }; + mac: ethernet@ff4e { + compatible = "rockchip,rk3308-mac"; + reg = <0x0 0xff4e 0x0 0x1>; + rockchip,grf = <>; + interrupts = ; + interrupt-names = "macirq"; + clocks = < SCLK_MAC>, < SCLK_MAC_RX_TX>, +< SCLK_MAC_RX_TX>, < SCLK_MAC_REF>, +< SCLK_MAC>, < ACLK_MAC>, +< PCLK_MAC>, < SCLK_MAC_RMII>; + clock-names = "stmmaceth", "mac_clk_rx", + "mac_clk_tx", "clk_mac_ref", + "clk_mac_refout", "aclk_mac", + "pclk_mac", "clk_mac_speed"; + phy-mode = "rmii"; + pinctrl-names = "default"; + pinctrl-0 = <_pins _refclk_12ma>; + resets = < SRST_MAC_A>; + reset-names = "stmmaceth"; + status = "disabled"; + }; + cru: clock-controller@ff50 { compatible = "rockchip,rk3308-cru"; reg = <0x0 0xff50 0x0 0x1000>; -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH 1/3] net: gmac_rockchip: Add support for rk3308
Add the glue code to allow the rk3308 variant of the Rockchip gmac to provide network functionality. Signed-off-by: David Wu --- drivers/net/gmac_rockchip.c | 65 + 1 file changed, 65 insertions(+) diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c index d2c52b4c46..e152faf083 100644 --- a/drivers/net/gmac_rockchip.c +++ b/drivers/net/gmac_rockchip.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -173,6 +174,47 @@ static int rk3288_gmac_fix_mac_speed(struct dw_eth_dev *priv) return 0; } +static int rk3308_gmac_fix_mac_speed(struct dw_eth_dev *priv) +{ + struct rk3308_grf *grf; + struct clk clk_speed; + int speed, ret; + enum { + RK3308_GMAC_SPEED_SHIFT = 0x0, + RK3308_GMAC_SPEED_MASK = BIT(0), + RK3308_GMAC_SPEED_10M = 0, + RK3308_GMAC_SPEED_100M = BIT(0), + }; + + ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed", + _speed); + if (ret) + return ret; + + switch (priv->phydev->speed) { + case 10: + speed = RK3308_GMAC_SPEED_10M; + ret = clk_set_rate(_speed, 250); + if (ret) + return ret; + break; + case 100: + speed = RK3308_GMAC_SPEED_100M; + ret = clk_set_rate(_speed, 2500); + if (ret) + return ret; + break; + default: + debug("Unknown phy speed: %d\n", priv->phydev->speed); + return -EINVAL; + } + + grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + rk_clrsetreg(>mac_con0, RK3308_GMAC_SPEED_MASK, speed); + + return 0; +} + static int rk3328_gmac_fix_mac_speed(struct dw_eth_dev *priv) { struct rk3328_grf_regs *grf; @@ -377,6 +419,22 @@ static void rk3288_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) pdata->tx_delay << RK3288_CLK_TX_DL_CFG_GMAC_SHIFT); } +static void rk3308_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata) +{ + struct rk3308_grf *grf; + enum { + RK3308_GMAC_PHY_INTF_SEL_SHIFT = 2, + RK3308_GMAC_PHY_INTF_SEL_MASK = GENMASK(4, 2), + RK3308_GMAC_PHY_INTF_SEL_RMII = BIT(4), + }; + + grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + + rk_clrsetreg(>mac_con0, +RK3308_GMAC_PHY_INTF_SEL_MASK, +RK3308_GMAC_PHY_INTF_SEL_RMII); +} + static void rk3328_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata) { struct rk3328_grf_regs *grf; @@ -646,6 +704,11 @@ const struct rk_gmac_ops rk3288_gmac_ops = { .set_to_rgmii = rk3288_gmac_set_to_rgmii, }; +const struct rk_gmac_ops rk3308_gmac_ops = { + .fix_mac_speed = rk3308_gmac_fix_mac_speed, + .set_to_rmii = rk3308_gmac_set_to_rmii, +}; + const struct rk_gmac_ops rk3328_gmac_ops = { .fix_mac_speed = rk3328_gmac_fix_mac_speed, .set_to_rgmii = rk3328_gmac_set_to_rgmii, @@ -673,6 +736,8 @@ static const struct udevice_id rockchip_gmac_ids[] = { .data = (ulong)_gmac_ops }, { .compatible = "rockchip,rk3288-gmac", .data = (ulong)_gmac_ops }, + { .compatible = "rockchip,rk3308-mac", + .data = (ulong)_gmac_ops }, { .compatible = "rockchip,rk3328-gmac", .data = (ulong)_gmac_ops }, { .compatible = "rockchip,rk3368-gmac", -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH 2/2] pinctrl: rockchip: Add pinctrl support for rk3308
The most pins of rk3308 are 2bits iomux, but the banks's register width is 0x8. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/Makefile | 1 + drivers/pinctrl/rockchip/pinctrl-rk3308.c | 464 ++ .../pinctrl/rockchip/pinctrl-rockchip-core.c | 3 +- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 1 + 4 files changed, 468 insertions(+), 1 deletion(-) create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3308.c diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index 83913f668f..fcf19f877a 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o obj-$(CONFIG_ROCKCHIP_RK322X) += pinctrl-rk322x.o obj-$(CONFIG_ROCKCHIP_RK3288) += pinctrl-rk3288.o +obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3308.c b/drivers/pinctrl/rockchip/pinctrl-rk3308.c new file mode 100644 index 00..abd57e54a5 --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl-rk3308.c @@ -0,0 +1,464 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 Rockchip Electronics Co., Ltd + */ + +#include +#include +#include +#include +#include + +#include "pinctrl-rockchip.h" + +static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { + { + .num = 1, + .pin = 14, + .reg = 0x28, + .bit = 12, + .mask = 0xf + }, { + .num = 1, + .pin = 15, + .reg = 0x2c, + .bit = 0, + .mask = 0x3 + }, { + .num = 1, + .pin = 18, + .reg = 0x30, + .bit = 4, + .mask = 0xf + }, { + .num = 1, + .pin = 19, + .reg = 0x30, + .bit = 8, + .mask = 0xf + }, { + .num = 1, + .pin = 20, + .reg = 0x30, + .bit = 12, + .mask = 0xf + }, { + .num = 1, + .pin = 21, + .reg = 0x34, + .bit = 0, + .mask = 0xf + }, { + .num = 1, + .pin = 22, + .reg = 0x34, + .bit = 4, + .mask = 0xf + }, { + .num = 1, + .pin = 23, + .reg = 0x34, + .bit = 8, + .mask = 0xf + }, { + .num = 3, + .pin = 12, + .reg = 0x68, + .bit = 8, + .mask = 0xf + }, { + .num = 3, + .pin = 13, + .reg = 0x68, + .bit = 12, + .mask = 0xf + }, { + .num = 2, + .pin = 2, + .reg = 0x608, + .bit = 0, + .mask = 0x7 + }, { + .num = 2, + .pin = 3, + .reg = 0x608, + .bit = 4, + .mask = 0x7 + }, { + .num = 2, + .pin = 16, + .reg = 0x610, + .bit = 8, + .mask = 0x7 + }, { + .num = 3, + .pin = 10, + .reg = 0x610, + .bit = 0, + .mask = 0x7 + }, { + .num = 3, + .pin = 11, + .reg = 0x610, + .bit = 4, + .mask = 0x7 + }, +}; + +static struct rockchip_mux_route_data rk3308_mux_route_data[] = { + { + /* rtc_clk */ + .bank_num = 0, + .pin = 19, + .func = 1, + .route_offset = 0x314, + .route_val = BIT(16 + 0) | BIT(0), + }, { + /* uart2_rxm0 */ + .bank_num = 1, + .pin = 22, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 2) | BIT(16 + 3), + }, { + /* uart2_rxm1 */ + .bank_num = 4, + .pin = 26, + .func = 2, + .route_offset = 0x314, + .route_val = BIT(16 + 2) | BIT(16 + 3) | BIT(2), + }, { + /* i2c3_sdam0 */ + .bank_num = 0, + .pin = 15, + .func = 2, + .route_offset = 0x608, + .route_val = BIT(16 + 8) | BIT(16 + 9), + }, { + /* i2c3_sdam1 */ + .bank_num = 3, + .pin = 12, + .func = 2, + .route_offs
[U-Boot] [PATCH 1/2] arm: rockchip: rk3308: Initialize the iomux configuration
When we want to use plus iomux feature, we need to enable them at spl. Signed-off-by: David Wu --- arch/arm/mach-rockchip/rk3308/rk3308.c | 33 ++ 1 file changed, 33 insertions(+) diff --git a/arch/arm/mach-rockchip/rk3308/rk3308.c b/arch/arm/mach-rockchip/rk3308/rk3308.c index f27f9e8c0b..bd99899094 100644 --- a/arch/arm/mach-rockchip/rk3308/rk3308.c +++ b/arch/arm/mach-rockchip/rk3308/rk3308.c @@ -72,6 +72,11 @@ enum { UART2_IO_SEL_M1, UART2_IO_SEL_USB, + GPIO2C0_SEL_SRC_CTRL_SHIFT = 11, + GPIO2C0_SEL_SRC_CTRL_MASK = BIT(11), + GPIO2C0_SEL_SRC_CTRL_IOMUX = 0, + GPIO2C0_SEL_SRC_CTRL_SEL_PLUS, + GPIO3B3_SEL_SRC_CTRL_SHIFT = 7, GPIO3B3_SEL_SRC_CTRL_MASK = BIT(7), GPIO3B3_SEL_SRC_CTRL_IOMUX = 0, @@ -97,6 +102,18 @@ enum { GPIO3B2_SEL_PLUS_EMMC_RSTN, GPIO3B2_SEL_PLUS_SPI1_MISO, GPIO3B2_SEL_PLUS_LCDC_D22_M1, + + I2C3_IOFUNC_SRC_CTRL_SHIFT = 10, + I2C3_IOFUNC_SRC_CTRL_MASK = BIT(10), + I2C3_IOFUNC_SRC_CTRL_SEL_PLUS = 1, + + GPIO2A3_SEL_SRC_CTRL_SHIFT = 7, + GPIO2A3_SEL_SRC_CTRL_MASK = BIT(7), + GPIO2A3_SEL_SRC_CTRL_SEL_PLUS = 1, + + GPIO2A2_SEL_SRC_CTRL_SHIFT = 3, + GPIO2A2_SEL_SRC_CTRL_MASK = BIT(3), + GPIO2A2_SEL_SRC_CTRL_SEL_PLUS = 1, }; enum { @@ -166,10 +183,26 @@ __weak void board_debug_uart_init(void) int arch_cpu_init(void) { static struct rk3308_sgrf * const sgrf = (void *)SGRF_BASE; + static struct rk3308_grf * const grf = (void *)GRF_BASE; /* Set CRYPTO SDMMC EMMC NAND SFC USB master bus to be secure access */ rk_clrreg(>con_secure0, 0x2b83); + + rk_clrsetreg(>soc_con13, +I2C3_IOFUNC_SRC_CTRL_MASK | GPIO2A3_SEL_SRC_CTRL_MASK | +GPIO2A2_SEL_SRC_CTRL_MASK, +I2C3_IOFUNC_SRC_CTRL_SEL_PLUS << I2C3_IOFUNC_SRC_CTRL_SHIFT | +GPIO2A3_SEL_SRC_CTRL_SEL_PLUS << GPIO2A3_SEL_SRC_CTRL_SHIFT | +GPIO2A2_SEL_SRC_CTRL_SEL_PLUS << GPIO2A2_SEL_SRC_CTRL_SHIFT); + + rk_clrsetreg(>soc_con15, +GPIO2C0_SEL_SRC_CTRL_MASK | GPIO3B3_SEL_SRC_CTRL_MASK | +GPIO3B2_SEL_SRC_CTRL_MASK, +GPIO2C0_SEL_SRC_CTRL_SEL_PLUS << GPIO2C0_SEL_SRC_CTRL_SHIFT | +GPIO3B3_SEL_SRC_CTRL_SEL_PLUS << GPIO3B3_SEL_SRC_CTRL_SHIFT | +GPIO3B3_SEL_SRC_CTRL_SEL_PLUS << GPIO3B2_SEL_SRC_CTRL_SHIFT); + return 0; } #endif -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH] pwm: rk_pwm: Make PWM driver to support all Rockchip Socs
The new PWM driver supports PWM polarity, lock and more functions. Signed-off-by: David Wu --- arch/arm/include/asm/arch-rockchip/pwm.h | 17 ++- drivers/pwm/rk_pwm.c | 139 +++ 2 files changed, 131 insertions(+), 25 deletions(-) diff --git a/arch/arm/include/asm/arch-rockchip/pwm.h b/arch/arm/include/asm/arch-rockchip/pwm.h index b5178db394..e8594055cd 100644 --- a/arch/arm/include/asm/arch-rockchip/pwm.h +++ b/arch/arm/include/asm/arch-rockchip/pwm.h @@ -7,13 +7,15 @@ #ifndef _ASM_ARCH_PWM_H #define _ASM_ARCH_PWM_H -struct rk3288_pwm { - u32 cnt; - u32 period_hpr; - u32 duty_lpr; - u32 ctrl; +struct rockchip_pwm_regs { + unsigned long duty; + unsigned long period; + unsigned long cntr; + unsigned long ctrl; }; -check_member(rk3288_pwm, ctrl, 0xc); + +#define PWM_CTRL_TIMER_EN (1 << 0) +#define PWM_CTRL_OUTPUT_EN (1 << 3) #define RK_PWM_DISABLE (0 << 0) #define RK_PWM_ENABLE (1 << 0) @@ -33,6 +35,9 @@ check_member(rk3288_pwm, ctrl, 0xc); #define PWM_OUTPUT_LEFT (0 << 5) #define PWM_OUTPUT_CENTER (1 << 5) +#define PWM_LOCK (1 << 6) +#define PWM_UNLOCK (0 << 6) + #define PWM_LP_ENABLE (1 << 8) #define PWM_LP_DISABLE (0 << 8) diff --git a/drivers/pwm/rk_pwm.c b/drivers/pwm/rk_pwm.c index 88db294cf1..c9d9b7c11b 100644 --- a/drivers/pwm/rk_pwm.c +++ b/drivers/pwm/rk_pwm.c @@ -15,22 +15,38 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + +struct rockchip_pwm_data { + struct rockchip_pwm_regs regs; + unsigned int prescaler; + bool supports_polarity; + bool supports_lock; + u32 enable_conf; + u32 enable_conf_mask; +}; + struct rk_pwm_priv { - struct rk3288_pwm *regs; + fdt_addr_t base; ulong freq; - uint enable_conf; + u32 conf_polarity; + const struct rockchip_pwm_data *data; }; static int rk_pwm_set_invert(struct udevice *dev, uint channel, bool polarity) { struct rk_pwm_priv *priv = dev_get_priv(dev); + if (!priv->data->supports_polarity) { + debug("%s: Do not support polarity\n", __func__); + return 0; + } + debug("%s: polarity=%u\n", __func__, polarity); - priv->enable_conf &= ~(PWM_DUTY_MASK | PWM_INACTIVE_MASK); if (polarity) - priv->enable_conf |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSTIVE; + priv->conf_polarity = PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSTIVE; else - priv->enable_conf |= PWM_DUTY_POSTIVE | PWM_INACTIVE_NEGATIVE; + priv->conf_polarity = PWM_DUTY_POSTIVE | PWM_INACTIVE_NEGATIVE; return 0; } @@ -39,20 +55,44 @@ static int rk_pwm_set_config(struct udevice *dev, uint channel, uint period_ns, uint duty_ns) { struct rk_pwm_priv *priv = dev_get_priv(dev); - struct rk3288_pwm *regs = priv->regs; + const struct rockchip_pwm_regs *regs = >data->regs; unsigned long period, duty; + u32 ctrl; debug("%s: period_ns=%u, duty_ns=%u\n", __func__, period_ns, duty_ns); - writel(PWM_SEL_SRC_CLK | PWM_OUTPUT_LEFT | PWM_LP_DISABLE | - PWM_CONTINUOUS | priv->enable_conf | - RK_PWM_DISABLE, - >ctrl); - period = lldiv((uint64_t)(priv->freq / 1000) * period_ns, 100); - duty = lldiv((uint64_t)(priv->freq / 1000) * duty_ns, 100); + ctrl = readl(priv->base + regs->ctrl); + /* +* Lock the period and duty of previous configuration, then +* change the duty and period, that would not be effective. +*/ + if (priv->data->supports_lock) { + ctrl |= PWM_LOCK; + writel(ctrl, priv->base + regs->ctrl); + } + + period = lldiv((uint64_t)priv->freq * period_ns, + priv->data->prescaler * 10); + duty = lldiv((uint64_t)priv->freq * duty_ns, +priv->data->prescaler * 10); + + writel(period, priv->base + regs->period); + writel(duty, priv->base + regs->duty); + + if (priv->data->supports_polarity) { + ctrl &= ~(PWM_DUTY_MASK | PWM_INACTIVE_MASK); + ctrl |= priv->conf_polarity; + } + + /* +* Unlock and set polarity at the same time, +* the configuration of duty, period and polarity +* would be effective together at next period. +*/ + if (priv->data->supports_lock) + ctrl &= ~PWM_LOCK; + writel(ctrl, priv->base + regs->ctrl); - wr
[U-Boot] [PATCH v3 10/10] pinctrl: rockchip: Also move common set_schmitter func into per Soc file
Only some Soc need Schmitter feature, so move the implementation into their own files. Signed-off-by: David Wu --- Change in v3: - None drivers/pinctrl/rockchip/pinctrl-rk3328.c | 17 - .../pinctrl/rockchip/pinctrl-rockchip-core.c | 19 +++ drivers/pinctrl/rockchip/pinctrl-rockchip.h | 5 ++--- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 17 - 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c index d4d37af206..8d37a6f945 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c @@ -264,6 +264,21 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +static int rk3328_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u8 bit; + u32 data; + + rk3328_calc_schmitt_reg_and_bit(bank, pin_num, , , ); + /* enable the write to the equivalent lower bits */ + data = BIT(bit + 16) | (enable << bit); + + return regmap_write(regmap, reg, data); +} + static struct rockchip_pin_bank rk3328_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), @@ -289,7 +304,7 @@ static struct rockchip_pin_ctrl rk3328_pin_ctrl = { .set_mux= rk3328_set_mux, .set_pull = rk3328_set_pull, .set_drive = rk3328_set_drive, - .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, + .set_schmitt= rk3328_set_schmitt, }; static const struct udevice_id rk3328_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index b3379a0d3f..80dc431d20 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -306,30 +306,20 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, { struct rockchip_pinctrl_priv *priv = bank->priv; struct rockchip_pin_ctrl *ctrl = priv->ctrl; - struct regmap *regmap; - int reg, ret; - u8 bit; - u32 data; debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num, pin_num, enable); - ret = ctrl->schmitt_calc_reg(bank, pin_num, , , ); - if (ret) - return ret; - - /* enable the write to the equivalent lower bits */ - data = BIT(bit + 16) | (enable << bit); + if (!ctrl->set_schmitt) + return -ENOTSUPP; - return regmap_write(regmap, reg, data); + return ctrl->set_schmitt(bank, pin_num, enable); } /* set the pin config settings for a specified pin */ static int rockchip_pinconf_set(struct rockchip_pin_bank *bank, u32 pin, u32 param, u32 arg) { - struct rockchip_pinctrl_priv *priv = bank->priv; - struct rockchip_pin_ctrl *ctrl = priv->ctrl; int rc; switch (param) { @@ -350,9 +340,6 @@ static int rockchip_pinconf_set(struct rockchip_pin_bank *bank, break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - if (!ctrl->schmitt_calc_reg) - return -ENOTSUPP; - rc = rockchip_set_schmitt(bank, pin, arg); if (rc < 0) return rc; diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip.h b/drivers/pinctrl/rockchip/pinctrl-rockchip.h index 1c6fc2c5b2..9651e9c7a6 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip.h +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip.h @@ -271,9 +271,8 @@ struct rockchip_pin_ctrl { int pin_num, int pull); int (*set_drive)(struct rockchip_pin_bank *bank, int pin_num, int strength); - int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit); + int (*set_schmitt)(struct rockchip_pin_bank *bank, + int pin_num, int enable); }; /** diff --git a/drivers/pinctrl/rockchip/pinctrl-rv1108.c b/drivers/pinctrl/rockchip/pinctrl-rv1108.c index 0bcf11bb41..54610a3e90 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rv1108.c +++ b/drivers/pinctrl/rockchip/pinctrl-rv1108.c @@ -237,6 +237,21 @@ static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +static int rv1108_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u8 bit; +
[U-Boot] [PATCH v3 09/10] pinctrl: rockchip: Clean the unused type and label
As the mux/pull/drive feature implement at own file, the type and label are not necessary. Signed-off-by: David Wu --- Change in v3: - None drivers/pinctrl/rockchip/pinctrl-rk3036.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3128.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3188.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk322x.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3368.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 12 drivers/pinctrl/rockchip/pinctrl-rv1108.c | 2 -- 10 files changed, 30 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 498b633f22..28c905129b 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -83,8 +83,6 @@ static struct rockchip_pin_bank rk3036_pin_banks[] = { static struct rockchip_pin_ctrl rk3036_pin_ctrl = { .pin_banks = rk3036_pin_banks, .nr_banks = ARRAY_SIZE(rk3036_pin_banks), - .label = "RK3036-GPIO", - .type = RK3036, .grf_mux_offset = 0xa8, .set_mux= rk3036_set_mux, .set_pull = rk3036_set_pull, diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c index 104b76c19e..3eb4d952bb 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c @@ -183,8 +183,6 @@ static struct rockchip_pin_bank rk3128_pin_banks[] = { static struct rockchip_pin_ctrl rk3128_pin_ctrl = { .pin_banks = rk3128_pin_banks, .nr_banks = ARRAY_SIZE(rk3128_pin_banks), - .label = "RK3128-GPIO", - .type = RK3128, .grf_mux_offset = 0xa8, .iomux_recalced = rk3128_mux_recalced_data, .niomux_recalced= ARRAY_SIZE(rk3128_mux_recalced_data), diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index e09c799e72..043764fc92 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c @@ -108,8 +108,6 @@ static struct rockchip_pin_bank rk3188_pin_banks[] = { static struct rockchip_pin_ctrl rk3188_pin_ctrl = { .pin_banks = rk3188_pin_banks, .nr_banks = ARRAY_SIZE(rk3188_pin_banks), - .label = "RK3188-GPIO", - .type = RK3188, .grf_mux_offset = 0x60, .set_mux= rk3188_set_mux, .set_pull = rk3188_set_pull, diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index b69d9795bb..c5e4fe30a7 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -268,8 +268,6 @@ static struct rockchip_pin_bank rk3228_pin_banks[] = { static struct rockchip_pin_ctrl rk3228_pin_ctrl = { .pin_banks = rk3228_pin_banks, .nr_banks = ARRAY_SIZE(rk3228_pin_banks), - .label = "RK3228-GPIO", - .type = RK3288, .grf_mux_offset = 0x0, .iomux_routes = rk3228_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 24af3597ec..7ae147f304 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -223,8 +223,6 @@ static struct rockchip_pin_bank rk3288_pin_banks[] = { static struct rockchip_pin_ctrl rk3288_pin_ctrl = { .pin_banks = rk3288_pin_banks, .nr_banks = ARRAY_SIZE(rk3288_pin_banks), - .label = "RK3288-GPIO", - .type = RK3288, .grf_mux_offset = 0x0, .pmu_mux_offset = 0x84, .iomux_routes = rk3288_mux_route_data, diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c index 7ac5c0226e..d4d37af206 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c @@ -281,8 +281,6 @@ static struct rockchip_pin_bank rk3328_pin_banks[] = { static struct rockchip_pin_ctrl rk3328_pin_ctrl = { .pin_banks = rk3328_pin_banks, .nr_banks = ARRAY_SIZE(rk3328_pin_banks), - .label = "RK3328-GPIO", - .type = RK3288, .grf_mux_offset = 0x0, .iomux_recalced
[U-Boot] [PATCH v3 08/10] pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' pull
RK3288 pmu_gpio0 pull setting have no higher 16 writing corresponding bits, need to read before write the register. Signed-off-by: David Wu --- Change in v3: - None drivers/pinctrl/rockchip/pinctrl-rk3288.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 9192aa3949..24af3597ec 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -116,8 +116,15 @@ static int rk3288_set_pull(struct rockchip_pin_bank *bank, return ret; } - /* enable the write to the equivalent lower bits */ - data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + /* bank0 is special, there are no higher 16 bit writing bits */ + if (bank->bank_num == 0) { + regmap_read(regmap, reg, ); + data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit); + } else { + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + } + data |= (ret << bit); ret = regmap_write(regmap, reg, data); -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v3 07/10] pinctrl: rockchip: Split the common set_pull() func into per Soc
As the common set_mux func(), implement the feature at the own file for each Soc. Signed-off-by: David Wu --- Change in v3: - None drivers/pinctrl/rockchip/pinctrl-rk3036.c | 23 - drivers/pinctrl/rockchip/pinctrl-rk3128.c | 23 - drivers/pinctrl/rockchip/pinctrl-rk3188.c | 29 +- drivers/pinctrl/rockchip/pinctrl-rk322x.c | 29 +- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 40 ++-- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 29 +- drivers/pinctrl/rockchip/pinctrl-rk3368.c | 40 ++-- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 40 ++-- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 97 --- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 7 +- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 30 +- 11 files changed, 275 insertions(+), 112 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 8969aea2e3..498b633f22 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -53,6 +53,27 @@ static void rk3036_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, *bit = pin_num % RK3036_PULL_PINS_PER_REG; }; +static int rk3036_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit; + u32 data; + + if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && + pull != PIN_CONFIG_BIAS_DISABLE) + return -ENOTSUPP; + + rk3036_calc_pull_reg_and_bit(bank, pin_num, , , ); + data = BIT(bit + 16); + if (pull == PIN_CONFIG_BIAS_DISABLE) + data |= BIT(bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + static struct rockchip_pin_bank rk3036_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -66,7 +87,7 @@ static struct rockchip_pin_ctrl rk3036_pin_ctrl = { .type = RK3036, .grf_mux_offset = 0xa8, .set_mux= rk3036_set_mux, - .pull_calc_reg = rk3036_calc_pull_reg_and_bit, + .set_pull = rk3036_set_pull, }; static const struct udevice_id rk3036_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c index de203334c7..104b76c19e 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c @@ -152,6 +152,27 @@ static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, *bit = pin_num % RK3128_PULL_PINS_PER_REG; } +static int rk3128_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit; + u32 data; + + if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && + pull != PIN_CONFIG_BIAS_DISABLE) + return -ENOTSUPP; + + rk3128_calc_pull_reg_and_bit(bank, pin_num, , , ); + data = BIT(bit + 16); + if (pull == PIN_CONFIG_BIAS_DISABLE) + data |= BIT(bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + static struct rockchip_pin_bank rk3128_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -170,7 +191,7 @@ static struct rockchip_pin_ctrl rk3128_pin_ctrl = { .iomux_routes = rk3128_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), .set_mux= rk3128_set_mux, - .pull_calc_reg = rk3128_calc_pull_reg_and_bit, + .set_pull = rk3128_set_pull, }; static const struct udevice_id rk3128_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index 617ae28ac8..e09c799e72 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c @@ -71,6 +71,33 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, } } +static int rk3188_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit, type; + u32 data; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + return -ENOTSUPP; + + rk3188_calc_pull_reg_and_bit(bank, pin_num, , , ); + type = bank->pull_type[pin_num / 8]; + ret = rockchip_translate_pull_value(type, pull); + if (ret < 0) { + debug("unsupported pull setting %d\n", pull); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + data
[U-Boot] [PATCH v3 06/10] pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' drive strength
RK3288 pmu_gpio0 drive strength setting have no higher 16 writing corresponding bits, need to read before write the register. Signed-off-by: David Wu --- Change in v3: - Add some comment drivers/pinctrl/rockchip/pinctrl-rk3288.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 6ae9f1c76e..d1b9aeb3d9 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -143,8 +143,15 @@ static int rk3288_set_drive(struct rockchip_pin_bank *bank, return ret; } - /* enable the write to the equivalent lower bits */ - data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + /* bank0 is special, there are no higher 16 bit writing bits. */ + if (bank->bank_num == 0) { + regmap_read(regmap, reg, ); + data &= ~(((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << bit); + } else { + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + } + data |= (ret << bit); ret = regmap_write(regmap, reg, data); return ret; -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v3 05/10] pinctrl: rockchip: Split the common set_drive() func into per Soc
As the common set_mux func(), implement the feature at the own file for each Soc. Signed-off-by: David Wu --- Change in v3: - None drivers/pinctrl/rockchip/pinctrl-rk322x.c | 25 - drivers/pinctrl/rockchip/pinctrl-rk3288.c | 35 +-- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 26 - drivers/pinctrl/rockchip/pinctrl-rk3368.c | 36 +-- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 75 ++- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 95 --- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 6 +- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 26 - 8 files changed, 224 insertions(+), 100 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index 442c40ce0b..10200ff3c8 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -208,6 +208,29 @@ static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, *bit *= ROCKCHIP_DRV_BITS_PER_PIN; } +static int rk3228_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg, ret; + u32 data; + u8 bit; + int type = bank->drv[pin_num / 8].drv_type; + + rk3228_calc_drv_reg_and_bit(bank, pin_num, , , ); + ret = rockchip_translate_drive_value(type, strength); + if (ret < 0) { + debug("unsupported driver strength %d\n", strength); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + return ret; +} + static struct rockchip_pin_bank rk3228_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -225,7 +248,7 @@ static struct rockchip_pin_ctrl rk3228_pin_ctrl = { .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), .set_mux= rk3228_set_mux, .pull_calc_reg = rk3228_calc_pull_reg_and_bit, - .drv_calc_reg = rk3228_calc_drv_reg_and_bit, + .set_drive = rk3228_set_drive, }; static const struct udevice_id rk3228_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 5040cd8f48..6ae9f1c76e 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -113,10 +113,6 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, if (bank->bank_num == 0) { *regmap = priv->regmap_pmu; *reg = RK3288_DRV_PMU_OFFSET; - - *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); - *bit = pin_num % ROCKCHIP_DRV_PINS_PER_REG; - *bit *= ROCKCHIP_DRV_BITS_PER_PIN; } else { *regmap = priv->regmap_base; *reg = RK3288_DRV_GRF_OFFSET; @@ -124,11 +120,34 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, /* correct the offset, as we're starting with the 2nd bank */ *reg -= 0x10; *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE; - *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); + } + + *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); + *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG); + *bit *= ROCKCHIP_DRV_BITS_PER_PIN; +} - *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG); - *bit *= ROCKCHIP_DRV_BITS_PER_PIN; +static int rk3288_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg, ret; + u32 data; + u8 bit; + int type = bank->drv[pin_num / 8].drv_type; + + rk3288_calc_drv_reg_and_bit(bank, pin_num, , , ); + ret = rockchip_translate_drive_value(type, strength); + if (ret < 0) { + debug("unsupported driver strength %d\n", strength); + return ret; } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + return ret; } static struct rockchip_pin_bank rk3288_pin_banks[] = { @@ -174,7 +193,7 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = { .niomux_routes = ARRAY_SIZE(rk3288_mux_route_data), .set_mux= rk3288_set_mux, .pull_calc_reg = rk3288_calc_pull_reg_and_bit, - .drv_calc_reg = rk3288_calc_drv_reg_and_bit, + .set_drive = rk3288_set_drive, }; s
[U-Boot] [PATCH v3 02/10] pinctrl: rockchip: Remove redundant spaces
Some files have the redundant spaces, remove them. Signed-off-by: David Wu --- Change in v3: - None drivers/pinctrl/rockchip/pinctrl-rk3036.c | 12 ++-- drivers/pinctrl/rockchip/pinctrl-rk3188.c | 12 ++-- drivers/pinctrl/rockchip/pinctrl-rk322x.c | 18 - drivers/pinctrl/rockchip/pinctrl-rk3288.c | 20 +-- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 24 +++ drivers/pinctrl/rockchip/pinctrl-rk3368.c | 16 +++ drivers/pinctrl/rockchip/pinctrl-rk3399.c | 24 +++ 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 2729b03443..2a651cd9b8 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -36,12 +36,12 @@ static struct rockchip_pin_bank rk3036_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3036_pin_ctrl = { - .pin_banks = rk3036_pin_banks, - .nr_banks = ARRAY_SIZE(rk3036_pin_banks), - .label = "RK3036-GPIO", - .type = RK3036, - .grf_mux_offset = 0xa8, - .pull_calc_reg = rk3036_calc_pull_reg_and_bit, + .pin_banks = rk3036_pin_banks, + .nr_banks = ARRAY_SIZE(rk3036_pin_banks), + .label = "RK3036-GPIO", + .type = RK3036, + .grf_mux_offset = 0xa8, + .pull_calc_reg = rk3036_calc_pull_reg_and_bit, }; static const struct udevice_id rk3036_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index 5ed9aec938..7cc52c0075 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c @@ -55,12 +55,12 @@ static struct rockchip_pin_bank rk3188_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3188_pin_ctrl = { - .pin_banks = rk3188_pin_banks, - .nr_banks = ARRAY_SIZE(rk3188_pin_banks), - .label = "RK3188-GPIO", - .type = RK3188, - .grf_mux_offset = 0x60, - .pull_calc_reg = rk3188_calc_pull_reg_and_bit, + .pin_banks = rk3188_pin_banks, + .nr_banks = ARRAY_SIZE(rk3188_pin_banks), + .label = "RK3188-GPIO", + .type = RK3188, + .grf_mux_offset = 0x60, + .pull_calc_reg = rk3188_calc_pull_reg_and_bit, }; static const struct udevice_id rk3188_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index d2a6cd7055..d67b48a06a 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -183,15 +183,15 @@ static struct rockchip_pin_bank rk3228_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3228_pin_ctrl = { - .pin_banks = rk3228_pin_banks, - .nr_banks = ARRAY_SIZE(rk3228_pin_banks), - .label = "RK3228-GPIO", - .type = RK3288, - .grf_mux_offset = 0x0, - .iomux_routes = rk3228_mux_route_data, - .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), - .pull_calc_reg = rk3228_calc_pull_reg_and_bit, - .drv_calc_reg = rk3228_calc_drv_reg_and_bit, + .pin_banks = rk3228_pin_banks, + .nr_banks = ARRAY_SIZE(rk3228_pin_banks), + .label = "RK3228-GPIO", + .type = RK3288, + .grf_mux_offset = 0x0, + .iomux_routes = rk3228_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), + .pull_calc_reg = rk3228_calc_pull_reg_and_bit, + .drv_calc_reg = rk3228_calc_drv_reg_and_bit, }; static const struct udevice_id rk3228_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 60585f3208..3648f37207 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -124,16 +124,16 @@ static struct rockchip_pin_bank rk3288_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3288_pin_ctrl = { - .pin_banks = rk3288_pin_banks, - .nr_banks = ARRAY_SIZE(rk3288_pin_banks), - .label = "RK3288-GPIO", - .type
[U-Boot] [PATCH v3 04/10] pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' iomux
RK3288 pmu_gpio0 iomux setting have no higher 16 writing corresponding bits, need to read before write the register. Signed-off-by: David Wu --- Change in v3: - Add some comment drivers/pinctrl/rockchip/pinctrl-rk3288.c | 10 +- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 1fa601d954..5040cd8f48 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -54,7 +54,15 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) } } - data = (mask << (bit + 16)); + /* bank0 is special, there are no higher 16 bit writing bits. */ + if (bank->bank_num == 0) { + regmap_read(regmap, reg, ); + data &= ~(mask << bit); + } else { + /* enable the write to the equivalent lower bits */ + data = (mask << (bit + 16)); + } + data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v3 03/10] pinctrl: rockchip: Split the common set_mux() into per Soc
Such as rk3288's pins of pmu_gpio0 are a special feature, which have no higher 16 writing corresponding bits, use common set_mux() func would introduce more code, so implement their set_mux() in each Soc's own file to reduce the size of code. Signed-off-by: David Wu --- Change in v3: - None drivers/pinctrl/rockchip/pinctrl-rk3036.c | 25 +++ drivers/pinctrl/rockchip/pinctrl-rk3128.c | 37 + drivers/pinctrl/rockchip/pinctrl-rk3188.c | 25 +++ drivers/pinctrl/rockchip/pinctrl-rk322x.c | 34 +++ drivers/pinctrl/rockchip/pinctrl-rk3288.c | 35 +++- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 37 + drivers/pinctrl/rockchip/pinctrl-rk3368.c | 25 +++ drivers/pinctrl/rockchip/pinctrl-rk3399.c | 34 +++ .../pinctrl/rockchip/pinctrl-rockchip-core.c | 41 +-- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 8 drivers/pinctrl/rockchip/pinctrl-rv1108.c | 28 + 11 files changed, 297 insertions(+), 32 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 2a651cd9b8..8969aea2e3 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -11,6 +11,30 @@ #include "pinctrl-rockchip.h" +static int rk3036_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int iomux_num = (pin / 8); + struct regmap *regmap; + int reg, ret, mask, mux_type; + u8 bit; + u32 data; + + regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + ? priv->regmap_pmu : priv->regmap_base; + + /* get basic quadrupel of mux registers and the correct reg inside */ + mux_type = bank->iomux[iomux_num].type; + reg = bank->iomux[iomux_num].offset; + reg += rockchip_get_mux_data(mux_type, pin, , ); + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + ret = regmap_write(regmap, reg, data); + + return ret; +} + #define RK3036_PULL_OFFSET 0x118 #define RK3036_PULL_PINS_PER_REG 16 #define RK3036_PULL_BANK_STRIDE8 @@ -41,6 +65,7 @@ static struct rockchip_pin_ctrl rk3036_pin_ctrl = { .label = "RK3036-GPIO", .type = RK3036, .grf_mux_offset = 0xa8, + .set_mux= rk3036_set_mux, .pull_calc_reg = rk3036_calc_pull_reg_and_bit, }; diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c index 43a6c173a0..de203334c7 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c @@ -98,6 +98,42 @@ static struct rockchip_mux_route_data rk3128_mux_route_data[] = { }, }; +static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int iomux_num = (pin / 8); + struct regmap *regmap; + int reg, ret, mask, mux_type; + u8 bit; + u32 data, route_reg, route_val; + + regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + ? priv->regmap_pmu : priv->regmap_base; + + /* get basic quadrupel of mux registers and the correct reg inside */ + mux_type = bank->iomux[iomux_num].type; + reg = bank->iomux[iomux_num].offset; + reg += rockchip_get_mux_data(mux_type, pin, , ); + + if (bank->recalced_mask & BIT(pin)) + rockchip_get_recalced_mux(bank, pin, , , ); + + if (bank->route_mask & BIT(pin)) { + if (rockchip_get_mux_route(bank, pin, mux, _reg, + _val)) { + ret = regmap_write(regmap, route_reg, route_val); + if (ret) + return ret; + } + } + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + ret = regmap_write(regmap, reg, data); + + return ret; +} + #define RK3128_PULL_OFFSET 0x118 #define RK3128_PULL_PINS_PER_REG 16 #define RK3128_PULL_BANK_STRIDE8 @@ -133,6 +169,7 @@ static struct rockchip_pin_ctrl rk3128_pin_ctrl = { .niomux_recalced= ARRAY_SIZE(rk3128_mux_recalced_data), .iomux_routes = rk3128_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), + .set_mux= rk3128_set_mux, .pull_calc_reg = rk3128_calc_pull_reg_and_bit, }; diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index 7cc52c0075..617ae28ac8 1
[U-Boot] [PATCH v3 01/10] pinctrl: rockchip: Add pull-pin-default param and remove unused param
Some Socs use the pull-pin-default config param, need to add it. And input-enable/disable config params are not necessary, remove it. Signed-off-by: David Wu --- Change in v3: - Add some commit message drivers/pinctrl/rockchip/pinctrl-rockchip-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index b84b079064..77ac981c40 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -509,9 +509,8 @@ static const struct pinconf_param rockchip_conf_params[] = { { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, + { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, - { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, - { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, }; -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v3 00/10] pinctrl: Split the common mux/drive/pull/schmitt func into per Soc
To reduce the pinctrl driver, implement the mux/drive/pull/schmitt func at per Soc. David Wu (10): pinctrl: rockchip: Add pull-pin-default param and remove unused param pinctrl: rockchip: Remove redundant spaces pinctrl: rockchip: Split the common set_mux() into per Soc pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' iomux pinctrl: rockchip: Split the common set_drive() func into per Soc pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' drive strength pinctrl: rockchip: Split the common set_pull() func into per Soc pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' pull pinctrl: rockchip: Clean the unused type and label pinctrl: rockchip: Also move common set_schmitter func into per Soc file drivers/pinctrl/rockchip/pinctrl-rk3036.c | 56 +++- drivers/pinctrl/rockchip/pinctrl-rk3128.c | 62 - drivers/pinctrl/rockchip/pinctrl-rk3188.c | 62 - drivers/pinctrl/rockchip/pinctrl-rk322x.c | 100 ++- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 146 -- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 125 - drivers/pinctrl/rockchip/pinctrl-rk3368.c | 111 ++-- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 167 ++-- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 255 -- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 36 ++- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 103 ++- 11 files changed, 891 insertions(+), 332 deletions(-) -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [PATCH v2 04/10] pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' iomux
Hi Philipp, 在 2019/4/4 下午3:19, Philipp Tomsich 写道: On 04.04.2019, at 05:51, David Wu wrote: RK3288 pmu_gpio0 iomux setting have no higher 16 writing corresponding bits, need to read before write the register. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 1fa601d954..d66ffdf24b 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -54,7 +54,13 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) } } - data = (mask << (bit + 16)); + if (bank->bank_num == 0) { + regmap_read(regmap, reg, ); Could you pull the regmap_read out of the if and make it common for all cases, so the differences between the paths are in data-manipulation only? Yes, the difference between the gpio0 and other pins is the data-manipulation, and i think the others don't need the regmap_read, so it is not a common case. + data &= ~(mask << bit); + } else { + data = (mask << (bit + 16)); + } + Please add a comment, so readers will be able to understand what is happening (and why) without referring to the TRM data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v2 10/10] pinctrl: rockchip: Also move common set_schmitter func into per Soc file
Only some Soc need Schmitter feature, so move the implementation into their own files. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 17 - .../pinctrl/rockchip/pinctrl-rockchip-core.c | 19 +++ drivers/pinctrl/rockchip/pinctrl-rockchip.h | 5 ++--- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 17 - 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c index d4d37af206..8d37a6f945 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c @@ -264,6 +264,21 @@ static int rk3328_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +static int rk3328_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u8 bit; + u32 data; + + rk3328_calc_schmitt_reg_and_bit(bank, pin_num, , , ); + /* enable the write to the equivalent lower bits */ + data = BIT(bit + 16) | (enable << bit); + + return regmap_write(regmap, reg, data); +} + static struct rockchip_pin_bank rk3328_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0), PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0), @@ -289,7 +304,7 @@ static struct rockchip_pin_ctrl rk3328_pin_ctrl = { .set_mux= rk3328_set_mux, .set_pull = rk3328_set_pull, .set_drive = rk3328_set_drive, - .schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit, + .set_schmitt= rk3328_set_schmitt, }; static const struct udevice_id rk3328_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index b3379a0d3f..80dc431d20 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -306,30 +306,20 @@ static int rockchip_set_schmitt(struct rockchip_pin_bank *bank, { struct rockchip_pinctrl_priv *priv = bank->priv; struct rockchip_pin_ctrl *ctrl = priv->ctrl; - struct regmap *regmap; - int reg, ret; - u8 bit; - u32 data; debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num, pin_num, enable); - ret = ctrl->schmitt_calc_reg(bank, pin_num, , , ); - if (ret) - return ret; - - /* enable the write to the equivalent lower bits */ - data = BIT(bit + 16) | (enable << bit); + if (!ctrl->set_schmitt) + return -ENOTSUPP; - return regmap_write(regmap, reg, data); + return ctrl->set_schmitt(bank, pin_num, enable); } /* set the pin config settings for a specified pin */ static int rockchip_pinconf_set(struct rockchip_pin_bank *bank, u32 pin, u32 param, u32 arg) { - struct rockchip_pinctrl_priv *priv = bank->priv; - struct rockchip_pin_ctrl *ctrl = priv->ctrl; int rc; switch (param) { @@ -350,9 +340,6 @@ static int rockchip_pinconf_set(struct rockchip_pin_bank *bank, break; case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - if (!ctrl->schmitt_calc_reg) - return -ENOTSUPP; - rc = rockchip_set_schmitt(bank, pin, arg); if (rc < 0) return rc; diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip.h b/drivers/pinctrl/rockchip/pinctrl-rockchip.h index 1c6fc2c5b2..9651e9c7a6 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip.h +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip.h @@ -271,9 +271,8 @@ struct rockchip_pin_ctrl { int pin_num, int pull); int (*set_drive)(struct rockchip_pin_bank *bank, int pin_num, int strength); - int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit); + int (*set_schmitt)(struct rockchip_pin_bank *bank, + int pin_num, int enable); }; /** diff --git a/drivers/pinctrl/rockchip/pinctrl-rv1108.c b/drivers/pinctrl/rockchip/pinctrl-rv1108.c index 0bcf11bb41..54610a3e90 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rv1108.c +++ b/drivers/pinctrl/rockchip/pinctrl-rv1108.c @@ -237,6 +237,21 @@ static int rv1108_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, return 0; } +static int rv1108_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u8 bit; + u32 data; + + rv1108_ca
[U-Boot] [PATCH v2 09/10] pinctrl: rockchip: Clean the unused type and label
As the mux/pull/drive feature implement at own file, the type and label are not necessary. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3036.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3128.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3188.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk322x.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3368.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 2 -- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 12 drivers/pinctrl/rockchip/pinctrl-rv1108.c | 2 -- 10 files changed, 30 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 498b633f22..28c905129b 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -83,8 +83,6 @@ static struct rockchip_pin_bank rk3036_pin_banks[] = { static struct rockchip_pin_ctrl rk3036_pin_ctrl = { .pin_banks = rk3036_pin_banks, .nr_banks = ARRAY_SIZE(rk3036_pin_banks), - .label = "RK3036-GPIO", - .type = RK3036, .grf_mux_offset = 0xa8, .set_mux= rk3036_set_mux, .set_pull = rk3036_set_pull, diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c index 104b76c19e..3eb4d952bb 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c @@ -183,8 +183,6 @@ static struct rockchip_pin_bank rk3128_pin_banks[] = { static struct rockchip_pin_ctrl rk3128_pin_ctrl = { .pin_banks = rk3128_pin_banks, .nr_banks = ARRAY_SIZE(rk3128_pin_banks), - .label = "RK3128-GPIO", - .type = RK3128, .grf_mux_offset = 0xa8, .iomux_recalced = rk3128_mux_recalced_data, .niomux_recalced= ARRAY_SIZE(rk3128_mux_recalced_data), diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index e09c799e72..043764fc92 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c @@ -108,8 +108,6 @@ static struct rockchip_pin_bank rk3188_pin_banks[] = { static struct rockchip_pin_ctrl rk3188_pin_ctrl = { .pin_banks = rk3188_pin_banks, .nr_banks = ARRAY_SIZE(rk3188_pin_banks), - .label = "RK3188-GPIO", - .type = RK3188, .grf_mux_offset = 0x60, .set_mux= rk3188_set_mux, .set_pull = rk3188_set_pull, diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index b69d9795bb..c5e4fe30a7 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -268,8 +268,6 @@ static struct rockchip_pin_bank rk3228_pin_banks[] = { static struct rockchip_pin_ctrl rk3228_pin_ctrl = { .pin_banks = rk3228_pin_banks, .nr_banks = ARRAY_SIZE(rk3228_pin_banks), - .label = "RK3228-GPIO", - .type = RK3288, .grf_mux_offset = 0x0, .iomux_routes = rk3228_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 51fb091af4..4ec96863ec 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -220,8 +220,6 @@ static struct rockchip_pin_bank rk3288_pin_banks[] = { static struct rockchip_pin_ctrl rk3288_pin_ctrl = { .pin_banks = rk3288_pin_banks, .nr_banks = ARRAY_SIZE(rk3288_pin_banks), - .label = "RK3288-GPIO", - .type = RK3288, .grf_mux_offset = 0x0, .pmu_mux_offset = 0x84, .iomux_routes = rk3288_mux_route_data, diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c index 7ac5c0226e..d4d37af206 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c @@ -281,8 +281,6 @@ static struct rockchip_pin_bank rk3328_pin_banks[] = { static struct rockchip_pin_ctrl rk3328_pin_ctrl = { .pin_banks = rk3328_pin_banks, .nr_banks = ARRAY_SIZE(rk3328_pin_banks), - .label = "RK3328-GPIO", - .type = RK3288, .grf_mux_offset = 0x0, .iomux_recalced = rk3328_mux
[U-Boot] [PATCH v2 08/10] pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' pull
RK3288 pmu_gpio0 pull setting have no higher 16 writing corresponding bits, need to read before write the register. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 2c25ab9f56..51fb091af4 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -114,8 +114,15 @@ static int rk3288_set_pull(struct rockchip_pin_bank *bank, return ret; } - /* enable the write to the equivalent lower bits */ - data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + /* bank0 is special, there are no higher 16 bit writing bits */ + if (bank->bank_num == 0) { + regmap_read(regmap, reg, ); + data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit); + } else { + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + } + data |= (ret << bit); ret = regmap_write(regmap, reg, data); -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v2 07/10] pinctrl: rockchip: Split the common set_pull() func into per Soc
As the common set_mux func(), implement the feature at the own file for each Soc. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3036.c | 23 - drivers/pinctrl/rockchip/pinctrl-rk3128.c | 23 - drivers/pinctrl/rockchip/pinctrl-rk3188.c | 29 +- drivers/pinctrl/rockchip/pinctrl-rk322x.c | 29 +- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 40 ++-- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 29 +- drivers/pinctrl/rockchip/pinctrl-rk3368.c | 40 ++-- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 40 ++-- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 97 --- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 7 +- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 30 +- 11 files changed, 275 insertions(+), 112 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 8969aea2e3..498b633f22 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -53,6 +53,27 @@ static void rk3036_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, *bit = pin_num % RK3036_PULL_PINS_PER_REG; }; +static int rk3036_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit; + u32 data; + + if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && + pull != PIN_CONFIG_BIAS_DISABLE) + return -ENOTSUPP; + + rk3036_calc_pull_reg_and_bit(bank, pin_num, , , ); + data = BIT(bit + 16); + if (pull == PIN_CONFIG_BIAS_DISABLE) + data |= BIT(bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + static struct rockchip_pin_bank rk3036_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -66,7 +87,7 @@ static struct rockchip_pin_ctrl rk3036_pin_ctrl = { .type = RK3036, .grf_mux_offset = 0xa8, .set_mux= rk3036_set_mux, - .pull_calc_reg = rk3036_calc_pull_reg_and_bit, + .set_pull = rk3036_set_pull, }; static const struct udevice_id rk3036_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c index de203334c7..104b76c19e 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c @@ -152,6 +152,27 @@ static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, *bit = pin_num % RK3128_PULL_PINS_PER_REG; } +static int rk3128_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit; + u32 data; + + if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT && + pull != PIN_CONFIG_BIAS_DISABLE) + return -ENOTSUPP; + + rk3128_calc_pull_reg_and_bit(bank, pin_num, , , ); + data = BIT(bit + 16); + if (pull == PIN_CONFIG_BIAS_DISABLE) + data |= BIT(bit); + ret = regmap_write(regmap, reg, data); + + return ret; +} + static struct rockchip_pin_bank rk3128_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -170,7 +191,7 @@ static struct rockchip_pin_ctrl rk3128_pin_ctrl = { .iomux_routes = rk3128_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), .set_mux= rk3128_set_mux, - .pull_calc_reg = rk3128_calc_pull_reg_and_bit, + .set_pull = rk3128_set_pull, }; static const struct udevice_id rk3128_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index 617ae28ac8..e09c799e72 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c @@ -71,6 +71,33 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, } } +static int rk3188_set_pull(struct rockchip_pin_bank *bank, + int pin_num, int pull) +{ + struct regmap *regmap; + int reg, ret; + u8 bit, type; + u32 data; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + return -ENOTSUPP; + + rk3188_calc_pull_reg_and_bit(bank, pin_num, , , ); + type = bank->pull_type[pin_num / 8]; + ret = rockchip_translate_pull_value(type, pull); + if (ret < 0) { + debug("unsupported pull setting %d\n", pull); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit)
[U-Boot] [PATCH v2 06/10] pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' drive strength
RK3288 pmu_gpio0 drive strength setting have no higher 16 writing corresponding bits, need to read before write the register. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index c52711914e..6f489d2d54 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -141,8 +141,14 @@ static int rk3288_set_drive(struct rockchip_pin_bank *bank, return ret; } - /* enable the write to the equivalent lower bits */ - data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + if (bank->bank_num == 0) { + regmap_read(regmap, reg, ); + data &= ~(((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << bit); + } else { + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + } + data |= (ret << bit); ret = regmap_write(regmap, reg, data); return ret; -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v2 05/10] pinctrl: rockchip: Split the common set_drive() func into per Soc
As the common set_mux func(), implement the feature at the own file for each Soc. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk322x.c | 25 - drivers/pinctrl/rockchip/pinctrl-rk3288.c | 35 +-- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 26 - drivers/pinctrl/rockchip/pinctrl-rk3368.c | 36 +-- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 75 ++- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 95 --- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 6 +- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 26 - 8 files changed, 224 insertions(+), 100 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index 442c40ce0b..10200ff3c8 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -208,6 +208,29 @@ static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, *bit *= ROCKCHIP_DRV_BITS_PER_PIN; } +static int rk3228_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg, ret; + u32 data; + u8 bit; + int type = bank->drv[pin_num / 8].drv_type; + + rk3228_calc_drv_reg_and_bit(bank, pin_num, , , ); + ret = rockchip_translate_drive_value(type, strength); + if (ret < 0) { + debug("unsupported driver strength %d\n", strength); + return ret; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + return ret; +} + static struct rockchip_pin_bank rk3228_pin_banks[] = { PIN_BANK(0, 32, "gpio0"), PIN_BANK(1, 32, "gpio1"), @@ -225,7 +248,7 @@ static struct rockchip_pin_ctrl rk3228_pin_ctrl = { .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), .set_mux= rk3228_set_mux, .pull_calc_reg = rk3228_calc_pull_reg_and_bit, - .drv_calc_reg = rk3228_calc_drv_reg_and_bit, + .set_drive = rk3228_set_drive, }; static const struct udevice_id rk3228_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index d66ffdf24b..c52711914e 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -111,10 +111,6 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, if (bank->bank_num == 0) { *regmap = priv->regmap_pmu; *reg = RK3288_DRV_PMU_OFFSET; - - *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); - *bit = pin_num % ROCKCHIP_DRV_PINS_PER_REG; - *bit *= ROCKCHIP_DRV_BITS_PER_PIN; } else { *regmap = priv->regmap_base; *reg = RK3288_DRV_GRF_OFFSET; @@ -122,11 +118,34 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, /* correct the offset, as we're starting with the 2nd bank */ *reg -= 0x10; *reg += bank->bank_num * ROCKCHIP_DRV_BANK_STRIDE; - *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); + } + + *reg += ((pin_num / ROCKCHIP_DRV_PINS_PER_REG) * 4); + *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG); + *bit *= ROCKCHIP_DRV_BITS_PER_PIN; +} - *bit = (pin_num % ROCKCHIP_DRV_PINS_PER_REG); - *bit *= ROCKCHIP_DRV_BITS_PER_PIN; +static int rk3288_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg, ret; + u32 data; + u8 bit; + int type = bank->drv[pin_num / 8].drv_type; + + rk3288_calc_drv_reg_and_bit(bank, pin_num, , , ); + ret = rockchip_translate_drive_value(type, strength); + if (ret < 0) { + debug("unsupported driver strength %d\n", strength); + return ret; } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (ret << bit); + ret = regmap_write(regmap, reg, data); + return ret; } static struct rockchip_pin_bank rk3288_pin_banks[] = { @@ -172,7 +191,7 @@ static struct rockchip_pin_ctrl rk3288_pin_ctrl = { .niomux_routes = ARRAY_SIZE(rk3288_mux_route_data), .set_mux= rk3288_set_mux, .pull_calc_reg = rk3288_calc_pull_reg_and_bit, - .drv_calc_reg = rk3288_calc_drv_reg_and_bit, + .set_drive = rk3288_set_drive, }; static const struct u
[U-Boot] [PATCH v2 03/10] pinctrl: rockchip: Split the common set_mux() into per Soc
Such as rk3288's pins of pmu_gpio0 are a special feature, which have no higher 16 writing corresponding bits, use common set_mux() func would introduce more code, so implement their set_mux() in each Soc's own file to reduce the size of code. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3036.c | 25 +++ drivers/pinctrl/rockchip/pinctrl-rk3128.c | 37 + drivers/pinctrl/rockchip/pinctrl-rk3188.c | 25 +++ drivers/pinctrl/rockchip/pinctrl-rk322x.c | 34 +++ drivers/pinctrl/rockchip/pinctrl-rk3288.c | 35 +++- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 37 + drivers/pinctrl/rockchip/pinctrl-rk3368.c | 25 +++ drivers/pinctrl/rockchip/pinctrl-rk3399.c | 34 +++ .../pinctrl/rockchip/pinctrl-rockchip-core.c | 41 +-- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 8 drivers/pinctrl/rockchip/pinctrl-rv1108.c | 28 + 11 files changed, 297 insertions(+), 32 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 2a651cd9b8..8969aea2e3 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -11,6 +11,30 @@ #include "pinctrl-rockchip.h" +static int rk3036_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int iomux_num = (pin / 8); + struct regmap *regmap; + int reg, ret, mask, mux_type; + u8 bit; + u32 data; + + regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + ? priv->regmap_pmu : priv->regmap_base; + + /* get basic quadrupel of mux registers and the correct reg inside */ + mux_type = bank->iomux[iomux_num].type; + reg = bank->iomux[iomux_num].offset; + reg += rockchip_get_mux_data(mux_type, pin, , ); + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + ret = regmap_write(regmap, reg, data); + + return ret; +} + #define RK3036_PULL_OFFSET 0x118 #define RK3036_PULL_PINS_PER_REG 16 #define RK3036_PULL_BANK_STRIDE8 @@ -41,6 +65,7 @@ static struct rockchip_pin_ctrl rk3036_pin_ctrl = { .label = "RK3036-GPIO", .type = RK3036, .grf_mux_offset = 0xa8, + .set_mux= rk3036_set_mux, .pull_calc_reg = rk3036_calc_pull_reg_and_bit, }; diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c index 43a6c173a0..de203334c7 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c @@ -98,6 +98,42 @@ static struct rockchip_mux_route_data rk3128_mux_route_data[] = { }, }; +static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +{ + struct rockchip_pinctrl_priv *priv = bank->priv; + int iomux_num = (pin / 8); + struct regmap *regmap; + int reg, ret, mask, mux_type; + u8 bit; + u32 data, route_reg, route_val; + + regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) + ? priv->regmap_pmu : priv->regmap_base; + + /* get basic quadrupel of mux registers and the correct reg inside */ + mux_type = bank->iomux[iomux_num].type; + reg = bank->iomux[iomux_num].offset; + reg += rockchip_get_mux_data(mux_type, pin, , ); + + if (bank->recalced_mask & BIT(pin)) + rockchip_get_recalced_mux(bank, pin, , , ); + + if (bank->route_mask & BIT(pin)) { + if (rockchip_get_mux_route(bank, pin, mux, _reg, + _val)) { + ret = regmap_write(regmap, route_reg, route_val); + if (ret) + return ret; + } + } + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + ret = regmap_write(regmap, reg, data); + + return ret; +} + #define RK3128_PULL_OFFSET 0x118 #define RK3128_PULL_PINS_PER_REG 16 #define RK3128_PULL_BANK_STRIDE8 @@ -133,6 +169,7 @@ static struct rockchip_pin_ctrl rk3128_pin_ctrl = { .niomux_recalced= ARRAY_SIZE(rk3128_mux_recalced_data), .iomux_routes = rk3128_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3128_mux_route_data), + .set_mux= rk3128_set_mux, .pull_calc_reg = rk3128_calc_pull_reg_and_bit, }; diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index 7cc52c0075..617ae28ac8 100644 --- a/drivers/pi
[U-Boot] [PATCH v2 02/10] pinctrl: rockchip: Remove redundant spaces
Some files have the redundant spaces, remove them. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3036.c | 12 ++-- drivers/pinctrl/rockchip/pinctrl-rk3188.c | 12 ++-- drivers/pinctrl/rockchip/pinctrl-rk322x.c | 18 - drivers/pinctrl/rockchip/pinctrl-rk3288.c | 20 +-- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 24 +++ drivers/pinctrl/rockchip/pinctrl-rk3368.c | 16 +++ drivers/pinctrl/rockchip/pinctrl-rk3399.c | 24 +++ 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3036.c b/drivers/pinctrl/rockchip/pinctrl-rk3036.c index 2729b03443..2a651cd9b8 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3036.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3036.c @@ -36,12 +36,12 @@ static struct rockchip_pin_bank rk3036_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3036_pin_ctrl = { - .pin_banks = rk3036_pin_banks, - .nr_banks = ARRAY_SIZE(rk3036_pin_banks), - .label = "RK3036-GPIO", - .type = RK3036, - .grf_mux_offset = 0xa8, - .pull_calc_reg = rk3036_calc_pull_reg_and_bit, + .pin_banks = rk3036_pin_banks, + .nr_banks = ARRAY_SIZE(rk3036_pin_banks), + .label = "RK3036-GPIO", + .type = RK3036, + .grf_mux_offset = 0xa8, + .pull_calc_reg = rk3036_calc_pull_reg_and_bit, }; static const struct udevice_id rk3036_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3188.c b/drivers/pinctrl/rockchip/pinctrl-rk3188.c index 5ed9aec938..7cc52c0075 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3188.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3188.c @@ -55,12 +55,12 @@ static struct rockchip_pin_bank rk3188_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3188_pin_ctrl = { - .pin_banks = rk3188_pin_banks, - .nr_banks = ARRAY_SIZE(rk3188_pin_banks), - .label = "RK3188-GPIO", - .type = RK3188, - .grf_mux_offset = 0x60, - .pull_calc_reg = rk3188_calc_pull_reg_and_bit, + .pin_banks = rk3188_pin_banks, + .nr_banks = ARRAY_SIZE(rk3188_pin_banks), + .label = "RK3188-GPIO", + .type = RK3188, + .grf_mux_offset = 0x60, + .pull_calc_reg = rk3188_calc_pull_reg_and_bit, }; static const struct udevice_id rk3188_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c index d2a6cd7055..d67b48a06a 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c @@ -183,15 +183,15 @@ static struct rockchip_pin_bank rk3228_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3228_pin_ctrl = { - .pin_banks = rk3228_pin_banks, - .nr_banks = ARRAY_SIZE(rk3228_pin_banks), - .label = "RK3228-GPIO", - .type = RK3288, - .grf_mux_offset = 0x0, - .iomux_routes = rk3228_mux_route_data, - .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), - .pull_calc_reg = rk3228_calc_pull_reg_and_bit, - .drv_calc_reg = rk3228_calc_drv_reg_and_bit, + .pin_banks = rk3228_pin_banks, + .nr_banks = ARRAY_SIZE(rk3228_pin_banks), + .label = "RK3228-GPIO", + .type = RK3288, + .grf_mux_offset = 0x0, + .iomux_routes = rk3228_mux_route_data, + .niomux_routes = ARRAY_SIZE(rk3228_mux_route_data), + .pull_calc_reg = rk3228_calc_pull_reg_and_bit, + .drv_calc_reg = rk3228_calc_drv_reg_and_bit, }; static const struct udevice_id rk3228_pinctrl_ids[] = { diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 60585f3208..3648f37207 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -124,16 +124,16 @@ static struct rockchip_pin_bank rk3288_pin_banks[] = { }; static struct rockchip_pin_ctrl rk3288_pin_ctrl = { - .pin_banks = rk3288_pin_banks, - .nr_banks = ARRAY_SIZE(rk3288_pin_banks), - .label = "RK3288-GPIO", - .type = RK3288, - .grf_mu
[U-Boot] [PATCH v2 04/10] pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' iomux
RK3288 pmu_gpio0 iomux setting have no higher 16 writing corresponding bits, need to read before write the register. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 1fa601d954..d66ffdf24b 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -54,7 +54,13 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) } } - data = (mask << (bit + 16)); + if (bank->bank_num == 0) { + regmap_read(regmap, reg, ); + data &= ~(mask << bit); + } else { + data = (mask << (bit + 16)); + } + data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v2 01/10] pinctrl: rockchip: Add pull-pin-default param and remove unused param
Some Socs use the pull-pin-default config param, need to add it. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rockchip-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index b84b079064..77ac981c40 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -509,9 +509,8 @@ static const struct pinconf_param rockchip_conf_params[] = { { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, + { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, - { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, - { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, }; -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH v2 00/10] pinctrl: Split the common mux/drive/pull/schmitt func into per Soc
To reduce the pinctrl driver, implement the mux/drive/pull/schmitt func at per Soc. David Wu (10): pinctrl: rockchip: Add pull-pin-default param and remove unused param pinctrl: rockchip: Remove redundant spaces pinctrl: rockchip: Split the common set_mux() into per Soc pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' iomux pinctrl: rockchip: Split the common set_drive() func into per Soc pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' drive strength pinctrl: rockchip: Split the common set_pull() func into per Soc pinctrl: rockchip: Special treatment for RK3288 gpio0 pins' pull pinctrl: rockchip: Clean the unused type and label pinctrl: rockchip: Also move common set_schmitter func into per Soc file drivers/pinctrl/rockchip/pinctrl-rk3036.c | 56 +++- drivers/pinctrl/rockchip/pinctrl-rk3128.c | 62 - drivers/pinctrl/rockchip/pinctrl-rk3188.c | 62 - drivers/pinctrl/rockchip/pinctrl-rk322x.c | 100 ++- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 143 -- drivers/pinctrl/rockchip/pinctrl-rk3328.c | 125 - drivers/pinctrl/rockchip/pinctrl-rk3368.c | 111 ++-- drivers/pinctrl/rockchip/pinctrl-rk3399.c | 167 ++-- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 255 -- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 36 ++- drivers/pinctrl/rockchip/pinctrl-rv1108.c | 103 ++- 11 files changed, 888 insertions(+), 332 deletions(-) -- 2.19.1 ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [PATCH 1/1] configs: tinker-rk3288 disable CONFIG_SPL_I2C_SUPPORT
Hi Philipp, This config does not look like it will be used in SPL and can be deleted. Reviewed-by: David Wu 在 2019/2/28 上午3:05, Heinrich Schuchardt 写道: The SPL for the Tinker Board has to fit into 32 KiB. Currently this limit is exceeded. CONFIG_SPL_I2C_SUPPORT is not needed to move to main U-Boot. So let's disable it. Suggested-by: David Wu Signed-off-by: Heinrich Schuchardt --- This solves only one of the problems with the boards in v2019.04. The next problem is that reading the environment from MMC fails. The patch [PATCH v3 1/1] configs: rk3288: Tinker Board SPL file must fit into 32 KiB https://lists.denx.de/pipermail/u-boot/2019-February/358883.html makes the problem visibe. --- configs/tinker-rk3288_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig index 68adf7635bf..03a7f81d63d 100644 --- a/configs/tinker-rk3288_defconfig +++ b/configs/tinker-rk3288_defconfig @@ -18,7 +18,6 @@ CONFIG_DEFAULT_FDT_FILE="rk3288-tinker.dtb" CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 -CONFIG_SPL_I2C_SUPPORT=y CONFIG_CMD_GPIO=y CONFIG_CMD_GPT=y CONFIG_CMD_I2C=y ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [PATCH] pinctrl: rockchip: Add 32bit writing function for rk3288 gpio0 pinctrl
Hi Philipp, 在 2019/3/29 下午10:40, Philipp Tomsich 写道: David, I am applying this one as a last-minute fix for 2019.4. However, I’ll still need the v2 for the next cycle, as I my review comments still apply. Sorry, there was a lot of things in March. I think I could push v2 at this week. Thanks, Philipp. On 12.02.2019, at 12:55, Philipp Tomsich <mailto:philipp.toms...@theobroma-systems.com>> wrote: On 12.02.2019, at 12:51, David Wu <mailto:david...@rock-chips.com>> wrote: There are no higher 16 writing corresponding bits for pmu_gpio0's iomux/drive/pull at rk3288, need to read the value from register firstly. Add the flag to distinguish it from normal registers. Signed-off-by: David Wu <mailto:david...@rock-chips.com>> --- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 17 ++-- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 39 ++- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 33 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 60585f3208..8b6ce11a63 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -92,10 +92,19 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, } static struct rockchip_pin_bank rk3288_pin_banks[] = { -PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, -IOMUX_SOURCE_PMU, -IOMUX_SOURCE_PMU, -IOMUX_UNROUTED +PIN_BANK_IOMUX_DRV_PULL_FLAGS(0, 24, "gpio0", + IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, + IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, + IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, + IOMUX_UNROUTED, + DRV_TYPE_WRITABLE_32BIT, + DRV_TYPE_WRITABLE_32BIT, + DRV_TYPE_WRITABLE_32BIT, + 0, + PULL_TYPE_WRITABLE_32BIT, + PULL_TYPE_WRITABLE_32BIT, + PULL_TYPE_WRITABLE_32BIT, + 0 ), PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, IOMUX_UNROUTED, diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index b84b079064..ce935656f0 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -228,7 +228,13 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) } } -data = (mask << (bit + 16)); +if (mux_type & IOMUX_WRITABLE_32BIT) { +regmap_read(regmap, reg, ); +data &= ~(mask << bit); +} else { +data = (mask << (bit + 16)); +} + This can not be optimised out by the compiler (for all the other platforms that don’t need it). Please structure this (and the entire driver) to not pull in unneeded baggage that is only used by one or a few devices. data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); @@ -252,7 +258,8 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, int reg, ret, i; u32 data, rmask_bits, temp; u8 bit; -int drv_type = bank->drv[pin_num / 8].drv_type; +/* Where need to clean the special mask for rockchip_perpin_drv_list */ +int drv_type = bank->drv[pin_num / 8].drv_type & (~DRV_TYPE_IO_MASK); debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num, pin_num, strength); @@ -324,10 +331,15 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, return -EINVAL; } -/* enable the write to the equivalent lower bits */ -data = ((1 << rmask_bits) - 1) << (bit + 16); -data |= (ret << bit); +if (bank->drv[pin_num / 8].drv_type & DRV_TYPE_WRITABLE_32BIT) { +regmap_read(regmap, reg, ); +data &= ~(((1 << rmask_bits) - 1) << bit); +} else { +/* enable the write to the equivalent lower bits */ +data = ((1 << rmask_bits) - 1) << (bit + 16); +} +data |= (ret << bit); ret = regmap_write(regmap, reg, data); return ret; } @@ -375,7 +387,11 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, case RK3288: case RK3368: case RK3399: -pull_type = bank->pull_type[pin_num / 8]; +/* +* Where need to clean the special mask for +* rockchip_pull_list. +*/ +pull_type = bank->pull_type[pin_num / 8] & (~PULL_TYPE_IO_MASK); ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); i++) { @@ -390,10 +406,15 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, return ret; } -/* enable the write to the equivalent lower bits */ -data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); -data |= (ret << bit); +if (bank->pull_type[pin_num / 8] & PULL_TYPE_WRITABLE_32BIT) { +regmap_read(regmap, reg, ); +data &= ~(((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << bit); +} else { +/* enable the write to the equivalent lower bits */ +data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); +} +data |= (ret << bit)
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Heiko, 在 2019/2/28 下午9:29, Heiko Stübner 写道: Hi Philipp, Am Donnerstag, 28. Februar 2019, 13:46:44 CET schrieb Heiko Stübner: Am Donnerstag, 28. Februar 2019, 13:36:52 CET schrieb Philipp Tomsich: On 28.02.2019, at 11:50, Heiko Stübner wrote: Hi David, Am Montag, 18. Februar 2019, 02:05:12 CET schrieb David Wu: Hi Heinrich and Michael, Another thing i see is that I missed a patch, for the 3288 gpio0, its iomux is special, there is no high 16-bit write-enabled bit. For Tinker board, it uses I2C0, the current driver will overwrite the I2C0 iomux, while request the GPIO0A4. It requires a patch: http://patchwork.ozlabs.org/patch/1040541/ <http://patchwork.ozlabs.org/patch/1040541/>> I've also just stumbled onto the issue of recent uboots not booting on rk3288. While your patch seems to have reached patchwork, somehow the u-boot list seems to have lost it - as it's neither in public archives nor in my inbox it seems. Please note that I had requested changes to that patch during review. I’ll ping David again on when he expect to have those changes implemented and ready. yeah, I saw that in patchwork, but couldn't comment due to the patch seemingly not having reach the actual u-boot list strangely. That patch doesn't seem to help me right now anyway, as I somehow seem be stuck on mem_malloc_init() hanging when called from initr_malloc() (board_r.c) and am not yet sure what is going on there (on u-boot-master from last friday). This problem seems to be memory-related somehow? My 2GB rk3288-evb comes up fine to the uboot prompt, while my 1GB rk3288-phycore hangs in said mem_malloc_init(). Is this issue introduced by the pinctrl patch? rk3288-evb (2GB): [...] Relocation Offset is: 7ed88000 Relocating to 7ed88000, new gd at 7cd7fed8, sp at 7cd76230 [...] initr_malloc: before mem_malloc_init using memory 0x7cd8-0x7ed88000 for malloc() initr_malloc: after mem_malloc_init [...] rk3288-phycore (1GB): [...] Relocation Offset is: 3ff7b000 Relocating to 3ff7b000, new gd at 3df72ee0, sp at 3df68f60 [...] initr_malloc: before mem_malloc_init using memory 0x3df73000-0x3ff7b000 for malloc() [HANG] Do you have some tips what I need to poke for this issue? Heiko Applying the patch does not make my board (phycore-rk3288 in this case) get farther though - I'll investigate more. But it looks like we should be having the same issue in the kernel, just never triggered it, as the gpio0 are of more esotheric uses normally. Anyway, I'm wondering if defining IOMUX_WRITABLE_32BIT alone wouldn't be enough and use that for iomux, pull and drv, similar to what we do for the pull/drv register source already. That way we could refrain from introducing DRV_TYPE_WRITABLE_32BIT and PULL_TYPE_WRITABLE_32BIT . Heiko 在 2019/2/17 下午8:41, Heinrich Schuchardt 写道: On 2/17/19 1:18 PM, Michael Nazzareno Trimarchi wrote: Hi [U-Boot] [PATCH 3/5] rockchip: rk3288-vyasa: increase heap space after relocation Can you check it if you have the same problem? Applying all the changes causes SPL not to start. CONFIG_SYS_MALLOC_F_LEN=0x4000 does not solve the problem. Best regards Heinrich Michael On Sun., 17 Feb. 2019, 1:11 pm Heinrich Schuchardt mailto:xypron.g...@gmx.de> wrote: On 2/17/19 9:19 AM, David Wu wrote: Hi Henrich, 在 2019/2/16 下午5:53, Heinrich Schuchardt 写道: On 2/13/19 11:56 AM, Philipp Tomsich wrote: Hello David, hello Philipp, what are your ideas to reduce the SPL size to under 0x7800 again? Or will you move all rk3288 boards to TPL like TARGET_VYASA_RK3288? CONFIG_SPL_I2C_SUPPORT is necessary for Tink spl? Remove this can make spl boot. As the Tinker does not use the i2c to read the MAC address from eeprom at the SPL stage, which is at uboot. Hello David, the SPL image size now just fits: Image Type: Rockchip RK32 (SD/MMC) boot image Data Size:30720 bytes SPL is successful. But MMC is failing in main U-Boot: ``` U-Boot SPL 2019.04-rc1-00239-gb89074f650 (Feb 17 2019 - 12:41:39 +0100) Returning to boot ROM... U-Boot 2019.04-rc1-00239-gb89074f650 (Feb 17 2019 - 12:41:39 +0100) Model: Tinker-RK3288 DRAM: 2 GiB MMC: dwmmc@ff0c: 1 Loading Environment from MMC... ``` No further output here. With some debug output enabled: ``` U-Boot SPL 2019.04-rc1-00239-gb89074f650-dirty (Feb 17 2019 - 13:05:10 +0100) Returning to boot ROM... mmc_bind: alias ret=0, devnum=1 env_init: Environment MMC init done (ret=-2) U-Boot 2019.04-rc1-00239-gb89074f650-dirty (Feb 17 2019 - 13:05:10 +0100) Model: Tinker-RK3288 DRAM: 2 GiB mmc_bind: alias ret=0, devnum=1 MMC: dwmmc@ff0c: 1 Loading Environment from MMC... ``` Any suggestion how to proceed? CC: Jaehoon. Best regards
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Philipp, 在 2019/2/28 下午8:36, Philipp Tomsich 写道: On 28.02.2019, at 11:50, Heiko Stübner <mailto:he...@sntech.de>> wrote: Hi David, Am Montag, 18. Februar 2019, 02:05:12 CET schrieb David Wu: Hi Heinrich and Michael, Another thing i see is that I missed a patch, for the 3288 gpio0, its iomux is special, there is no high 16-bit write-enabled bit. For Tinker board, it uses I2C0, the current driver will overwrite the I2C0 iomux, while request the GPIO0A4. It requires a patch: http://patchwork.ozlabs.org/patch/1040541/ I've also just stumbled onto the issue of recent uboots not booting on rk3288. While your patch seems to have reached patchwork, somehow the u-boot list seems to have lost it - as it's neither in public archives nor in my inbox it seems. Please note that I had requested changes to that patch during review. I’ll ping David again on when he expect to have those changes implemented and ready. Yes, I am preparing this part of the modification for your request, and after the change. need to verify the more chips. Just recently more things are on going. Applying the patch does not make my board (phycore-rk3288 in this case) get farther though - I'll investigate more. But it looks like we should be having the same issue in the kernel, just never triggered it, as the gpio0 are of more esotheric uses normally. Anyway, I'm wondering if defining IOMUX_WRITABLE_32BIT alone wouldn't be enough and use that for iomux, pull and drv, similar to what we do for the pull/drv register source already. That way we could refrain from introducing DRV_TYPE_WRITABLE_32BIT and PULL_TYPE_WRITABLE_32BIT . Heiko 在 2019/2/17 下午8:41, Heinrich Schuchardt 写道: On 2/17/19 1:18 PM, Michael Nazzareno Trimarchi wrote: Hi [U-Boot] [PATCH 3/5] rockchip: rk3288-vyasa: increase heap space after relocation Can you check it if you have the same problem? Applying all the changes causes SPL not to start. CONFIG_SYS_MALLOC_F_LEN=0x4000 does not solve the problem. Best regards Heinrich Michael On Sun., 17 Feb. 2019, 1:11 pm Heinrich Schuchardt mailto:xypron.g...@gmx.de> <mailto:xypron.g...@gmx.de> wrote: On 2/17/19 9:19 AM, David Wu wrote: Hi Henrich, 在 2019/2/16 下午5:53, Heinrich Schuchardt 写道: On 2/13/19 11:56 AM, Philipp Tomsich wrote: Hello David, hello Philipp, what are your ideas to reduce the SPL size to under 0x7800 again? Or will you move all rk3288 boards to TPL like TARGET_VYASA_RK3288? CONFIG_SPL_I2C_SUPPORT is necessary for Tink spl? Remove this can make spl boot. As the Tinker does not use the i2c to read the MAC address from eeprom at the SPL stage, which is at uboot. Hello David, the SPL image size now just fits: Image Type: Rockchip RK32 (SD/MMC) boot image Data Size: 30720 bytes SPL is successful. But MMC is failing in main U-Boot: ``` U-Boot SPL 2019.04-rc1-00239-gb89074f650 (Feb 17 2019 - 12:41:39 +0100) Returning to boot ROM... U-Boot 2019.04-rc1-00239-gb89074f650 (Feb 17 2019 - 12:41:39 +0100) Model: Tinker-RK3288 DRAM: 2 GiB MMC: dwmmc@ff0c: 1 Loading Environment from MMC... ``` No further output here. With some debug output enabled: ``` U-Boot SPL 2019.04-rc1-00239-gb89074f650-dirty (Feb 17 2019 - 13:05:10 +0100) Returning to boot ROM... mmc_bind: alias ret=0, devnum=1 env_init: Environment MMC init done (ret=-2) U-Boot 2019.04-rc1-00239-gb89074f650-dirty (Feb 17 2019 - 13:05:10 +0100) Model: Tinker-RK3288 DRAM: 2 GiB mmc_bind: alias ret=0, devnum=1 MMC: dwmmc@ff0c: 1 Loading Environment from MMC... ``` Any suggestion how to proceed? CC: Jaehoon. Best regards Heinrich ___ U-Boot mailing list U-Boot@lists.denx.de <mailto:U-Boot@lists.denx.de> https://lists.denx.de/listinfo/u-boot ___ U-Boot mailing list U-Boot@lists.denx.de <mailto:U-Boot@lists.denx.de> https://lists.denx.de/listinfo/u-boot ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Heinrich and Michael, Another thing i see is that I missed a patch, for the 3288 gpio0, its iomux is special, there is no high 16-bit write-enabled bit. For Tinker board, it uses I2C0, the current driver will overwrite the I2C0 iomux, while request the GPIO0A4. It requires a patch: http://patchwork.ozlabs.org/patch/1040541/ 在 2019/2/17 下午8:41, Heinrich Schuchardt 写道: On 2/17/19 1:18 PM, Michael Nazzareno Trimarchi wrote: Hi [U-Boot] [PATCH 3/5] rockchip: rk3288-vyasa: increase heap space after relocation Can you check it if you have the same problem? Applying all the changes causes SPL not to start. CONFIG_SYS_MALLOC_F_LEN=0x4000 does not solve the problem. Best regards Heinrich Michael On Sun., 17 Feb. 2019, 1:11 pm Heinrich Schuchardt mailto:xypron.g...@gmx.de> wrote: On 2/17/19 9:19 AM, David Wu wrote: > Hi Henrich, > > 在 2019/2/16 下午5:53, Heinrich Schuchardt 写道: >> On 2/13/19 11:56 AM, Philipp Tomsich wrote: >> >> Hello David, hello Philipp, >> >> what are your ideas to reduce the SPL size to under 0x7800 again? >> Or will you move all rk3288 boards to TPL like TARGET_VYASA_RK3288? > > CONFIG_SPL_I2C_SUPPORT is necessary for Tink spl? Remove this can make > spl boot. As the Tinker does not use the i2c to read the MAC address > from eeprom at the SPL stage, which is at uboot. Hello David, the SPL image size now just fits: Image Type: Rockchip RK32 (SD/MMC) boot image Data Size: 30720 bytes SPL is successful. But MMC is failing in main U-Boot: ``` U-Boot SPL 2019.04-rc1-00239-gb89074f650 (Feb 17 2019 - 12:41:39 +0100) Returning to boot ROM... U-Boot 2019.04-rc1-00239-gb89074f650 (Feb 17 2019 - 12:41:39 +0100) Model: Tinker-RK3288 DRAM: 2 GiB MMC: dwmmc@ff0c: 1 Loading Environment from MMC... ``` No further output here. With some debug output enabled: ``` U-Boot SPL 2019.04-rc1-00239-gb89074f650-dirty (Feb 17 2019 - 13:05:10 +0100) Returning to boot ROM... mmc_bind: alias ret=0, devnum=1 env_init: Environment MMC init done (ret=-2) U-Boot 2019.04-rc1-00239-gb89074f650-dirty (Feb 17 2019 - 13:05:10 +0100) Model: Tinker-RK3288 DRAM: 2 GiB mmc_bind: alias ret=0, devnum=1 MMC: dwmmc@ff0c: 1 Loading Environment from MMC... ``` Any suggestion how to proceed? CC: Jaehoon. Best regards Heinrich ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Henrich, 在 2019/2/16 下午5:53, Heinrich Schuchardt 写道: On 2/13/19 11:56 AM, Philipp Tomsich wrote: On 13.02.2019, at 11:52, David Wu wrote: Hi philipp, 在 2019/2/13 下午6:47, Philipp Tomsich 写道: On 13.02.2019, at 11:33, David Wu wrote: 在 2019/2/13 下午6:13, Philipp Tomsich 写道: On 13.02.2019, at 11:10, David Wu wrote: Hi Philipp, 在 2019/2/12 下午9:54, Philipp Tomsich 写道: On 12.02.2019, at 13:38, David Wu wrote: Hi Philipp, 在 2019/2/10 上午2:24, Philipp Tomsich 写道: That said, I have been fighting issues from this patchset when trying to read from devices on the i2c0 bus on a RK3399—which had me add a “simple” pinctrl device again, as pulling all the dependencies into the SPL is a pain. I think you can also add the simple ops if necessary. Full pinctrl should only be used at the U-boot stage, or the SPL stage where the TPL is available. For most boards about 3288, there is no need to enable pinctrl at SPL stage, such as Tinker board. Could you check whether TPL_MAX_SIZE and SPL_MAX_SIZE are correct for the RK3288? If not, please submit a patch. It is correct, 32KB. Interesting... I wonder why the build did not fail then, if SPL became too big. Popmetal is okay, the SPL is too big for Tinker, i didn't test Tinker. If it is too big for Tinker: does the build fail or silently ignore the error? build is okay, mkimage can get the error, i just build, not to mkimage for Tinker. This is more than enough (mkimage is part of the build for me!) I was just wondering why Heinrich ran into this problem and didn’t see a build error (even at the mkimage stage). Hello David, hello Philipp, what are your ideas to reduce the SPL size to under 0x7800 again? Or will you move all rk3288 boards to TPL like TARGET_VYASA_RK3288? CONFIG_SPL_I2C_SUPPORT is necessary for Tink spl? Remove this can make spl boot. As the Tinker does not use the i2c to read the MAC address from eeprom at the SPL stage, which is at uboot. Best regards Heinrich ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi philipp, 在 2019/2/13 下午6:47, Philipp Tomsich 写道: On 13.02.2019, at 11:33, David Wu wrote: 在 2019/2/13 下午6:13, Philipp Tomsich 写道: On 13.02.2019, at 11:10, David Wu wrote: Hi Philipp, 在 2019/2/12 下午9:54, Philipp Tomsich 写道: On 12.02.2019, at 13:38, David Wu wrote: Hi Philipp, 在 2019/2/10 上午2:24, Philipp Tomsich 写道: That said, I have been fighting issues from this patchset when trying to read from devices on the i2c0 bus on a RK3399—which had me add a “simple” pinctrl device again, as pulling all the dependencies into the SPL is a pain. I think you can also add the simple ops if necessary. Full pinctrl should only be used at the U-boot stage, or the SPL stage where the TPL is available. For most boards about 3288, there is no need to enable pinctrl at SPL stage, such as Tinker board. Could you check whether TPL_MAX_SIZE and SPL_MAX_SIZE are correct for the RK3288? If not, please submit a patch. It is correct, 32KB. Interesting... I wonder why the build did not fail then, if SPL became too big. Popmetal is okay, the SPL is too big for Tinker, i didn't test Tinker. If it is too big for Tinker: does the build fail or silently ignore the error? build is okay, mkimage can get the error, i just build, not to mkimage for Tinker. ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Philipp, 在 2019/2/13 下午6:30, Philipp Tomsich 写道: The 10k comes from a direct comparison on our RK3399-Q7, after pulling in all the required DTS nodes and properties vs. a minimal simple pinctrl for I2C only (which is ~ 100 bytes of code). So according to your mind, do not use DTS at the SPL stage, still follow the original way, use the periph id? ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
在 2019/2/13 下午6:13, Philipp Tomsich 写道: On 13.02.2019, at 11:10, David Wu wrote: Hi Philipp, 在 2019/2/12 下午9:54, Philipp Tomsich 写道: On 12.02.2019, at 13:38, David Wu wrote: Hi Philipp, 在 2019/2/10 上午2:24, Philipp Tomsich 写道: That said, I have been fighting issues from this patchset when trying to read from devices on the i2c0 bus on a RK3399—which had me add a “simple” pinctrl device again, as pulling all the dependencies into the SPL is a pain. I think you can also add the simple ops if necessary. Full pinctrl should only be used at the U-boot stage, or the SPL stage where the TPL is available. For most boards about 3288, there is no need to enable pinctrl at SPL stage, such as Tinker board. Could you check whether TPL_MAX_SIZE and SPL_MAX_SIZE are correct for the RK3288? If not, please submit a patch. It is correct, 32KB. Interesting... I wonder why the build did not fail then, if SPL became too big. Popmetal is okay, the SPL is too big for Tinker, i didn't test Tinker. Anyway, let’s file this under “things to revisit, if the problem recurs”. Thanks, Philipp. ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Philipp, 在 2019/2/12 下午9:53, Philipp Tomsich 写道: On 12.02.2019, at 13:38, David Wu wrote: Hi Philipp, 在 2019/2/10 上午2:24, Philipp Tomsich 写道: That said, I have been fighting issues from this patchset when trying to read from devices on the i2c0 bus on a RK3399—which had me add a “simple” pinctrl device again, as pulling all the dependencies into the SPL is a pain. I think you can also add the simple ops if necessary. Full pinctrl should only be used at the U-boot stage, or the SPL stage where the TPL is available. I started on this and will submit it with the follow-on changes that depend on this, as I don’t want to pull in the ~10k of extra size. 10k is a bit exaggerated, I think I can split some common functions into each Soc chip file, can reduce some size. For the simple ops, do you feel like get prop from "pinctrl-0", and then the pinctrl process is similar to what it is now. There’s a number of failure modes in the SPL/TPL path from missing DTB nodes (as one would need to add pre-reloc tags to all pinctrl and dependent nodes). For most boards about 3288, there is no need to enable pinctrl at SPL stage, such as Tinker board. Unfortunately, in this merge I had to make a judgement call between insisting on code-quality and getting the full pinctrl-driver merged. With this release cycle being longer and having 5 RCs, I figured we’ll have time to iron out any wrinkles... ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Philipp, 在 2019/2/12 下午9:54, Philipp Tomsich 写道: On 12.02.2019, at 13:38, David Wu wrote: Hi Philipp, 在 2019/2/10 上午2:24, Philipp Tomsich 写道: That said, I have been fighting issues from this patchset when trying to read from devices on the i2c0 bus on a RK3399—which had me add a “simple” pinctrl device again, as pulling all the dependencies into the SPL is a pain. I think you can also add the simple ops if necessary. Full pinctrl should only be used at the U-boot stage, or the SPL stage where the TPL is available. For most boards about 3288, there is no need to enable pinctrl at SPL stage, such as Tinker board. Could you check whether TPL_MAX_SIZE and SPL_MAX_SIZE are correct for the RK3288? If not, please submit a patch. It is correct, 32KB. Unfortunately, in this merge I had to make a judgement call between insisting on code-quality and getting the full pinctrl-driver merged. With this release cycle being longer and having 5 RCs, I figured we’ll have time to iron out any wrinkles... ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Philipp, 在 2019/2/10 上午2:24, Philipp Tomsich 写道: That said, I have been fighting issues from this patchset when trying to read from devices on the i2c0 bus on a RK3399—which had me add a “simple” pinctrl device again, as pulling all the dependencies into the SPL is a pain. I think you can also add the simple ops if necessary. Full pinctrl should only be used at the U-boot stage, or the SPL stage where the TPL is available. For most boards about 3288, there is no need to enable pinctrl at SPL stage, such as Tinker board. Unfortunately, in this merge I had to make a judgement call between insisting on code-quality and getting the full pinctrl-driver merged. With this release cycle being longer and having 5 RCs, I figured we’ll have time to iron out any wrinkles... ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
Re: [U-Boot] [BUG] booting on the Tinker Board (tinker-rk3288_defconfig) is broken
Hi Heinrich, 在 2019/2/10 上午12:39, Heinrich Schuchardt 写道: On 2/9/19 4:24 PM, Philipp Tomsich wrote: On 09.02.2019, at 16:08, Philipp Tomsich wrote: Heinrich, My guess is that this is fallout from David Wu’s new pinctrl driver (which has really been the bulk of changes in this cycle). I can’t test or debug on the rk3288 due to a lack of hardware. If you want to start digging, that the changes in commit 08c817c39908f9d120df1e4c90ddad4a11fc3891 Author: David Wu Date: Wed Jan 2 20:51:00 2019 +0800 ARM: rockchip: Remove the pinctrl request at rk3288-board-spl If we use the new pinctrl driver, the pinctrl setup will be done by device probe. Remove the pinctrl setup at rk3288-board-spl. Signed-off-by: David Wu Reviewed-by: Kever Yang Reviewed-by: Philipp Tomsich look like they have the potential to break everything, including the UART pinctrl. Thanks, Philipp., Hello Philipp, I would not know how to analyze the bug if there isn't even a console. The reason i see, that is the u-boot-spl-dtb.bin is too large for bootrom, while supports full pinctrl at SPL stage. Compared to the popmetal-rk3288_defconfig, CONFIG_SPL_I2C_SUPPORT is not enabled at PopMetal. Remove this config to reduces the spl bin size, makes the Tinker board to boot. As the tinker does not use the i2c to read the MAC address from eeprom at the SPL stage, which is at uboot. Another thing is that I missed a patch, for the 3288 gpio0, its iomux is special, there is no high 16-bit write-enabled bit. For Tinker board, it uses I2C0, the current driver will overwrite the I2C0 iomux, while request the GPIO0A4. It requires a patch. If David or you send me a git branch to compile I will test it. Has any of the rk3288 boards been tested before merging? Yes, I tested the patch at RK3288 PopMetal board once, and just tested one board for per Soc, i didn't have a Tinker board in my hand to verify it. The new pinctrl driver could work at PopMetal: U-Boot SPL 2019.01-rc1-9-gdd7b9156fe (Feb 12 2019 - 09:33:17 +0800) Returning to boot ROM... U-Boot 2019.01-rc1-9-gdd7b9156fe (Feb 12 2019 - 09:33:17 +0800) Model: PopMetal-RK3288 DRAM: 2 GiB MMC: dwmmc@ff0c: 1, dwmmc@ff0f: 0 Loading Environment from MMC... *** Warning - bad CRC, using default environment In:serial Out: serial Err: serial Model: PopMetal-RK3288 Net: eth-1: ethernet@ff29 Hit any key to stop autoboot: 0 switch to partitions #0, OK mmc0(part 0) is current device ** No partition table - mmc 0 ** Card did not respond to voltage select! starting USB... USB0: scanning bus 0 for devices... 2 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found Device 0: unknown device No ethernet found. => I think we should keep Simon in CC as he is one of the ROCKCHIP maintainers. Best regards Heinrich ___ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot
[U-Boot] [PATCH] pinctrl: rockchip: Add 32bit writing function for rk3288 gpio0 pinctrl
There are no higher 16 writing corresponding bits for pmu_gpio0's iomux/drive/pull at rk3288, need to read the value from register firstly. Add the flag to distinguish it from normal registers. Signed-off-by: David Wu --- drivers/pinctrl/rockchip/pinctrl-rk3288.c | 17 ++-- .../pinctrl/rockchip/pinctrl-rockchip-core.c | 39 ++- drivers/pinctrl/rockchip/pinctrl-rockchip.h | 33 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c index 60585f3208..8b6ce11a63 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c +++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c @@ -92,10 +92,19 @@ static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, } static struct rockchip_pin_bank rk3288_pin_banks[] = { - PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU, -IOMUX_SOURCE_PMU, -IOMUX_SOURCE_PMU, -IOMUX_UNROUTED + PIN_BANK_IOMUX_DRV_PULL_FLAGS(0, 24, "gpio0", + IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, + IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, + IOMUX_SOURCE_PMU | IOMUX_WRITABLE_32BIT, + IOMUX_UNROUTED, + DRV_TYPE_WRITABLE_32BIT, + DRV_TYPE_WRITABLE_32BIT, + DRV_TYPE_WRITABLE_32BIT, + 0, + PULL_TYPE_WRITABLE_32BIT, + PULL_TYPE_WRITABLE_32BIT, + PULL_TYPE_WRITABLE_32BIT, + 0 ), PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED, IOMUX_UNROUTED, diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c index b84b079064..ce935656f0 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c @@ -228,7 +228,13 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) } } - data = (mask << (bit + 16)); + if (mux_type & IOMUX_WRITABLE_32BIT) { + regmap_read(regmap, reg, ); + data &= ~(mask << bit); + } else { + data = (mask << (bit + 16)); + } + data |= (mux & mask) << bit; ret = regmap_write(regmap, reg, data); @@ -252,7 +258,8 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, int reg, ret, i; u32 data, rmask_bits, temp; u8 bit; - int drv_type = bank->drv[pin_num / 8].drv_type; + /* Where need to clean the special mask for rockchip_perpin_drv_list */ + int drv_type = bank->drv[pin_num / 8].drv_type & (~DRV_TYPE_IO_MASK); debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num, pin_num, strength); @@ -324,10 +331,15 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank, return -EINVAL; } - /* enable the write to the equivalent lower bits */ - data = ((1 << rmask_bits) - 1) << (bit + 16); - data |= (ret << bit); + if (bank->drv[pin_num / 8].drv_type & DRV_TYPE_WRITABLE_32BIT) { + regmap_read(regmap, reg, ); + data &= ~(((1 << rmask_bits) - 1) << bit); + } else { + /* enable the write to the equivalent lower bits */ + data = ((1 << rmask_bits) - 1) << (bit + 16); + } + data |= (ret << bit); ret = regmap_write(regmap, reg, data); return ret; } @@ -375,7 +387,11 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, case RK3288: case RK3368: case RK3399: - pull_type = bank->pull_type[pin_num / 8]; + /* +* Where need to clean the special mask for +* rockchip_pull_list. +*/ + pull_type = bank->pull_type[pin_num / 8] & (~PULL_TYPE_IO_MASK); ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); i++) { @@ -390,10 +406,15 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, return ret; } - /* enable the write to the equivalent lower bits */ - data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) <<
Re: [U-Boot] [PATCH v2 0/9] Add common pinctrl driver support for rockchip
Ping Philipp... 在 2019/1/22 上午2:50, Simon Glass 写道: Hi, On Thu, 3 Jan 2019 at 01:51, David Wu wrote: The common pinctrl driver for rockchip Socs, it depends the PINCTRL_FULL config. If use it, the default pinctrl setup from DTS could be configured at device probe. Changes in v2: - Remove px30, rk2928, rk3066*. - Split it to multiple files for the relevant per-SoC data structures. David Wu (9): rockchip: rk3399-evb: defconfig: Enable FDT for new pinctrl driver ARM: rockchip: rk3188: Remove the pinctrl setup and enable uart at SPL ARM: rockchip: Kconfig: Remove the SPL_PINCTRL for rk3188 ARM: rockchip: Remove the pinctrl request at rk3288-board-spl rk3288: chrome: defconfig: Enable FDT for new pinctrl driver pinctrl: rockchip: Add common rockchip pinctrl driver rockchip: defconfig: Clean the unused pinctrl config pinctrl: rockchip: Clean the unused rockchip pinctrl drivers ARM: dts: rk322x: Correct the uart2 default pin configuration arch/arm/dts/rk322x.dtsi | 11 +- arch/arm/mach-rockchip/Kconfig| 1 - arch/arm/mach-rockchip/rk3188-board-spl.c | 41 +- arch/arm/mach-rockchip/rk3288-board-spl.c | 79 -- configs/chromebit_mickey_defconfig| 4 - configs/chromebook_jerry_defconfig| 4 - configs/chromebook_minnie_defconfig | 4 - configs/evb-px5_defconfig | 1 - configs/evb-rk3128_defconfig | 1 - configs/evb-rk3229_defconfig | 1 - configs/evb-rk3288_defconfig | 2 - configs/evb-rk3399_defconfig | 2 - configs/evb-rv1108_defconfig | 1 - configs/fennec-rk3288_defconfig | 2 - configs/firefly-rk3288_defconfig | 2 - configs/firefly-rk3399_defconfig | 1 - configs/geekbox_defconfig | 1 - configs/kylin-rk3036_defconfig| 1 - configs/lion-rk3368_defconfig | 1 - configs/miqi-rk3288_defconfig | 2 - configs/phycore-rk3288_defconfig | 2 - configs/popmetal-rk3288_defconfig | 2 - configs/puma-rk3399_defconfig | 1 - configs/rock2_defconfig | 2 - configs/rock_defconfig| 1 - configs/sandbox_defconfig | 2 - configs/sandbox_flattree_defconfig| 2 - configs/sandbox_noblk_defconfig | 2 - configs/sheep-rk3368_defconfig| 1 - configs/tinker-rk3288_defconfig | 2 - configs/vyasa-rk3288_defconfig| 2 - drivers/pinctrl/Kconfig | 91 +- drivers/pinctrl/Makefile | 2 +- drivers/pinctrl/rockchip/Kconfig | 17 + drivers/pinctrl/rockchip/Makefile | 19 +- drivers/pinctrl/rockchip/pinctrl-rk3036.c | 65 ++ drivers/pinctrl/rockchip/pinctrl-rk3128.c | 155 +++ drivers/pinctrl/rockchip/pinctrl-rk3188.c | 82 ++ drivers/pinctrl/rockchip/pinctrl-rk322x.c | 215 drivers/pinctrl/rockchip/pinctrl-rk3288.c | 157 +++ drivers/pinctrl/rockchip/pinctrl-rk3328.c | 227 drivers/pinctrl/rockchip/pinctrl-rk3368.c | 116 ++ drivers/pinctrl/rockchip/pinctrl-rk3399.c | 193 .../pinctrl/rockchip/pinctrl-rockchip-core.c | 788 ++ drivers/pinctrl/rockchip/pinctrl-rockchip.h | 302 ++ drivers/pinctrl/rockchip/pinctrl-rv1108.c | 203 drivers/pinctrl/rockchip/pinctrl_rk3036.c | 671 drivers/pinctrl/rockchip/pinctrl_rk3128.c | 186 drivers/pinctrl/rockchip/pinctrl_rk3188.c | 989 -- drivers/pinctrl/rockchip/pinctrl_rk322x.c | 894 drivers/pinctrl/rockchip/pinctrl_rk3288.c | 869 --- drivers/pinctrl/rockchip/pinctrl_rk3328.c | 705 - drivers/pinctrl/rockchip/pinctrl_rk3368.c | 739 - drivers/pinctrl/rockchip/pinctrl_rk3399.c | 503 - drivers/pinctrl/rockchip/pinctrl_rv1108.c | 580 -- 55 files changed, 2543 insertions(+), 6406 deletions(-) create mode 100644 drivers/pinctrl/rockchip/Kconfig create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3036.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3128.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3188.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk322x.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3288.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3328.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3368.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3399.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rockchip-core.c create mode 100644 drivers/pinctrl/rockchip/pinctrl-rockchip.h create mode 100644 drivers/pinctrl