pinctrl: rockchip: support rk3288
Subsystems (3)
Heiko Stübner
maintainercover pinctrl: rockchip: support rk3288
This series adds support for the rk3288 SoC.
The first patch generalizes the gpio-only handling of the rk3188 into a general quirk-handling making it possible to deprecate the special bank compatible and also to add quirks of later SoCs.
Patches 2 to 5 enable the driver to handle the quirks of rk3288 and patch 6 then simply adds the description of the rk3288 banks.
Tested on a rk3288-evb and on a rk3188-radxarock with both the deprecated and new regular notation for bank0.
Heiko Stuebner (6):
pinctrl: rockchip: generalize bank-quirks
pinctrl: rockchip: precalculate iomux offsets
pinctrl: rockchip: add support for 4bit wide iomux settings
pinctrl: rockchip: enable iomuxes from pmu space
pinctrl: rockchip: support unrouted iomuxes per bank
pinctrl: rockchip: add support for rk3288 pin-controller
.../bindings/pinctrl/rockchip,pinctrl.txt | 4 +- drivers/pinctrl/pinctrl-rockchip.c | 251 +++++++++++++++++---- 2 files changed, 215 insertions(+), 39 deletions(-)
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH 1/6 pinctrl: rockchip: generalize bank-quirks
Upcoming Rockchip SoCs have additional quirks to handle. Currently they would be handled by giving the bank a special compatible property. But the nature of the new quirks would require a lot of them. Also as we want to move to the separate dw_gpio driver in the future, these bank-definitions should be extended at all.
Describing the bank quirks this way also enables us to deprecate the special bank compatible string for bank0 on rk3188 and simplify the handling code.
--- .../bindings/pinctrl/rockchip,pinctrl.txt | 3 +- drivers/pinctrl/pinctrl-rockchip.c | 59 ++++++++++++++-------- 2 files changed, 41 insertions(+), 20 deletions(-)
Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +2 -1
@@ -36,7 +36,7 @@ Deprecated properties for iomux controller: Use rockchip,grf and rockchip,pmu described above instead. Required properties for gpio sub nodes: - - compatible: "rockchip,gpio-bank", "rockchip,rk3188-gpio-bank0" + - compatible: "rockchip,gpio-bank" - reg: register of the gpio bank (different than the iomux registerset) - interrupts: base interrupt of the gpio bank in the interrupt controller - clocks: clock that drives this bank
@@ -50,6 +50,7 @@ Required properties for gpio sub nodes: bindings/interrupt-controller/interrupts.txt Deprecated properties for gpio sub nodes: + - compatible: "rockchip,rk3188-gpio-bank0" - reg: second element: separate pull register for rk3188 bank0, use rockchip,pmu described above instead
drivers/pinctrl/pinctrl-rockchip.c +39 -19
138 lines not on this page · raw message
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH 2/6 pinctrl: rockchip: precalculate iomux offsets
In reply to Heiko StübnerAn upcoming SoC introduces an interesting quirk to iomux handling making the calculation of the iomux register-offset harder. To keep the complexity down when getting/setting the mux, precalculate the actual register offset at probe-time.
--- drivers/pinctrl/pinctrl-rockchip.c | 56 ++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 11 deletions(-)
drivers/pinctrl/pinctrl-rockchip.c +45 -11
@@ -71,9 +71,13 @@ enum rockchip_pinctrl_type {/** * @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; };/**
@@ -119,6 +123,12 @@ struct rockchip_pin_bank { .bank_num = id, \ .nr_pins = pins, \ .name = label, \ + .iomux = { \ + { .offset = -1 }, \ + { .offset = -1 }, \ + { .offset = -1 }, \ + { .offset = -1 }, \ + }, \ }#define PIN_BANK_IOMUX_FLAGS (id, pins, label, iom0, iom1, iom2, iom3) \
@@ -127,10 +137,10 @@ struct rockchip_pin_bank { .nr_pins = pins, \ .name = label, \ .iomux = { \ - { .type = iom0, }, \ - { .type = iom1, }, \ - { .type = iom2, }, \ - { .type = iom3, }, \ + { .type = iom0, .offset = -1 }, \ + { .type = iom1, .offset = -1 }, \ + { .type = iom2, .offset = -1 }, \ + { .type = iom3, .offset = -1 }, \ }, \ }
@@ -376,9 +386,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)return RK_FUNC_GPIO ;/* get basic quadrupel of mux registers and the correct reg inside */ - reg = info->ctrl->mux_offset; - reg += bank->bank_num *0x10 ; - reg += iomux_num *4 ; + reg = bank->iomux[iomux_num].offset; bit = (pin %8 ) *2 ; ret =regmap_read (info->regmap_base, reg, &val);
@@ -427,9 +435,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) bank->bank_num, pin, mux);/* get basic quadrupel of mux registers and the correct reg inside */ - reg = info->ctrl->mux_offset; - reg += bank->bank_num *0x10 ; - reg += iomux_num *4 ; + reg = bank->iomux[iomux_num].offset; bit = (pin %8 ) *2 ;spin_lock_irqsave (&bank->slock, flags);
@@ -1532,7 +1538,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct device_node *np;struct rockchip_pin_ctrl *ctrl;struct rockchip_pin_bank *bank; -int i; +int grf_offs, i, j; match =of_match_node (rockchip_pinctrl_dt_match, node); ctrl = (struct rockchip_pin_ctrl *)match->data;
@@ -1554,12 +1560,40 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( } } + grf_offs = ctrl->mux_offset; bank = ctrl->pin_banks;for (i =0 ; i < ctrl->nr_banks; ++i, ++bank) { +int bank_pins =0 ; +spin_lock_init (&bank->slock); bank->drvdata = d; bank->pin_base = ctrl->nr_pins; ctrl->nr_pins += bank->nr_pins; + +/* calculate iomux offsets */ +for (j =0 ; j <4 ; j++) { +struct rockchip_iomux *iom = &bank->iomux[j]; + +if (bank_pins >= bank->nr_pins) +break ; + +/* preset offset value, set new start value */ +if (iom->offset >=0 ) { + grf_offs = iom->offset; + }else {/* set current offset */ + iom->offset = grf_offs; + } + +dev_dbg (d->dev,"bank %d, iomux %d has offset 0x%x\n" , + i, j, iom->offset); + +/* +* Increase offset according to iomux width. +*/ + grf_offs +=4 ; + + bank_pins +=8 ; + } }return ctrl;
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH 3/6 pinctrl: rockchip: add support for 4bit wide iomux settings
In reply to Heiko StübnerIn the upcoming rk3288 SoC some iomux settings are 4bit wide instead of the regular 2bit. Therefore add a flag to mark iomuxes as such and adapt the mux-access as well as the offset calculation accordingly.
--- drivers/pinctrl/pinctrl-rockchip.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-)
drivers/pinctrl/pinctrl-rockchip.c +26 -8
@@ -68,6 +68,7 @@ enum rockchip_pinctrl_type {* Encode variants of iomux registers into a type variable */ #define IOMUX_GPIO_ONLY BIT(0) +#define IOMUX_WIDTH_4BIT BIT(1)/** * @type: iomux variant using IOMUX_* constants
@@ -376,7 +377,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)struct rockchip_pinctrl *info = bank->drvdata;int iomux_num = (pin /8 );unsigned int val; -int reg, ret; +int reg, ret, mask;u8 bit;if (iomux_num >3 )
@@ -386,14 +387,21 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)return RK_FUNC_GPIO ;/* get basic quadrupel of mux registers and the correct reg inside */ + mask = (bank->iomux[iomux_num].type &IOMUX_WIDTH_4BIT ) ?0xf :0x3 ; reg = bank->iomux[iomux_num].offset; - bit = (pin %8 ) *2 ; +if (bank->iomux[iomux_num].type &IOMUX_WIDTH_4BIT ) { +if ((pin %8 ) >=4 ) + reg +=0x4 ; + bit = (pin %4 ) *4 ; + }else { + bit = (pin %8 ) *2 ; + } ret =regmap_read (info->regmap_base, reg, &val);if (ret)return ret; -return ((val >> bit) &3 ); +return ((val >> bit) & mask); }/*
@@ -413,7 +421,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) {struct rockchip_pinctrl *info = bank->drvdata;int iomux_num = (pin /8 ); -int reg, ret; +int reg, ret, mask;unsigned long flags;u8 bit;u32 data;
@@ -435,13 +443,20 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) bank->bank_num, pin, mux);/* get basic quadrupel of mux registers and the correct reg inside */ + mask = (bank->iomux[iomux_num].type &IOMUX_WIDTH_4BIT ) ?0xf :0x3 ; reg = bank->iomux[iomux_num].offset; - bit = (pin %8 ) *2 ; +if (bank->iomux[iomux_num].type &IOMUX_WIDTH_4BIT ) { +if ((pin %8 ) >=4 ) + reg +=0x4 ; + bit = (pin %4 ) *4 ; + }else { + bit = (pin %8 ) *2 ; + }spin_lock_irqsave (&bank->slock, flags); - data = (3 << (bit +16 )); - data |= (mux &3 ) << bit; + data = (mask << (bit +16 )); + data |= (mux & mask) << bit; ret =regmap_write (info->regmap_base, reg, data);spin_unlock_irqrestore (&bank->slock, flags);
@@ -1573,6 +1588,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(/* calculate iomux offsets */ for (j =0 ; j <4 ; j++) {struct rockchip_iomux *iom = &bank->iomux[j]; +int inc;if (bank_pins >= bank->nr_pins)break ;
@@ -1589,8 +1605,10 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(/* * Increase offset according to iomux width. +* 4bit iomux'es are spread over two registers. */ - grf_offs +=4 ; + inc = (iom->type &IOMUX_WIDTH_4BIT ) ?8 :4 ; + grf_offs += inc; bank_pins +=8 ; }
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH 4/6 pinctrl: rockchip: enable iomuxes from pmu space
In reply to Heiko StübnerThe upcoming rk3288 moves some iomux settings to the pmu register space. Therefore add a flag for this and adapt the mux functions accordingly.
--- drivers/pinctrl/pinctrl-rockchip.c | 42 +++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-)
drivers/pinctrl/pinctrl-rockchip.c +30 -12
@@ -69,6 +69,7 @@ enum rockchip_pinctrl_type {*/ #define IOMUX_GPIO_ONLY BIT(0)#define IOMUX_WIDTH_4BIT BIT(1) +#define IOMUX_SOURCE_PMU BIT(2)/** * @type: iomux variant using IOMUX_* constants
@@ -153,7 +154,8 @@ struct rockchip_pin_ctrl {u32 nr_pins;char *label;enum rockchip_pinctrl_type type; -int mux_offset; +int grf_mux_offset; +int pmu_mux_offset;void (*pull_calc_reg)(struct rockchip_pin_bank *bank,int pin_num,struct regmap **regmap,int *reg,u8 *bit);
@@ -376,6 +378,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) {struct rockchip_pinctrl *info = bank->drvdata;int iomux_num = (pin /8 ); +struct regmap *regmap;unsigned int val;int reg, ret, mask;u8 bit;
@@ -386,6 +389,9 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)if (bank->iomux[iomux_num].type &IOMUX_GPIO_ONLY )return RK_FUNC_GPIO ; + regmap = (bank->iomux[iomux_num].type &IOMUX_SOURCE_PMU ) + ? info->regmap_pmu : info->regmap_base; +/* get basic quadrupel of mux registers and the correct reg inside */ mask = (bank->iomux[iomux_num].type &IOMUX_WIDTH_4BIT ) ?0xf :0x3 ; reg = bank->iomux[iomux_num].offset;
@@ -397,7 +403,7 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin) bit = (pin %8 ) *2 ; } - ret =regmap_read (info->regmap_base, reg, &val); + ret =regmap_read (regmap, reg, &val);if (ret)return ret;
@@ -421,6 +427,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) {struct rockchip_pinctrl *info = bank->drvdata;int iomux_num = (pin /8 ); +struct regmap *regmap;int reg, ret, mask;unsigned long flags;u8 bit;
@@ -442,6 +449,9 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)dev_dbg (info->dev,"setting mux of GPIO%d-%d to %d\n" , bank->bank_num, pin, mux); + regmap = (bank->iomux[iomux_num].type &IOMUX_SOURCE_PMU ) + ? info->regmap_pmu : info->regmap_base; +/* get basic quadrupel of mux registers and the correct reg inside */ mask = (bank->iomux[iomux_num].type &IOMUX_WIDTH_4BIT ) ?0xf :0x3 ; reg = bank->iomux[iomux_num].offset;
@@ -457,7 +467,7 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) data = (mask << (bit +16 )); data |= (mux & mask) << bit; - ret =regmap_write (info->regmap_base, reg, data); + ret =regmap_write (regmap, reg, data);spin_unlock_irqrestore (&bank->slock, flags);
@@ -1553,7 +1563,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct device_node *np;struct rockchip_pin_ctrl *ctrl;struct rockchip_pin_bank *bank; -int grf_offs, i, j; +int grf_offs, pmu_offs, i, j; match =of_match_node (rockchip_pinctrl_dt_match, node); ctrl = (struct rockchip_pin_ctrl *)match->data;
@@ -1575,7 +1585,8 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data( } } - grf_offs = ctrl->mux_offset; + grf_offs = ctrl->grf_mux_offset; + pmu_offs = ctrl->pmu_mux_offset; bank = ctrl->pin_banks;for (i =0 ; i < ctrl->nr_banks; ++i, ++bank) {int bank_pins =0 ;
@@ -1595,9 +1606,13 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(/* preset offset value, set new start value */ if (iom->offset >=0 ) { - grf_offs = iom->offset; +if (iom->type &IOMUX_SOURCE_PMU ) + pmu_offs = iom->offset; +else + grf_offs = iom->offset; }else {/* set current offset */ - iom->offset = grf_offs; + iom->offset = (iom->type &IOMUX_SOURCE_PMU ) ? + pmu_offs : grf_offs; } dev_dbg(d->dev, "bank %d, iomux %d has offset 0x%x\n",
@@ -1608,7 +1623,10 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(* 4bit iomux'es are spread over two registers. */ inc = (iom->type &IOMUX_WIDTH_4BIT ) ?8 :4 ; - grf_offs += inc; +if (iom->type &IOMUX_SOURCE_PMU ) + pmu_offs += inc; +else + grf_offs += inc; bank_pins +=8 ; }
@@ -1715,7 +1733,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk2928_pin_banks), .label = "RK2928-GPIO", .type = RK2928, - .mux_offset = 0xa8, + .grf_mux_offset = 0xa8, .pull_calc_reg = rk2928_calc_pull_reg_and_bit, };
@@ -1733,7 +1751,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk3066a_pin_banks), .label = "RK3066a-GPIO", .type = RK2928, - .mux_offset = 0xa8, + .grf_mux_offset = 0xa8, .pull_calc_reg = rk2928_calc_pull_reg_and_bit, };
@@ -1749,7 +1767,7 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk3066b_pin_banks), .label = "RK3066b-GPIO", .type = RK3066B, - .mux_offset = 0x60, + .grf_mux_offset = 0x60, };static struct rockchip_pin_bank rk3188_pin_banks[] = {
@@ -1764,7 +1782,7 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk3188_pin_banks), .label = "RK3188-GPIO", .type = RK3188, - .mux_offset = 0x60, + .grf_mux_offset = 0x60, .pull_calc_reg = rk3188_calc_pull_reg_and_bit, };
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH 5/6 pinctrl: rockchip: support unrouted iomuxes per bank
In reply to Heiko StübnerOn the upcoming RK3288 SoC contain some unrouted pins in their banks. So while for example pin8 of bank5 stays pin8 with all its settings (register offset etc), pins 0 to 7 are not routed outside the SoC at all.
Therefore add a flag to mark these unrouted iomuxes to prevent people from using them.
--- drivers/pinctrl/pinctrl-rockchip.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/pinctrl/pinctrl-rockchip.c +11 -0
@@ -70,6 +70,7 @@ enum rockchip_pinctrl_type {#define IOMUX_GPIO_ONLY BIT(0)#define IOMUX_WIDTH_4BIT BIT(1)#define IOMUX_SOURCE_PMU BIT(2) +#define IOMUX_UNROUTED BIT(3)/** * @type: iomux variant using IOMUX_* constants
@@ -386,6 +387,11 @@ static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)if (iomux_num >3 )return -EINVAL ; +if (bank->iomux[iomux_num].type &IOMUX_UNROUTED ) { +dev_err (info->dev,"pin %d is unrouted\n" , pin); +return -EINVAL ; + } +if (bank->iomux[iomux_num].type &IOMUX_GPIO_ONLY )return RK_FUNC_GPIO ;
@@ -436,6 +442,11 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)if (iomux_num >3 )return -EINVAL ; +if (bank->iomux[iomux_num].type &IOMUX_UNROUTED ) { +dev_err (info->dev,"pin %d is unrouted\n" , pin); +return -EINVAL ; + } +if (bank->iomux[iomux_num].type &IOMUX_GPIO_ONLY ) {if (mux !=RK_FUNC_GPIO ) { dev_err(info->dev,
Signature · 1 line
1.9.0
Heiko Stübner
maintainerPATCH 6/6 pinctrl: rockchip: add support for rk3288 pin-controller
In reply to Heiko StübnerThe pin-controller of the new RK3288 contains all the quirks just added in the previous patches.
--- .../bindings/pinctrl/rockchip,pinctrl.txt | 1 + drivers/pinctrl/pinctrl-rockchip.c | 73 ++++++++++++++++++++++ 2 files changed, 74 insertions(+)
Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.txt +1 -0
@@ -21,6 +21,7 @@ defined as gpio sub-nodes of the pinmux controller. Required properties for iomux controller: - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl" "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl" + "rockchip,rk3288-pinctrl" - rockchip,grf: phandle referencing a syscon providing the "general register files"
drivers/pinctrl/pinctrl-rockchip.c +73 -0
91 lines not on this page · raw message
Signature · 1 line
1.9.0
cover pinctrl: rockchip: support rk3288
In reply to Heiko StübnerQuoted 12 lines · Heiko St?bner
This series adds support for the rk3288 SoC.
The first patch generalizes the gpio-only handling of the rk3188 into a general quirk-handling making it possible to deprecate the special bank compatible and also to add quirks of later SoCs.
Patches 2 to 5 enable the driver to handle the quirks of rk3288 and patch 6 then simply adds the description of the rk3288 banks.
Tested on a rk3288-evb and on a rk3188-radxarock with both the deprecated and new regular notation for bank0.
Quoted 7 lines
Heiko Stuebner (6):
pinctrl: rockchip: generalize bank-quirks
pinctrl: rockchip: precalculate iomux offsets
pinctrl: rockchip: add support for 4bit wide iomux settings
pinctrl: rockchip: enable iomuxes from pmu space
pinctrl: rockchip: support unrouted iomuxes per bank
pinctrl: rockchip: add support for rk3288 pin-controller
Excellent and nice broken-down patch series Heiko!
All patches applied for v3.17.
Yours,
Linus Walleij