linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Add iomux-route switching support
@ 2017-05-25 13:12 David Wu
  2017-05-25 13:12 ` [PATCH 1/4] pinctrl: rockchip: " David Wu
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
  To: heiko, linus.walleij
  Cc: huangtao, dianders, linux-rockchip, linux-gpio, linux-kernel, David Wu

The rk3228, rk3328, rk3399 have an interesting new feature,
some things like one specific uart can use multiple pins to
output data, but control of that seems to be split. The actual
pin config is identical for all pins - each needs to be configured
to function 2.

Use one pin of a specifc group to be set to its special pinmux function,
then configure the corresponding routing bits. If the pinmux setting is
wrong for that pin the ip block won't work correctly anyway.

David Wu (4):
  pinctrl: rockchip: Add iomux-route switching support
  pinctrl: rockchip: Add iomux-route switching support for rk3228
  pinctrl: rockchip: Add iomux-route switching support for rk3328
  pinctrl: rockchip: Add iomux-route switching support for rk3399

 drivers/pinctrl/pinctrl-rockchip.c | 487 ++++++++++++++++++++++++++++++++++---
 1 file changed, 458 insertions(+), 29 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/4] pinctrl: rockchip: Add iomux-route switching support
  2017-05-25 13:12 [PATCH 0/4] Add iomux-route switching support David Wu
@ 2017-05-25 13:12 ` David Wu
  2017-05-25 13:12 ` [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228 David Wu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
  To: heiko, linus.walleij
  Cc: huangtao, dianders, linux-rockchip, linux-gpio, linux-kernel, David Wu

On the some rockchip soc, some things like one specific uart can use
multiple pins, but control of that seems to be split. Somewhere between
the pin io-cells and the uart it seems to have some sort of switch to
decide to which pin to actually route the data.

+-------+    +--------+  /- GPIO4_B0 (pinmux 2)

| uart2 | -- | switch | --- GPIO4_C0 (pinmux 2)

+-------+    +--------+  \- GPIO4_C3 (pinmux 2)
(switch selects one of the 3 pins base on the GRF_SOC_CON7[BIT0, BIT1])

The routing switch is determined by one pin of a specific group to be set
to its special pinmux function. If the pinmux setting is wrong for that
pin the ip block won't work correctly anyway.

Signed-off-by: David Wu <david.wu@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index f141aa0..f5dd1c3 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -146,6 +146,7 @@ struct rockchip_drv {
  * @irq_lock: bus lock for irq chip
  * @new_irqs: newly configured irqs which must be muxed as GPIOs in
  *	irq_bus_sync_unlock()
+ * @route_mask: bits describing the routing pins of per bank
  */
 struct rockchip_pin_bank {
 	void __iomem			*reg_base;
@@ -170,6 +171,7 @@ struct rockchip_pin_bank {
 	u32				toggle_edge_mode;
 	struct mutex			irq_lock;
 	u32				new_irqs;
+	u32				route_mask;
 };
 
 #define PIN_BANK(id, pins, label)			\
@@ -316,6 +318,8 @@ struct rockchip_pin_ctrl {
 	int	(*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
 				    int pin_num, struct regmap **regmap,
 				    int *reg, u8 *bit);
+	bool	(*iomux_route)(u8 bank_num, int pin, int mux,
+			       u32 *reg, u32 *value);
 };
 
 struct rockchip_pin_config {
@@ -383,6 +387,22 @@ struct rockchip_mux_recalced_data {
 	u8 mask;
 };
 
+/**
+ * struct rockchip_mux_recalced_data: represent a pin iomux data.
+ * @bank: bank number.
+ * @pin: index at register or used to calc index.
+ * @func: the min pin.
+ * @route_offset: the max pin.
+ * @route_val: the register offset.
+ */
+struct rockchip_mux_route_data {
+	u8 bank;
+	u8 pin;
+	u8 func;
+	u32 route_offset;
+	u32 route_val;
+};
+
 static struct regmap_config rockchip_regmap_config = {
 	.reg_bits = 32,
 	.val_bits = 32,
@@ -683,7 +703,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	struct regmap *regmap;
 	int reg, ret, mask, mux_type;
 	u8 bit;
-	u32 data, rmask;
+	u32 data, rmask, route_reg, route_val;
 
 	ret = rockchip_verify_mux(bank, pin, mux);
 	if (ret < 0)
@@ -719,6 +739,15 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
 	if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
 		ctrl->iomux_recalc(bank->bank_num, pin, &reg, &bit, &mask);
 
+	if (ctrl->iomux_route && (bank->route_mask & BIT(pin))) {
+		if (ctrl->iomux_route(bank->bank_num, pin, mux,
+				      &route_reg, &route_val)) {
+			ret = regmap_write(regmap, route_reg, route_val);
+			if (ret)
+				return ret;
+		}
+	}
+
 	data = (mask << (bit + 16));
 	rmask = data | (data >> 16);
 	data |= (mux & mask) << bit;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228
  2017-05-25 13:12 [PATCH 0/4] Add iomux-route switching support David Wu
  2017-05-25 13:12 ` [PATCH 1/4] pinctrl: rockchip: " David Wu
