From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 19 Dec 2024 01:47:39 +0000 Subject: [PATCH] add wifi6 8852be driver --- kernel/drivers/pinctrl/pinctrl-rockchip.c | 1667 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 1,275 insertions(+), 392 deletions(-) diff --git a/kernel/drivers/pinctrl/pinctrl-rockchip.c b/kernel/drivers/pinctrl/pinctrl-rockchip.c index 939a29c..858192d 100644 --- a/kernel/drivers/pinctrl/pinctrl-rockchip.c +++ b/kernel/drivers/pinctrl/pinctrl-rockchip.c @@ -20,10 +20,10 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/bitops.h> -#include <linux/gpio.h> +#include <linux/gpio/driver.h> #include <linux/of_address.h> -#include <linux/of_irq.h> #include <linux/of_device.h> +#include <linux/of_irq.h> #include <linux/pinctrl/machine.h> #include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinctrl.h> @@ -40,7 +40,7 @@ #include "pinconf.h" #include "pinctrl-rockchip.h" -/** +/* * Generate a bitmask for setting a value (v) with a write mask bit in hiword * register 31:16 area. */ @@ -117,6 +117,25 @@ { .drv_type = type2, .offset = -1 }, \ { .drv_type = type3, .offset = -1 }, \ }, \ + } + +#define PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(id, pins, label, iom0, iom1, \ + iom2, iom3, pull0, pull1, \ + pull2, pull3) \ + { \ + .bank_num = id, \ + .nr_pins = pins, \ + .name = label, \ + .iomux = { \ + { .type = iom0, .offset = -1 }, \ + { .type = iom1, .offset = -1 }, \ + { .type = iom2, .offset = -1 }, \ + { .type = iom3, .offset = -1 }, \ + }, \ + .pull_type[0] = pull0, \ + .pull_type[1] = pull1, \ + .pull_type[2] = pull2, \ + .pull_type[3] = pull3, \ } #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1, \ @@ -204,7 +223,7 @@ .route_location = FLAG, \ } -#define PX30S_PIN_BANK_FLAGS(ID, PIN, LABEL, MTYPE, DTYPE) \ +#define S_PIN_BANK_FLAGS(ID, PIN, LABEL, MTYPE, DTYPE) \ PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(ID, PIN, LABEL, \ MTYPE, MTYPE, MTYPE, MTYPE, \ DTYPE, DTYPE, DTYPE, DTYPE, \ @@ -218,6 +237,12 @@ #define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) + +#define RK3588_PIN_BANK_FLAGS(ID, PIN, LABEL, M, P) \ + PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(ID, PIN, LABEL, M, M, M, M, P, P, P, P) + +static struct pinctrl_dev *g_pctldev; +static DEFINE_MUTEX(iomux_lock); static struct regmap_config rockchip_regmap_config = { .reg_bits = 32, @@ -309,6 +334,7 @@ { struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); const struct rockchip_pin_group *grp; + struct device *dev = info->dev; struct pinctrl_map *new_map; struct device_node *parent; int map_num = 1; @@ -320,8 +346,7 @@ */ grp = pinctrl_name_to_group(info, np->name); if (!grp) { - dev_err(info->dev, "unable to find group for node %pOFn\n", - np); + dev_err(dev, "unable to find group for node %pOFn\n", np); return -EINVAL; } @@ -355,7 +380,7 @@ new_map[i].data.configs.num_configs = grp->data[i].nconfigs; } - dev_dbg(pctldev->dev, "maps: function %s group %s num %d\n", + dev_dbg(dev, "maps: function %s group %s num %d\n", (*map)->data.mux.function, (*map)->data.mux.group, map_num); return 0; @@ -510,159 +535,110 @@ static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { { + /* gpio1b6_sel */ .num = 1, .pin = 14, .reg = 0x28, .bit = 12, .mask = 0xf }, { + /* gpio1b7_sel */ .num = 1, .pin = 15, .reg = 0x2c, .bit = 0, .mask = 0x3 }, { + /* gpio1c2_sel */ .num = 1, .pin = 18, .reg = 0x30, .bit = 4, .mask = 0xf }, { + /* gpio1c3_sel */ .num = 1, .pin = 19, .reg = 0x30, .bit = 8, .mask = 0xf }, { + /* gpio1c4_sel */ .num = 1, .pin = 20, .reg = 0x30, .bit = 12, .mask = 0xf }, { + /* gpio1c5_sel */ .num = 1, .pin = 21, .reg = 0x34, .bit = 0, .mask = 0xf }, { + /* gpio1c6_sel */ .num = 1, .pin = 22, .reg = 0x34, .bit = 4, .mask = 0xf }, { + /* gpio1c7_sel */ .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 - }, -}; - -static struct rockchip_mux_recalced_data rk3308b_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 - }, { + /* gpio2a2_sel_plus */ .num = 2, .pin = 2, .reg = 0x608, .bit = 0, .mask = 0x7 }, { + /* gpio2a3_sel_plus */ .num = 2, .pin = 3, .reg = 0x608, .bit = 4, .mask = 0x7 }, { + /* gpio2c0_sel_plus */ .num = 2, .pin = 16, .reg = 0x610, .bit = 8, .mask = 0x7 }, { + /* gpio3b2_sel_plus */ .num = 3, .pin = 10, .reg = 0x610, .bit = 0, .mask = 0x7 }, { + /* gpio3b3_sel_plus */ .num = 3, .pin = 11, .reg = 0x610, .bit = 4, .mask = 0x7 + }, { + /* gpio3b4_sel */ + .num = 3, + .pin = 12, + .reg = 0x68, + .bit = 8, + .mask = 0xf + }, { + /* gpio3b5_sel */ + .num = 3, + .pin = 13, + .reg = 0x68, + .bit = 12, + .mask = 0xf }, }; @@ -725,16 +701,23 @@ }; static struct rockchip_mux_route_data rv1126_mux_route_data[] = { + RK_MUXROUTE_GRF(3, RK_PD2, 1, 0x10260, WRITE_MASK_VAL(0, 0, 0)), /* I2S0_MCLK_M0 */ RK_MUXROUTE_GRF(3, RK_PD1, 1, 0x10260, WRITE_MASK_VAL(0, 0, 0)), /* I2S0_SCLK_RX_M0 */ RK_MUXROUTE_GRF(3, RK_PD0, 1, 0x10260, WRITE_MASK_VAL(0, 0, 0)), /* I2S0_SCLK_TX_M0 */ + RK_MUXROUTE_GRF(3, RK_PB0, 3, 0x10260, WRITE_MASK_VAL(0, 0, 1)), /* I2S0_MCLK_M1 */ RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x10260, WRITE_MASK_VAL(0, 0, 1)), /* I2S0_SCLK_RX_M1 */ RK_MUXROUTE_GRF(3, RK_PA4, 3, 0x10260, WRITE_MASK_VAL(0, 0, 1)), /* I2S0_SCLK_TX_M1 */ + RK_MUXROUTE_GRF(0, RK_PD4, 4, 0x10260, WRITE_MASK_VAL(3, 2, 0)), /* I2S1_MCLK_M0 */ RK_MUXROUTE_GRF(1, RK_PA1, 4, 0x10260, WRITE_MASK_VAL(3, 2, 0)), /* I2S1_SCLK_M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x10260, WRITE_MASK_VAL(3, 2, 1)), /* I2S1_MCLK_M1 */ RK_MUXROUTE_GRF(1, RK_PD6, 2, 0x10260, WRITE_MASK_VAL(3, 2, 1)), /* I2S1_SCLK_M1 */ + RK_MUXROUTE_GRF(2, RK_PC7, 6, 0x10260, WRITE_MASK_VAL(3, 2, 2)), /* I2S1_MCLK_M2 */ RK_MUXROUTE_GRF(2, RK_PD1, 6, 0x10260, WRITE_MASK_VAL(3, 2, 2)), /* I2S1_SCLK_M2 */ + RK_MUXROUTE_GRF(1, RK_PD0, 1, 0x10260, WRITE_MASK_VAL(4, 4, 0)), /* I2S2_MCLK_M0 */ RK_MUXROUTE_GRF(1, RK_PC6, 1, 0x10260, WRITE_MASK_VAL(4, 4, 0)), /* I2S2_SCLK_M0 */ + RK_MUXROUTE_GRF(2, RK_PB3, 2, 0x10260, WRITE_MASK_VAL(4, 4, 1)), /* I2S2_MCLK_M1 */ RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x10260, WRITE_MASK_VAL(4, 4, 1)), /* I2S2_SCLK_M1 */ RK_MUXROUTE_GRF(3, RK_PD4, 2, 0x10260, WRITE_MASK_VAL(12, 12, 0)), /* PDM_CLK0_M0 */ @@ -916,22 +899,6 @@ RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ - RK_MUXROUTE_SAME(0, RK_PC7, 2, 0x314, BIT(16 + 4)), /* i2c3_sdam0 */ - RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x314, BIT(16 + 4) | BIT(4)), /* i2c3_sdam1 */ - RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ - RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ - RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclktxm1 */ - RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, BIT(16 + 3) | BIT(3)), /* i2s-8ch-1-sclkrxm1 */ - RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, BIT(16 + 12) | BIT(16 + 13)), /* pdm-clkm0 */ - RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(12)), /* pdm-clkm1 */ - RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, BIT(16 + 12) | BIT(16 + 13) | BIT(13)), /* pdm-clkm2 */ - RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, BIT(16 + 2) | BIT(2)), /* pdm-clkm-m2 */ -}; - -static struct rockchip_mux_route_data rk3308b_mux_route_data[] = { - RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, BIT(16 + 0) | BIT(0)), /* rtc_clk */ - RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, BIT(16 + 2) | BIT(16 + 3)), /* uart2_rxm0 */ - RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, BIT(16 + 2) | BIT(16 + 3) | BIT(2)), /* uart2_rxm1 */ RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, BIT(16 + 8) | BIT(16 + 9)), /* i2c3_sdam0 */ RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(8)), /* i2c3_sdam1 */ RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, BIT(16 + 8) | BIT(16 + 9) | BIT(9)), /* i2c3_sdam2 */ @@ -965,7 +932,9 @@ RK_MUXROUTE_SAME(2, RK_PC3, 2, 0x50, BIT(16 + 3)), /* pdm_sdi0m0 */ RK_MUXROUTE_SAME(1, RK_PC7, 3, 0x50, BIT(16 + 3) | BIT(3)), /* pdm_sdi0m1 */ RK_MUXROUTE_SAME(3, RK_PA2, 4, 0x50, BIT(16 + 4) | BIT(16 + 5) | BIT(5)), /* spi_rxdm2 */ + RK_MUXROUTE_SAME(1, RK_PC6, 1, 0x50, BIT(16 + 6)), /* i2s2_sclkm0 */ RK_MUXROUTE_SAME(1, RK_PD0, 1, 0x50, BIT(16 + 6)), /* i2s2_sdim0 */ + RK_MUXROUTE_SAME(3, RK_PA0, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sclkm1 */ RK_MUXROUTE_SAME(3, RK_PA2, 6, 0x50, BIT(16 + 6) | BIT(6)), /* i2s2_sdim1 */ RK_MUXROUTE_SAME(2, RK_PC6, 3, 0x50, BIT(16 + 7) | BIT(7)), /* card_iom1 */ RK_MUXROUTE_SAME(2, RK_PC0, 3, 0x50, BIT(16 + 8) | BIT(8)), /* tsp_d5m1 */ @@ -1054,25 +1023,25 @@ RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ - RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ - RK_MUXROUTE_GRF(1, RK_PA3, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux sclk tx M0 */ - RK_MUXROUTE_GRF(1, RK_PA4, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux sclk rx M0 */ - RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ - RK_MUXROUTE_GRF(3, RK_PC7, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux sclk tx M1 */ - RK_MUXROUTE_GRF(4, RK_PA6, 5, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux sclk rx M1 */ - RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ - RK_MUXROUTE_GRF(2, RK_PD1, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux sclk tx M2 */ - RK_MUXROUTE_GRF(3, RK_PC3, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux sclk rx M2 */ - RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ - RK_MUXROUTE_GRF(2, RK_PC2, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux sclk tx M0 */ - RK_MUXROUTE_GRF(2, RK_PB7, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux sclk rx M0 */ - RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ - RK_MUXROUTE_GRF(4, RK_PB7, 4, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S1 IO mux sclk tx M1 */ - RK_MUXROUTE_GRF(4, RK_PC1, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S1 IO mux sclk rx M1 */ - RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ - RK_MUXROUTE_GRF(3, RK_PA3, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux sclk M0 */ - RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ - RK_MUXROUTE_GRF(4, RK_PC3, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux sclk M1 */ + RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 MCLK mux M0 */ + RK_MUXROUTE_GRF(1, RK_PA4, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 SCLKRX mux M0 */ + RK_MUXROUTE_GRF(1, RK_PA3, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 SCLKTX mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 MCLK mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA6, 5, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 SCLKRX mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC7, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 SCLKTX mux M1 */ + RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 MCLK mux M2 */ + RK_MUXROUTE_GRF(3, RK_PC3, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 SCLKRX mux M2 */ + RK_MUXROUTE_GRF(2, RK_PD1, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 SCLKTX mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 MCLK mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB7, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 SCLKRX mux M0 */ + RK_MUXROUTE_GRF(2, RK_PC2, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 SCLKTX mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 MCLK mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC1, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 SCLKRX mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB7, 4, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 SCLKTX mux M1 */ + RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 MCLK mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA3, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 SCLK mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 MCLK mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC3, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 SCLK mux M1 */ RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ @@ -1117,6 +1086,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) { struct rockchip_pinctrl *info = bank->drvdata; + struct rockchip_pin_ctrl *ctrl = info->ctrl; int iomux_num = (pin / 8); struct regmap *regmap; unsigned int val; @@ -1162,6 +1132,27 @@ if (bank->recalced_mask & BIT(pin)) rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); + if (ctrl->type == RK3588) { + if (bank->bank_num == 0) { + if ((pin >= RK_PB4) && (pin <= RK_PD7)) { + u32 reg0 = 0; + + reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */ + ret = regmap_read(regmap, reg0, &val); + if (ret) + return ret; + + if (((val >> bit) & mask) != 8) + return ((val >> bit) & mask); + + reg = reg + 0x8000; /* BUS_IOC_BASE */ + regmap = info->regmap_base; + } + } else if (bank->bank_num > 0) { + reg += 0x8000; /* BUS_IOC_BASE */ + } + } + ret = regmap_read(regmap, reg, &val); if (ret) return ret; @@ -1173,20 +1164,20 @@ int pin, int mux) { struct rockchip_pinctrl *info = bank->drvdata; + struct device *dev = info->dev; int iomux_num = (pin / 8); if (iomux_num > 3) return -EINVAL; if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) { - dev_err(info->dev, "pin %d is unrouted\n", pin); + dev_err(dev, "pin %d is unrouted\n", pin); return -EINVAL; } if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) { if (mux != RK_FUNC_GPIO) { - dev_err(info->dev, - "pin %d only supports a gpio mux\n", pin); + dev_err(dev, "pin %d only supports a gpio mux\n", pin); return -ENOTSUPP; } } @@ -1210,6 +1201,8 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) { struct rockchip_pinctrl *info = bank->drvdata; + struct rockchip_pin_ctrl *ctrl = info->ctrl; + struct device *dev = info->dev; int iomux_num = (pin / 8); struct regmap *regmap; int reg, ret, mask, mux_type; @@ -1223,8 +1216,7 @@ if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) return 0; - dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", - bank->bank_num, pin, mux); + dev_dbg(dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU) regmap = info->regmap_pmu; @@ -1253,6 +1245,64 @@ if (bank->recalced_mask & BIT(pin)) rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask); + + /* rk3562 force jtag m1 */ + if (ctrl->type == RK3562) { + if (bank->bank_num == 1) { + if ((pin == RK_PB5) || (pin == RK_PB6)) { + if (mux == 1) { + regmap_update_bits(regmap, 0x504, 0x10001, 0x10001); + } else { + regmap_update_bits(regmap, 0x504, 0x10001, 0x10000); + } + } + } + } + + if (ctrl->type == RK3588) { + if (bank->bank_num == 0) { + if ((pin >= RK_PB4) && (pin <= RK_PD7)) { + if (mux < 8) { + u32 reg0 = 0; + + reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */ + data = (mask << (bit + 16)); + rmask = data | (data >> 16); + data |= (mux & mask) << bit; + ret = regmap_update_bits(regmap, reg0, rmask, data); + + reg0 = reg + 0x8000; /* BUS_IOC_BASE */ + data = (mask << (bit + 16)); + rmask = data | (data >> 16); + regmap = info->regmap_base; + ret |= regmap_update_bits(regmap, reg0, rmask, data); + } else { + u32 reg0 = 0; + + reg0 = reg + 0x4000 - 0xC; /* PMU2_IOC_BASE */ + data = (mask << (bit + 16)); + rmask = data | (data >> 16); + data |= 8 << bit; + ret = regmap_update_bits(regmap, reg0, rmask, data); + + reg0 = reg + 0x8000; /* BUS_IOC_BASE */ + data = (mask << (bit + 16)); + rmask = data | (data >> 16); + data |= (mux & mask) << bit; + regmap = info->regmap_base; + ret |= regmap_update_bits(regmap, reg0, rmask, data); + } + } else { + data = (mask << (bit + 16)); + rmask = data | (data >> 16); + data |= (mux & mask) << bit; + ret = regmap_update_bits(regmap, reg, rmask, data); + } + return ret; + } else if (bank->bank_num > 0) { + reg += 0x8000; /* BUS_IOC_BASE */ + } + } if (mux > mask) return -EINVAL; @@ -1302,9 +1352,9 @@ #define PX30_PULL_PINS_PER_REG 8 #define PX30_PULL_BANK_STRIDE 16 -static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1324,6 +1374,8 @@ *reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4); *bit = (pin_num % PX30_PULL_PINS_PER_REG); *bit *= PX30_PULL_BITS_PER_PIN; + + return 0; } #define PX30_DRV_PMU_OFFSET 0x20 @@ -1332,9 +1384,9 @@ #define PX30_DRV_PINS_PER_REG 8 #define PX30_DRV_BANK_STRIDE 16 -static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1354,6 +1406,8 @@ *reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4); *bit = (pin_num % PX30_DRV_PINS_PER_REG); *bit *= PX30_DRV_BITS_PER_PIN; + + return 0; } #define PX30_SCHMITT_PMU_OFFSET 0x38 @@ -1387,15 +1441,175 @@ return 0; } +#define RV1106_DRV_BITS_PER_PIN 8 +#define RV1106_DRV_PINS_PER_REG 2 +#define RV1106_DRV_GPIO0_OFFSET 0x10 +#define RV1106_DRV_GPIO1_OFFSET 0x80 +#define RV1106_DRV_GPIO2_OFFSET 0x100C0 +#define RV1106_DRV_GPIO3_OFFSET 0x20100 +#define RV1106_DRV_GPIO4_OFFSET 0x30020 + +static int rv1106_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* GPIO0_IOC is located in PMU */ + switch (bank->bank_num) { + case 0: + *regmap = info->regmap_pmu; + *reg = RV1106_DRV_GPIO0_OFFSET; + break; + + case 1: + *regmap = info->regmap_base; + *reg = RV1106_DRV_GPIO1_OFFSET; + break; + + case 2: + *regmap = info->regmap_base; + *reg = RV1106_DRV_GPIO2_OFFSET; + break; + + case 3: + *regmap = info->regmap_base; + *reg = RV1106_DRV_GPIO3_OFFSET; + break; + + case 4: + *regmap = info->regmap_base; + *reg = RV1106_DRV_GPIO4_OFFSET; + break; + + default: + dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); + break; + } + + *reg += ((pin_num / RV1106_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RV1106_DRV_PINS_PER_REG; + *bit *= RV1106_DRV_BITS_PER_PIN; + + return 0; +} + +#define RV1106_PULL_BITS_PER_PIN 2 +#define RV1106_PULL_PINS_PER_REG 8 +#define RV1106_PULL_GPIO0_OFFSET 0x38 +#define RV1106_PULL_GPIO1_OFFSET 0x1C0 +#define RV1106_PULL_GPIO2_OFFSET 0x101D0 +#define RV1106_PULL_GPIO3_OFFSET 0x201E0 +#define RV1106_PULL_GPIO4_OFFSET 0x30070 + +static int rv1106_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* GPIO0_IOC is located in PMU */ + switch (bank->bank_num) { + case 0: + *regmap = info->regmap_pmu; + *reg = RV1106_PULL_GPIO0_OFFSET; + break; + + case 1: + *regmap = info->regmap_base; + *reg = RV1106_PULL_GPIO1_OFFSET; + break; + + case 2: + *regmap = info->regmap_base; + *reg = RV1106_PULL_GPIO2_OFFSET; + break; + + case 3: + *regmap = info->regmap_base; + *reg = RV1106_PULL_GPIO3_OFFSET; + break; + + case 4: + *regmap = info->regmap_base; + *reg = RV1106_PULL_GPIO4_OFFSET; + break; + + default: + dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); + break; + } + + *reg += ((pin_num / RV1106_PULL_PINS_PER_REG) * 4); + *bit = pin_num % RV1106_PULL_PINS_PER_REG; + *bit *= RV1106_PULL_BITS_PER_PIN; + + return 0; +} + +#define RV1106_SMT_BITS_PER_PIN 1 +#define RV1106_SMT_PINS_PER_REG 8 +#define RV1106_SMT_GPIO0_OFFSET 0x40 +#define RV1106_SMT_GPIO1_OFFSET 0x280 +#define RV1106_SMT_GPIO2_OFFSET 0x10290 +#define RV1106_SMT_GPIO3_OFFSET 0x202A0 +#define RV1106_SMT_GPIO4_OFFSET 0x300A0 + +static int rv1106_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + /* GPIO0_IOC is located in PMU */ + switch (bank->bank_num) { + case 0: + *regmap = info->regmap_pmu; + *reg = RV1106_SMT_GPIO0_OFFSET; + break; + + case 1: + *regmap = info->regmap_base; + *reg = RV1106_SMT_GPIO1_OFFSET; + break; + + case 2: + *regmap = info->regmap_base; + *reg = RV1106_SMT_GPIO2_OFFSET; + break; + + case 3: + *regmap = info->regmap_base; + *reg = RV1106_SMT_GPIO3_OFFSET; + break; + + case 4: + *regmap = info->regmap_base; + *reg = RV1106_SMT_GPIO4_OFFSET; + break; + + default: + dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); + break; + } + + *reg += ((pin_num / RV1106_SMT_PINS_PER_REG) * 4); + *bit = pin_num % RV1106_SMT_PINS_PER_REG; + *bit *= RV1106_SMT_BITS_PER_PIN; + + return 0; +} + #define RV1108_PULL_PMU_OFFSET 0x10 #define RV1108_PULL_OFFSET 0x110 #define RV1108_PULL_PINS_PER_REG 8 #define RV1108_PULL_BITS_PER_PIN 2 #define RV1108_PULL_BANK_STRIDE 16 -static void rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rv1108_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1414,6 +1628,8 @@ *reg += ((pin_num / RV1108_PULL_PINS_PER_REG) * 4); *bit = (pin_num % RV1108_PULL_PINS_PER_REG); *bit *= RV1108_PULL_BITS_PER_PIN; + + return 0; } #define RV1108_DRV_PMU_OFFSET 0x20 @@ -1422,9 +1638,9 @@ #define RV1108_DRV_PINS_PER_REG 8 #define RV1108_DRV_BANK_STRIDE 16 -static void rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rv1108_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1444,6 +1660,8 @@ *reg += ((pin_num / RV1108_DRV_PINS_PER_REG) * 4); *bit = pin_num % RV1108_DRV_PINS_PER_REG; *bit *= RV1108_DRV_BITS_PER_PIN; + + return 0; } #define RV1108_SCHMITT_PMU_OFFSET 0x30 @@ -1483,9 +1701,9 @@ #define RV1126_PULL_BANK_STRIDE 16 #define RV1126_GPIO_C4_D7(p) (p >= 20 && p <= 31) /* GPIO0_C4 ~ GPIO0_D7 */ -static void rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1497,7 +1715,7 @@ *reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4); *bit = pin_num % RV1126_PULL_PINS_PER_REG; *bit *= RV1126_PULL_BITS_PER_PIN; - return; + return 0; } *regmap = info->regmap_pmu; *reg = RV1126_PULL_PMU_OFFSET; @@ -1510,6 +1728,8 @@ *reg += ((pin_num / RV1126_PULL_PINS_PER_REG) * 4); *bit = (pin_num % RV1126_PULL_PINS_PER_REG); *bit *= RV1126_PULL_BITS_PER_PIN; + + return 0; } #define RV1126_DRV_PMU_OFFSET 0x20 @@ -1518,9 +1738,9 @@ #define RV1126_DRV_PINS_PER_REG 4 #define RV1126_DRV_BANK_STRIDE 32 -static void rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1533,7 +1753,7 @@ *reg -= 0x4; *bit = pin_num % RV1126_DRV_PINS_PER_REG; *bit *= RV1126_DRV_BITS_PER_PIN; - return; + return 0; } *regmap = info->regmap_pmu; *reg = RV1126_DRV_PMU_OFFSET; @@ -1546,6 +1766,8 @@ *reg += ((pin_num / RV1126_DRV_PINS_PER_REG) * 4); *bit = pin_num % RV1126_DRV_PINS_PER_REG; *bit *= RV1126_DRV_BITS_PER_PIN; + + return 0; } #define RV1126_SCHMITT_PMU_OFFSET 0x60 @@ -1585,15 +1807,35 @@ return 0; } +#define RK3308_SCHMITT_PINS_PER_REG 8 +#define RK3308_SCHMITT_BANK_STRIDE 16 +#define RK3308_SCHMITT_GRF_OFFSET 0x1a0 + +static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + *regmap = info->regmap_base; + *reg = RK3308_SCHMITT_GRF_OFFSET; + + *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; + *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); + *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; + + return 0; +} + #define RK1808_PULL_PMU_OFFSET 0x10 #define RK1808_PULL_GRF_OFFSET 0x80 #define RK1808_PULL_PINS_PER_REG 8 #define RK1808_PULL_BITS_PER_PIN 2 #define RK1808_PULL_BANK_STRIDE 16 -static void rk1808_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk1808_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1609,6 +1851,8 @@ *reg += ((pin_num / RK1808_PULL_PINS_PER_REG) * 4); *bit = (pin_num % RK1808_PULL_PINS_PER_REG); *bit *= RK1808_PULL_BITS_PER_PIN; + + return 0; } #define RK1808_DRV_PMU_OFFSET 0x20 @@ -1617,10 +1861,10 @@ #define RK1808_DRV_PINS_PER_REG 8 #define RK1808_DRV_BANK_STRIDE 16 -static void rk1808_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, - struct regmap **regmap, - int *reg, u8 *bit) +static int rk1808_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1636,6 +1880,8 @@ *reg += ((pin_num / RK1808_DRV_PINS_PER_REG) * 4); *bit = pin_num % RK1808_DRV_PINS_PER_REG; *bit *= RK1808_DRV_BITS_PER_PIN; + + return 0; } #define RK1808_SR_PMU_OFFSET 0x0030 @@ -1694,9 +1940,9 @@ #define RK2928_PULL_PINS_PER_REG 16 #define RK2928_PULL_BANK_STRIDE 8 -static void rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk2928_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1706,13 +1952,15 @@ *reg += (pin_num / RK2928_PULL_PINS_PER_REG) * 4; *bit = pin_num % RK2928_PULL_PINS_PER_REG; + + return 0; }; #define RK3128_PULL_OFFSET 0x118 -static void rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3128_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1722,6 +1970,8 @@ *reg += ((pin_num / RK2928_PULL_PINS_PER_REG) * 4); *bit = pin_num % RK2928_PULL_PINS_PER_REG; + + return 0; } #define RK3188_PULL_OFFSET 0x164 @@ -1730,9 +1980,9 @@ #define RK3188_PULL_BANK_STRIDE 16 #define RK3188_PULL_PMU_OFFSET 0x64 -static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1762,12 +2012,14 @@ *bit = 7 - (pin_num % RK3188_PULL_PINS_PER_REG); *bit *= RK3188_PULL_BITS_PER_PIN; } + + return 0; } #define RK3288_PULL_OFFSET 0x140 -static void rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3288_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1791,6 +2043,8 @@ *bit = (pin_num % RK3188_PULL_PINS_PER_REG); *bit *= RK3188_PULL_BITS_PER_PIN; } + + return 0; } #define RK3288_DRV_PMU_OFFSET 0x70 @@ -1799,9 +2053,9 @@ #define RK3288_DRV_PINS_PER_REG 8 #define RK3288_DRV_BANK_STRIDE 16 -static void rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3288_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1825,13 +2079,15 @@ *bit = (pin_num % RK3288_DRV_PINS_PER_REG); *bit *= RK3288_DRV_BITS_PER_PIN; } + + return 0; } #define RK3228_PULL_OFFSET 0x100 -static void rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3228_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1842,13 +2098,15 @@ *bit = (pin_num % RK3188_PULL_PINS_PER_REG); *bit *= RK3188_PULL_BITS_PER_PIN; + + return 0; } #define RK3228_DRV_GRF_OFFSET 0x200 -static void rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3228_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1859,13 +2117,15 @@ *bit = (pin_num % RK3288_DRV_PINS_PER_REG); *bit *= RK3288_DRV_BITS_PER_PIN; + + return 0; } #define RK3308_PULL_OFFSET 0xa0 -static void rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3308_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1876,13 +2136,15 @@ *bit = (pin_num % RK3188_PULL_PINS_PER_REG); *bit *= RK3188_PULL_BITS_PER_PIN; + + return 0; } #define RK3308_DRV_GRF_OFFSET 0x100 -static void rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3308_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1893,14 +2155,39 @@ *bit = (pin_num % RK3288_DRV_PINS_PER_REG); *bit *= RK3288_DRV_BITS_PER_PIN; + + return 0; +} + +#define RK3308_SLEW_RATE_GRF_OFFSET 0x150 +#define RK3308_SLEW_RATE_BANK_STRIDE 16 +#define RK3308_SLEW_RATE_PINS_PER_GRF_REG 8 + +static int rk3308_calc_slew_rate_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + int pins_per_reg; + + *regmap = info->regmap_base; + *reg = RK3308_SLEW_RATE_GRF_OFFSET; + *reg += (bank->bank_num) * RK3308_SLEW_RATE_BANK_STRIDE; + pins_per_reg = RK3308_SLEW_RATE_PINS_PER_GRF_REG; + + *reg += ((pin_num / pins_per_reg) * 4); + *bit = pin_num % pins_per_reg; + + return 0; } #define RK3368_PULL_GRF_OFFSET 0x100 #define RK3368_PULL_PMU_OFFSET 0x10 -static void rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3368_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1924,14 +2211,16 @@ *bit = (pin_num % RK3188_PULL_PINS_PER_REG); *bit *= RK3188_PULL_BITS_PER_PIN; } + + return 0; } #define RK3368_DRV_PMU_OFFSET 0x20 #define RK3368_DRV_GRF_OFFSET 0x200 -static void rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3368_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1955,15 +2244,17 @@ *bit = (pin_num % RK3288_DRV_PINS_PER_REG); *bit *= RK3288_DRV_BITS_PER_PIN; } + + return 0; } #define RK3399_PULL_GRF_OFFSET 0xe040 #define RK3399_PULL_PMU_OFFSET 0x40 #define RK3399_DRV_3BITS_PER_PIN 3 -static void rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3399_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -1989,11 +2280,13 @@ *bit = (pin_num % RK3188_PULL_PINS_PER_REG); *bit *= RK3188_PULL_BITS_PER_PIN; } + + return 0; } -static void rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3399_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; int drv_num = (pin_num / 8); @@ -2010,6 +2303,8 @@ *bit = (pin_num % 8) * 3; else *bit = (pin_num % 8) * 2; + + return 0; } #define RK3528_DRV_BITS_PER_PIN 8 @@ -2020,9 +2315,9 @@ #define RK3528_DRV_GPIO3_OFFSET 0x20190 #define RK3528_DRV_GPIO4_OFFSET 0x101C0 -static void rk3528_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3528_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -2056,6 +2351,8 @@ *reg += ((pin_num / RK3528_DRV_PINS_PER_REG) * 4); *bit = pin_num % RK3528_DRV_PINS_PER_REG; *bit *= RK3528_DRV_BITS_PER_PIN; + + return 0; } #define RK3528_PULL_BITS_PER_PIN 2 @@ -2066,9 +2363,9 @@ #define RK3528_PULL_GPIO3_OFFSET 0x20230 #define RK3528_PULL_GPIO4_OFFSET 0x10240 -static void rk3528_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3528_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -2102,6 +2399,8 @@ *reg += ((pin_num / RK3528_PULL_PINS_PER_REG) * 4); *bit = pin_num % RK3528_PULL_PINS_PER_REG; *bit *= RK3528_PULL_BITS_PER_PIN; + + return 0; } #define RK3528_SMT_BITS_PER_PIN 1 @@ -2152,6 +2451,151 @@ return 0; } +#define RK3562_DRV_BITS_PER_PIN 8 +#define RK3562_DRV_PINS_PER_REG 2 +#define RK3562_DRV_GPIO0_OFFSET 0x20070 +#define RK3562_DRV_GPIO1_OFFSET 0x200 +#define RK3562_DRV_GPIO2_OFFSET 0x240 +#define RK3562_DRV_GPIO3_OFFSET 0x10280 +#define RK3562_DRV_GPIO4_OFFSET 0x102C0 + +static int rk3562_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + *regmap = info->regmap_base; + switch (bank->bank_num) { + case 0: + *reg = RK3562_DRV_GPIO0_OFFSET; + break; + + case 1: + *reg = RK3562_DRV_GPIO1_OFFSET; + break; + + case 2: + *reg = RK3562_DRV_GPIO2_OFFSET; + break; + + case 3: + *reg = RK3562_DRV_GPIO3_OFFSET; + break; + + case 4: + *reg = RK3562_DRV_GPIO4_OFFSET; + break; + + default: + dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); + break; + } + + *reg += ((pin_num / RK3562_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RK3562_DRV_PINS_PER_REG; + *bit *= RK3562_DRV_BITS_PER_PIN; + + return 0; +} + +#define RK3562_PULL_BITS_PER_PIN 2 +#define RK3562_PULL_PINS_PER_REG 8 +#define RK3562_PULL_GPIO0_OFFSET 0x20020 +#define RK3562_PULL_GPIO1_OFFSET 0x80 +#define RK3562_PULL_GPIO2_OFFSET 0x90 +#define RK3562_PULL_GPIO3_OFFSET 0x100A0 +#define RK3562_PULL_GPIO4_OFFSET 0x100B0 + +static int rk3562_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + *regmap = info->regmap_base; + switch (bank->bank_num) { + case 0: + *reg = RK3562_PULL_GPIO0_OFFSET; + break; + + case 1: + *reg = RK3562_PULL_GPIO1_OFFSET; + break; + + case 2: + *reg = RK3562_PULL_GPIO2_OFFSET; + break; + + case 3: + *reg = RK3562_PULL_GPIO3_OFFSET; + break; + + case 4: + *reg = RK3562_PULL_GPIO4_OFFSET; + break; + + default: + dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); + break; + } + + *reg += ((pin_num / RK3562_PULL_PINS_PER_REG) * 4); + *bit = pin_num % RK3562_PULL_PINS_PER_REG; + *bit *= RK3562_PULL_BITS_PER_PIN; + + return 0; +} + +#define RK3562_SMT_BITS_PER_PIN 2 +#define RK3562_SMT_PINS_PER_REG 8 +#define RK3562_SMT_GPIO0_OFFSET 0x20030 +#define RK3562_SMT_GPIO1_OFFSET 0xC0 +#define RK3562_SMT_GPIO2_OFFSET 0xD0 +#define RK3562_SMT_GPIO3_OFFSET 0x100E0 +#define RK3562_SMT_GPIO4_OFFSET 0x100F0 + +static int rk3562_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + + *regmap = info->regmap_base; + switch (bank->bank_num) { + case 0: + *reg = RK3562_SMT_GPIO0_OFFSET; + break; + + case 1: + *reg = RK3562_SMT_GPIO1_OFFSET; + break; + + case 2: + *reg = RK3562_SMT_GPIO2_OFFSET; + break; + + case 3: + *reg = RK3562_SMT_GPIO3_OFFSET; + break; + + case 4: + *reg = RK3562_SMT_GPIO4_OFFSET; + break; + + default: + dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); + break; + } + + *reg += ((pin_num / RK3562_SMT_PINS_PER_REG) * 4); + *bit = pin_num % RK3562_SMT_PINS_PER_REG; + *bit *= RK3562_SMT_BITS_PER_PIN; + + return 0; +} + #define RK3568_SR_PMU_OFFSET 0x60 #define RK3568_SR_GRF_OFFSET 0x0180 #define RK3568_SR_BANK_STRIDE 0x10 @@ -2186,9 +2630,9 @@ #define RK3568_PULL_PINS_PER_REG 8 #define RK3568_PULL_BANK_STRIDE 0x10 -static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -2209,6 +2653,8 @@ *bit = (pin_num % RK3568_PULL_PINS_PER_REG); *bit *= RK3568_PULL_BITS_PER_PIN; } + + return 0; } #define RK3568_DRV_PMU_OFFSET 0x70 @@ -2217,9 +2663,9 @@ #define RK3568_DRV_PINS_PER_REG 2 #define RK3568_DRV_BANK_STRIDE 0x40 -static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, struct regmap **regmap, - int *reg, u8 *bit) +static int rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) { struct rockchip_pinctrl *info = bank->drvdata; @@ -2246,6 +2692,197 @@ ((bank->bank_num == 2 || bank->bank_num == 3 || bank->bank_num == 4) && (pin_num == 7 || pin_num == 15 || pin_num == 23 || pin_num == 31))) *bit -= RK3568_DRV_BITS_PER_PIN; + + return 0; +} + +#define RK3588_PMU1_IOC_REG (0x0000) +#define RK3588_PMU2_IOC_REG (0x4000) +#define RK3588_BUS_IOC_REG (0x8000) +#define RK3588_VCCIO1_4_IOC_REG (0x9000) +#define RK3588_VCCIO3_5_IOC_REG (0xA000) +#define RK3588_VCCIO2_IOC_REG (0xB000) +#define RK3588_VCCIO6_IOC_REG (0xC000) +#define RK3588_EMMC_IOC_REG (0xD000) + +static const u32 rk3588_ds_regs[][2] = { + {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0010}, + {RK_GPIO0_A4, RK3588_PMU1_IOC_REG + 0x0014}, + {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0018}, + {RK_GPIO0_B4, RK3588_PMU2_IOC_REG + 0x0014}, + {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0018}, + {RK_GPIO0_C4, RK3588_PMU2_IOC_REG + 0x001C}, + {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0020}, + {RK_GPIO0_D4, RK3588_PMU2_IOC_REG + 0x0024}, + {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0020}, + {RK_GPIO1_A4, RK3588_VCCIO1_4_IOC_REG + 0x0024}, + {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0028}, + {RK_GPIO1_B4, RK3588_VCCIO1_4_IOC_REG + 0x002C}, + {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0030}, + {RK_GPIO1_C4, RK3588_VCCIO1_4_IOC_REG + 0x0034}, + {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x0038}, + {RK_GPIO1_D4, RK3588_VCCIO1_4_IOC_REG + 0x003C}, + {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0040}, + {RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0044}, + {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0048}, + {RK_GPIO2_B4, RK3588_VCCIO3_5_IOC_REG + 0x004C}, + {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0050}, + {RK_GPIO2_C4, RK3588_VCCIO3_5_IOC_REG + 0x0054}, + {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x0058}, + {RK_GPIO2_D4, RK3588_EMMC_IOC_REG + 0x005C}, + {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0060}, + {RK_GPIO3_A4, RK3588_VCCIO3_5_IOC_REG + 0x0064}, + {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0068}, + {RK_GPIO3_B4, RK3588_VCCIO3_5_IOC_REG + 0x006C}, + {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0070}, + {RK_GPIO3_C4, RK3588_VCCIO3_5_IOC_REG + 0x0074}, + {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x0078}, + {RK_GPIO3_D4, RK3588_VCCIO3_5_IOC_REG + 0x007C}, + {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0080}, + {RK_GPIO4_A4, RK3588_VCCIO6_IOC_REG + 0x0084}, + {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0088}, + {RK_GPIO4_B4, RK3588_VCCIO6_IOC_REG + 0x008C}, + {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0090}, + {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0090}, + {RK_GPIO4_C4, RK3588_VCCIO3_5_IOC_REG + 0x0094}, + {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x0098}, +}; + +static const u32 rk3588_p_regs[][2] = { + {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0020}, + {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0024}, + {RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0028}, + {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x002C}, + {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0030}, + {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0110}, + {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0114}, + {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0118}, + {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x011C}, + {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0120}, + {RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0120}, + {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0124}, + {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0128}, + {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x012C}, + {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0130}, + {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0134}, + {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0138}, + {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x013C}, + {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0140}, + {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0144}, + {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0148}, + {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0148}, + {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x014C}, +}; + +static const u32 rk3588_smt_regs[][2] = { + {RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0030}, + {RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0034}, + {RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0040}, + {RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0044}, + {RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0048}, + {RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0210}, + {RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0214}, + {RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0218}, + {RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x021C}, + {RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0220}, + {RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0220}, + {RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0224}, + {RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0228}, + {RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x022C}, + {RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0230}, + {RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0234}, + {RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0238}, + {RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x023C}, + {RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0240}, + {RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0244}, + {RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0248}, + {RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0248}, + {RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x024C}, +}; + +#define RK3588_PULL_BITS_PER_PIN 2 +#define RK3588_PULL_PINS_PER_REG 8 + +static int rk3588_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + u8 bank_num = bank->bank_num; + u32 pin = bank_num * 32 + pin_num; + int i; + + for (i = ARRAY_SIZE(rk3588_p_regs) - 1; i >= 0; i--) { + if (pin >= rk3588_p_regs[i][0]) { + *reg = rk3588_p_regs[i][1]; + break; + } + BUG_ON(i == 0); + } + + *regmap = info->regmap_base; + *reg += ((pin - rk3588_p_regs[i][0]) / RK3588_PULL_PINS_PER_REG) * 4; + *bit = pin_num % RK3588_PULL_PINS_PER_REG; + *bit *= RK3588_PULL_BITS_PER_PIN; + + return 0; +} + +#define RK3588_DRV_BITS_PER_PIN 4 +#define RK3588_DRV_PINS_PER_REG 4 + +static int rk3588_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + u8 bank_num = bank->bank_num; + u32 pin = bank_num * 32 + pin_num; + int i; + + for (i = ARRAY_SIZE(rk3588_ds_regs) - 1; i >= 0; i--) { + if (pin >= rk3588_ds_regs[i][0]) { + *reg = rk3588_ds_regs[i][1]; + break; + } + BUG_ON(i == 0); + } + + *regmap = info->regmap_base; + *reg += ((pin - rk3588_ds_regs[i][0]) / RK3588_DRV_PINS_PER_REG) * 4; + *bit = pin_num % RK3588_DRV_PINS_PER_REG; + *bit *= RK3588_DRV_BITS_PER_PIN; + + return 0; +} + +#define RK3588_SMT_BITS_PER_PIN 1 +#define RK3588_SMT_PINS_PER_REG 8 + +static int rk3588_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, + int pin_num, + struct regmap **regmap, + int *reg, u8 *bit) +{ + struct rockchip_pinctrl *info = bank->drvdata; + u8 bank_num = bank->bank_num; + u32 pin = bank_num * 32 + pin_num; + int i; + + for (i = ARRAY_SIZE(rk3588_smt_regs) - 1; i >= 0; i--) { + if (pin >= rk3588_smt_regs[i][0]) { + *reg = rk3588_smt_regs[i][1]; + break; + } + BUG_ON(i == 0); + } + + *regmap = info->regmap_base; + *reg += ((pin - rk3588_smt_regs[i][0]) / RK3588_SMT_PINS_PER_REG) * 4; + *bit = pin_num % RK3588_SMT_PINS_PER_REG; + *bit *= RK3588_SMT_BITS_PER_PIN; + + return 0; } static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = { @@ -2262,13 +2899,16 @@ { struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; + struct device *dev = info->dev; struct regmap *regmap; int reg, ret; u32 data, temp, rmask_bits; u8 bit; int drv_type = bank->drv[pin_num / 8].drv_type; - ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); + ret = ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); + if (ret) + return ret; switch (drv_type) { case DRV_TYPE_IO_1V8_3V0_AUTO: @@ -2307,7 +2947,7 @@ bit -= 16; break; default: - dev_err(info->dev, "unsupported bit: %d for pinctrl drive type: %d\n", + dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", bit, drv_type); return -EINVAL; } @@ -2320,8 +2960,7 @@ rmask_bits = RK3288_DRV_BITS_PER_PIN; break; default: - dev_err(info->dev, "unsupported pinctrl drive type: %d\n", - drv_type); + dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); return -EINVAL; } @@ -2354,21 +2993,28 @@ { struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; + struct device *dev = info->dev; struct regmap *regmap; int reg, ret, i, err; u32 data, rmask, rmask_bits, temp; u8 bit; int drv_type = bank->drv[pin_num / 8].drv_type; - dev_dbg(info->dev, "setting drive of GPIO%d-%d to %d\n", + dev_dbg(dev, "setting drive of GPIO%d-%d to %d\n", bank->bank_num, pin_num, strength); - ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); - if (ctrl->type == RV1126) { + ret = ctrl->drv_calc_reg(bank, pin_num, ®map, ®, &bit); + if (ret) + return ret; + + if (ctrl->type == RV1126 || ctrl->type == RK3588) { rmask_bits = RV1126_DRV_BITS_PER_PIN; ret = strength; goto config; - } else if (ctrl->type == RK3568 || ctrl->type == RK3528) { + } else if (ctrl->type == RV1106 || + ctrl->type == RK3528 || + ctrl->type == RK3562 || + ctrl->type == RK3568) { rmask_bits = RK3568_DRV_BITS_PER_PIN; ret = (1 << (strength + 1)) - 1; goto config; @@ -2386,8 +3032,7 @@ } if (ret < 0) { - dev_err(info->dev, "unsupported driver strength %d\n", - strength); + dev_err(dev, "unsupported driver strength %d\n", strength); return ret; } @@ -2426,7 +3071,7 @@ bit -= 16; break; default: - dev_err(info->dev, "unsupported bit: %d for pinctrl drive type: %d\n", + dev_err(dev, "unsupported bit: %d for pinctrl drive type: %d\n", bit, drv_type); return -EINVAL; } @@ -2438,8 +3083,7 @@ rmask_bits = RK3288_DRV_BITS_PER_PIN; break; default: - dev_err(info->dev, "unsupported pinctrl drive type: %d\n", - drv_type); + dev_err(dev, "unsupported pinctrl drive type: %d\n", drv_type); return -EINVAL; } @@ -2508,6 +3152,7 @@ { struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; + struct device *dev = info->dev; struct regmap *regmap; int reg, ret, pull_type; u8 bit; @@ -2517,7 +3162,9 @@ if (ctrl->type == RK3066B) return PIN_CONFIG_BIAS_DISABLE; - ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); + ret = ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); + if (ret) + return ret; ret = regmap_read(regmap, reg, &data); if (ret) @@ -2530,6 +3177,7 @@ ? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT : PIN_CONFIG_BIAS_DISABLE; case PX30: + case RV1106: case RV1108: case RV1126: case RK1808: @@ -2539,14 +3187,24 @@ case RK3368: case RK3399: case RK3528: + case RK3562: case RK3568: + case RK3588: pull_type = bank->pull_type[pin_num / 8]; data >>= bit; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; + /* + * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6, + * where that pull up value becomes 3. + */ + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { + if (data == 3) + data = 1; + } return rockchip_pull_list[pull_type][data]; default: - dev_err(info->dev, "unsupported pinctrl type\n"); + dev_err(dev, "unsupported pinctrl type\n"); return -EINVAL; }; } @@ -2556,19 +3214,21 @@ { struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; + struct device *dev = info->dev; struct regmap *regmap; int reg, ret, i, pull_type; u8 bit; u32 data, rmask; - dev_dbg(info->dev, "setting pull of GPIO%d-%d to %d\n", - bank->bank_num, pin_num, pull); + dev_dbg(dev, "setting pull of GPIO%d-%d to %d\n", bank->bank_num, pin_num, pull); /* rk3066b does support any pulls */ if (ctrl->type == RK3066B) return pull ? -EINVAL : 0; - ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); + ret = ctrl->pull_calc_reg(bank, pin_num, ®map, ®, &bit); + if (ret) + return ret; switch (ctrl->type) { case RK2928: @@ -2579,6 +3239,7 @@ ret = regmap_write(regmap, reg, data); break; case PX30: + case RV1106: case RV1108: case RV1126: case RK1808: @@ -2588,7 +3249,9 @@ case RK3368: case RK3399: case RK3528: + case RK3562: case RK3568: + case RK3588: pull_type = bank->pull_type[pin_num / 8]; ret = -EINVAL; for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[pull_type]); @@ -2599,7 +3262,7 @@ } } /* - * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, + * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6, * where that pull up value becomes 3. */ if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { @@ -2608,8 +3271,7 @@ } if (ret < 0) { - dev_err(info->dev, "unsupported pull setting %d\n", - pull); + dev_err(dev, "unsupported pull setting %d\n", pull); return ret; } @@ -2621,32 +3283,11 @@ ret = regmap_update_bits(regmap, reg, rmask, data); break; default: - dev_err(info->dev, "unsupported pinctrl type\n"); + dev_err(dev, "unsupported pinctrl type\n"); return -EINVAL; } return ret; -} - -#define RK3308_SCHMITT_PINS_PER_REG 8 -#define RK3308_SCHMITT_BANK_STRIDE 16 -#define RK3308_SCHMITT_GRF_OFFSET 0x1a0 - -static int rk3308_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, - int pin_num, - struct regmap **regmap, - int *reg, u8 *bit) -{ - struct rockchip_pinctrl *info = bank->drvdata; - - *regmap = info->regmap_base; - *reg = RK3308_SCHMITT_GRF_OFFSET; - - *reg += bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; - *reg += ((pin_num / RK3308_SCHMITT_PINS_PER_REG) * 4); - *bit = pin_num % RK3308_SCHMITT_PINS_PER_REG; - - return 0; } #define RK3328_SCHMITT_BITS_PER_PIN 1 @@ -2719,6 +3360,7 @@ data >>= bit; switch (ctrl->type) { + case RK3562: case RK3568: return data & ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1); default: @@ -2733,12 +3375,13 @@ { struct rockchip_pinctrl *info = bank->drvdata; struct rockchip_pin_ctrl *ctrl = info->ctrl; + struct device *dev = info->dev; struct regmap *regmap; int reg, ret; u8 bit; u32 data, rmask; - dev_dbg(info->dev, "setting input schmitt of GPIO%d-%d to %d\n", + dev_dbg(dev, "setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num, pin_num, enable); ret = ctrl->schmitt_calc_reg(bank, pin_num, ®map, ®, &bit); @@ -2747,6 +3390,7 @@ /* enable the write to the equivalent lower bits */ switch (ctrl->type) { + case RK3562: case RK3568: data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); rmask = data | (data >> 16); @@ -2881,10 +3525,11 @@ struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); const unsigned int *pins = info->groups[group].pins; const struct rockchip_pin_config *data = info->groups[group].data; + struct device *dev = info->dev; struct rockchip_pin_bank *bank; int cnt, ret = 0; - dev_dbg(info->dev, "enable function %s group %s\n", + dev_dbg(dev, "enable function %s group %s\n", info->functions[selector].name, info->groups[group].name); /* @@ -2932,6 +3577,7 @@ case RK3066B: return pull ? false : true; case PX30: + case RV1106: case RV1108: case RV1126: case RK1808: @@ -2941,11 +3587,31 @@ case RK3368: case RK3399: case RK3528: + case RK3562: case RK3568: + case RK3588: return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); } return false; +} + +static int rockchip_pinconf_defer_pin(struct rockchip_pin_bank *bank, + unsigned int pin, u32 param, u32 arg) +{ + struct rockchip_pin_deferred *cfg; + + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + + cfg->pin = pin; + cfg->param = param; + cfg->arg = arg; + + list_add_tail(&cfg->head, &bank->deferred_pins); + + return 0; } /* set the pin config settings for a specified pin */ @@ -2963,6 +3629,25 @@ for (i = 0; i < num_configs; i++) { param = pinconf_to_config_param(configs[i]); arg = pinconf_to_config_argument(configs[i]); + + if (param == PIN_CONFIG_OUTPUT || param == PIN_CONFIG_INPUT_ENABLE) { + /* + * Check for gpio driver not being probed yet. + * The lock makes sure that either gpio-probe has completed + * or the gpio driver hasn't probed yet. + */ + mutex_lock(&bank->deferred_lock); + if (!gpio || !gpio->direction_output) { + rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param, + arg); + mutex_unlock(&bank->deferred_lock); + if (rc) + return rc; + + break; + } + mutex_unlock(&bank->deferred_lock); + } switch (param) { case PIN_CONFIG_BIAS_DISABLE: @@ -2989,10 +3674,8 @@ case PIN_CONFIG_OUTPUT: rc = rockchip_set_mux(bank, pin - bank->pin_base, RK_FUNC_GPIO); - if (rc != RK_FUNC_GPIO) { - dev_err(info->dev, "pin-%d fail to mux to gpio, %d\n", pin, rc); + if (rc != RK_FUNC_GPIO) return -EINVAL; - } rc = gpio->direction_output(gpio, pin - bank->pin_base, arg); @@ -3077,13 +3760,13 @@ break; case PIN_CONFIG_OUTPUT: rc = rockchip_get_mux(bank, pin - bank->pin_base); - if (rc != 0) + if (rc != RK_FUNC_GPIO) return -EINVAL; - /* 0 for output, 1 for input */ - rc = gpio->get_direction(gpio, pin - bank->pin_base); - if (rc) - return -EINVAL; + if (!gpio || !gpio->get) { + arg = 0; + break; + } rc = gpio->get(gpio, pin - bank->pin_base); if (rc < 0) @@ -3143,24 +3826,13 @@ {}, }; -static bool is_function_node(const struct device_node *np) -{ - if (of_match_node(rockchip_bank_match, np)) - return false; - - if (!strncmp(np->name, "pcfg", 4)) - return false; - - return true; -} - static void rockchip_pinctrl_child_count(struct rockchip_pinctrl *info, struct device_node *np) { struct device_node *child; for_each_child_of_node(np, child) { - if (!is_function_node(child)) + if (of_match_node(rockchip_bank_match, child)) continue; info->nfunctions++; @@ -3173,6 +3845,7 @@ struct rockchip_pinctrl *info, u32 index) { + struct device *dev = info->dev; struct rockchip_pin_bank *bank; int size; const __be32 *list; @@ -3180,7 +3853,7 @@ int i, j; int ret; - dev_dbg(info->dev, "group(%d): %pOFn\n", index, np); + dev_dbg(dev, "group(%d): %pOFn\n", index, np); /* Initialise group */ grp->name = np->name; @@ -3192,19 +3865,13 @@ list = of_get_property(np, "rockchip,pins", &size); /* we do not check return since it's safe node passed down */ size /= sizeof(*list); - if (!size || size % 4) { - dev_err(info->dev, "wrong pins number or pins and configs should be by 4\n"); - return -EINVAL; - } + if (!size || size % 4) + return dev_err_probe(dev, -EINVAL, "wrong pins number or pins and configs should be by 4\n"); grp->npins = size / 4; - grp->pins = devm_kcalloc(info->dev, grp->npins, sizeof(unsigned int), - GFP_KERNEL); - grp->data = devm_kcalloc(info->dev, - grp->npins, - sizeof(struct rockchip_pin_config), - GFP_KERNEL); + grp->pins = devm_kcalloc(dev, grp->npins, sizeof(*grp->pins), GFP_KERNEL); + grp->data = devm_kcalloc(dev, grp->npins, sizeof(*grp->data), GFP_KERNEL); if (!grp->pins || !grp->data) return -ENOMEM; @@ -3227,6 +3894,7 @@ np_config = of_find_node_by_phandle(be32_to_cpup(phandle)); ret = pinconf_generic_parse_dt_config(np_config, NULL, &grp->data[j].configs, &grp->data[j].nconfigs); + of_node_put(np_config); if (ret) return ret; } @@ -3238,6 +3906,7 @@ struct rockchip_pinctrl *info, u32 index) { + struct device *dev = info->dev; struct device_node *child; struct rockchip_pmx_func *func; struct rockchip_pin_group *grp; @@ -3245,7 +3914,7 @@ static u32 grp_index; u32 i = 0; - dev_dbg(info->dev, "parse function(%d): %pOFn\n", index, np); + dev_dbg(dev, "parse function(%d): %pOFn\n", index, np); func = &info->functions[index]; @@ -3255,8 +3924,7 @@ if (func->ngroups <= 0) return 0; - func->groups = devm_kcalloc(info->dev, - func->ngroups, sizeof(char *), GFP_KERNEL); + func->groups = devm_kcalloc(dev, func->ngroups, sizeof(*func->groups), GFP_KERNEL); if (!func->groups) return -ENOMEM; @@ -3284,32 +3952,26 @@ rockchip_pinctrl_child_count(info, np); - dev_dbg(&pdev->dev, "nfunctions = %d\n", info->nfunctions); - dev_dbg(&pdev->dev, "ngroups = %d\n", info->ngroups); + dev_dbg(dev, "nfunctions = %d\n", info->nfunctions); + dev_dbg(dev, "ngroups = %d\n", info->ngroups); - info->functions = devm_kcalloc(dev, - info->nfunctions, - sizeof(struct rockchip_pmx_func), - GFP_KERNEL); + info->functions = devm_kcalloc(dev, info->nfunctions, sizeof(*info->functions), GFP_KERNEL); if (!info->functions) return -ENOMEM; - info->groups = devm_kcalloc(dev, - info->ngroups, - sizeof(struct rockchip_pin_group), - GFP_KERNEL); + info->groups = devm_kcalloc(dev, info->ngroups, sizeof(*info->groups), GFP_KERNEL); if (!info->groups) return -ENOMEM; i = 0; for_each_child_of_node(np, child) { - if (!is_function_node(child)) + if (of_match_node(rockchip_bank_match, child)) continue; ret = rockchip_pinctrl_parse_functions(child, info, i++); if (ret) { - dev_err(&pdev->dev, "failed to parse function\n"); + dev_err(dev, "failed to parse function\n"); of_node_put(child); return ret; } @@ -3324,6 +3986,7 @@ struct pinctrl_desc *ctrldesc = &info->pctl; struct pinctrl_pin_desc *pindesc, *pdesc; struct rockchip_pin_bank *pin_bank; + struct device *dev = &pdev->dev; int pin, bank, ret; int k; @@ -3333,9 +3996,7 @@ ctrldesc->pmxops = &rockchip_pmx_ops; ctrldesc->confops = &rockchip_pinconf_ops; - pindesc = devm_kcalloc(&pdev->dev, - info->ctrl->nr_pins, sizeof(*pindesc), - GFP_KERNEL); + pindesc = devm_kcalloc(dev, info->ctrl->nr_pins, sizeof(*pindesc), GFP_KERNEL); if (!pindesc) return -ENOMEM; @@ -3351,41 +4012,24 @@ pin_bank->name, pin); pdesc++; } + + INIT_LIST_HEAD(&pin_bank->deferred_pins); + mutex_init(&pin_bank->deferred_lock); } ret = rockchip_pinctrl_parse_dt(pdev, info); if (ret) return ret; - info->pctl_dev = devm_pinctrl_register(&pdev->dev, ctrldesc, info); - if (IS_ERR(info->pctl_dev)) { - dev_err(&pdev->dev, "could not register pinctrl driver\n"); - return PTR_ERR(info->pctl_dev); - } + info->pctl_dev = devm_pinctrl_register(dev, ctrldesc, info); + if (IS_ERR(info->pctl_dev)) + return dev_err_probe(dev, PTR_ERR(info->pctl_dev), "could not register pinctrl driver\n"); return 0; } static const struct of_device_id rockchip_pinctrl_dt_match[]; - -/* Ctrl data specially handle */ -static int rk3308b_ctrl_data_re_init(struct rockchip_pin_ctrl *ctrl) -{ - /* - * Special for rk3308b, where we need to replace the recalced - * and routed arrays. - */ - if (soc_is_rk3308b()) { - ctrl->iomux_recalced = rk3308b_mux_recalced_data; - ctrl->niomux_recalced = ARRAY_SIZE(rk3308b_mux_recalced_data); - ctrl->iomux_routes = rk3308b_mux_route_data; - ctrl->niomux_routes = ARRAY_SIZE(rk3308b_mux_route_data); - - } - - return 0; -} - +static struct rockchip_pin_bank rk3308bs_pin_banks[]; static struct rockchip_pin_bank px30s_pin_banks[]; /* retrieve the soc specific data */ @@ -3393,22 +4037,19 @@ struct rockchip_pinctrl *d, struct platform_device *pdev) { + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; const struct of_device_id *match; - struct device_node *node = pdev->dev.of_node; struct rockchip_pin_ctrl *ctrl; struct rockchip_pin_bank *bank; int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j; match = of_match_node(rockchip_pinctrl_dt_match, node); ctrl = (struct rockchip_pin_ctrl *)match->data; + if (IS_ENABLED(CONFIG_CPU_RK3308) && soc_is_rk3308bs()) + ctrl->pin_banks = rk3308bs_pin_banks; if (IS_ENABLED(CONFIG_CPU_PX30) && soc_is_px30s()) ctrl->pin_banks = px30s_pin_banks; - - /* Ctrl data re-initialize for some Socs */ - if (ctrl->ctrl_data_re_init) { - if (ctrl->ctrl_data_re_init(ctrl)) - return NULL; - } grf_offs = ctrl->grf_mux_offset; pmu_offs = ctrl->pmu_mux_offset; @@ -3455,7 +4096,7 @@ drv_pmu_offs : drv_grf_offs; } - dev_dbg(d->dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", + dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n", i, j, iom->offset, drv->offset); /* @@ -3562,60 +4203,56 @@ /* SoC data specially handle */ -/* rk3308b SoC data initialize */ -#define RK3308B_GRF_SOC_CON13 0x608 -#define RK3308B_GRF_SOC_CON15 0x610 +/* rk3308 SoC data initialize */ +#define RK3308_GRF_SOC_CON13 0x608 +#define RK3308_GRF_SOC_CON15 0x610 -/* RK3308B_GRF_SOC_CON13 */ -#define RK3308B_GRF_I2C3_IOFUNC_SRC_CTRL (BIT(16 + 10) | BIT(10)) -#define RK3308B_GRF_GPIO2A3_SEL_SRC_CTRL (BIT(16 + 7) | BIT(7)) -#define RK3308B_GRF_GPIO2A2_SEL_SRC_CTRL (BIT(16 + 3) | BIT(3)) +/* RK3308_GRF_SOC_CON13 */ +#define RK3308_GRF_I2C3_IOFUNC_SRC_CTRL (BIT(16 + 10) | BIT(10)) +#define RK3308_GRF_GPIO2A3_SEL_SRC_CTRL (BIT(16 + 7) | BIT(7)) +#define RK3308_GRF_GPIO2A2_SEL_SRC_CTRL (BIT(16 + 3) | BIT(3)) -/* RK3308B_GRF_SOC_CON15 */ -#define RK3308B_GRF_GPIO2C0_SEL_SRC_CTRL (BIT(16 + 11) | BIT(11)) -#define RK3308B_GRF_GPIO3B3_SEL_SRC_CTRL (BIT(16 + 7) | BIT(7)) -#define RK3308B_GRF_GPIO3B2_SEL_SRC_CTRL (BIT(16 + 3) | BIT(3)) +/* RK3308_GRF_SOC_CON15 */ +#define RK3308_GRF_GPIO2C0_SEL_SRC_CTRL (BIT(16 + 11) | BIT(11)) +#define RK3308_GRF_GPIO3B3_SEL_SRC_CTRL (BIT(16 + 7) | BIT(7)) +#define RK3308_GRF_GPIO3B2_SEL_SRC_CTRL (BIT(16 + 3) | BIT(3)) -static int rk3308b_soc_data_init(struct rockchip_pinctrl *info) +static int rk3308_soc_data_init(struct rockchip_pinctrl *info) { int ret; /* * Enable the special ctrl of selected sources. */ - if (soc_is_rk3308b()) { - ret = regmap_write(info->regmap_base, RK3308B_GRF_SOC_CON13, - RK3308B_GRF_I2C3_IOFUNC_SRC_CTRL | - RK3308B_GRF_GPIO2A3_SEL_SRC_CTRL | - RK3308B_GRF_GPIO2A2_SEL_SRC_CTRL); - if (ret) - return ret; - ret = regmap_write(info->regmap_base, RK3308B_GRF_SOC_CON15, - RK3308B_GRF_GPIO2C0_SEL_SRC_CTRL | - RK3308B_GRF_GPIO3B3_SEL_SRC_CTRL | - RK3308B_GRF_GPIO3B2_SEL_SRC_CTRL); - if (ret) - return ret; - } + ret = regmap_write(info->regmap_base, RK3308_GRF_SOC_CON13, + RK3308_GRF_I2C3_IOFUNC_SRC_CTRL | + RK3308_GRF_GPIO2A3_SEL_SRC_CTRL | + RK3308_GRF_GPIO2A2_SEL_SRC_CTRL); + if (ret) + return ret; - return 0; + ret = regmap_write(info->regmap_base, RK3308_GRF_SOC_CON15, + RK3308_GRF_GPIO2C0_SEL_SRC_CTRL | + RK3308_GRF_GPIO3B3_SEL_SRC_CTRL | + RK3308_GRF_GPIO3B2_SEL_SRC_CTRL); + + return ret; + } static int rockchip_pinctrl_probe(struct platform_device *pdev) { struct rockchip_pinctrl *info; struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node, *node; struct rockchip_pin_ctrl *ctrl; - struct device_node *np = pdev->dev.of_node, *node; struct resource *res; void __iomem *base; int ret; - if (!dev->of_node) { - dev_err(dev, "device tree node not found\n"); - return -ENODEV; - } + if (!dev->of_node) + return dev_err_probe(dev, -ENODEV, "device tree node not found\n"); info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); if (!info) @@ -3624,44 +4261,39 @@ info->dev = dev; ctrl = rockchip_pinctrl_get_soc_data(info, pdev); - if (!ctrl) { - dev_err(dev, "driver data not available\n"); - return -EINVAL; - } + if (!ctrl) + return dev_err_probe(dev, -EINVAL, "driver data not available\n"); info->ctrl = ctrl; node = of_parse_phandle(np, "rockchip,grf", 0); if (node) { info->regmap_base = syscon_node_to_regmap(node); + of_node_put(node); if (IS_ERR(info->regmap_base)) return PTR_ERR(info->regmap_base); } else { - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(base)) return PTR_ERR(base); rockchip_regmap_config.max_register = resource_size(res) - 4; rockchip_regmap_config.name = "rockchip,pinctrl"; - info->regmap_base = devm_regmap_init_mmio(&pdev->dev, base, - &rockchip_regmap_config); + info->regmap_base = + devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); /* to check for the old dt-bindings */ info->reg_size = resource_size(res); /* Honor the old binding, with pull registers as 2nd resource */ if (ctrl->type == RK3188 && info->reg_size < 0x200) { - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - base = devm_ioremap_resource(&pdev->dev, res); + base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); if (IS_ERR(base)) return PTR_ERR(base); - rockchip_regmap_config.max_register = - resource_size(res) - 4; + rockchip_regmap_config.max_register = resource_size(res) - 4; rockchip_regmap_config.name = "rockchip,pinctrl-pull"; - info->regmap_pull = devm_regmap_init_mmio(&pdev->dev, - base, - &rockchip_regmap_config); + info->regmap_pull = + devm_regmap_init_mmio(dev, base, &rockchip_regmap_config); } } @@ -3669,13 +4301,13 @@ node = of_parse_phandle(np, "rockchip,pmu", 0); if (node) { info->regmap_pmu = syscon_node_to_regmap(node); + of_node_put(node); if (IS_ERR(info->regmap_pmu)) return PTR_ERR(info->regmap_pmu); } - /* Special handle for some Socs */ - if (ctrl->soc_data_init) { - ret = ctrl->soc_data_init(info); + if (IS_ENABLED(CONFIG_CPU_RK3308) && ctrl->type == RK3308) { + ret = rk3308_soc_data_init(info); if (ret) return ret; } @@ -3685,16 +4317,49 @@ return ret; platform_set_drvdata(pdev, info); + g_pctldev = info->pctl_dev; - ret = of_platform_populate(np, rockchip_bank_match, NULL, NULL); - if (ret) { - dev_err(&pdev->dev, "failed to register gpio device\n"); - return ret; - } + ret = of_platform_populate(np, NULL, NULL, &pdev->dev); + if (ret) + return dev_err_probe(dev, ret, "failed to register gpio device\n"); + dev_info(dev, "probed %s\n", dev_name(dev)); return 0; } + +static int rockchip_pinctrl_remove(struct platform_device *pdev) +{ + struct rockchip_pinctrl *info = platform_get_drvdata(pdev); + struct rockchip_pin_bank *bank; + struct rockchip_pin_deferred *cfg; + int i; + + g_pctldev = NULL; + of_platform_depopulate(&pdev->dev); + + for (i = 0; i < info->ctrl->nr_banks; i++) { + bank = &info->ctrl->pin_banks[i]; + + mutex_lock(&bank->deferred_lock); + while (!list_empty(&bank->deferred_pins)) { + cfg = list_first_entry(&bank->deferred_pins, + struct rockchip_pin_deferred, head); + list_del(&cfg->head); + kfree(cfg); + } + mutex_unlock(&bank->deferred_lock); + } + + return 0; +} + +static struct rockchip_pin_bank px30s_pin_banks[] __maybe_unused = { + S_PIN_BANK_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), +}; static struct rockchip_pin_bank px30_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, @@ -3719,13 +4384,6 @@ ), }; -static struct rockchip_pin_bank px30s_pin_banks[] __maybe_unused = { - PX30S_PIN_BANK_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU, DRV_TYPE_IO_SMIC), - PX30S_PIN_BANK_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), - PX30S_PIN_BANK_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), - PX30S_PIN_BANK_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, DRV_TYPE_IO_SMIC), -}; - static struct rockchip_pin_ctrl px30_pin_ctrl __maybe_unused = { .pin_banks = px30_pin_banks, .nr_banks = ARRAY_SIZE(px30_pin_banks), @@ -3739,6 +4397,48 @@ .drv_calc_reg = px30_calc_drv_reg_and_bit, .schmitt_calc_reg = px30_calc_schmitt_reg_and_bit, .slew_rate_calc_reg = px30_calc_slew_rate_reg_and_bit, +}; + +static struct rockchip_pin_bank rv1106_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU, + IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU), + PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0, 0x08, 0x10, 0x18), + PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0x10020, 0x10028, 0, 0), + PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0x20040, 0x20048, 0x20050, 0x20058), + PIN_BANK_IOMUX_FLAGS_OFFSET(4, 24, "gpio4", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0, + 0x30000, 0x30008, 0x30010, 0), +}; + +static struct rockchip_pin_ctrl rv1106_pin_ctrl __maybe_unused = { + .pin_banks = rv1106_pin_banks, + .nr_banks = ARRAY_SIZE(rv1106_pin_banks), + .label = "RV1106-GPIO", + .type = RV1106, + .pull_calc_reg = rv1106_calc_pull_reg_and_bit, + .drv_calc_reg = rv1106_calc_drv_reg_and_bit, + .schmitt_calc_reg = rv1106_calc_schmitt_reg_and_bit, }; static struct rockchip_pin_bank rv1108_pin_banks[] = { @@ -4011,6 +4711,14 @@ .drv_calc_reg = rk3288_calc_drv_reg_and_bit, }; +static struct rockchip_pin_bank rk3308bs_pin_banks[] __maybe_unused = { + S_PIN_BANK_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), + S_PIN_BANK_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT, DRV_TYPE_IO_SMIC), +}; + static struct rockchip_pin_bank rk3308_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, @@ -4044,11 +4752,10 @@ .niomux_recalced = ARRAY_SIZE(rk3308_mux_recalced_data), .iomux_routes = rk3308_mux_route_data, .niomux_routes = ARRAY_SIZE(rk3308_mux_route_data), - .ctrl_data_re_init = rk3308b_ctrl_data_re_init, - .soc_data_init = rk3308b_soc_data_init, .pull_calc_reg = rk3308_calc_pull_reg_and_bit, .drv_calc_reg = rk3308_calc_drv_reg_and_bit, .schmitt_calc_reg = rk3308_calc_schmitt_reg_and_bit, + .slew_rate_calc_reg = rk3308_calc_slew_rate_reg_and_bit, }; static struct rockchip_pin_bank rk3328_pin_banks[] = { @@ -4213,6 +4920,49 @@ .schmitt_calc_reg = rk3528_calc_schmitt_reg_and_bit, }; +static struct rockchip_pin_bank rk3562_pin_banks[] = { + PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0x20000, 0x20008, 0x20010, 0x20018), + PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0, 0x08, 0x10, 0x18), + PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0x20, 0, 0, 0), + PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0x10040, 0x10048, 0x10050, 0x10058), + PIN_BANK_IOMUX_FLAGS_OFFSET(4, 16, "gpio4", + IOMUX_WIDTH_4BIT, + IOMUX_WIDTH_4BIT, + 0, + 0, + 0x10060, 0x10068, 0, 0), +}; + +static struct rockchip_pin_ctrl rk3562_pin_ctrl __maybe_unused = { + .pin_banks = rk3562_pin_banks, + .nr_banks = ARRAY_SIZE(rk3562_pin_banks), + .label = "RK3562-GPIO", + .type = RK3562, + .pull_calc_reg = rk3562_calc_pull_reg_and_bit, + .drv_calc_reg = rk3562_calc_drv_reg_and_bit, + .schmitt_calc_reg = rk3562_calc_schmitt_reg_and_bit, +}; + static struct rockchip_pin_bank rk3568_pin_banks[] = { PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, @@ -4253,12 +5003,39 @@ .schmitt_calc_reg = rk3568_calc_schmitt_reg_and_bit, }; +static struct rockchip_pin_bank rk3588_pin_banks[] = { + RK3588_PIN_BANK_FLAGS(0, 32, "gpio0", + IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + RK3588_PIN_BANK_FLAGS(1, 32, "gpio1", + IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + RK3588_PIN_BANK_FLAGS(2, 32, "gpio2", + IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + RK3588_PIN_BANK_FLAGS(3, 32, "gpio3", + IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + RK3588_PIN_BANK_FLAGS(4, 32, "gpio4", + IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), +}; + +static struct rockchip_pin_ctrl rk3588_pin_ctrl __maybe_unused = { + .pin_banks = rk3588_pin_banks, + .nr_banks = ARRAY_SIZE(rk3588_pin_banks), + .label = "RK3588-GPIO", + .type = RK3588, + .pull_calc_reg = rk3588_calc_pull_reg_and_bit, + .drv_calc_reg = rk3588_calc_drv_reg_and_bit, + .schmitt_calc_reg = rk3588_calc_schmitt_reg_and_bit, +}; + static const struct of_device_id rockchip_pinctrl_dt_match[] = { #ifdef CONFIG_CPU_PX30 { .compatible = "rockchip,px30-pinctrl", .data = &px30_pin_ctrl }, #endif -#ifdef CONFIG_CPU_RV110X +#ifdef CONFIG_CPU_RV1106 + { .compatible = "rockchip,rv1106-pinctrl", + .data = &rv1106_pin_ctrl }, +#endif +#ifdef CONFIG_CPU_RV1108 { .compatible = "rockchip,rv1108-pinctrl", .data = &rv1108_pin_ctrl }, #endif @@ -4320,15 +5097,24 @@ { .compatible = "rockchip,rk3528-pinctrl", .data = &rk3528_pin_ctrl }, #endif +#ifdef CONFIG_CPU_RK3562 + { .compatible = "rockchip,rk3562-pinctrl", + .data = &rk3562_pin_ctrl }, +#endif #ifdef CONFIG_CPU_RK3568 { .compatible = "rockchip,rk3568-pinctrl", .data = &rk3568_pin_ctrl }, +#endif +#ifdef CONFIG_CPU_RK3588 + { .compatible = "rockchip,rk3588-pinctrl", + .data = &rk3588_pin_ctrl }, #endif {}, }; static struct platform_driver rockchip_pinctrl_driver = { .probe = rockchip_pinctrl_probe, + .remove = rockchip_pinctrl_remove, .driver = { .name = "rockchip-pinctrl", .pm = &rockchip_pinctrl_dev_pm_ops, @@ -4348,6 +5134,103 @@ } module_exit(rockchip_pinctrl_drv_unregister); +/** + * rk_iomux_set - set the rockchip iomux by pin number. + * + * @bank: the gpio bank index, from 0 to the max bank num. + * @pin: the gpio pin index, from 0 to 31. + * @mux: the pointer to store mux value. + * + * Return 0 if set success, else return error code. + */ +int rk_iomux_set(int bank, int pin, int mux) +{ + struct pinctrl_dev *pctldev = g_pctldev; + struct rockchip_pinctrl *info; + struct rockchip_pin_bank *gpio; + struct rockchip_pin_group *grp = NULL; + struct rockchip_pin_config *cfg = NULL; + int i, j, ret; + + if (!g_pctldev) + return -ENODEV; + + info = pinctrl_dev_get_drvdata(pctldev); + if (bank >= info->ctrl->nr_banks) + return -EINVAL; + + if (pin > 31 || pin < 0) + return -EINVAL; + + gpio = &info->ctrl->pin_banks[bank]; + + mutex_lock(&iomux_lock); + for (i = 0; i < info->ngroups; i++) { + grp = &info->groups[i]; + for (j = 0; j < grp->npins; i++) { + if (grp->pins[i] == (gpio->pin_base + pin)) { + cfg = grp->data; + break; + } + } + } + + ret = rockchip_set_mux(gpio, pin, mux); + if (ret) { + dev_err(info->dev, "mux GPIO%d-%d %d fail\n", bank, pin, mux); + goto out; + } + + if (cfg && (cfg->func != mux)) + cfg->func = mux; + +out: + mutex_unlock(&iomux_lock); + + return ret; +} +EXPORT_SYMBOL_GPL(rk_iomux_set); + +/** + * rk_iomux_get - get the rockchip iomux by pin number. + * + * @bank: the gpio bank index, from 0 to the max bank num. + * @pin: the gpio pin index, from 0 to 31. + * @mux: the pointer to store mux value. + * + * Return 0 if get success, else return error code. + */ +int rk_iomux_get(int bank, int pin, int *mux) +{ + struct pinctrl_dev *pctldev = g_pctldev; + struct rockchip_pinctrl *info; + struct rockchip_pin_bank *gpio; + int ret; + + if (!g_pctldev) + return -ENODEV; + if (!mux) + return -EINVAL; + + info = pinctrl_dev_get_drvdata(pctldev); + if (bank >= info->ctrl->nr_banks) + return -EINVAL; + + if (pin > 31 || pin < 0) + return -EINVAL; + + gpio = &info->ctrl->pin_banks[bank]; + + mutex_lock(&iomux_lock); + ret = rockchip_get_mux(gpio, pin); + mutex_unlock(&iomux_lock); + + *mux = ret; + + return (ret >= 0) ? 0 : ret; +} +EXPORT_SYMBOL_GPL(rk_iomux_get); + MODULE_DESCRIPTION("ROCKCHIP Pin Controller Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:pinctrl-rockchip"); -- Gitblit v1.6.2