mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/5] RK3568 pinctrl
@ 2021-06-08 14:05 Sascha Hauer
  2021-06-08 14:05 ` [PATCH 1/5] pinctrl: Rockchip: rename mux_offset to grf_mux_offset Sascha Hauer
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Sascha Hauer @ 2021-06-08 14:05 UTC (permalink / raw)
  To: Barebox List

Another step in getting Rockchip rk3568 support upstream: This series
adds pinctrl support for that SoC.
Unfortunately I don't have access to a board that was previously
supported by the driver, so I can't test if it still works. The rk3568
seems to work ok though, the register settings I have checked look sane.

Sascha

Sascha Hauer (5):
  pinctrl: Rockchip: rename mux_offset to grf_mux_offset
  pinctrl: Rockchip: print resource_size_t with %pa
  pinctrl: Rockchip: Update from Linux
  pinctrl: Rockchip: implement drive strength setting
  pinctrl: Rockchip: Add RK3568 support

 drivers/pinctrl/pinctrl-rockchip.c | 777 ++++++++++++++++++++++++++++-
 1 file changed, 754 insertions(+), 23 deletions(-)

-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 1/5] pinctrl: Rockchip: rename mux_offset to grf_mux_offset
  2021-06-08 14:05 [PATCH 0/5] RK3568 pinctrl Sascha Hauer
@ 2021-06-08 14:05 ` Sascha Hauer
  2021-06-08 14:05 ` [PATCH 2/5] pinctrl: Rockchip: print resource_size_t with %pa Sascha Hauer
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Sascha Hauer @ 2021-06-08 14:05 UTC (permalink / raw)
  To: Barebox List

Rename variable to match with Linux Kernel.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/pinctrl/pinctrl-rockchip.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 58f2c4af26..c85109fd2b 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -70,7 +70,7 @@ struct rockchip_pin_ctrl {
 	u32				nr_pins;
 	char				*label;
 	enum rockchip_pinctrl_type	type;
-	int				mux_offset;
+	int				grf_mux_offset;
 	void	(*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
 				 void __iomem **reg, u8 *bit);
 };
@@ -229,7 +229,7 @@ static int rockchip_pinctrl_set_func(struct rockchip_pin_bank *bank, int pin,
 				     int mux)
 {
 	struct rockchip_pinctrl *info = bank->drvdata;
-	void __iomem *reg = info->reg_base + info->ctrl->mux_offset;
+	void __iomem *reg = info->reg_base + info->ctrl->grf_mux_offset;
 	u8 bit;
 	u32 data;
 
@@ -462,7 +462,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
 	.pin_banks	= rk2928_pin_banks,
 	.nr_banks	= ARRAY_SIZE(rk2928_pin_banks),
 	.type		= RK2928,
-	.mux_offset	= 0xa8,
+	.grf_mux_offset	= 0xa8,
 	.pull_calc_reg	= rk2928_calc_pull_reg_and_bit,
 };
 
@@ -479,7 +479,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
 	.pin_banks	= rk3066a_pin_banks,
 	.nr_banks	= ARRAY_SIZE(rk3066a_pin_banks),
 	.type		= RK2928,
-	.mux_offset	= 0xa8,
+	.grf_mux_offset	= 0xa8,
 	.pull_calc_reg	= rk2928_calc_pull_reg_and_bit,
 };
 
@@ -494,7 +494,7 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
 	.pin_banks	= rk3066b_pin_banks,
 	.nr_banks	= ARRAY_SIZE(rk3066b_pin_banks),
 	.type		= RK3066B,
-	.mux_offset	= 0x60,
+	.grf_mux_offset	= 0x60,
 };
 
 static struct rockchip_pin_bank rk3188_pin_banks[] = {
@@ -508,7 +508,7 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
 	.pin_banks	= rk3188_pin_banks,
 	.nr_banks	= ARRAY_SIZE(rk3188_pin_banks),
 	.type		= RK3188,
-	.mux_offset	= 0x60,
+	.grf_mux_offset	= 0x60,
 	.pull_calc_reg	= rk3188_calc_pull_reg_and_bit,
 };
 
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 2/5] pinctrl: Rockchip: print resource_size_t with %pa
  2021-06-08 14:05 [PATCH 0/5] RK3568 pinctrl Sascha Hauer
  2021-06-08 14:05 ` [PATCH 1/5] pinctrl: Rockchip: rename mux_offset to grf_mux_offset Sascha Hauer
@ 2021-06-08 14:05 ` Sascha Hauer
  2021-06-08 14:05 ` [PATCH 3/5] pinctrl: Rockchip: Update from Linux Sascha Hauer
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 11+ messages in thread
From: Sascha Hauer @ 2021-06-08 14:05 UTC (permalink / raw)
  To: Barebox List

resource_size_t is correctly printed with %pa.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/pinctrl/pinctrl-rockchip.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index c85109fd2b..3b44847afb 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -342,8 +342,8 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
 
 	res = request_iomem_region(dev_name(dev), node_res.start, node_res.end);
 	if (IS_ERR(res)) {
-		dev_err(dev, "cannot request iomem region %08x\n",
-			node_res.start);
+		dev_err(dev, "cannot request iomem region %pa\n",
+			&node_res.start);
 		return PTR_ERR(res);
 	}
 
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 3/5] pinctrl: Rockchip: Update from Linux
  2021-06-08 14:05 [PATCH 0/5] RK3568 pinctrl Sascha Hauer
  2021-06-08 14:05 ` [PATCH 1/5] pinctrl: Rockchip: rename mux_offset to grf_mux_offset Sascha Hauer
  2021-06-08 14:05 ` [PATCH 2/5] pinctrl: Rockchip: print resource_size_t with %pa Sascha Hauer