@ 2017-05-25 13:12 ` David Wu
  2017-05-25 21:12   ` Heiko Stuebner
  2017-05-25 13:12 ` [PATCH 3/4] pinctrl: rockchip: Add iomux-route switching support for rk3328 David Wu
  2017-05-25 13:12 ` [PATCH 4/4] pinctrl: rockchip: Add iomux-route switching support for rk3399 David Wu
  3 siblings, 1 reply; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
  To: heiko, linus.walleij
  Cc: huangtao, dianders, linux-rockchip, linux-gpio, linux-kernel, David Wu

There are 9 IP blocks pin routes need to be switched, that are
pwm-0, pwm-1, pwm-2, pwm-3, sdio, spi, emmc, uart2, uart1.

Signed-off-by: David Wu <david.wu@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 176 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 172 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index f5dd1c3..be4c16e 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -187,6 +187,20 @@ struct rockchip_pin_bank {
 		},					\
 	}
 
+#define PIN_BANK_ROUTE(id, pins, label, route)		\
+	{						\
+		.bank_num	= id,			\
+		.nr_pins	= pins,			\
+		.name		= label,		\
+		.route_mask	= route,		\
+		.iomux		= {			\
+			{ .offset = -1 },		\
+			{ .offset = -1 },		\
+			{ .offset = -1 },		\
+			{ .offset = -1 },		\
+		},					\
+	}
+
 #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)	\
 	{								\
 		.bank_num	= id,					\
@@ -605,6 +619,159 @@ static void rk3328_recalc_mux(u8 bank_num, int pin, int *reg,
 	*bit = data->bit;
 }
 
+static const struct rockchip_mux_route_data  rk3228_mux_route_data[] = {
+	{
+		/* pwm0-0 */
+		.bank = 0,
+		.pin = 26,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16),
+	}, {
+		/* pwm0-1 */
+		.bank = 3,
+		.pin = 21,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16) | BIT(0),
+	}, {
+		/* pwm1-0 */
+		.bank = 0,
+		.pin = 27,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 1),
+	}, {
+		/* pwm1-1 */
+		.bank = 0,
+		.pin = 30,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 1) | BIT(1),
+	}, {
+		/* pwm2-0 */
+		.bank = 0,
+		.pin = 28,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 2),
+	}, {
+		/* pwm2-1 */
+		.bank = 1,
+		.pin = 12,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 2) | BIT(2),
+	}, {
+		/* pwm3-0 */
+		.bank = 3,
+		.pin = 26,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 3),
+	}, {
+		/* pwm3-1 */
+		.bank = 1,
+		.pin = 11,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 3) | BIT(3),
+	}, {
+		/* sdio-0_d0 */
+		.bank = 1,
+		.pin = 1,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 4),
+	}, {
+		/* sdio-1_d0 */
+		.bank = 3,
+		.pin = 2,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 4) | BIT(4),
+	}, {
+		/* spi-0_rx */
+		.bank = 0,
+		.pin = 13,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 5),
+	}, {
+		/* spi-1_rx */
+		.bank = 2,
+		.pin = 0,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 5) | BIT(5),
+	}, {
+		/* emmc-0_cmd */
+		.bank = 1,
+		.pin = 22,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 7),
+	}, {
+		/* emmc-1_cmd */
+		.bank = 2,
+		.pin = 4,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 7) | BIT(7),
+	}, {
+		/* uart2-0_rx */
+		.bank = 1,
+		.pin = 19,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 8),
+	}, {
+		/* uart2-1_rx */
+		.bank = 1,
+		.pin = 10,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 8) | BIT(8),
+	}, {
+		/* uart1-0_rx */
+		.bank = 1,
+		.pin = 10,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 11),
+	}, {
+		/* uart1-1_rx */
+		.bank = 3,
+		.pin = 13,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 11) | BIT(11),
+	},
+};
+
+static bool rk3228_set_mux_route(u8 bank_num, int pin,
+				 int mux, u32 *reg, u32 *value)
+{
+	const struct rockchip_mux_route_data *data = NULL;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(rk3228_mux_route_data); i++)
+		if ((rk3228_mux_route_data[i].bank == bank_num) &&
+		    (rk3228_mux_route_data[i].pin == pin) &&
+		    (rk3228_mux_route_data[i].func == mux)) {
+			data = &rk3228_mux_route_data[i];
+			break;
+		}
+
+	if (!data)
+		return false;
+
+	*reg = data->route_offset;
+	*value = data->route_val;
+
+	return true;
+}
+
 static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
 {
 	struct rockchip_pinctrl *info = bank->drvdata;
@@ -2852,10 +3019,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 };
 
 static struct rockchip_pin_bank rk3228_pin_banks[] = {
-	PIN_BANK(0, 32, "gpio0"),
-	PIN_BANK(1, 32, "gpio1"),
-	PIN_BANK(2, 32, "gpio2"),
-	PIN_BANK(3, 32, "gpio3"),
+	PIN_BANK_ROUTE(0, 32, "gpio0", 0x5c002000),
+	PIN_BANK_ROUTE(1, 32, "gpio1", 0x00483c02),
+	PIN_BANK_ROUTE(2, 32, "gpio2", 0x00000011),
+	PIN_BANK_ROUTE(3, 32, "gpio3", 0x04202004),
 };
 
 static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
