* [PATCH 1/4] pinctrl: rockchip: Add iomux-route switching support
[not found] ` <1495717952-9762-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
@ 2017-05-25 13:12 ` David Wu
2017-05-25 13:12 ` [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228 David Wu
2017-05-25 13:12 ` [PATCH 3/4] pinctrl: rockchip: Add iomux-route switching support for rk3328 David Wu
2 siblings, 0 replies; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
To: heiko-4mtYJXux2i+zQB+pC5nmwQ,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A
Cc: huangtao-TNX95d0MmH7DzftRWevZcw,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
dianders-F7+t8E8rja9g9hUCZPvPmw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, David Wu
On the some rockchip soc, some things like one specific uart can use
multiple pins, but control of that seems to be split. Somewhere between
the pin io-cells and the uart it seems to have some sort of switch to
decide to which pin to actually route the data.
+-------+ +--------+ /- GPIO4_B0 (pinmux 2)
| uart2 | -- | switch | --- GPIO4_C0 (pinmux 2)
+-------+ +--------+ \- GPIO4_C3 (pinmux 2)
(switch selects one of the 3 pins base on the GRF_SOC_CON7[BIT0, BIT1])
The routing switch is determined by one pin of a specific group to be set
to its special pinmux function. If the pinmux setting is wrong for that
pin the ip block won't work correctly anyway.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
drivers/pinctrl/pinctrl-rockchip.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index f141aa0..f5dd1c3 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -146,6 +146,7 @@ struct rockchip_drv {
* @irq_lock: bus lock for irq chip
* @new_irqs: newly configured irqs which must be muxed as GPIOs in
* irq_bus_sync_unlock()
+ * @route_mask: bits describing the routing pins of per bank
*/
struct rockchip_pin_bank {
void __iomem *reg_base;
@@ -170,6 +171,7 @@ struct rockchip_pin_bank {
u32 toggle_edge_mode;
struct mutex irq_lock;
u32 new_irqs;
+ u32 route_mask;
};
#define PIN_BANK(id, pins, label) \
@@ -316,6 +318,8 @@ struct rockchip_pin_ctrl {
int (*schmitt_calc_reg)(struct rockchip_pin_bank *bank,
int pin_num, struct regmap **regmap,
int *reg, u8 *bit);
+ bool (*iomux_route)(u8 bank_num, int pin, int mux,
+ u32 *reg, u32 *value);
};
struct rockchip_pin_config {
@@ -383,6 +387,22 @@ struct rockchip_mux_recalced_data {
u8 mask;
};
+/**
+ * struct rockchip_mux_recalced_data: represent a pin iomux data.
+ * @bank: bank number.
+ * @pin: index at register or used to calc index.
+ * @func: the min pin.
+ * @route_offset: the max pin.
+ * @route_val: the register offset.
+ */
+struct rockchip_mux_route_data {
+ u8 bank;
+ u8 pin;
+ u8 func;
+ u32 route_offset;
+ u32 route_val;
+};
+
static struct regmap_config rockchip_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
@@ -683,7 +703,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, rmask;
+ u32 data, rmask, route_reg, route_val;
ret = rockchip_verify_mux(bank, pin, mux);
if (ret < 0)
@@ -719,6 +739,15 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (ctrl->iomux_recalc && (mux_type & IOMUX_RECALCED))
ctrl->iomux_recalc(bank->bank_num, pin, ®, &bit, &mask);
+ if (ctrl->iomux_route && (bank->route_mask & BIT(pin))) {
+ if (ctrl->iomux_route(bank->bank_num, pin, mux,
+ &route_reg, &route_val)) {
+ ret = regmap_write(regmap, route_reg, route_val);
+ if (ret)
+ return ret;
+ }
+ }
+
data = (mask << (bit + 16));
rmask = data | (data >> 16);
data |= (mux & mask) << bit;
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228
[not found] ` <1495717952-9762-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
2017-05-25 13:12 ` [PATCH 1/4] pinctrl: rockchip: " David Wu
@ 2017-05-25 13:12 ` David Wu
2017-05-25 21:12 ` Heiko Stuebner
2017-05-25 13:12 ` [PATCH 3/4] pinctrl: rockchip: Add iomux-route switching support for rk3328 David Wu
2 siblings, 1 reply; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
To: heiko-4mtYJXux2i+zQB+pC5nmwQ,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A
Cc: huangtao-TNX95d0MmH7DzftRWevZcw,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
dianders-F7+t8E8rja9g9hUCZPvPmw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, David Wu
There are 9 IP blocks pin routes need to be switched, that are
pwm-0, pwm-1, pwm-2, pwm-3, sdio, spi, emmc, uart2, uart1.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
drivers/pinctrl/pinctrl-rockchip.c | 176 ++++++++++++++++++++++++++++++++++++-
1 file changed, 172 insertions(+), 4 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index f5dd1c3..be4c16e 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -187,6 +187,20 @@ struct rockchip_pin_bank {
}, \
}
+#define PIN_BANK_ROUTE(id, pins, label, route) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .route_mask = route, \
+ .iomux = { \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ { .offset = -1 }, \
+ }, \
+ }
+
#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
{ \
.bank_num = id, \
@@ -605,6 +619,159 @@ static void rk3328_recalc_mux(u8 bank_num, int pin, int *reg,
*bit = data->bit;
}
+static const struct rockchip_mux_route_data rk3228_mux_route_data[] = {
+ {
+ /* pwm0-0 */
+ .bank = 0,
+ .pin = 26,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16),
+ }, {
+ /* pwm0-1 */
+ .bank = 3,
+ .pin = 21,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16) | BIT(0),
+ }, {
+ /* pwm1-0 */
+ .bank = 0,
+ .pin = 27,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 1),
+ }, {
+ /* pwm1-1 */
+ .bank = 0,
+ .pin = 30,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 1) | BIT(1),
+ }, {
+ /* pwm2-0 */
+ .bank = 0,
+ .pin = 28,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 2),
+ }, {
+ /* pwm2-1 */
+ .bank = 1,
+ .pin = 12,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 2) | BIT(2),
+ }, {
+ /* pwm3-0 */
+ .bank = 3,
+ .pin = 26,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 3),
+ }, {
+ /* pwm3-1 */
+ .bank = 1,
+ .pin = 11,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 3) | BIT(3),
+ }, {
+ /* sdio-0_d0 */
+ .bank = 1,
+ .pin = 1,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 4),
+ }, {
+ /* sdio-1_d0 */
+ .bank = 3,
+ .pin = 2,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 4) | BIT(4),
+ }, {
+ /* spi-0_rx */
+ .bank = 0,
+ .pin = 13,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 5),
+ }, {
+ /* spi-1_rx */
+ .bank = 2,
+ .pin = 0,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 5) | BIT(5),
+ }, {
+ /* emmc-0_cmd */
+ .bank = 1,
+ .pin = 22,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 7),
+ }, {
+ /* emmc-1_cmd */
+ .bank = 2,
+ .pin = 4,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 7) | BIT(7),
+ }, {
+ /* uart2-0_rx */
+ .bank = 1,
+ .pin = 19,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 8),
+ }, {
+ /* uart2-1_rx */
+ .bank = 1,
+ .pin = 10,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 8) | BIT(8),
+ }, {
+ /* uart1-0_rx */
+ .bank = 1,
+ .pin = 10,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 11),
+ }, {
+ /* uart1-1_rx */
+ .bank = 3,
+ .pin = 13,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 11) | BIT(11),
+ },
+};
+
+static bool rk3228_set_mux_route(u8 bank_num, int pin,
+ int mux, u32 *reg, u32 *value)
+{
+ const struct rockchip_mux_route_data *data = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(rk3228_mux_route_data); i++)
+ if ((rk3228_mux_route_data[i].bank == bank_num) &&
+ (rk3228_mux_route_data[i].pin == pin) &&
+ (rk3228_mux_route_data[i].func == mux)) {
+ data = &rk3228_mux_route_data[i];
+ break;
+ }
+
+ if (!data)
+ return false;
+
+ *reg = data->route_offset;
+ *value = data->route_val;
+
+ return true;
+}
+
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
struct rockchip_pinctrl *info = bank->drvdata;
@@ -2852,10 +3019,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
};
static struct rockchip_pin_bank rk3228_pin_banks[] = {
- PIN_BANK(0, 32, "gpio0"),
- PIN_BANK(1, 32, "gpio1"),
- PIN_BANK(2, 32, "gpio2"),
- PIN_BANK(3, 32, "gpio3"),
+ PIN_BANK_ROUTE(0, 32, "gpio0", 0x5c002000),
+ PIN_BANK_ROUTE(1, 32, "gpio1", 0x00483c02),
+ PIN_BANK_ROUTE(2, 32, "gpio2", 0x00000011),
+ PIN_BANK_ROUTE(3, 32, "gpio3", 0x04202004),
};
static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
@@ -2866,6 +3033,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
.grf_mux_offset = 0x0,
.pull_calc_reg = rk3228_calc_pull_reg_and_bit,
.drv_calc_reg = rk3228_calc_drv_reg_and_bit,
+ .iomux_route = rk3228_set_mux_route,
};
static struct rockchip_pin_bank rk3288_pin_banks[] = {
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228
2017-05-25 13:12 ` [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228 David Wu
@ 2017-05-25 21:12 ` Heiko Stuebner
2017-05-26 3:38 ` David.Wu
0 siblings, 1 reply; 7+ messages in thread
From: Heiko Stuebner @ 2017-05-25 21:12 UTC (permalink / raw)
To: David Wu
Cc: linus.walleij, huangtao, dianders, linux-rockchip, linux-gpio,
linux-kernel
Hi David,
Am Donnerstag, 25. Mai 2017, 21:12:30 CEST schrieb David Wu:
> There are 9 IP blocks pin routes need to be switched, that are
> pwm-0, pwm-1, pwm-2, pwm-3, sdio, spi, emmc, uart2, uart1.
>
> Signed-off-by: David Wu <david.wu@rock-chips.com>
This series come pretty close to what I had in mind, but I do have some
change requests inline below.
The comments are in this patch but apply to the whole series.
> ---
> drivers/pinctrl/pinctrl-rockchip.c | 176 ++++++++++++++++++++++++++++++++++++-
> 1 file changed, 172 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
> index f5dd1c3..be4c16e 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.c
> +++ b/drivers/pinctrl/pinctrl-rockchip.c
> @@ -187,6 +187,20 @@ struct rockchip_pin_bank {
> }, \
> }
>
> +#define PIN_BANK_ROUTE(id, pins, label, route) \
> + { \
> + .bank_num = id, \
> + .nr_pins = pins, \
> + .name = label, \
> + .route_mask = route, \
> + .iomux = { \
> + { .offset = -1 }, \
> + { .offset = -1 }, \
> + { .offset = -1 }, \
> + { .offset = -1 }, \
> + }, \
> + }
> +
> #define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
> { \
> .bank_num = id, \
> @@ -605,6 +619,159 @@ static void rk3328_recalc_mux(u8 bank_num, int pin, int *reg,
> *bit = data->bit;
> }
>
> +static const struct rockchip_mux_route_data rk3228_mux_route_data[] = {
> + {
> + /* pwm0-0 */
> + .bank = 0,
> + .pin = 26,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16),
> + }, {
> + /* pwm0-1 */
> + .bank = 3,
> + .pin = 21,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16) | BIT(0),
> + }, {
> + /* pwm1-0 */
> + .bank = 0,
> + .pin = 27,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 1),
> + }, {
> + /* pwm1-1 */
> + .bank = 0,
> + .pin = 30,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 1) | BIT(1),
> + }, {
> + /* pwm2-0 */
> + .bank = 0,
> + .pin = 28,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 2),
> + }, {
> + /* pwm2-1 */
> + .bank = 1,
> + .pin = 12,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 2) | BIT(2),
> + }, {
> + /* pwm3-0 */
> + .bank = 3,
> + .pin = 26,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 3),
> + }, {
> + /* pwm3-1 */
> + .bank = 1,
> + .pin = 11,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 3) | BIT(3),
> + }, {
> + /* sdio-0_d0 */
> + .bank = 1,
> + .pin = 1,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 4),
> + }, {
> + /* sdio-1_d0 */
> + .bank = 3,
> + .pin = 2,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 4) | BIT(4),
> + }, {
> + /* spi-0_rx */
> + .bank = 0,
> + .pin = 13,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 5),
> + }, {
> + /* spi-1_rx */
> + .bank = 2,
> + .pin = 0,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 5) | BIT(5),
> + }, {
> + /* emmc-0_cmd */
> + .bank = 1,
> + .pin = 22,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 7),
> + }, {
> + /* emmc-1_cmd */
> + .bank = 2,
> + .pin = 4,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 7) | BIT(7),
> + }, {
> + /* uart2-0_rx */
> + .bank = 1,
> + .pin = 19,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 8),
> + }, {
> + /* uart2-1_rx */
> + .bank = 1,
> + .pin = 10,
> + .func = 2,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 8) | BIT(8),
> + }, {
> + /* uart1-0_rx */
> + .bank = 1,
> + .pin = 10,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 11),
> + }, {
> + /* uart1-1_rx */
> + .bank = 3,
> + .pin = 13,
> + .func = 1,
> + .route_offset = 0x50,
> + .route_val = BIT(16 + 11) | BIT(11),
> + },
> +};
> +
> +static bool rk3228_set_mux_route(u8 bank_num, int pin,
> + int mux, u32 *reg, u32 *value)
instead of referencing this function in the per-soc struct, please make
it generic and reference the route array + size in the per-soc struct.
Except for referencing a different array, the function is the same
everywhere, so there is no need to duplicate it for each soc.
> +{
> + const struct rockchip_mux_route_data *data = NULL;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(rk3228_mux_route_data); i++)
> + if ((rk3228_mux_route_data[i].bank == bank_num) &&
> + (rk3228_mux_route_data[i].pin == pin) &&
> + (rk3228_mux_route_data[i].func == mux)) {
> + data = &rk3228_mux_route_data[i];
> + break;
> + }
> +
> + if (!data)
> + return false;
> +
> + *reg = data->route_offset;
> + *value = data->route_val;
> +
> + return true;
> +}
> +
> static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
> {
> struct rockchip_pinctrl *info = bank->drvdata;
> @@ -2852,10 +3019,10 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
> };
>
> static struct rockchip_pin_bank rk3228_pin_banks[] = {
> - PIN_BANK(0, 32, "gpio0"),
> - PIN_BANK(1, 32, "gpio1"),
> - PIN_BANK(2, 32, "gpio2"),
> - PIN_BANK(3, 32, "gpio3"),
> + PIN_BANK_ROUTE(0, 32, "gpio0", 0x5c002000),
> + PIN_BANK_ROUTE(1, 32, "gpio1", 0x00483c02),
> + PIN_BANK_ROUTE(2, 32, "gpio2", 0x00000011),
> + PIN_BANK_ROUTE(3, 32, "gpio3", 0x04202004),
Requiring developers to calculate this pin-bit-value for each bank
is cumbersome and error-prone. With the routes-struct known in
the driver (see above and below), you can keep the the value element
in rockchip_pin_bank, but calculate the per-bank value dynamically
when the bank gets created.
For example in rockchip_pinctrl_get_soc_data just parse the route-struct
and calculate that value when the driver probes.
This reduces possible errors and also spares us the clutter of all the
additional PIN_BANK_* defines.
> };
>
> static struct rockchip_pin_ctrl rk3228_pin_ctrl = {
> @@ -2866,6 +3033,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
> .grf_mux_offset = 0x0,
> .pull_calc_reg = rk3228_calc_pull_reg_and_bit,
> .drv_calc_reg = rk3228_calc_drv_reg_and_bit,
> + .iomux_route = rk3228_set_mux_route,
.iomux_routes = rk3228_mux_route_data,
.niomux_routes = ARRAY_SIZE(rk3228_mux_route_data),
Heiko
> };
>
> static struct rockchip_pin_bank rk3288_pin_banks[] = {
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228
2017-05-25 21:12 ` Heiko Stuebner
@ 2017-05-26 3:38 ` David.Wu
0 siblings, 0 replies; 7+ messages in thread
From: David.Wu @ 2017-05-26 3:38 UTC (permalink / raw)
To: Heiko Stuebner
Cc: linus.walleij, huangtao, dianders, linux-rockchip, linux-gpio,
linux-kernel
Hi Heiko,
在 2017/5/26 5:12, Heiko Stuebner 写道:
> Requiring developers to calculate this pin-bit-value for each bank
> is cumbersome and error-prone. With the routes-struct known in
> the driver (see above and below), you can keep the the value element
> in rockchip_pin_bank, but calculate the per-bank value dynamically
> when the bank gets created.
>
> For example in rockchip_pinctrl_get_soc_data just parse the route-struct
> and calculate that value when the driver probes.
>
> This reduces possible errors and also spares us the clutter of all the
> additional PIN_BANK_* defines.
It is good to calculate the per-bank value dynamically, Thanks.☺
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 3/4] pinctrl: rockchip: Add iomux-route switching support for rk3328
[not found] ` <1495717952-9762-1-git-send-email-david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
2017-05-25 13:12 ` [PATCH 1/4] pinctrl: rockchip: " David Wu
2017-05-25 13:12 ` [PATCH 2/4] pinctrl: rockchip: Add iomux-route switching support for rk3228 David Wu
@ 2017-05-25 13:12 ` David Wu
2 siblings, 0 replies; 7+ messages in thread
From: David Wu @ 2017-05-25 13:12 UTC (permalink / raw)
To: heiko-4mtYJXux2i+zQB+pC5nmwQ,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A
Cc: huangtao-TNX95d0MmH7DzftRWevZcw,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
dianders-F7+t8E8rja9g9hUCZPvPmw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, David Wu
There are 8 IP blocks pin routes need to be switched, that are
uart2dbg, gmac-m1-optimized, pdm, spi, i2s2, card, tsp, cif.
Signed-off-by: David Wu <david.wu-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
---
drivers/pinctrl/pinctrl-rockchip.c | 140 ++++++++++++++++++++++++++++++++++---
1 file changed, 130 insertions(+), 10 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index be4c16e..6eab4581 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -214,6 +214,21 @@ struct rockchip_pin_bank {
}, \
}
+#define PIN_BANK_IOMUX_FLAGS_ROUTE(id, pins, label, route, iom0, iom1, \
+ iom2, iom3) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .route_mask = route, \
+ .iomux = { \
+ { .type = iom0, .offset = -1 }, \
+ { .type = iom1, .offset = -1 }, \
+ { .type = iom2, .offset = -1 }, \
+ { .type = iom3, .offset = -1 }, \
+ }, \
+ }
+
#define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
{ \
.bank_num = id, \
@@ -772,6 +787,110 @@ static bool rk3228_set_mux_route(u8 bank_num, int pin,
return true;
}
+static const struct rockchip_mux_route_data rk3328_mux_route_data[] = {
+ {
+ /* uart2dbg_rxm0 */
+ .bank = 1,
+ .pin = 1,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16) | BIT(16 + 1),
+ }, {
+ /* uart2dbg_rxm1 */
+ .bank = 2,
+ .pin = 1,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16) | BIT(16 + 1) | BIT(0),
+ }, {
+ /* gmac-m1-optimized_rxd0 */
+ .bank = 1,
+ .pin = 11,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 2) | BIT(16 + 10) | BIT(2) | BIT(10),
+ }, {
+ /* pdm_sdi0m0 */
+ .bank = 2,
+ .pin = 19,
+ .func = 2,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 3),
+ }, {
+ /* pdm_sdi0m1 */
+ .bank = 1,
+ .pin = 23,
+ .func = 3,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 3) | BIT(3),
+ }, {
+ /* spi_rxdm2 */
+ .bank = 3,
+ .pin = 2,
+ .func = 4,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 4) | BIT(16 + 5) | BIT(5),
+ }, {
+ /* i2s2_sdim0 */
+ .bank = 1,
+ .pin = 24,
+ .func = 1,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 6),
+ }, {
+ /* i2s2_sdim1 */
+ .bank = 3,
+ .pin = 2,
+ .func = 6,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 6) | BIT(6),
+ }, {
+ /* card_iom1 */
+ .bank = 2,
+ .pin = 22,
+ .func = 3,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 7) | BIT(7),
+ }, {
+ /* tsp_d5m1 */
+ .bank = 2,
+ .pin = 16,
+ .func = 3,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 8) | BIT(8),
+ }, {
+ /* cif_data5m1 */
+ .bank = 2,
+ .pin = 16,
+ .func = 4,
+ .route_offset = 0x50,
+ .route_val = BIT(16 + 9) | BIT(9),
+ },
+};
+
+static bool rk3328_set_mux_route(u8 bank_num, int pin, int mux,
+ u32 *reg, u32 *value)
+{
+ const struct rockchip_mux_route_data *data = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(rk3328_mux_route_data); i++)
+ if ((rk3328_mux_route_data[i].bank == bank_num) &&
+ (rk3328_mux_route_data[i].pin == pin) &&
+ (rk3328_mux_route_data[i].func == mux)) {
+ data = &rk3328_mux_route_data[i];
+ break;
+ }
+
+ if (!data)
+ return false;
+
+ *reg = data->route_offset;
+ *value = data->route_val;
+
+ return true;
+}
+
static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
{
struct rockchip_pinctrl *info = bank->drvdata;
@@ -3081,16 +3200,16 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
static struct rockchip_pin_bank rk3328_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", 0, 0, 0, 0),
- PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
- PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0,
- IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
- IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
- 0),
- PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3",
- IOMUX_WIDTH_3BIT,
- IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
- 0,
- 0),
+ PIN_BANK_IOMUX_FLAGS_ROUTE(1, 32, "gpio1", 0x01800802, 0, 0, 0, 0),
+ PIN_BANK_IOMUX_FLAGS_ROUTE(2, 32, "gpio2", 0x00490002, 0,
+ IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
+ IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
+ 0),
+ PIN_BANK_IOMUX_FLAGS_ROUTE(3, 32, "gpio3", 0x00000004,
+ IOMUX_WIDTH_3BIT,
+ IOMUX_WIDTH_3BIT | IOMUX_RECALCED,
+ 0,
+ 0),
};
static struct rockchip_pin_ctrl rk3328_pin_ctrl = {
@@ -3103,6 +3222,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
.drv_calc_reg = rk3228_calc_drv_reg_and_bit,
.iomux_recalc = rk3328_recalc_mux,
.schmitt_calc_reg = rk3328_calc_schmitt_reg_and_bit,
+ .iomux_route = rk3328_set_mux_route,
};
static struct rockchip_pin_bank rk3368_pin_banks[] = {
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread