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;
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);
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;
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, 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);
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;
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);
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;
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);
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;
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, 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);
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;
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, 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);
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;
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);
*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;
}
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)
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] = {
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;
#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
*/
#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
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
}, \
}
+#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, \
.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.
* @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.
*/
u8 bank_num;
u8 pin;
u8 func;
+ enum rockchip_pin_route_type route_type : 8;
u32 route_offset;
u32 route_val;
};
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);