@@ -2866,6 +3033,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 		.grf_mux_offset		= 0x0,
 		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
+		.iomux_route		= rk3228_set_mux_route,
 };
 
 static struct rockchip_pin_bank rk3288_pin_banks[] = {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/4] pinctrl: rockchip: Add iomux-route switching support for rk3328
  2017-05-25 13:12 [PATCH 0/4] Add iomux-route switching support David Wu
  2017-05-25 13:12 ` [PATCH 1/4] pinctrl: rockchip: " David Wu
  2017-05-25 13:12 ` [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228 David Wu
@ 2017-05-25 13:12 ` David Wu
  2017-05-25 13:12 ` [PATCH 4/4] pinctrl: rockchip: Add iomux-route switching support for rk3399 David Wu
  3 siblings, 0 replies; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
  To: heiko, linus.walleij
  Cc: huangtao, dianders, linux-rockchip, linux-gpio, linux-kernel, David Wu

There are 8 IP blocks pin routes need to be switched, that are
uart2dbg, gmac-m1-optimized, pdm, spi, i2s2, card, tsp, cif.

Signed-off-by: David Wu <david.wu@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 140 ++++++++++++++++++++++++++++++++++---
 1 file changed, 130 insertions(+), 10 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index be4c16e..6eab4581 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -214,6 +214,21 @@ struct rockchip_pin_bank {
 		},							\
 	}
 
+#define PIN_BANK_IOMUX_FLAGS_ROUTE(id, pins, label, route, iom0, iom1,	\
+				   iom2, iom3)				\
+	{								\
+		.bank_num	= id,					\
+		.nr_pins	= pins,					\
+		.name		= label,				\
+		.route_mask	= route,				\
+		.iomux		= {					\
+			{ .type = iom0, .offset = -1 },			\
+			{ .type = iom1, .offset = -1 },			\
+			{ .type = iom2, .offset = -1 },			\
+			{ .type = iom3, .offset = -1 },			\
+		},							\
+	}
+
 #define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
 	{								\
 		.bank_num	= id,					\
@@ -772,6 +787,110 @@ static bool rk3228_set_mux_route(u8 bank_num, int pin,
 	return true;
 }
 
+static const struct rockchip_mux_route_data  rk3328_mux_route_data[] = {
+	{
+		/* uart2dbg_rxm0 */
+		.bank = 1,
+		.pin = 1,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16) | BIT(16 + 1),
+	}, {
+		/* uart2dbg_rxm1 */
+		.bank = 2,
+		.pin = 1,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16) | BIT(16 + 1) | BIT(0),
+	}, {
+		/* gmac-m1-optimized_rxd0 */
+		.bank = 1,
+		.pin = 11,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 2) | BIT(16 + 10) | BIT(2) | BIT(10),
+	}, {
+		/* pdm_sdi0m0 */
+		.bank = 2,
+		.pin = 19,
+		.func = 2,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 3),
+	}, {
+		/* pdm_sdi0m1 */
+		.bank = 1,
+		.pin = 23,
+		.func = 3,
+		.route_offset = 0x50,
+		.route_val =  BIT(16 + 3) | BIT(3),
+	}, {
+		/* spi_rxdm2 */
+		.bank = 3,
+		.pin = 2,
+		.func = 4,
+		.route_offset = 0x50,
+		.route_val =  BIT(16 + 4) | BIT(16 + 5) | BIT(5),
+	}, {
+		/* i2s2_sdim0 */
+		.bank = 1,
+		.pin = 24,
+		.func = 1,
+		.route_offset = 0x50,
+		.route_val = BIT(16 + 6),
+	}, {
+		/* i2s2_sdim1 */
+		.bank = 3,
+		.pin = 2,
+		.func = 6,
+		.route_offset = 0x50,
+		.route_val =  BIT(16 + 6) | BIT(6),
+	}, {
+		/* card_iom1 */
+		.bank = 2,
+		.pin = 22,
+		.func = 3,
+		.route_offset = 0x50,
+		.route_val =  BIT(16 + 7) | BIT(7),
+	}, {
+		/* tsp_d5m1 */
+		.bank = 2,
+		.pin = 16,
+		.func = 3,
+		.route_offset = 0x50,
+		.route_val =  BIT(16 + 8) | BIT(8),
+	}, {
+		/* cif_data5m1 */
+		.bank = 2,
+		.pin = 16,
+		.func = 4,
+		.route_offset = 0x50,
+		.route_val =  BIT(16 + 9) | BIT(9),
+	},
+};
+
+static bool rk3328_set_mux_route(u8 bank_num, int pin, int mux,
+				 u32 *reg, u32 *value)
+{
+	const struct rockchip_mux_route_data *data = NULL;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(rk3328_mux_route_data); i++)
+		if ((rk3328_mux_route_data[i].bank == bank_num) &&
+		    (rk3328_mux_route_data[i].pin == pin) &&
+		    (rk3328_mux_route_data[i].func == mux)) {
+			data = &rk3328_mux_route_data[i];
+			break;
+		}
+
+	if (!data)
+		return false;
+
+	*reg = data->route_offset;
+	*value = data->route_val;
+
+	return true;
+}
+
 static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
 {
 	struct rockchip_pinctrl *info = bank->drvdata;
@@ -3081,16 +3200,16 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 
 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),
-	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
-			     IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
-			     IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
-			     0),
-	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
-			     IOMUX_WIDTH_3BIT,
-			     IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
-			     0,
-			     0),
+	PIN_BANK_IOMUX_FLAGS_ROUTE(1, 32, "gpio1", 0x01800802, 0, 0, 0, 0),
+	PIN_BANK_IOMUX_FLAGS_ROUTE(2, 32, "gpio2", 0x00490002, 0,
+				   IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
+				   IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
+				   0),
+	PIN_BANK_IOMUX_FLAGS_ROUTE(3, 32, "gpio3", 0x00000004,
+				   IOMUX_WIDTH_3BIT,
+				   IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
+				   0,
+				   0),
 };
 
 static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
@@ -3103,6 +3222,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
 		.iomux_recalc		= rk3328_recalc_mux,
 		.schmitt_calc_reg	= rk3328_calc_schmitt_reg_and_bit,
+		.iomux_route		= rk3328_set_mux_route,
 };
 
 static struct rockchip_pin_bank rk3368_pin_banks[] = {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/4] pinctrl: rockchip: Add iomux-route switching support for rk3399
  2017-05-25 13:12 [PATCH 0/4] Add iomux-route switching support David Wu
                   ` (2 preceding siblings ...)
  2017-05-25 13:12 ` [PATCH 3/4] pinctrl: rockchip: Add iomux-route switching support for rk3328 David Wu
