Skip to content

Commit

Permalink
pinctrl: rockchip: precalculate iomux offsets
Browse files Browse the repository at this point in the history
An 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.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Heiko Stübner authored and Linus Walleij committed Jul 11, 2014
1 parent fc72c92 commit 6bc0d12
Showing 1 changed file with 45 additions and 11 deletions.
56 changes: 45 additions & 11 deletions drivers/pinctrl/pinctrl-rockchip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/**
Expand Down Expand Up @@ -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) \
Expand All @@ -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 }, \
}, \
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1515,7 +1521,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;
Expand All @@ -1537,12 +1543,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;
Expand Down

0 comments on commit 6bc0d12

Please sign in to comment.