@ 2021-06-08 14:05 ` Sascha Hauer
  2021-06-08 14:05 ` [PATCH 4/5] pinctrl: Rockchip: implement drive strength setting Sascha Hauer
  2021-06-08 14:05 ` [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support Sascha Hauer
  4 siblings, 0 replies; 11+ messages in thread
From: Sascha Hauer @ 2021-06-08 14:05 UTC (permalink / raw)
  To: Barebox List

The Linux Rockchip pinctrl driver is more flexible when it comes
to register offsets which are different between SoCs. This patch
updates different pieces of the driver to prepare merging support
for newer SoCs.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/pinctrl/pinctrl-rockchip.c | 283 ++++++++++++++++++++++++++++-
 1 file changed, 275 insertions(+), 8 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 3b44847afb..4b69d0d069 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -27,6 +27,7 @@
 #include <of.h>
 #include <of_address.h>
 #include <pinctrl.h>
+#include <dt-bindings/pinctrl/rockchip.h>
 
 #include <linux/basic_mmio_gpio.h>
 #include <linux/clk.h>
@@ -43,6 +44,54 @@ enum rockchip_pin_bank_type {
 	RK3188_BANK0,
 };
 
+/*
+ * Encode variants of iomux registers into a type variable
+ */
+#define IOMUX_GPIO_ONLY		BIT(0)
+#define IOMUX_WIDTH_4BIT	BIT(1)
+#define IOMUX_SOURCE_PMU	BIT(2)
+#define IOMUX_UNROUTED		BIT(3)
+#define IOMUX_WIDTH_3BIT	BIT(4)
+#define IOMUX_WIDTH_2BIT	BIT(5)
+
+/**
+ * struct rockchip_iomux
+ * @type: iomux variant using IOMUX_* constants
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ *	    an initial offset value the relevant source offset can be reset
+ *	    to a new value for autocalculating the following iomux registers.
+ */
+struct rockchip_iomux {
+	int				type;
+	int				offset;
+};
+
+/*
+ * enum type index corresponding to rockchip_perpin_drv_list arrays index.
+ */
+enum rockchip_pin_drv_type {
+	DRV_TYPE_IO_DEFAULT = 0,
+	DRV_TYPE_IO_1V8_OR_3V0,
+	DRV_TYPE_IO_1V8_ONLY,
+	DRV_TYPE_IO_1V8_3V0_AUTO,
+	DRV_TYPE_IO_3V3_ONLY,
+	DRV_TYPE_MAX
+};
+
+/**
+ * struct rockchip_drv
+ * @drv_type: drive strength variant using rockchip_perpin_drv_type
+ * @offset: if initialized to -1 it will be autocalculated, by specifying
+ *	    an initial offset value the relevant source offset can be reset
+ *	    to a new value for autocalculating the following drive strength
+ *	    registers. if used chips own cal_drv func instead to calculate
+ *	    registers offset, the variant could be ignored.
+ */
+struct rockchip_drv {
+	enum rockchip_pin_drv_type	drv_type;
+	int				offset;
+};
+
 struct rockchip_pin_bank {
 	void __iomem			*reg_base;
 	struct clk			*clk;
@@ -50,11 +99,14 @@ struct rockchip_pin_bank {
 	u8				nr_pins;
 	char				*name;
 	u8				bank_num;
+	struct rockchip_iomux		iomux[4];
+	struct rockchip_drv		drv[4];
 	enum rockchip_pin_bank_type	bank_type;
 	bool				valid;
 	struct device_node		*of_node;
 	struct rockchip_pinctrl		*drvdata;
 	struct bgpio_chip		bgpio_chip;
+	u32				route_mask;
 };
 
 #define PIN_BANK(id, pins, label)			\
@@ -64,6 +116,62 @@ struct rockchip_pin_bank {
 		.name		= label,		\
 	}
 
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3)	\
+	{								\
+		.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 },			\
+		},							\
+	}
+
+#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG)		\
+	{								\
+		.bank_num	= ID,					\
+		.pin		= PIN,					\
+		.func		= FUNC,					\
+		.route_offset	= REG,					\
+		.route_val	= VAL,					\
+		.route_location	= FLAG,					\
+	}
+
+#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME)
+
+#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF)
+
+#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU)
+
+enum rockchip_mux_route_location {
+	ROCKCHIP_ROUTE_SAME = 0,
+	ROCKCHIP_ROUTE_PMU,
+	ROCKCHIP_ROUTE_GRF,
+};
+
+/**
+ * struct rockchip_mux_recalced_data: represent a pin iomux data.
+ * @bank_num: bank number.
+ * @pin: index at register or used to calc index.
+ * @func: the min pin.
+ * @route_location: the mux route location (same, pmu, grf).
+ * @route_offset: the max pin.
+ * @route_val: the register offset.
+ */
+struct rockchip_mux_route_data {
+	u8 bank_num;
+	u8 pin;
+	u8 func;
+	enum rockchip_mux_route_location route_location;
+	u32 route_offset;
+	u32 route_val;
+};
+
 struct rockchip_pin_ctrl {
 	struct rockchip_pin_bank	*pin_banks;
 	u32				nr_banks;
@@ -71,6 +179,11 @@ struct rockchip_pin_ctrl {
 	char				*label;
 	enum rockchip_pinctrl_type	type;
 	int				grf_mux_offset;
+	int				pmu_mux_offset;
+	int				grf_drv_offset;
+	int				pmu_drv_offset;
+	struct rockchip_mux_route_data *iomux_routes;
+	u32				niomux_routes;
 	void	(*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
 				 void __iomem **reg, u8 *bit);
 };
@@ -225,18 +338,90 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
 	}
 }
 
+static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
+	RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
+	RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
+};
+
+static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
+				   int mux, u32 *loc, u32 *reg, u32 *value)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	struct rockchip_mux_route_data *data;
+	int i;
+
+	for (i = 0; i < ctrl->niomux_routes; i++) {
+		data = &ctrl->iomux_routes[i];
+		if ((data->bank_num == bank->bank_num) &&
+		    (data->pin == pin) && (data->func == mux))
+			break;
+	}
+
+	if (i >= ctrl->niomux_routes)
+		return false;
+
+	*loc = data->route_location;
+	*reg = data->route_offset;
+	*value = data->route_val;
+
+	return true;
+}
+
 static int rockchip_pinctrl_set_func(struct rockchip_pin_bank *bank, int pin,
 				     int mux)
 {
 	struct rockchip_pinctrl *info = bank->drvdata;
-	void __iomem *reg = info->reg_base + info->ctrl->grf_mux_offset;
+	void __iomem *reg;
 	u8 bit;
-	u32 data;
+	u32 data, route_location, route_reg, route_val;
+	int iomux_num = (pin / 8);
+	int mux_type;
+	int mask;
+
+	reg = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+				? info->reg_pmu : info->reg_base;
+
+	/* get basic quadrupel of mux registers and the correct reg inside */
+	mux_type = bank->iomux[iomux_num].type;
+	reg += bank->iomux[iomux_num].offset;
+
+	dev_dbg(info->pctl_dev.dev, "setting func of GPIO%d-%d to %d\n",
+		 bank->bank_num, pin, mux);
+
+	if (mux_type & IOMUX_WIDTH_4BIT) {
+		if ((pin % 8) >= 4)
+			reg += 0x4;
+		bit = (pin % 4) * 4;
+		mask = 0xf;
+	} else if (mux_type & IOMUX_WIDTH_3BIT) {
+		if ((pin % 8) >= 5)
+			reg += 0x4;
+		bit = (pin % 8 % 5) * 3;
+		mask = 0x7;
+	} else {
+		bit = (pin % 8) * 2;
+		mask = 0x3;
+	}
+
+	if (bank->route_mask & BIT(pin)) {
+		if (rockchip_get_mux_route(bank, pin, mux, &route_location,
+					   &route_reg, &route_val)) {
+			void __iomem  *route = reg;
+
+			/* handle special locations */
+			switch (route_location) {
+			case ROCKCHIP_ROUTE_PMU:
+				route = info->reg_pmu;
+				break;
+			case ROCKCHIP_ROUTE_GRF:
+				route = info->reg_base;
+				break;
+			}
 
-	/* get basic quadruple of mux registers and the correct reg inside */
-	reg += bank->bank_num * 0x10;
-	reg += (pin / 8) * 4;
-	bit = (pin % 8) * 2;
+			writel(route_val, route + route_reg);
+		}
+	}
 
 	data = 3 << (bit + 16);
 	data |= (mux & 3) << bit;
@@ -373,7 +558,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
 	struct rockchip_pin_ctrl *ctrl;
 	struct rockchip_pin_bank *bank;
 	char *name;
-	int i;
+	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;
@@ -395,11 +580,91 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
 		}
 	}
 
+	grf_offs = ctrl->grf_mux_offset;
+	pmu_offs = ctrl->pmu_mux_offset;
+	drv_pmu_offs = ctrl->pmu_drv_offset;
+	drv_grf_offs = ctrl->grf_drv_offset;
 	bank = ctrl->pin_banks;
 	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		int bank_pins = 0;
+
 		bank->drvdata = d;
 		bank->pin_base = ctrl->nr_pins;
 		ctrl->nr_pins += bank->nr_pins;
+
+		/* calculate iomux and drv offsets */
+		for (j = 0; j < 4; j++) {
+			struct rockchip_iomux *iom = &bank->iomux[j];
+			struct rockchip_drv *drv = &bank->drv[j];
+			int inc;
+
+			if (bank_pins >= bank->nr_pins)
+				break;
+
+			/* preset iomux offset value, set new start value */
+			if (iom->offset >= 0) {
+				if (iom->type & IOMUX_SOURCE_PMU)
+					pmu_offs = iom->offset;
+				else
+					grf_offs = iom->offset;
+			} else { /* set current iomux offset */
+				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+							pmu_offs : grf_offs;
+			}
+
+			/* preset drv offset value, set new start value */
+			if (drv->offset >= 0) {
+				if (iom->type & IOMUX_SOURCE_PMU)
+					drv_pmu_offs = drv->offset;
+				else
+					drv_grf_offs = drv->offset;
+			} else { /* set current drv offset */
+				drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+						drv_pmu_offs : drv_grf_offs;
+			}
+
+			dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
+				i, j, iom->offset, drv->offset);
+
+			/*
+			 * Increase offset according to iomux width.
+			 * 4bit iomux'es are spread over two registers.
+			 */
+			inc = (iom->type & (IOMUX_WIDTH_4BIT |
+					    IOMUX_WIDTH_3BIT |
+					    IOMUX_WIDTH_2BIT)) ? 8 : 4;
+			if (iom->type & IOMUX_SOURCE_PMU)
+				pmu_offs += inc;
+			else
+				grf_offs += inc;
+
+			/*
+			 * Increase offset according to drv width.
+			 * 3bit drive-strenth'es are spread over two registers.
+			 */
+			if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
+			    (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
+				inc = 8;
+			else
+				inc = 4;
+
+			if (iom->type & IOMUX_SOURCE_PMU)
+				drv_pmu_offs += inc;
+			else
+				drv_grf_offs += inc;
+
+			bank_pins += 8;
+		}
+
+		/* calculate the per-bank route_mask */
+		for (j = 0; j < ctrl->niomux_routes; j++) {
+			int pin = 0;
+
+			if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
+				pin = ctrl->iomux_routes[j].pin;
+				bank->route_mask |= BIT(pin);
+			}
+		}
 	}
 
 	return ctrl;
@@ -498,7 +763,7 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
 };
 
 static struct rockchip_pin_bank rk3188_pin_banks[] = {
-	PIN_BANK(0, 32, "gpio0"),
+	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
 	PIN_BANK(1, 32, "gpio1"),
 	PIN_BANK(2, 32, "gpio2"),
 	PIN_BANK(3, 32, "gpio3"),
@@ -509,6 +774,8 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
 	.nr_banks	= ARRAY_SIZE(rk3188_pin_banks),
 	.type		= RK3188,
 	.grf_mux_offset	= 0x60,
+	.iomux_routes	= rk3188_mux_route_data,
+	.niomux_routes	= ARRAY_SIZE(rk3188_mux_route_data),
 	.pull_calc_reg	= rk3188_calc_pull_reg_and_bit,
 };
 
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 4/5] pinctrl: Rockchip: implement drive strength setting
  2021-06-08 14:05 [PATCH 0/5] RK3568 pinctrl Sascha Hauer
                   ` (2 preceding siblings ...)
  2021-06-08 14:05 ` [PATCH 3/5] pinctrl: Rockchip: Update from Linux Sascha Hauer
@ 2021-06-08 14:05 ` Sascha Hauer
  2021-06-09  8:13   ` Ahmad Fatoum
  2021-06-08 14:05 ` [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support Sascha Hauer
  4 siblings, 1 reply; 11+ messages in thread
From: Sascha Hauer @ 2021-06-08 14:05 UTC (permalink / raw)
  To: Barebox List

Newer SoCs support a drive strength setting per pin. This patch adds
support for it. Currently a no-op as no currently supported SoC in the
driver has support for this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/pinctrl/pinctrl-rockchip.c | 126 ++++++++++++++++++++++++++++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 4b69d0d069..3bdae5c229 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -186,6 +186,8 @@ struct rockchip_pin_ctrl {
 	u32				niomux_routes;
 	void	(*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
 				 void __iomem **reg, u8 *bit);
+	void	(*drv_calc_reg)(struct rockchip_pin_bank *bank,
+				    int pin_num, void __iomem **reg, u8 *bit);
 };
 
 struct rockchip_pinctrl {
@@ -468,12 +470,129 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
 	return 0;
 }
 
+static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
+	{ 2, 4, 8, 12, -1, -1, -1, -1 },
+	{ 3, 6, 9, 12, -1, -1, -1, -1 },
+	{ 5, 10, 15, 20, -1, -1, -1, -1 },
+	{ 4, 6, 8, 10, 12, 14, 16, 18 },
+	{ 4, 7, 10, 13, 16, 19, 22, 26 }
+};
+
+#define RK3288_DRV_BITS_PER_PIN		2
+#define RK3399_DRV_3BITS_PER_PIN	3
+
+static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+				     int pin_num, int strength)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+	struct rockchip_pin_ctrl *ctrl = info->ctrl;
+	int ret, i;
+	void __iomem *reg;
+	u32 data, rmask, rmask_bits, temp, val;
+	u8 bit;
+	int drv_type = bank->drv[pin_num / 8].drv_type;
+
+	if (!ctrl->drv_calc_reg)
+		return -ENOTSUPP;
+
+	dev_dbg(info->pctl_dev.dev, "setting drive of GPIO%d-%d to %d\n",
+		bank->bank_num, pin_num, strength);
+
+	ctrl->drv_calc_reg(bank, pin_num, &reg, &bit);
+
+	ret = -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
+		if (rockchip_perpin_drv_list[drv_type][i] == strength) {
+			ret = i;
+			break;
+		} else if (rockchip_perpin_drv_list[drv_type][i] < 0) {
+			ret = rockchip_perpin_drv_list[drv_type][i];
+			break;
+		}
+	}
+
+	if (ret < 0) {
+		dev_err(info->pctl_dev.dev, "unsupported driver strength %d\n",
+			strength);
+		return ret;
+	}
+
+	switch (drv_type) {
+	case DRV_TYPE_IO_1V8_3V0_AUTO:
+	case DRV_TYPE_IO_3V3_ONLY:
+		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
+		switch (bit) {
+		case 0 ... 12:
+			/* regular case, nothing to do */
+			break;
+		case 15:
+			/*
+			 * drive-strength offset is special, as it is spread
+			 * over 2 registers, the bit data[15] contains bit 0
+			 * of the value while temp[1:0] contains bits 2 and 1
+			 */
+			data = (ret & 0x1) << 15;
+			temp = (ret >> 0x1) & 0x3;
+
+			rmask = BIT(15) | BIT(31);
+			data |= BIT(31);
+
+			val = readl(reg);
+			val &= ~rmask;
+			val |= data & rmask;
+			writel(val, reg);
+
+			rmask = 0x3 | (0x3 << 16);
+			temp |= (0x3 << 16);
+			reg += 0x4;
+
+			val = readl(reg);
+			val &= ~rmask;
+			val |= temp & rmask;
+			writel(val, reg);
+
+			return ret;
+		case 18 ... 21:
+			/* setting fully enclosed in the second register */
+			reg += 4;
+			bit -= 16;
+			break;
+		default:
+			dev_err(info->pctl_dev.dev, "unsupported bit: %d for pinctrl drive type: %d\n",
+				bit, drv_type);
+			return -EINVAL;
+		}
+		break;
+	case DRV_TYPE_IO_DEFAULT:
+	case DRV_TYPE_IO_1V8_OR_3V0:
+	case DRV_TYPE_IO_1V8_ONLY:
+		rmask_bits = RK3288_DRV_BITS_PER_PIN;
+		break;
+	default:
+		dev_err(info->pctl_dev.dev, "unsupported pinctrl drive type: %d\n",
+			drv_type);
+		return -EINVAL;
+	}
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << rmask_bits) - 1) << (bit + 16);
+	rmask = data | (data >> 16);
+	data |= (ret << bit);
+
+	val = readl(reg);
+	val &= ~rmask;
+	val |= data & rmask;
+	writel(val, reg);
+
+	return ret;
+}
+
 static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
 				      struct device_node *np)
 {
 	struct rockchip_pinctrl *info = to_rockchip_pinctrl(pdev);
 	const __be32 *list;
-	int i, size;
+	int i, size, ret;
 	int bank_num, pin_num, func;
 
 	/*
@@ -492,6 +611,7 @@ static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
 		const __be32 *phandle;
 		struct device_node *np_config;
 		struct rockchip_pin_bank *bank;
+		u32 drive_strength;
 
 		bank_num = be32_to_cpu(*list++);
 		pin_num = be32_to_cpu(*list++);
@@ -506,6 +626,10 @@ static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
 		rockchip_pinctrl_set_func(bank, pin_num, func);
 		rockchip_pinctrl_set_pull(bank, pin_num,
 					  parse_bias_config(np_config));
+
+		ret = of_property_read_u32(np_config, "drive-strength", &drive_strength);
+		if (!ret)
+			rockchip_set_drive_perpin(bank, pin_num, drive_strength);
 	}
 
 	return 0;
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support
  2021-06-08 14:05 [PATCH 0/5] RK3568 pinctrl Sascha Hauer
                   ` (3 preceding siblings ...)
  2021-06-08 14:05 ` [PATCH 4/5] pinctrl: Rockchip: implement drive strength setting Sascha Hauer
@ 2021-06-08 14:05 ` Sascha Hauer
  2021-06-09  8:01   ` Ahmad Fatoum
  2021-06-09  8:11   ` Ahmad Fatoum
  4 siblings, 2 replies; 11+ messages in thread
From: Sascha Hauer @ 2021-06-08 14:05 UTC (permalink / raw)
  To: Barebox List

This adds support for the RK3568 SoC to the Rockchip pinctrl driver.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/pinctrl/pinctrl-rockchip.c | 354 ++++++++++++++++++++++++++++-
 1 file changed, 347 insertions(+), 7 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 3bdae5c229..cee496a85a 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -37,6 +37,7 @@ enum rockchip_pinctrl_type {
 	RK2928,
 	RK3066B,
 	RK3188,
+	RK3568,
 };
 
 enum rockchip_pin_bank_type {
@@ -44,6 +45,13 @@ enum rockchip_pin_bank_type {
 	RK3188_BANK0,
 };
 
+/**
+ * Generate a bitmask for setting a value (v) with a write mask bit in hiword
+ * register 31:16 area.
+ */
+#define WRITE_MASK_VAL(h, l, v) \
+	(GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
+
 /*
  * Encode variants of iomux registers into a type variable
  */
@@ -78,6 +86,15 @@ enum rockchip_pin_drv_type {
 	DRV_TYPE_MAX
 };
 
+/*
+ * enum type index corresponding to rockchip_pull_list arrays index.
+ */
+enum rockchip_pin_pull_type {
+	PULL_TYPE_IO_DEFAULT = 0,
+	PULL_TYPE_IO_1V8_ONLY,
+	PULL_TYPE_MAX
+};
+
 /**
  * struct rockchip_drv
  * @drv_type: drive strength variant using rockchip_perpin_drv_type
@@ -211,6 +228,110 @@ enum {
 	RK_GPIO_EXT_PORT	= 0x50,
 };
 
+/* GPIO registers */
+enum {
+	RK_GPIOV2_DR_L	= 0x00,
+	RK_GPIOV2_DR_H	= 0x04,
+	RK_GPIOV2_DDR_L	= 0x08,
+	RK_GPIOV2_DDR_H	= 0x0c,
+};
+
+static struct rockchip_pin_bank *gc_to_rockchip_pinctrl(struct gpio_chip *gc)
+{
+	struct bgpio_chip *bgc = to_bgpio_chip(gc);
+
+	return container_of(bgc, struct rockchip_pin_bank, bgpio_chip);
+}
+
+static int rockchip_gpiov2_direction_input(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+	u32 mask;
+
+	mask = 1 << (16 + (gpio % 16));
+
+	if (gpio < 16)
+		writel(mask, bank->reg_base + RK_GPIOV2_DDR_L);
+	else
+		writel(mask, bank->reg_base + RK_GPIOV2_DDR_H);
+
+	return 0;
+}
+
+static int rockchip_gpiov2_get_direction(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+	u32 r;
+
+	if (gpio < 16)
+		r = readl(bank->reg_base + RK_GPIOV2_DDR_L);
+	else
+		r = readl(bank->reg_base + RK_GPIOV2_DDR_H);
+
+	return r & BIT(gpio % 16) ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
+}
+
+static void rockchip_gpiov2_set_value(struct gpio_chip *gc, unsigned int gpio,
+				      int val)
+{
+	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+	u32 mask, vval = 0;
+
+	mask = 1 << (16 + (gpio % 16));
+	if (val)
+		vval = 1 << (gpio % 16);
+
+	if (gpio < 16)
+		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
+	else
+		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
+}
+
+static int rockchip_gpiov2_direction_output(struct gpio_chip *gc,
+					    unsigned int gpio, int val)
+{
+	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+	u32 mask, out, vval = 0;
+
+	mask = 1 << (16 + (gpio % 16));
+	out = 1 << (gpio % 16);
+	if (val)
+		vval = 1 << (gpio % 16);
+
+	if (gpio < 16) {
+		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
+		writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_L);
+	} else {
+		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
+		writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_H);
+	}
+
+	return 0;
+}
+
+static int rockchip_gpiov2_get_value(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+	u32 mask, r;
+
+	mask = 1 << (gpio % 16);
+
+	if (gpio < 16)
+		r = readl(bank->reg_base + RK_GPIOV2_DR_L);
+	else
+		r = readl(bank->reg_base + RK_GPIOV2_DR_L);
+
+	return r & mask ? 1 : 0;
+}
+
+static struct gpio_ops rockchip_gpio_ops = {
+	.direction_input = rockchip_gpiov2_direction_input,
+	.direction_output = rockchip_gpiov2_direction_output,
+	.get = rockchip_gpiov2_get_value,
+	.set = rockchip_gpiov2_set_value,
+	.get_direction = rockchip_gpiov2_get_direction,
+};
+
 static int rockchip_gpiolib_register(struct device_d *dev,
 				     struct rockchip_pinctrl *info)
 {
@@ -221,6 +342,8 @@ static int rockchip_gpiolib_register(struct device_d *dev,
 	int i;
 
 	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+		struct gpio_chip *gpio = &bank->bgpio_chip.gc;
+
 		if (!bank->valid) {
 			dev_warn(dev, "bank %s is not valid\n", bank->name);
 			continue;
@@ -228,12 +351,24 @@ static int rockchip_gpiolib_register(struct device_d *dev,
 
 		reg_base = bank->reg_base;
 
-		ret = bgpio_init(&bank->bgpio_chip, dev, 4,
-				 reg_base + RK_GPIO_EXT_PORT,
-				 reg_base + RK_GPIO_SWPORT_DR, NULL,
-				 reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
-		if (ret)
-			goto fail;
+		if (ctrl->type == RK3568) {
+			gpio->ngpio = 32;
+			gpio->dev = dev;
+			gpio->ops = &rockchip_gpio_ops;
+			gpio->base = of_alias_get_id(bank->of_node, "gpio");
+			if (gpio->base < 0)
+				return -EINVAL;
+			gpio->base *= 32;
+		} else {
+			ret = bgpio_init(&bank->bgpio_chip, dev, 4,
+					 reg_base + RK_GPIO_EXT_PORT,
+					 reg_base + RK_GPIO_SWPORT_DR, NULL,
+					 reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
+			if (ret)
+				goto fail;
+		}
+
+		bank->bgpio_chip.gc.dev = of_find_device_by_node(bank->of_node);
 
 		bank->bgpio_chip.gc.ngpio = bank->nr_pins;
 		ret = gpiochip_add(&bank->bgpio_chip.gc);
@@ -340,6 +475,63 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
 	}
 }
 
+#define RK3568_PULL_PMU_OFFSET		0x20
+#define RK3568_PULL_GRF_OFFSET		0x80
+#define RK3568_PULL_BITS_PER_PIN	2
+#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, void __iomem **reg,
+					 u8 *bit)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+
+	if (bank->bank_num == 0) {
+		*reg = info->reg_pmu + RK3568_PULL_PMU_OFFSET;
+		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
+		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
+
+		*bit = pin_num % RK3568_PULL_PINS_PER_REG;
+		*bit *= RK3568_PULL_BITS_PER_PIN;
+	} else {
+		*reg = info->reg_base + RK3568_PULL_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
+		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
+
+		*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
+		*bit *= RK3568_PULL_BITS_PER_PIN;
+	}
+}
+
+#define RK3568_DRV_PMU_OFFSET		0x70
+#define RK3568_DRV_GRF_OFFSET		0x200
+#define RK3568_DRV_BITS_PER_PIN		8
+#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, void __iomem **reg, u8 *bit)
+{
+	struct rockchip_pinctrl *info = bank->drvdata;
+
+	/* The first 32 pins of the first bank are located in PMU */
+	if (bank->bank_num == 0) {
+		*reg = info->reg_pmu + RK3568_DRV_PMU_OFFSET;
+		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
+
+		*bit = pin_num % RK3568_DRV_PINS_PER_REG;
+		*bit *= RK3568_DRV_BITS_PER_PIN;
+	} else {
+		*reg = info->reg_base + RK3568_DRV_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
+		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
+
+		*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
+		*bit *= RK3568_DRV_BITS_PER_PIN;
+	}
+}
+
 static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
 	RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
 	RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
@@ -458,6 +650,7 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
 		writel(data, reg);
 		break;
 	case RK3188:
+	case RK3568:
 		data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
 		data |= pull << bit;
 		writel(data, reg);
@@ -499,6 +692,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
 		bank->bank_num, pin_num, strength);
 
 	ctrl->drv_calc_reg(bank, pin_num, &reg, &bit);
+	if (ctrl->type == RK3568) {
+		rmask_bits = RK3568_DRV_BITS_PER_PIN;
+		ret = (1 << (strength + 1)) - 1;
+		goto config;
+	}
 
 	ret = -EINVAL;
 	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
@@ -574,6 +772,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
 		return -EINVAL;
 	}
 