@ 2017-05-25 13:12 ` David Wu
  3 siblings, 0 replies; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
  To: heiko, linus.walleij
  Cc: huangtao, dianders, linux-rockchip, linux-gpio, linux-kernel, David Wu

There are 2 IP blocks pin routes need to be switched, that are
uart2dbg, pcie_clkreq.

Signed-off-by: David Wu <david.wu@rock-chips.com>
---
 drivers/pinctrl/pinctrl-rockchip.c | 140 +++++++++++++++++++++++++++++++++----
 1 file changed, 126 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 6eab4581..44c5aff3 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -248,6 +248,27 @@ struct rockchip_pin_bank {
 		},							\
 	}
 
+#define PIN_BANK_DRV_FLAGS_ROUTE(id, pins, label, route, type0, type1,  \
+				 type2, type3)				\
+	{								\
+		.bank_num	= id,					\
+		.nr_pins	= pins,					\
+		.name		= label,				\
+		.route_mask	= route,				\
+		.iomux		= {					\
+			{ .offset = -1 },				\
+			{ .offset = -1 },				\
+			{ .offset = -1 },				\
+			{ .offset = -1 },				\
+		},							\
+		.drv		= {					\
+			{ .drv_type = type0, .offset = -1 },		\
+			{ .drv_type = type1, .offset = -1 },		\
+			{ .drv_type = type2, .offset = -1 },		\
+			{ .drv_type = type3, .offset = -1 },		\
+		},							\
+	}
+
 #define PIN_BANK_DRV_FLAGS_PULL_FLAGS(id, pins, label, drv0, drv1,	\
 				      drv2, drv3, pull0, pull1,		\
 				      pull2, pull3)			\
@@ -273,6 +294,32 @@ struct rockchip_pin_bank {
 		.pull_type[3] = pull3,					\
 	}
 
+#define PIN_BANK_DRV_FLAGS_PULL_FLAGS_ROUTE(id, pins, label, route,	\
+					    drv0, drv1, drv2, drv3,	\
+					    pull0, pull1, pull2, pull3) \
+	{								\
+		.bank_num	= id,					\
+		.nr_pins	= pins,					\
+		.name		= label,				\
+		.route_mask	= route,				\
+		.iomux		= {					\
+			{ .offset = -1 },				\
+			{ .offset = -1 },				\
+			{ .offset = -1 },				\
+			{ .offset = -1 },				\
+		},							\
+		.drv		= {					\
+			{ .drv_type = drv0, .offset = -1 },		\
+			{ .drv_type = drv1, .offset = -1 },		\
+			{ .drv_type = drv2, .offset = -1 },		\
+			{ .drv_type = drv3, .offset = -1 },		\
+		},							\
+		.pull_type[0] = pull0,					\
+		.pull_type[1] = pull1,					\
+		.pull_type[2] = pull2,					\
+		.pull_type[3] = pull3,					\
+	}
+
 #define PIN_BANK_IOMUX_DRV_FLAGS_OFFSET(id, pins, label, iom0, iom1,	\
 					iom2, iom3, drv0, drv1, drv2,	\
 					drv3, offset0, offset1,		\
@@ -891,6 +938,68 @@ static bool rk3328_set_mux_route(u8 bank_num, int pin, int mux,
 	return true;
 }
 
+static const struct rockchip_mux_route_data  rk3399_mux_route_data[] = {
+	{
+		/* uart2dbga_rx */
+		.bank = 4,
+		.pin = 8,
+		.func = 2,
+		.route_offset = 0xe21c,
+		.route_val = BIT(16 + 10) | BIT(16 + 11),
+	}, {
+		/* uart2dbgb_rx */
+		.bank = 4,
+		.pin = 16,
+		.func = 2,
+		.route_offset = 0xe21c,
+		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(10),
+	}, {
+		/* uart2dbgc_rx */
+		.bank = 4,
+		.pin = 19,
+		.func = 1,
+		.route_offset = 0xe21c,
+		.route_val = BIT(16 + 10) | BIT(16 + 11) | BIT(11),
+	}, {
+		/* pcie_clkreqn */
+		.bank = 2,
+		.pin = 26,
+		.func = 2,
+		.route_offset = 0xe21c,
+		.route_val = BIT(16 + 14),
+	}, {
+		/* pcie_clkreqnb */
+		.bank = 4,
+		.pin = 24,
+		.func = 1,
+		.route_offset = 0xe21c,
+		.route_val = BIT(16 + 14) | BIT(14),
+	},
+};
+
+static bool rk3399_set_mux_route(u8 bank_num, int pin, int mux,
+				 u32 *reg, u32 *value)
+{
+	const struct rockchip_mux_route_data *data = NULL;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(rk3399_mux_route_data); i++)
+		if ((rk3399_mux_route_data[i].bank == bank_num) &&
+		    (rk3399_mux_route_data[i].pin == pin) &&
+		    (rk3399_mux_route_data[i].func == mux)) {
+			data = &rk3399_mux_route_data[i];
+			break;
+		}
+
+	if (!data)
+		return false;
+
+	*reg = data->route_offset;
+	*value = data->route_val;
+
+	return true;
+}
+
 static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
 {
 	struct rockchip_pinctrl *info = bank->drvdata;
@@ -3279,25 +3388,27 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 					0x30,
 					0x38
 					),
-	PIN_BANK_DRV_FLAGS_PULL_FLAGS(2, 32, "gpio2", DRV_TYPE_IO_1V8_OR_3V0,
-				      DRV_TYPE_IO_1V8_OR_3V0,
-				      DRV_TYPE_IO_1V8_ONLY,
-				      DRV_TYPE_IO_1V8_ONLY,
-				      PULL_TYPE_IO_DEFAULT,
-				      PULL_TYPE_IO_DEFAULT,
-				      PULL_TYPE_IO_1V8_ONLY,
-				      PULL_TYPE_IO_1V8_ONLY
-				      ),
+	PIN_BANK_DRV_FLAGS_PULL_FLAGS_ROUTE(2, 32, "gpio2", 0x04000000,
+					    DRV_TYPE_IO_1V8_OR_3V0,
+					    DRV_TYPE_IO_1V8_OR_3V0,
+					    DRV_TYPE_IO_1V8_ONLY,
+					    DRV_TYPE_IO_1V8_ONLY,
+					    PULL_TYPE_IO_DEFAULT,
+					    PULL_TYPE_IO_DEFAULT,
+					    PULL_TYPE_IO_1V8_ONLY,
+					    PULL_TYPE_IO_1V8_ONLY
+					    ),
 	PIN_BANK_DRV_FLAGS(3, 32, "gpio3", DRV_TYPE_IO_3V3_ONLY,
 			   DRV_TYPE_IO_3V3_ONLY,
 			   DRV_TYPE_IO_3V3_ONLY,
 			   DRV_TYPE_IO_1V8_OR_3V0
 			   ),
-	PIN_BANK_DRV_FLAGS(4, 32, "gpio4", DRV_TYPE_IO_1V8_OR_3V0,
-			   DRV_TYPE_IO_1V8_3V0_AUTO,
-			   DRV_TYPE_IO_1V8_OR_3V0,
-			   DRV_TYPE_IO_1V8_OR_3V0
-			   ),
+	PIN_BANK_DRV_FLAGS_ROUTE(4, 32, "gpio4", 0x01090100,
+				 DRV_TYPE_IO_1V8_OR_3V0,
+				 DRV_TYPE_IO_1V8_3V0_AUTO,
+				 DRV_TYPE_IO_1V8_OR_3V0,
+				 DRV_TYPE_IO_1V8_OR_3V0
+				 ),
 };
 
 static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
@@ -3311,6 +3422,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 		.pmu_drv_offset		= 0x80,
 		.pull_calc_reg		= rk3399_calc_pull_reg_and_bit,
 		.drv_calc_reg		= rk3399_calc_drv_reg_and_bit,
+		.iomux_route		= rk3399_set_mux_route,
 };
 
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228
  2017-05-25 13:12 ` [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228 David Wu
@ 2017-05-25 21:12   ` Heiko Stuebner
  2017-05-26  3:38     ` David.Wu
  0 siblings, 1 reply; 7+ messages in thread
From: Heiko Stuebner @ 2017-05-25 21:12 UTC (permalink / raw)
  To: David Wu
  Cc: linus.walleij, huangtao, dianders, linux-rockchip, linux-gpio,
	linux-kernel

Hi David,

Am Donnerstag, 25. Mai 2017, 21:12:30 CEST schrieb David Wu:
> There are 9 IP blocks pin routes need to be switched, that are
> pwm-0, pwm-1, pwm-2, pwm-3, sdio, spi, emmc, uart2, uart1.
> 
> Signed-off-by: David Wu <david.wu@rock-chips.com>

This series come pretty close to what I had in mind, but I do have some
change requests inline below.

The comments are in this patch but apply to the whole series.


> ---
>  drivers/pinctrl/pinctrl-rockchip.c | 176 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 172 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index f5dd1c3..be4c16e 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -187,6 +187,20 @@ struct rockchip_pin_bank {
>  		},					\
>  	}
>  
> +#define PIN_BANK_ROUTE(id, pins, label, route)		\
> +	{						\
> +		.bank_num	= id,			\
> +		.nr_pins	= pins,			\
> +		.name		= label,		\
> +		.route_mask	= route,		\
> +		.iomux		= {			\
> +			{ .offset = -1 },		\
> +			{ .offset = -1 },		\
> +			{ .offset = -1 },		\
> +			{ .offset = -1 },		\
> +		},					\
> +	}
> +
>  #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)	\
>  	{								\
>  		.bank_num	= id,					\
> @@ -605,6 +619,159 @@ static void rk3328_recalc_mux(u8 bank_num, int pin, int *reg,
>  	*bit = data->bit;
>  }
>  
> +static const struct rockchip_mux_route_data  rk3228_mux_route_data[] = {
> +	{
> +		/* pwm0-0 */
> +		.bank = 0,
> +		.pin = 26,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16),
> +	}, {
> +		/* pwm0-1 */
> +		.bank = 3,
> +		.pin = 21,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16) | BIT(0),
> +	}, {
> +		/* pwm1-0 */
> +		.bank = 0,
> +		.pin = 27,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 1),
> +	}, {
> +		/* pwm1-1 */
> +		.bank = 0,
> +		.pin = 30,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 1) | BIT(1),
> +	}, {
> +		/* pwm2-0 */
> +		.bank = 0,
> +		.pin = 28,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 2),
> +	}, {
> +		/* pwm2-1 */
> +		.bank = 1,
> +		.pin = 12,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 2) | BIT(2),
> +	}, {
> +		/* pwm3-0 */
> +		.bank = 3,
> +		.pin = 26,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 3),
> +	}, {
> +		/* pwm3-1 */
> +		.bank = 1,
> +		.pin = 11,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 3) | BIT(3),
> +	}, {
> +		/* sdio-0_d0 */
> +		.bank = 1,
> +		.pin = 1,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 4),
> +	}, {
> +		/* sdio-1_d0 */
> +		.bank = 3,
> +		.pin = 2,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 4) | BIT(4),
> +	}, {
> +		/* spi-0_rx */
> +		.bank = 0,
> +		.pin = 13,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 5),
> +	}, {
> +		/* spi-1_rx */
> +		.bank = 2,
> +		.pin = 0,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 5) | BIT(5),
> +	}, {
> +		/* emmc-0_cmd */
> +		.bank = 1,
> +		.pin = 22,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 7),
> +	}, {
> +		/* emmc-1_cmd */
> +		.bank = 2,
> +		.pin = 4,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 7) | BIT(7),
> +	}, {
> +		/* uart2-0_rx */
> +		.bank = 1,
> +		.pin = 19,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 8),
> +	}, {
> +		/* uart2-1_rx */
> +		.bank = 1,
> +		.pin = 10,
> +		.func = 2,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 8) | BIT(8),
> +	}, {
> +		/* uart1-0_rx */
> +		.bank = 1,
> +		.pin = 10,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 11),
> +	}, {
> +		/* uart1-1_rx */
> +		.bank = 3,
> +		.pin = 13,
> +		.func = 1,
> +		.route_offset = 0x50,
> +		.route_val = BIT(16 + 11) | BIT(11),
> +	},
> +};
> +
> +static bool rk3228_set_mux_route(u8 bank_num, int pin,
> +				 int mux, u32 *reg, u32 *value)

