Skip to content

Commit c6c4dc7

Browse files
Andre-ARMlinusw
authored andcommitted
pinctrl: sunxi: move bank K register offset
The Allwinner pincontroller register layout used to allow for at least 11 banks per controller, any more banks would reside at a second controller instance. When the per-bank register map size was increased with the D1, it turned out that the last bank (port K) of those maximum 11 banks actually would not fit anymore in the 512 bytes reserved for the pincontroller registers. On new SoCs Allwinner thus moved the last bank beyond the existing registers, at offset 0x500. So far SoCs never used more than 9 banks per controller, but the new Allwinner A523 actually uses all 11 banks. Since that SoC also uses the extended layout, its PortK needs to be programmed at offset 0x500. Factor out the bank offset calculation into a new function, and handle the case for the last bank separately. Since none of the older SoCs ever used PortK, we can ignore this case, and just always use offset 0x500 for the last bank. Signed-off-by: Andre Przywara <[email protected]> Reviewed-by: Chen-Yu Tsai <[email protected]> Link: https://lore.kernel.org/[email protected] Signed-off-by: Linus Walleij <[email protected]>
1 parent 4713b70 commit c6c4dc7

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

drivers/pinctrl/sunxi/pinctrl-sunxi.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,29 @@ static struct irq_chip sunxi_pinctrl_level_irq_chip;
5858
* The following functions calculate the register and the bit offset to access.
5959
* They take a pin number which is relative to the start of the current device.
6060
*/
61+
62+
/*
63+
* When using the extended register layout, Bank K does not fit into the
64+
* space used for the other banks. Instead it lives at offset 0x500.
65+
*/
66+
static u32 sunxi_bank_offset(const struct sunxi_pinctrl *pctl, u32 pin)
67+
{
68+
u32 offset = 0;
69+
70+
if (pin >= PK_BASE) {
71+
pin -= PK_BASE;
72+
offset = PIO_BANK_K_OFFSET;
73+
}
74+
75+
return offset + (pin / PINS_PER_BANK) * pctl->bank_mem_size;
76+
}
77+
6178
static void sunxi_mux_reg(const struct sunxi_pinctrl *pctl,
6279
u32 pin, u32 *reg, u32 *shift, u32 *mask)
6380
{
64-
u32 bank = pin / PINS_PER_BANK;
6581
u32 offset = pin % PINS_PER_BANK * MUX_FIELD_WIDTH;
6682

67-
*reg = bank * pctl->bank_mem_size + MUX_REGS_OFFSET +
83+
*reg = sunxi_bank_offset(pctl, pin) + MUX_REGS_OFFSET +
6884
offset / BITS_PER_TYPE(u32) * sizeof(u32);
6985
*shift = offset % BITS_PER_TYPE(u32);
7086
*mask = (BIT(MUX_FIELD_WIDTH) - 1) << *shift;
@@ -73,10 +89,9 @@ static void sunxi_mux_reg(const struct sunxi_pinctrl *pctl,
7389
static void sunxi_data_reg(const struct sunxi_pinctrl *pctl,
7490
u32 pin, u32 *reg, u32 *shift, u32 *mask)
7591
{
76-
u32 bank = pin / PINS_PER_BANK;
7792
u32 offset = pin % PINS_PER_BANK * DATA_FIELD_WIDTH;
7893

79-
*reg = bank * pctl->bank_mem_size + DATA_REGS_OFFSET +
94+
*reg = sunxi_bank_offset(pctl, pin) + DATA_REGS_OFFSET +
8095
offset / BITS_PER_TYPE(u32) * sizeof(u32);
8196
*shift = offset % BITS_PER_TYPE(u32);
8297
*mask = (BIT(DATA_FIELD_WIDTH) - 1) << *shift;
@@ -85,10 +100,9 @@ static void sunxi_data_reg(const struct sunxi_pinctrl *pctl,
85100
static void sunxi_dlevel_reg(const struct sunxi_pinctrl *pctl,
86101
u32 pin, u32 *reg, u32 *shift, u32 *mask)
87102
{
88-
u32 bank = pin / PINS_PER_BANK;
89103
u32 offset = pin % PINS_PER_BANK * pctl->dlevel_field_width;
90104

91-
*reg = bank * pctl->bank_mem_size + DLEVEL_REGS_OFFSET +
105+
*reg = sunxi_bank_offset(pctl, pin) + DLEVEL_REGS_OFFSET +
92106
offset / BITS_PER_TYPE(u32) * sizeof(u32);
93107
*shift = offset % BITS_PER_TYPE(u32);
94108
*mask = (BIT(pctl->dlevel_field_width) - 1) << *shift;
@@ -97,10 +111,9 @@ static void sunxi_dlevel_reg(const struct sunxi_pinctrl *pctl,
97111
static void sunxi_pull_reg(const struct sunxi_pinctrl *pctl,
98112
u32 pin, u32 *reg, u32 *shift, u32 *mask)
99113
{
100-
u32 bank = pin / PINS_PER_BANK;
101114
u32 offset = pin % PINS_PER_BANK * PULL_FIELD_WIDTH;
102115

103-
*reg = bank * pctl->bank_mem_size + pctl->pull_regs_offset +
116+
*reg = sunxi_bank_offset(pctl, pin) + pctl->pull_regs_offset +
104117
offset / BITS_PER_TYPE(u32) * sizeof(u32);
105118
*shift = offset % BITS_PER_TYPE(u32);
106119
*mask = (BIT(PULL_FIELD_WIDTH) - 1) << *shift;

drivers/pinctrl/sunxi/pinctrl-sunxi.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#define PG_BASE 192
2626
#define PH_BASE 224
2727
#define PI_BASE 256
28+
#define PJ_BASE 288
29+
#define PK_BASE 320
2830
#define PL_BASE 352
2931
#define PM_BASE 384
3032
#define PN_BASE 416
@@ -89,6 +91,8 @@
8991
#define PIO_POW_MOD_SEL_REG 0x340
9092
#define PIO_POW_MOD_CTL_REG 0x344
9193

94+
#define PIO_BANK_K_OFFSET 0x500
95+
9296
enum sunxi_desc_bias_voltage {
9397
BIAS_VOLTAGE_NONE,
9498
/*

0 commit comments

Comments
 (0)