+config:
 	/* enable the write to the equivalent lower bits */
 	data = ((1 << rmask_bits) - 1) << (bit + 16);
 	rmask = data | (data >> 16);
@@ -800,6 +999,8 @@ static int rockchip_pinctrl_probe(struct device_d *dev)
 	struct rockchip_pin_ctrl *ctrl;
 	int ret;
 
+	of_platform_populate(dev->device_node, NULL, NULL);
+
 	info = xzalloc(sizeof(struct rockchip_pinctrl));
 
 	ctrl = rockchip_pinctrl_get_soc_data(info, dev);
@@ -903,6 +1104,140 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
 	.pull_calc_reg	= rk3188_calc_pull_reg_and_bit,
 };
 
+static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+	RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */
+	RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */
+	RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */
+	RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */
+	RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */
+	RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */
+	RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */
+	RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */
+	RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */
+	RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */
+	RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */
+	RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */
+	RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
+	RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */
+	RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */
+	RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */
+	RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */
+	RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */
+	RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */
+	RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */
+	RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */
+	RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */
+	RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
+	RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
+	RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
+	RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */
+	RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */
+	RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */
+	RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */
+	RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */
+	RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */
+	RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */
+	RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */
+	RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */
+	RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */
+	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(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */
+	RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */
+	RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */
+	RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO 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 */
+	RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
+	RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */
+	RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */
+	RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */
+	RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */
+	RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */
+	RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
+	RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */
+	RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */
+};
+
+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,
+					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT),
+};
+
+static struct rockchip_pin_ctrl rk3568_pin_ctrl = {
+	.pin_banks		= rk3568_pin_banks,
+	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
+	.label			= "RK3568-GPIO",
+	.type			= RK3568,
+	.grf_mux_offset		= 0x0,
+	.pmu_mux_offset		= 0x0,
+	.grf_drv_offset		= 0x0200,
+	.pmu_drv_offset		= 0x0070,
+	.iomux_routes		= rk3568_mux_route_data,
+	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
+	.pull_calc_reg		= rk3568_calc_pull_reg_and_bit,
+	.drv_calc_reg		= rk3568_calc_drv_reg_and_bit,
+};
+
 static struct of_device_id rockchip_pinctrl_dt_match[] = {
 	{
 		.compatible = "rockchip,rk2928-pinctrl",
@@ -919,7 +1254,12 @@ static struct of_device_id rockchip_pinctrl_dt_match[] = {
 	{
 		.compatible = "rockchip,rk3188-pinctrl",
 		.data = &rk3188_pin_ctrl,
-	}, {
+	},
+	{
+		.compatible = "rockchip,rk3568-pinctrl",
+		.data = &rk3568_pin_ctrl
+	},
+	{
 		/* sentinel */
 	}
 };
-- 
2.29.2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support
  2021-06-08 14:05 ` [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support Sascha Hauer
@ 2021-06-09  8:01   ` Ahmad Fatoum
  2021-06-09  9:41     ` Sascha Hauer
  2021-06-09  8:11   ` Ahmad Fatoum
  1 sibling, 1 reply; 11+ messages in thread
From: Ahmad Fatoum @ 2021-06-09  8:01 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List

Hello Sascha,

On 08.06.21 16:05, Sascha Hauer wrote:
> This adds support for the RK3568 SoC to the Rockchip pinctrl driver.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/pinctrl/pinctrl-rockchip.c | 354 ++++++++++++++++++++++++++++-
>  1 file changed, 347 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index 3bdae5c229..cee496a85a 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -37,6 +37,7 @@ enum rockchip_pinctrl_type {
>  	RK2928,
>  	RK3066B,
>  	RK3188,
> +	RK3568,
>  };
>  
>  enum rockchip_pin_bank_type {
> @@ -44,6 +45,13 @@ enum rockchip_pin_bank_type {
>  	RK3188_BANK0,
>  };
>  
> +/**
> + * Generate a bitmask for setting a value (v) with a write mask bit in hiword
> + * register 31:16 area.
> + */
> +#define WRITE_MASK_VAL(h, l, v) \
> +	(GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
> +
>  /*
>   * Encode variants of iomux registers into a type variable
>   */
> @@ -78,6 +86,15 @@ enum rockchip_pin_drv_type {
>  	DRV_TYPE_MAX
>  };
>  
> +/*
> + * enum type index corresponding to rockchip_pull_list arrays index.
> + */
> +enum rockchip_pin_pull_type {
> +	PULL_TYPE_IO_DEFAULT = 0,
> +	PULL_TYPE_IO_1V8_ONLY,
> +	PULL_TYPE_MAX
> +};
> +
>  /**
>   * struct rockchip_drv
>   * @drv_type: drive strength variant using rockchip_perpin_drv_type
> @@ -211,6 +228,110 @@ enum {
>  	RK_GPIO_EXT_PORT	= 0x50,
>  };
>  
> +/* GPIO registers */
> +enum {
> +	RK_GPIOV2_DR_L	= 0x00,
> +	RK_GPIOV2_DR_H	= 0x04,
> +	RK_GPIOV2_DDR_L	= 0x08,
> +	RK_GPIOV2_DDR_H	= 0x0c,
> +};
> +
> +static struct rockchip_pin_bank *gc_to_rockchip_pinctrl(struct gpio_chip *gc)
> +{
> +	struct bgpio_chip *bgc = to_bgpio_chip(gc);
> +
> +	return container_of(bgc, struct rockchip_pin_bank, bgpio_chip);
> +}
> +
> +static int rockchip_gpiov2_direction_input(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask;
> +
> +	mask = 1 << (16 + (gpio % 16));
> +
> +	if (gpio < 16)
> +		writel(mask, bank->reg_base + RK_GPIOV2_DDR_L);
> +	else
> +		writel(mask, bank->reg_base + RK_GPIOV2_DDR_H);
> +
> +	return 0;
> +}
> +
> +static int rockchip_gpiov2_get_direction(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 r;
> +
> +	if (gpio < 16)
> +		r = readl(bank->reg_base + RK_GPIOV2_DDR_L);
> +	else
> +		r = readl(bank->reg_base + RK_GPIOV2_DDR_H);
> +
> +	return r & BIT(gpio % 16) ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
> +}
> +
> +static void rockchip_gpiov2_set_value(struct gpio_chip *gc, unsigned int gpio,
> +				      int val)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask, vval = 0;
> +
> +	mask = 1 << (16 + (gpio % 16));
> +	if (val)
> +		vval = 1 << (gpio % 16);
> +
> +	if (gpio < 16)
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
> +	else
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
> +}
> +
> +static int rockchip_gpiov2_direction_output(struct gpio_chip *gc,
> +					    unsigned int gpio, int val)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask, out, vval = 0;
> +
> +	mask = 1 << (16 + (gpio % 16));
> +	out = 1 << (gpio % 16);
> +	if (val)
> +		vval = 1 << (gpio % 16);
> +
> +	if (gpio < 16) {
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
> +		writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_L);
> +	} else {
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
> +		writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_H);
> +	}
> +
> +	return 0;
> +}
> +
> +static int rockchip_gpiov2_get_value(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask, r;
> +
> +	mask = 1 << (gpio % 16);
> +
> +	if (gpio < 16)
> +		r = readl(bank->reg_base + RK_GPIOV2_DR_L);
> +	else
> +		r = readl(bank->reg_base + RK_GPIOV2_DR_L);
> +
> +	return r & mask ? 1 : 0;
> +}
> +
> +static struct gpio_ops rockchip_gpio_ops = {
> +	.direction_input = rockchip_gpiov2_direction_input,
> +	.direction_output = rockchip_gpiov2_direction_output,
> +	.get = rockchip_gpiov2_get_value,
> +	.set = rockchip_gpiov2_set_value,
> +	.get_direction = rockchip_gpiov2_get_direction,
> +};
> +
>  static int rockchip_gpiolib_register(struct device_d *dev,
>  				     struct rockchip_pinctrl *info)
>  {
> @@ -221,6 +342,8 @@ static int rockchip_gpiolib_register(struct device_d *dev,
>  	int i;
>  
>  	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
> +		struct gpio_chip *gpio = &bank->bgpio_chip.gc;
> +
>  		if (!bank->valid) {
>  			dev_warn(dev, "bank %s is not valid\n", bank->name);
>  			continue;
> @@ -228,12 +351,24 @@ static int rockchip_gpiolib_register(struct device_d *dev,
>  
>  		reg_base = bank->reg_base;
>  
> -		ret = bgpio_init(&bank->bgpio_chip, dev, 4,
> -				 reg_base + RK_GPIO_EXT_PORT,
> -				 reg_base + RK_GPIO_SWPORT_DR, NULL,
> -				 reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
> -		if (ret)
> -			goto fail;
> +		if (ctrl->type == RK3568) {
> +			gpio->ngpio = 32;
> +			gpio->dev = dev;
> +			gpio->ops = &rockchip_gpio_ops;
> +			gpio->base = of_alias_get_id(bank->of_node, "gpio");
> +			if (gpio->base < 0)
> +				return -EINVAL;
> +			gpio->base *= 32;
> +		} else {
> +			ret = bgpio_init(&bank->bgpio_chip, dev, 4,
> +					 reg_base + RK_GPIO_EXT_PORT,
> +					 reg_base + RK_GPIO_SWPORT_DR, NULL,
> +					 reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
> +			if (ret)
> +				goto fail;
> +		}
> +
> +		bank->bgpio_chip.gc.dev = of_find_device_by_node(bank->of_node);
>  
>  		bank->bgpio_chip.gc.ngpio = bank->nr_pins;
>  		ret = gpiochip_add(&bank->bgpio_chip.gc);
> @@ -340,6 +475,63 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
>  	}
>  }
>  
> +#define RK3568_PULL_PMU_OFFSET		0x20
> +#define RK3568_PULL_GRF_OFFSET		0x80
> +#define RK3568_PULL_BITS_PER_PIN	2
> +#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, void __iomem **reg,
> +					 u8 *bit)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +
> +	if (bank->bank_num == 0) {
> +		*reg = info->reg_pmu + RK3568_PULL_PMU_OFFSET;
> +		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
> +		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> +
> +		*bit = pin_num % RK3568_PULL_PINS_PER_REG;
> +		*bit *= RK3568_PULL_BITS_PER_PIN;
> +	} else {
> +		*reg = info->reg_base + RK3568_PULL_GRF_OFFSET;
> +		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
> +		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> +
> +		*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
> +		*bit *= RK3568_PULL_BITS_PER_PIN;
> +	}
> +}
> +
> +#define RK3568_DRV_PMU_OFFSET		0x70
> +#define RK3568_DRV_GRF_OFFSET		0x200
> +#define RK3568_DRV_BITS_PER_PIN		8
> +#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, void __iomem **reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +
> +	/* The first 32 pins of the first bank are located in PMU */
> +	if (bank->bank_num == 0) {
> +		*reg = info->reg_pmu + RK3568_DRV_PMU_OFFSET;
> +		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> +
> +		*bit = pin_num % RK3568_DRV_PINS_PER_REG;
> +		*bit *= RK3568_DRV_BITS_PER_PIN;
> +	} else {
> +		*reg = info->reg_base + RK3568_DRV_GRF_OFFSET;
> +		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
> +		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> +
> +		*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
> +		*bit *= RK3568_DRV_BITS_PER_PIN;
> +	}
> +}
> +
>  static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
>  	RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
>  	RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
> @@ -458,6 +650,7 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
>  		writel(data, reg);
>  		break;
>  	case RK3188:
> +	case RK3568:
>  		data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
>  		data |= pull << bit;

Linux does this for pull (== ret):

 /*
  * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6,
  * where that pull up value becomes 3.
  */
 if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
         if (ret == 1)
                 ret = 3;
 }