instead of referencing this function in the per-soc struct, please make
it generic and reference the route array + size in the per-soc struct.

Except for referencing a different array, the function is the same
everywhere, so there is no need to duplicate it for each soc.

> +{
> +	const struct rockchip_mux_route_data *data = NULL;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(rk3228_mux_route_data); i++)
> +		if ((rk3228_mux_route_data[i].bank == bank_num) &&
> +		    (rk3228_mux_route_data[i].pin == pin) &&
> +		    (rk3228_mux_route_data[i].func == mux)) {
> +			data = &rk3228_mux_route_data[i];
> +			break;
> +		}
> +
> +	if (!data)
> +		return false;
> +
> +	*reg = data->route_offset;
> +	*value = data->route_val;
> +
> +	return true;
> +}
> +
>  static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
>  {
>  	struct rockchip_pinctrl *info = bank->drvdata;
> @@ -2852,10 +3019,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
>  };
>  
>  static struct rockchip_pin_bank rk3228_pin_banks[] = {
> -	PIN_BANK(0, 32, "gpio0"),
> -	PIN_BANK(1, 32, "gpio1"),
> -	PIN_BANK(2, 32, "gpio2"),
> -	PIN_BANK(3, 32, "gpio3"),
> +	PIN_BANK_ROUTE(0, 32, "gpio0", 0x5c002000),
> +	PIN_BANK_ROUTE(1, 32, "gpio1", 0x00483c02),
> +	PIN_BANK_ROUTE(2, 32, "gpio2", 0x00000011),
> +	PIN_BANK_ROUTE(3, 32, "gpio3", 0x04202004),

Requiring developers to calculate this pin-bit-value for each bank
is cumbersome and error-prone. With the routes-struct known in
the driver (see above and below), you can keep the the value element
in rockchip_pin_bank, but calculate the per-bank value dynamically
when the bank gets created.

For example in rockchip_pinctrl_get_soc_data just parse the route-struct
and calculate that value when the driver probes.

This reduces possible errors and also spares us the clutter of all the
additional PIN_BANK_* defines.


>  };
>  
>  static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
> @@ -2866,6 +3033,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
>  		.grf_mux_offset		= 0x0,
>  		.pull_calc_reg		= rk3228_calc_pull_reg_and_bit,
>  		.drv_calc_reg		= rk3228_calc_drv_reg_and_bit,
> +		.iomux_route		= rk3228_set_mux_route,

		.iomux_routes	= rk3228_mux_route_data,
		.niomux_routes	= ARRAY_SIZE(rk3228_mux_route_data),


Heiko

>  };
>  
>  static struct rockchip_pin_bank rk3288_pin_banks[] = {
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228
  2017-05-25 21:12   ` Heiko Stuebner
@ 2017-05-26  3:38     ` David.Wu
  0 siblings, 0 replies; 7+ messages in thread
From: David.Wu @ 2017-05-26  3:38 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: linus.walleij, huangtao, dianders, linux-rockchip, linux-gpio,
	linux-kernel

Hi Heiko,

在 2017/5/26 5:12, Heiko Stuebner 写道:
> Requiring developers to calculate this pin-bit-value for each bank
> is cumbersome and error-prone. With the routes-struct known in
> the driver (see above and below), you can keep the the value element
> in rockchip_pin_bank, but calculate the per-bank value dynamically
> when the bank gets created.
> 
> For example in rockchip_pinctrl_get_soc_data just parse the route-struct
> and calculate that value when the driver probes.
> 
> This reduces possible errors and also spares us the clutter of all the
> additional PIN_BANK_* defines.

It is good to calculate the per-bank value dynamically, Thanks.☺

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-05-26  3:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-25 13:12 [PATCH 0/4] Add iomux-route switching support David Wu
2017-05-25 13:12 ` [PATCH 1/4] pinctrl: rockchip: " David Wu
2017-05-25 13:12 ` [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228 David Wu
2017-05-25 21:12   ` Heiko Stuebner
2017-05-26  3:38     ` David.Wu
2017-05-25 13:12 ` [PATCH 3/4] pinctrl: rockchip: Add iomux-route switching support for rk3328 David Wu
2017-05-25 13:12 ` [PATCH 4/4] pinctrl: rockchip: Add iomux-route switching support for rk3399 David Wu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).