pinctrl: rockchip: Add pinctrl route types

Some pins in rockchip are routed via Top GRF and PMU GRF
instead of direct regmap.

Add support to handle all these routing paths so that the
SoC pinctrl drivers will use them accordingly.

Signed-off-by: Jianqun Xu <jay.xu@rock-chips.com>
Signed-off-by: Jagan Teki <jagan@edgeble.ai>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
This commit is contained in:
Jagan Teki 2022-12-14 23:20:56 +05:30 committed by Kever Yang
parent 0900840b46
commit 32b2ea9818
9 changed files with 102 additions and 78 deletions

View File

@ -80,7 +80,7 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, route_reg, route_val;
u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@ -90,15 +90,6 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);

View File

@ -106,7 +106,7 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, route_reg, route_val;
u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@ -119,15 +119,6 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);

View File

@ -150,7 +150,7 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, route_reg, route_val;
u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@ -160,15 +160,6 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);

View File

@ -37,7 +37,7 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, route_reg, route_val;
u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@ -47,15 +47,6 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
/* bank0 is special, there are no higher 16 bit writing bits. */
if (bank->bank_num == 0) {
regmap_read(regmap, reg, &data);

View File

@ -258,7 +258,7 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, route_reg, route_val;
u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@ -271,15 +271,6 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);

View File

@ -130,7 +130,7 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, route_reg, route_val;
u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@ -143,15 +143,6 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);

View File

@ -59,7 +59,7 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
u32 data, route_reg, route_val;
u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@ -69,15 +69,6 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
if (bank->route_mask & BIT(pin)) {
if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
&route_val)) {
ret = regmap_write(regmap, route_reg, route_val);
if (ret)
return ret;
}
}
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);

View File

@ -62,8 +62,9 @@ void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
*bit = data->bit;
}
bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
int mux, u32 *reg, u32 *value)
static enum rockchip_pin_route_type
rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
int mux, u32 *reg, u32 *value)
{
struct rockchip_pinctrl_priv *priv = bank->priv;
struct rockchip_pin_ctrl *ctrl = priv->ctrl;
@ -78,12 +79,12 @@ bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
}
if (i >= ctrl->niomux_routes)
return false;
return ROUTE_TYPE_INVALID;
*reg = data->route_offset;
*value = data->route_val;
return true;
return data->route_type;
}
int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask)
@ -214,8 +215,40 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
return -ENOTSUPP;
ret = ctrl->set_mux(bank, pin, mux);
if (ret)
return ret;
return ret;
if (bank->route_mask & BIT(pin)) {
struct regmap *regmap;
u32 route_reg = 0, route_val = 0;
ret = rockchip_get_mux_route(bank, pin, mux,
&route_reg, &route_val);
switch (ret) {
case ROUTE_TYPE_DEFAULT:
if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
regmap = priv->regmap_pmu;
else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
else
regmap = priv->regmap_base;
regmap_write(regmap, route_reg, route_val);
break;
case ROUTE_TYPE_TOPGRF:
regmap_write(priv->regmap_base, route_reg, route_val);
break;
case ROUTE_TYPE_PMUGRF:
regmap_write(priv->regmap_pmu, route_reg, route_val);
break;
case ROUTE_TYPE_INVALID:
fallthrough;
default:
break;
}
}
return 0;
}
static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
@ -545,7 +578,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
inc = (iom->type & (IOMUX_WIDTH_4BIT |
IOMUX_WIDTH_3BIT |
IOMUX_8WIDTH_2BIT)) ? 8 : 4;
if (iom->type & IOMUX_SOURCE_PMU)
if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
pmu_offs += inc;
else
grf_offs += inc;

View File

@ -9,6 +9,9 @@
#include <linux/bitops.h>
#include <linux/types.h>
#define RK_GENMASK_VAL(h, l, v) \
(GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
/**
* Encode variants of iomux registers into a type variable
*/
@ -18,6 +21,7 @@
#define IOMUX_UNROUTED BIT(3)
#define IOMUX_WIDTH_3BIT BIT(4)
#define IOMUX_8WIDTH_2BIT BIT(5)
#define IOMUX_L_SOURCE_PMU BIT(6)
/**
* Defined some common pins constants
@ -62,6 +66,22 @@ enum rockchip_pin_pull_type {
PULL_TYPE_MAX
};
/**
* Rockchip pinctrl route type
*
* DEFAULT : Same regmap as pin iomux
* TOPGRF : Mux route setting in topgrf
* PMUGRF : Mux route setting in pmugrf
* INVALID : Nnot need to set mux route
*/
enum rockchip_pin_route_type {
ROUTE_TYPE_DEFAULT = 0,
ROUTE_TYPE_TOPGRF = 1,
ROUTE_TYPE_PMUGRF = 2,
ROUTE_TYPE_INVALID = -1,
};
/**
* @drv_type: drive strength variant using rockchip_perpin_drv_type
* @offset: if initialized to -1 it will be autocalculated, by specifying
@ -126,6 +146,21 @@ struct rockchip_pin_bank {
}, \
}
#define PIN_BANK_IOMUX_FLAGS_OFFSET(id, pins, label, iom0, iom1, iom2, \
iom3, offset0, offset1, offset2, \
offset3) \
{ \
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
.iomux = { \
{ .type = iom0, .offset = offset0 }, \
{ .type = iom1, .offset = offset1 }, \
{ .type = iom2, .offset = offset2 }, \
{ .type = iom3, .offset = offset3 }, \
}, \
}
#define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
{ \
.bank_num = id, \
@ -220,6 +255,25 @@ struct rockchip_pin_bank {
.pull_type[3] = pull3, \
}
#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_type = FLAG, \
}
#define MR_DEFAULT(ID, PIN, FUNC, REG, VAL) \
PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_DEFAULT)
#define MR_TOPGRF(ID, PIN, FUNC, REG, VAL) \
PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_TOPGRF)
#define MR_PMUGRF(ID, PIN, FUNC, REG, VAL) \
PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_PMUGRF)
/**
* struct rockchip_mux_recalced_data: recalculate a pin iomux data.
* @num: bank number.
@ -241,6 +295,7 @@ struct rockchip_mux_recalced_data {
* @bank_num: bank number.
* @pin: index at register or used to calc index.
* @func: the min pin.
* @route_type: the register type.
* @route_offset: the max pin.
* @route_val: the register offset.
*/
@ -248,6 +303,7 @@ struct rockchip_mux_route_data {
u8 bank_num;
u8 pin;
u8 func;
enum rockchip_pin_route_type route_type : 8;
u32 route_offset;
u32 route_val;
};
@ -289,8 +345,6 @@ extern const struct pinctrl_ops rockchip_pinctrl_ops;
int rockchip_pinctrl_probe(struct udevice *dev);
void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
int *reg, u8 *bit, int *mask);
bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
int mux, u32 *reg, u32 *value);
int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask);
int rockchip_translate_drive_value(int type, int strength);
int rockchip_translate_pull_value(int type, int pull);