Should we do this too?

>  		writel(data, reg);
> @@ -499,6 +692,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
>  		bank->bank_num, pin_num, strength);
>  
>  	ctrl->drv_calc_reg(bank, pin_num, &reg, &bit);
> +	if (ctrl->type == RK3568) {
> +		rmask_bits = RK3568_DRV_BITS_PER_PIN;
> +		ret = (1 << (strength + 1)) - 1;
> +		goto config;
> +	}
>  
>  	ret = -EINVAL;
>  	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
> @@ -574,6 +772,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
>  		return -EINVAL;
>  	}
>  
> +config:
>  	/* enable the write to the equivalent lower bits */
>  	data = ((1 << rmask_bits) - 1) << (bit + 16);
>  	rmask = data | (data >> 16);
> @@ -800,6 +999,8 @@ static int rockchip_pinctrl_probe(struct device_d *dev)
>  	struct rockchip_pin_ctrl *ctrl;
>  	int ret;
>  
> +	of_platform_populate(dev->device_node, NULL, NULL);
> +
>  	info = xzalloc(sizeof(struct rockchip_pinctrl));
>  
>  	ctrl = rockchip_pinctrl_get_soc_data(info, dev);
> @@ -903,6 +1104,140 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
>  	.pull_calc_reg	= rk3188_calc_pull_reg_and_bit,
>  };
>  
> +static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
> +	RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */
> +	RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */
> +	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(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */
> +	RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO 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 */
> +	RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */
> +	RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */
> +	RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */
> +	RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */
> +};
> +
> +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,
> +					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> +					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +};
> +
> +static struct rockchip_pin_ctrl rk3568_pin_ctrl = {
> +	.pin_banks		= rk3568_pin_banks,
> +	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
> +	.label			= "RK3568-GPIO",
> +	.type			= RK3568,
> +	.grf_mux_offset		= 0x0,
> +	.pmu_mux_offset		= 0x0,
> +	.grf_drv_offset		= 0x0200,
> +	.pmu_drv_offset		= 0x0070,
> +	.iomux_routes		= rk3568_mux_route_data,
> +	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
> +	.pull_calc_reg		= rk3568_calc_pull_reg_and_bit,
> +	.drv_calc_reg		= rk3568_calc_drv_reg_and_bit,
> +};
> +
>  static struct of_device_id rockchip_pinctrl_dt_match[] = {
>  	{
>  		.compatible = "rockchip,rk2928-pinctrl",
> @@ -919,7 +1254,12 @@ static struct of_device_id rockchip_pinctrl_dt_match[] = {
>  	{
>  		.compatible = "rockchip,rk3188-pinctrl",
>  		.data = &rk3188_pin_ctrl,
> -	}, {
> +	},
> +	{
> +		.compatible = "rockchip,rk3568-pinctrl",
> +		.data = &rk3568_pin_ctrl
> +	},
> +	{
>  		/* sentinel */
>  	}
>  };
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support
  2021-06-08 14:05 ` [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support Sascha Hauer
  2021-06-09  8:01   ` Ahmad Fatoum
@ 2021-06-09  8:11   ` Ahmad Fatoum
  2021-06-09  9:45     ` Sascha Hauer
  1 sibling, 1 reply; 11+ messages in thread
From: Ahmad Fatoum @ 2021-06-09  8:11 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List



On 08.06.21 16:05, Sascha Hauer wrote:
> This adds support for the RK3568 SoC to the Rockchip pinctrl driver.

Unlike Linux, barebox doesn't propagate pinctrl probe deferrment from the
probe of other drivers. This driver here is registered at console_initcall
level, which may be too late to apply pin config for console drivers.

I think the driver should be moved to core_platform_driver.

> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/pinctrl/pinctrl-rockchip.c | 354 ++++++++++++++++++++++++++++-
>  1 file changed, 347 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index 3bdae5c229..cee496a85a 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -37,6 +37,7 @@ enum rockchip_pinctrl_type {
>  	RK2928,
>  	RK3066B,
>  	RK3188,
> +	RK3568,
>  };
>  
>  enum rockchip_pin_bank_type {
> @@ -44,6 +45,13 @@ enum rockchip_pin_bank_type {
>  	RK3188_BANK0,
>  };
>  
> +/**
> + * Generate a bitmask for setting a value (v) with a write mask bit in hiword
> + * register 31:16 area.
> + */
> +#define WRITE_MASK_VAL(h, l, v) \
> +	(GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
> +
>  /*
>   * Encode variants of iomux registers into a type variable
>   */
> @@ -78,6 +86,15 @@ enum rockchip_pin_drv_type {
>  	DRV_TYPE_MAX
>  };
>  
> +/*
> + * enum type index corresponding to rockchip_pull_list arrays index.
> + */
> +enum rockchip_pin_pull_type {
> +	PULL_TYPE_IO_DEFAULT = 0,
> +	PULL_TYPE_IO_1V8_ONLY,
> +	PULL_TYPE_MAX
> +};
> +
>  /**
>   * struct rockchip_drv
>   * @drv_type: drive strength variant using rockchip_perpin_drv_type
> @@ -211,6 +228,110 @@ enum {
>  	RK_GPIO_EXT_PORT	= 0x50,
>  };
>  
> +/* GPIO registers */
> +enum {
> +	RK_GPIOV2_DR_L	= 0x00,
> +	RK_GPIOV2_DR_H	= 0x04,
> +	RK_GPIOV2_DDR_L	= 0x08,
> +	RK_GPIOV2_DDR_H	= 0x0c,
> +};
> +
> +static struct rockchip_pin_bank *gc_to_rockchip_pinctrl(struct gpio_chip *gc)
> +{
> +	struct bgpio_chip *bgc = to_bgpio_chip(gc);
> +
> +	return container_of(bgc, struct rockchip_pin_bank, bgpio_chip);
> +}
> +
> +static int rockchip_gpiov2_direction_input(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask;
> +
> +	mask = 1 << (16 + (gpio % 16));
> +
> +	if (gpio < 16)
> +		writel(mask, bank->reg_base + RK_GPIOV2_DDR_L);
> +	else
> +		writel(mask, bank->reg_base + RK_GPIOV2_DDR_H);
> +
> +	return 0;
> +}
> +
> +static int rockchip_gpiov2_get_direction(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 r;
> +
> +	if (gpio < 16)
> +		r = readl(bank->reg_base + RK_GPIOV2_DDR_L);
> +	else
> +		r = readl(bank->reg_base + RK_GPIOV2_DDR_H);
> +
> +	return r & BIT(gpio % 16) ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
> +}
> +
> +static void rockchip_gpiov2_set_value(struct gpio_chip *gc, unsigned int gpio,
> +				      int val)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask, vval = 0;
> +
> +	mask = 1 << (16 + (gpio % 16));
> +	if (val)
> +		vval = 1 << (gpio % 16);
> +
> +	if (gpio < 16)
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
> +	else
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
> +}
> +
> +static int rockchip_gpiov2_direction_output(struct gpio_chip *gc,
> +					    unsigned int gpio, int val)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask, out, vval = 0;
> +
> +	mask = 1 << (16 + (gpio % 16));
> +	out = 1 << (gpio % 16);
> +	if (val)
> +		vval = 1 << (gpio % 16);
> +
> +	if (gpio < 16) {
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
> +		writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_L);
> +	} else {
> +		writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
> +		writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_H);
> +	}
> +
> +	return 0;
> +}
> +
> +static int rockchip_gpiov2_get_value(struct gpio_chip *gc, unsigned int gpio)
> +{
> +	struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
> +	u32 mask, r;
> +
> +	mask = 1 << (gpio % 16);
> +
> +	if (gpio < 16)
> +		r = readl(bank->reg_base + RK_GPIOV2_DR_L);
> +	else
> +		r = readl(bank->reg_base + RK_GPIOV2_DR_L);
> +
> +	return r & mask ? 1 : 0;
> +}
> +
> +static struct gpio_ops rockchip_gpio_ops = {
> +	.direction_input = rockchip_gpiov2_direction_input,
> +	.direction_output = rockchip_gpiov2_direction_output,
> +	.get = rockchip_gpiov2_get_value,
> +	.set = rockchip_gpiov2_set_value,
> +	.get_direction = rockchip_gpiov2_get_direction,
> +};
> +
>  static int rockchip_gpiolib_register(struct device_d *dev,
>  				     struct rockchip_pinctrl *info)
>  {
> @@ -221,6 +342,8 @@ static int rockchip_gpiolib_register(struct device_d *dev,
>  	int i;
>  
>  	for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
> +		struct gpio_chip *gpio = &bank->bgpio_chip.gc;
> +
>  		if (!bank->valid) {
>  			dev_warn(dev, "bank %s is not valid\n", bank->name);
>  			continue;
> @@ -228,12 +351,24 @@ static int rockchip_gpiolib_register(struct device_d *dev,
>  
>  		reg_base = bank->reg_base;
>  
> -		ret = bgpio_init(&bank->bgpio_chip, dev, 4,
> -				 reg_base + RK_GPIO_EXT_PORT,
> -				 reg_base + RK_GPIO_SWPORT_DR, NULL,
> -				 reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
> -		if (ret)
> -			goto fail;
> +		if (ctrl->type == RK3568) {
> +			gpio->ngpio = 32;
> +			gpio->dev = dev;
> +			gpio->ops = &rockchip_gpio_ops;
> +			gpio->base = of_alias_get_id(bank->of_node, "gpio");
> +			if (gpio->base < 0)
> +				return -EINVAL;
> +			gpio->base *= 32;
> +		} else {
> +			ret = bgpio_init(&bank->bgpio_chip, dev, 4,
> +					 reg_base + RK_GPIO_EXT_PORT,
> +					 reg_base + RK_GPIO_SWPORT_DR, NULL,
> +					 reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
> +			if (ret)
> +				goto fail;
> +		}
> +
> +		bank->bgpio_chip.gc.dev = of_find_device_by_node(bank->of_node);
>  
>  		bank->bgpio_chip.gc.ngpio = bank->nr_pins;
>  		ret = gpiochip_add(&bank->bgpio_chip.gc);
> @@ -340,6 +475,63 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
>  	}
>  }
>  
> +#define RK3568_PULL_PMU_OFFSET		0x20
> +#define RK3568_PULL_GRF_OFFSET		0x80
> +#define RK3568_PULL_BITS_PER_PIN	2
> +#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, void __iomem **reg,
> +					 u8 *bit)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +
> +	if (bank->bank_num == 0) {
> +		*reg = info->reg_pmu + RK3568_PULL_PMU_OFFSET;
> +		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
> +		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> +
> +		*bit = pin_num % RK3568_PULL_PINS_PER_REG;
> +		*bit *= RK3568_PULL_BITS_PER_PIN;
> +	} else {
> +		*reg = info->reg_base + RK3568_PULL_GRF_OFFSET;
> +		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
> +		*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> +
> +		*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
> +		*bit *= RK3568_PULL_BITS_PER_PIN;
> +	}
> +}
> +
> +#define RK3568_DRV_PMU_OFFSET		0x70
> +#define RK3568_DRV_GRF_OFFSET		0x200
> +#define RK3568_DRV_BITS_PER_PIN		8
> +#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, void __iomem **reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +
> +	/* The first 32 pins of the first bank are located in PMU */
> +	if (bank->bank_num == 0) {
> +		*reg = info->reg_pmu + RK3568_DRV_PMU_OFFSET;
> +		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> +
> +		*bit = pin_num % RK3568_DRV_PINS_PER_REG;
> +		*bit *= RK3568_DRV_BITS_PER_PIN;
> +	} else {
> +		*reg = info->reg_base + RK3568_DRV_GRF_OFFSET;
> +		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
> +		*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> +
> +		*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
> +		*bit *= RK3568_DRV_BITS_PER_PIN;
> +	}
> +}
> +
>  static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
>  	RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
>  	RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
> @@ -458,6 +650,7 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
>  		writel(data, reg);
>  		break;
>  	case RK3188:
> +	case RK3568:
>  		data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
>  		data |= pull << bit;
>  		writel(data, reg);
> @@ -499,6 +692,11 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
>  		bank->bank_num, pin_num, strength);
>  
>  	ctrl->drv_calc_reg(bank, pin_num, &reg, &bit);
> +	if (ctrl->type == RK3568) {
> +		rmask_bits = RK3568_DRV_BITS_PER_PIN;
> +		ret = (1 << (strength + 1)) - 1;
> +		goto config;
> +	}
>  
>  	ret = -EINVAL;
>  	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
> @@ -574,6 +772,7 @@ static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
>  		return -EINVAL;
>  	}
>  
> +config:
>  	/* enable the write to the equivalent lower bits */
>  	data = ((1 << rmask_bits) - 1) << (bit + 16);
>  	rmask = data | (data >> 16);
> @@ -800,6 +999,8 @@ static int rockchip_pinctrl_probe(struct device_d *dev)
>  	struct rockchip_pin_ctrl *ctrl;
>  	int ret;
>  
> +	of_platform_populate(dev->device_node, NULL, NULL);
> +
>  	info = xzalloc(sizeof(struct rockchip_pinctrl));
>  
>  	ctrl = rockchip_pinctrl_get_soc_data(info, dev);
> @@ -903,6 +1104,140 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
>  	.pull_calc_reg	= rk3188_calc_pull_reg_and_bit,
>  };
>  
> +static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
> +	RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
> +	RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
> +	RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */
> +	RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */
> +	RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */
> +	RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */
> +	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(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */
> +	RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */
> +	RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO 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 */
> +	RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
> +	RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */
> +	RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */
> +	RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */
> +	RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */
> +	RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
> +	RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */
> +	RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */
> +};
> +
> +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,
> +					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> +					     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT),
> +};
> +
> +static struct rockchip_pin_ctrl rk3568_pin_ctrl = {
> +	.pin_banks		= rk3568_pin_banks,
> +	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
> +	.label			= "RK3568-GPIO",
> +	.type			= RK3568,
> +	.grf_mux_offset		= 0x0,
> +	.pmu_mux_offset		= 0x0,
> +	.grf_drv_offset		= 0x0200,
> +	.pmu_drv_offset		= 0x0070,
> +	.iomux_routes		= rk3568_mux_route_data,
> +	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
> +	.pull_calc_reg		= rk3568_calc_pull_reg_and_bit,
> +	.drv_calc_reg		= rk3568_calc_drv_reg_and_bit,
> +};
> +
>  static struct of_device_id rockchip_pinctrl_dt_match[] = {
>  	{
>  		.compatible = "rockchip,rk2928-pinctrl",
> @@ -919,7 +1254,12 @@ static struct of_device_id rockchip_pinctrl_dt_match[] = {
>  	{
>  		.compatible = "rockchip,rk3188-pinctrl",
>  		.data = &rk3188_pin_ctrl,
> -	}, {
> +	},
> +	{
> +		.compatible = "rockchip,rk3568-pinctrl",
> +		.data = &rk3568_pin_ctrl
> +	},
> +	{
>  		/* sentinel */
>  	}
>  };
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 4/5] pinctrl: Rockchip: implement drive strength setting
  2021-06-08 14:05 ` [PATCH 4/5] pinctrl: Rockchip: implement drive strength setting Sascha Hauer
@ 2021-06-09  8:13   ` Ahmad Fatoum
  0 siblings, 0 replies; 11+ messages in thread
From: Ahmad Fatoum @ 2021-06-09  8:13 UTC (permalink / raw)
  To: Sascha Hauer, Barebox List

On 08.06.21 16:05, Sascha Hauer wrote:
> Newer SoCs support a drive strength setting per pin. This patch adds
> support for it. Currently a no-op as no currently supported SoC in the
> driver has support for this.

Thanks. I've a rk3399 that should make use of this soon. :)

> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/pinctrl/pinctrl-rockchip.c | 126 ++++++++++++++++++++++++++++-
>  1 file changed, 125 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index 4b69d0d069..3bdae5c229 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -186,6 +186,8 @@ struct rockchip_pin_ctrl {
>  	u32				niomux_routes;
>  	void	(*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
>  				 void __iomem **reg, u8 *bit);
> +	void	(*drv_calc_reg)(struct rockchip_pin_bank *bank,
> +				    int pin_num, void __iomem **reg, u8 *bit);
>  };
>  
>  struct rockchip_pinctrl {
> @@ -468,12 +470,129 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
>  	return 0;
>  }
>  
> +static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
> +	{ 2, 4, 8, 12, -1, -1, -1, -1 },
> +	{ 3, 6, 9, 12, -1, -1, -1, -1 },
> +	{ 5, 10, 15, 20, -1, -1, -1, -1 },
> +	{ 4, 6, 8, 10, 12, 14, 16, 18 },
> +	{ 4, 7, 10, 13, 16, 19, 22, 26 }
> +};
> +
> +#define RK3288_DRV_BITS_PER_PIN		2
> +#define RK3399_DRV_3BITS_PER_PIN	3
> +
> +static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
> +				     int pin_num, int strength)
> +{
> +	struct rockchip_pinctrl *info = bank->drvdata;
> +	struct rockchip_pin_ctrl *ctrl = info->ctrl;
> +	int ret, i;
> +	void __iomem *reg;
> +	u32 data, rmask, rmask_bits, temp, val;
> +	u8 bit;
> +	int drv_type = bank->drv[pin_num / 8].drv_type;
> +
> +	if (!ctrl->drv_calc_reg)
> +		return -ENOTSUPP;
> +
> +	dev_dbg(info->pctl_dev.dev, "setting drive of GPIO%d-%d to %d\n",
> +		bank->bank_num, pin_num, strength);
> +
> +	ctrl->drv_calc_reg(bank, pin_num, &reg, &bit);
> +
> +	ret = -EINVAL;
> +	for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
> +		if (rockchip_perpin_drv_list[drv_type][i] == strength) {
> +			ret = i;
> +			break;
> +		} else if (rockchip_perpin_drv_list[drv_type][i] < 0) {
> +			ret = rockchip_perpin_drv_list[drv_type][i];
> +			break;
> +		}
> +	}
> +
> +	if (ret < 0) {
> +		dev_err(info->pctl_dev.dev, "unsupported driver strength %d\n",
> +			strength);
> +		return ret;
> +	}
> +
> +	switch (drv_type) {
> +	case DRV_TYPE_IO_1V8_3V0_AUTO:
> +	case DRV_TYPE_IO_3V3_ONLY:
> +		rmask_bits = RK3399_DRV_3BITS_PER_PIN;
> +		switch (bit) {
> +		case 0 ... 12:
> +			/* regular case, nothing to do */
> +			break;
> +		case 15:
> +			/*
> +			 * drive-strength offset is special, as it is spread
> +			 * over 2 registers, the bit data[15] contains bit 0
> +			 * of the value while temp[1:0] contains bits 2 and 1
> +			 */
> +			data = (ret & 0x1) << 15;
> +			temp = (ret >> 0x1) & 0x3;
> +
> +			rmask = BIT(15) | BIT(31);
> +			data |= BIT(31);
> +
> +			val = readl(reg);
> +			val &= ~rmask;
> +			val |= data & rmask;
> +			writel(val, reg);
> +
> +			rmask = 0x3 | (0x3 << 16);
> +			temp |= (0x3 << 16);
> +			reg += 0x4;
> +
> +			val = readl(reg);
> +			val &= ~rmask;
> +			val |= temp & rmask;
> +			writel(val, reg);
> +
> +			return ret;
> +		case 18 ... 21:
> +			/* setting fully enclosed in the second register */
> +			reg += 4;
> +			bit -= 16;
> +			break;
> +		default:
> +			dev_err(info->pctl_dev.dev, "unsupported bit: %d for pinctrl drive type: %d\n",
> +				bit, drv_type);
> +			return -EINVAL;
> +		}
> +		break;
> +	case DRV_TYPE_IO_DEFAULT:
> +	case DRV_TYPE_IO_1V8_OR_3V0:
> +	case DRV_TYPE_IO_1V8_ONLY:
> +		rmask_bits = RK3288_DRV_BITS_PER_PIN;
> +		break;
> +	default:
> +		dev_err(info->pctl_dev.dev, "unsupported pinctrl drive type: %d\n",
> +			drv_type);
> +		return -EINVAL;
> +	}
> +
> +	/* enable the write to the equivalent lower bits */
> +	data = ((1 << rmask_bits) - 1) << (bit + 16);
> +	rmask = data | (data >> 16);
> +	data |= (ret << bit);
> +
> +	val = readl(reg);
> +	val &= ~rmask;
> +	val |= data & rmask;
> +	writel(val, reg);
> +
> +	return ret;
> +}
> +
>  static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
>  				      struct device_node *np)
>  {
>  	struct rockchip_pinctrl *info = to_rockchip_pinctrl(pdev);
>  	const __be32 *list;
> -	int i, size;
> +	int i, size, ret;
>  	int bank_num, pin_num, func;
>  
>  	/*
> @@ -492,6 +611,7 @@ static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
>  		const __be32 *phandle;
>  		struct device_node *np_config;
>  		struct rockchip_pin_bank *bank;
> +		u32 drive_strength;
>  
>  		bank_num = be32_to_cpu(*list++);
>  		pin_num = be32_to_cpu(*list++);
> @@ -506,6 +626,10 @@ static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
>  		rockchip_pinctrl_set_func(bank, pin_num, func);
>  		rockchip_pinctrl_set_pull(bank, pin_num,
>  					  parse_bias_config(np_config));
> +
> +		ret = of_property_read_u32(np_config, "drive-strength", &drive_strength);
> +		if (!ret)
> +			rockchip_set_drive_perpin(bank, pin_num, drive_strength);
>  	}
>  
>  	return 0;
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support
  2021-06-09  8:01   ` Ahmad Fatoum
@ 2021-06-09  9:41     ` Sascha Hauer
  0 siblings, 0 replies; 11+ messages in thread
From: Sascha Hauer @ 2021-06-09  9:41 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

Hi Ahmad,

On Wed, Jun 09, 2021 at 10:01:12AM +0200, Ahmad Fatoum wrote:
> >  static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
> >  	RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
> >  	RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
> > @@ -458,6 +650,7 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
> >  		writel(data, reg);
> >  		break;
> >  	case RK3188:
> > +	case RK3568:
> >  		data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
> >  		data |= pull << bit;
> 
> Linux does this for pull (== ret):
> 
>  /*
>   * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6,
>   * where that pull up value becomes 3.
>   */
>  if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) {
>          if (ret == 1)
>                  ret = 3;
>  }
> 
> Should we do this too?
>

Yes. In our case this becomes:

	if (ctrl->type == RK3568 &&
	    bank->bank_num == 0 &&
	    pin_num >= 27 &&
	    pin_num <= 30 &&
	    pull == RK_BIAS_PULL_UP)
		pull = 3;
Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

* Re: [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support
  2021-06-09  8:11   ` Ahmad Fatoum
@ 2021-06-09  9:45     ` Sascha Hauer
  0 siblings, 0 replies; 11+ messages in thread
From: Sascha Hauer @ 2021-06-09  9:45 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: Barebox List

On Wed, Jun 09, 2021 at 10:11:46AM +0200, Ahmad Fatoum wrote:
> 
> 
> On 08.06.21 16:05, Sascha Hauer wrote:
> > This adds support for the RK3568 SoC to the Rockchip pinctrl driver.
> 
> Unlike Linux, barebox doesn't propagate pinctrl probe deferrment from the
> probe of other drivers. This driver here is registered at console_initcall
> level, which may be too late to apply pin config for console drivers.
> 
> I think the driver should be moved to core_platform_driver.

Yes, likely. I'll add a patch for that.

Could you trim the context from your answers a bit? I often have to scan
long patch mails to see that there's nothing to see.

Sascha


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


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

end of thread, other threads:[~2021-06-09  9:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-08 14:05 [PATCH 0/5] RK3568 pinctrl Sascha Hauer
2021-06-08 14:05 ` [PATCH 1/5] pinctrl: Rockchip: rename mux_offset to grf_mux_offset Sascha Hauer
2021-06-08 14:05 ` [PATCH 2/5] pinctrl: Rockchip: print resource_size_t with %pa Sascha Hauer
2021-06-08 14:05 ` [PATCH 3/5] pinctrl: Rockchip: Update from Linux Sascha Hauer
2021-06-08 14:05 ` [PATCH 4/5] pinctrl: Rockchip: implement drive strength setting Sascha Hauer
2021-06-09  8:13   ` Ahmad Fatoum
2021-06-08 14:05 ` [PATCH 5/5] pinctrl: Rockchip: Add RK3568 support Sascha Hauer
2021-06-09  8:01   ` Ahmad Fatoum
2021-06-09  9:41     ` Sascha Hauer
2021-06-09  8:11   ` Ahmad Fatoum
2021-06-09  9:45     ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox