summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2021-06-16 10:54:37 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2021-06-16 10:54:37 +0200
commit906bc49aab6a2679d3ee8da31af79844db3dd940 (patch)
tree87b5dac8771cc4887393336c2c1e4c58c25f6b71 /drivers
parent0ae461c2ee6baed1a94b88c0ecfc4a9d0f4e5201 (diff)
parent3fbbaf1740bb04cfcf87136ffe0308af950696c1 (diff)
downloadbarebox-906bc49aab6a2679d3ee8da31af79844db3dd940.tar.gz
barebox-906bc49aab6a2679d3ee8da31af79844db3dd940.tar.xz
Merge branch 'for-next/pinctrl'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c790
1 files changed, 766 insertions, 24 deletions
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 58f2c4af26..be44067c8f 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -27,6 +27,7 @@
#include <of.h>
#include <of_address.h>
#include <pinctrl.h>
+#include <dt-bindings/pinctrl/rockchip.h>
#include <linux/basic_mmio_gpio.h>
#include <linux/clk.h>
@@ -36,6 +37,7 @@ enum rockchip_pinctrl_type {
RK2928,
RK3066B,
RK3188,
+ RK3568,
};
enum rockchip_pin_bank_type {
@@ -43,6 +45,70 @@ enum rockchip_pin_bank_type {
RK3188_BANK0,
};
+/**
+ * Generate a bitmask for setting a value (v) with a write mask bit in hiword
+ * register 31:16 area.
+ */
+#define WRITE_MASK_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_GPIO_ONLY BIT(0)
+#define IOMUX_WIDTH_4BIT BIT(1)
+#define IOMUX_SOURCE_PMU BIT(2)
+#define IOMUX_UNROUTED BIT(3)
+#define IOMUX_WIDTH_3BIT BIT(4)
+#define IOMUX_WIDTH_2BIT BIT(5)
+
+/**
+ * struct rockchip_iomux
+ * @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;
+};
+
+/*
+ * enum type index corresponding to rockchip_perpin_drv_list arrays index.
+ */
+enum rockchip_pin_drv_type {
+ DRV_TYPE_IO_DEFAULT = 0,
+ DRV_TYPE_IO_1V8_OR_3V0,
+ DRV_TYPE_IO_1V8_ONLY,
+ DRV_TYPE_IO_1V8_3V0_AUTO,
+ DRV_TYPE_IO_3V3_ONLY,
+ DRV_TYPE_MAX
+};
+
+/*
+ * enum type index corresponding to rockchip_pull_list arrays index.
+ */
+enum rockchip_pin_pull_type {
+ PULL_TYPE_IO_DEFAULT = 0,
+ PULL_TYPE_IO_1V8_ONLY,
+ PULL_TYPE_MAX
+};
+
+/**
+ * struct rockchip_drv
+ * @drv_type: drive strength variant using rockchip_perpin_drv_type
+ * @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 drive strength
+ * registers. if used chips own cal_drv func instead to calculate
+ * registers offset, the variant could be ignored.
+ */
+struct rockchip_drv {
+ enum rockchip_pin_drv_type drv_type;
+ int offset;
+};
+
struct rockchip_pin_bank {
void __iomem *reg_base;
struct clk *clk;
@@ -50,11 +116,14 @@ struct rockchip_pin_bank {
u8 nr_pins;
char *name;
u8 bank_num;
+ struct rockchip_iomux iomux[4];
+ struct rockchip_drv drv[4];
enum rockchip_pin_bank_type bank_type;
bool valid;
struct device_node *of_node;
struct rockchip_pinctrl *drvdata;
struct bgpio_chip bgpio_chip;
+ u32 route_mask;
};
#define PIN_BANK(id, pins, label) \
@@ -64,15 +133,78 @@ struct rockchip_pin_bank {
.name = label, \
}
+#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .type = iom0, .offset = -1 }, \
+ { .type = iom1, .offset = -1 }, \
+ { .type = iom2, .offset = -1 }, \
+ { .type = iom3, .offset = -1 }, \
+ }, \
+ }
+
+#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_location = FLAG, \
+ }
+
+#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \
+ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME)
+
+#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \
+ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF)
+
+#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \
+ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU)
+
+enum rockchip_mux_route_location {
+ ROCKCHIP_ROUTE_SAME = 0,
+ ROCKCHIP_ROUTE_PMU,
+ ROCKCHIP_ROUTE_GRF,
+};
+
+/**
+ * struct rockchip_mux_recalced_data: represent a pin iomux data.
+ * @bank_num: bank number.
+ * @pin: index at register or used to calc index.
+ * @func: the min pin.
+ * @route_location: the mux route location (same, pmu, grf).
+ * @route_offset: the max pin.
+ * @route_val: the register offset.
+ */
+struct rockchip_mux_route_data {
+ u8 bank_num;
+ u8 pin;
+ u8 func;
+ enum rockchip_mux_route_location route_location;
+ u32 route_offset;
+ u32 route_val;
+};
+
struct rockchip_pin_ctrl {
struct rockchip_pin_bank *pin_banks;
u32 nr_banks;
u32 nr_pins;
char *label;
enum rockchip_pinctrl_type type;
- int mux_offset;
+ int grf_mux_offset;
+ int pmu_mux_offset;
+ int grf_drv_offset;
+ int pmu_drv_offset;
+ struct rockchip_mux_route_data *iomux_routes;
+ u32 niomux_routes;
void (*pull_calc_reg)(struct rockchip_pin_bank *bank, int pin_num,
void __iomem **reg, u8 *bit);
+ void (*drv_calc_reg)(struct rockchip_pin_bank *bank,
+ int pin_num, void __iomem **reg, u8 *bit);
};
struct rockchip_pinctrl {
@@ -96,6 +228,110 @@ enum {
RK_GPIO_EXT_PORT = 0x50,
};
+/* GPIO registers */
+enum {
+ RK_GPIOV2_DR_L = 0x00,
+ RK_GPIOV2_DR_H = 0x04,
+ RK_GPIOV2_DDR_L = 0x08,
+ RK_GPIOV2_DDR_H = 0x0c,
+};
+
+static struct rockchip_pin_bank *gc_to_rockchip_pinctrl(struct gpio_chip *gc)
+{
+ struct bgpio_chip *bgc = to_bgpio_chip(gc);
+
+ return container_of(bgc, struct rockchip_pin_bank, bgpio_chip);
+}
+
+static int rockchip_gpiov2_direction_input(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+ u32 mask;
+
+ mask = 1 << (16 + (gpio % 16));
+
+ if (gpio < 16)
+ writel(mask, bank->reg_base + RK_GPIOV2_DDR_L);
+ else
+ writel(mask, bank->reg_base + RK_GPIOV2_DDR_H);
+
+ return 0;
+}
+
+static int rockchip_gpiov2_get_direction(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+ u32 r;
+
+ if (gpio < 16)
+ r = readl(bank->reg_base + RK_GPIOV2_DDR_L);
+ else
+ r = readl(bank->reg_base + RK_GPIOV2_DDR_H);
+
+ return r & BIT(gpio % 16) ? GPIOF_DIR_OUT : GPIOF_DIR_IN;
+}
+
+static void rockchip_gpiov2_set_value(struct gpio_chip *gc, unsigned int gpio,
+ int val)
+{
+ struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+ u32 mask, vval = 0;
+
+ mask = 1 << (16 + (gpio % 16));
+ if (val)
+ vval = 1 << (gpio % 16);
+
+ if (gpio < 16)
+ writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
+ else
+ writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
+}
+
+static int rockchip_gpiov2_direction_output(struct gpio_chip *gc,
+ unsigned int gpio, int val)
+{
+ struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+ u32 mask, out, vval = 0;
+
+ mask = 1 << (16 + (gpio % 16));
+ out = 1 << (gpio % 16);
+ if (val)
+ vval = 1 << (gpio % 16);
+
+ if (gpio < 16) {
+ writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_L);
+ writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_L);
+ } else {
+ writel(mask | vval, bank->reg_base + RK_GPIOV2_DR_H);
+ writel(mask | out, bank->reg_base + RK_GPIOV2_DDR_H);
+ }
+
+ return 0;
+}
+
+static int rockchip_gpiov2_get_value(struct gpio_chip *gc, unsigned int gpio)
+{
+ struct rockchip_pin_bank *bank = gc_to_rockchip_pinctrl(gc);
+ u32 mask, r;
+
+ mask = 1 << (gpio % 16);
+
+ if (gpio < 16)
+ r = readl(bank->reg_base + RK_GPIOV2_DR_L);
+ else
+ r = readl(bank->reg_base + RK_GPIOV2_DR_L);
+
+ return r & mask ? 1 : 0;
+}
+
+static struct gpio_ops rockchip_gpio_ops = {
+ .direction_input = rockchip_gpiov2_direction_input,
+ .direction_output = rockchip_gpiov2_direction_output,
+ .get = rockchip_gpiov2_get_value,
+ .set = rockchip_gpiov2_set_value,
+ .get_direction = rockchip_gpiov2_get_direction,
+};
+
static int rockchip_gpiolib_register(struct device_d *dev,
struct rockchip_pinctrl *info)
{
@@ -106,6 +342,8 @@ static int rockchip_gpiolib_register(struct device_d *dev,
int i;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+ struct gpio_chip *gpio = &bank->bgpio_chip.gc;
+
if (!bank->valid) {
dev_warn(dev, "bank %s is not valid\n", bank->name);
continue;
@@ -113,12 +351,24 @@ static int rockchip_gpiolib_register(struct device_d *dev,
reg_base = bank->reg_base;
- ret = bgpio_init(&bank->bgpio_chip, dev, 4,
- reg_base + RK_GPIO_EXT_PORT,
- reg_base + RK_GPIO_SWPORT_DR, NULL,
- reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
- if (ret)
- goto fail;
+ if (ctrl->type == RK3568) {
+ gpio->ngpio = 32;
+ gpio->dev = dev;
+ gpio->ops = &rockchip_gpio_ops;
+ gpio->base = of_alias_get_id(bank->of_node, "gpio");
+ if (gpio->base < 0)
+ return -EINVAL;
+ gpio->base *= 32;
+ } else {
+ ret = bgpio_init(&bank->bgpio_chip, dev, 4,
+ reg_base + RK_GPIO_EXT_PORT,
+ reg_base + RK_GPIO_SWPORT_DR, NULL,
+ reg_base + RK_GPIO_SWPORT_DDR, NULL, 0);
+ if (ret)
+ goto fail;
+ }
+
+ bank->bgpio_chip.gc.dev = of_find_device_by_node(bank->of_node);
bank->bgpio_chip.gc.ngpio = bank->nr_pins;
ret = gpiochip_add(&bank->bgpio_chip.gc);
@@ -225,18 +475,147 @@ static void rk3188_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
}
}
+#define RK3568_PULL_PMU_OFFSET 0x20
+#define RK3568_PULL_GRF_OFFSET 0x80
+#define RK3568_PULL_BITS_PER_PIN 2
+#define RK3568_PULL_PINS_PER_REG 8
+#define RK3568_PULL_BANK_STRIDE 0x10
+
+static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, void __iomem **reg,
+ u8 *bit)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+ if (bank->bank_num == 0) {
+ *reg = info->reg_pmu + RK3568_PULL_PMU_OFFSET;
+ *reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
+ *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
+
+ *bit = pin_num % RK3568_PULL_PINS_PER_REG;
+ *bit *= RK3568_PULL_BITS_PER_PIN;
+ } else {
+ *reg = info->reg_base + RK3568_PULL_GRF_OFFSET;
+ *reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
+ *reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
+
+ *bit = (pin_num % RK3568_PULL_PINS_PER_REG);
+ *bit *= RK3568_PULL_BITS_PER_PIN;
+ }
+}
+
+#define RK3568_DRV_PMU_OFFSET 0x70
+#define RK3568_DRV_GRF_OFFSET 0x200
+#define RK3568_DRV_BITS_PER_PIN 8
+#define RK3568_DRV_PINS_PER_REG 2
+#define RK3568_DRV_BANK_STRIDE 0x40
+
+static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, void __iomem **reg, u8 *bit)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+
+ /* The first 32 pins of the first bank are located in PMU */
+ if (bank->bank_num == 0) {
+ *reg = info->reg_pmu + RK3568_DRV_PMU_OFFSET;
+ *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
+
+ *bit = pin_num % RK3568_DRV_PINS_PER_REG;
+ *bit *= RK3568_DRV_BITS_PER_PIN;
+ } else {
+ *reg = info->reg_base + RK3568_DRV_GRF_OFFSET;
+ *reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
+ *reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
+
+ *bit = (pin_num % RK3568_DRV_PINS_PER_REG);
+ *bit *= RK3568_DRV_BITS_PER_PIN;
+ }
+}
+
+static struct rockchip_mux_route_data rk3188_mux_route_data[] = {
+ RK_MUXROUTE_SAME(0, RK_PD0, 1, 0xa0, BIT(16 + 11)), /* non-iomuxed emmc/flash pins on flash-dqs */
+ RK_MUXROUTE_SAME(0, RK_PD0, 2, 0xa0, BIT(16 + 11) | BIT(11)), /* non-iomuxed emmc/flash pins on emmc-clk */
+};
+
+static bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
+ int mux, u32 *loc, u32 *reg, u32 *value)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
+ struct rockchip_mux_route_data *data;
+ int i;
+
+ for (i = 0; i < ctrl->niomux_routes; i++) {
+ data = &ctrl->iomux_routes[i];
+ if ((data->bank_num == bank->bank_num) &&
+ (data->pin == pin) && (data->func == mux))
+ break;
+ }
+
+ if (i >= ctrl->niomux_routes)
+ return false;
+
+ *loc = data->route_location;
+ *reg = data->route_offset;
+ *value = data->route_val;
+
+ return true;
+}
+
static int rockchip_pinctrl_set_func(struct rockchip_pin_bank *bank, int pin,
int mux)
{
struct rockchip_pinctrl *info = bank->drvdata;
- void __iomem *reg = info->reg_base + info->ctrl->mux_offset;
+ void __iomem *base, *reg;
u8 bit;
- u32 data;
+ u32 data, route_location, route_reg, route_val;
+ int iomux_num = (pin / 8);
+ int mux_type;
+ int mask;
+
+ base = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ ? info->reg_pmu : info->reg_base;
+
+ /* get basic quadrupel of mux registers and the correct reg inside */
+ mux_type = bank->iomux[iomux_num].type;
+ reg = base + bank->iomux[iomux_num].offset;
+
+ dev_dbg(info->pctl_dev.dev, "setting func of GPIO%d-%d to %d\n",
+ bank->bank_num, pin, mux);
+
+ if (mux_type & IOMUX_WIDTH_4BIT) {
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ mask = 0xf;
+ } else if (mux_type & IOMUX_WIDTH_3BIT) {
+ if ((pin % 8) >= 5)
+ reg += 0x4;
+ bit = (pin % 8 % 5) * 3;
+ mask = 0x7;
+ } else {
+ bit = (pin % 8) * 2;
+ mask = 0x3;
+ }
- /* get basic quadruple of mux registers and the correct reg inside */
- reg += bank->bank_num * 0x10;
- reg += (pin / 8) * 4;
- bit = (pin % 8) * 2;
+ if (bank->route_mask & BIT(pin)) {
+ if (rockchip_get_mux_route(bank, pin, mux, &route_location,
+ &route_reg, &route_val)) {
+ void __iomem *route = base;
+
+ /* handle special locations */
+ switch (route_location) {
+ case ROCKCHIP_ROUTE_PMU:
+ route = info->reg_pmu;
+ break;
+ case ROCKCHIP_ROUTE_GRF:
+ route = info->reg_base;
+ break;
+ }
+
+ writel(route_val, route + route_reg);
+ }
+ }
data = 3 << (bit + 16);
data |= (mux & 3) << bit;
@@ -271,6 +650,18 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
writel(data, reg);
break;
case RK3188:
+ case RK3568:
+ /*
+ * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6,
+ * where that pull up value becomes 3.
+ */
+ if (ctrl->type == RK3568 &&
+ bank->bank_num == 0 &&
+ pin_num >= 27 &&
+ pin_num <= 30 &&
+ pull == RK_BIAS_PULL_UP)
+ pull = 3;
+
data = ((1 << RK3188_PULL_BITS_PER_PIN) - 1) << (bit + 16);
data |= pull << bit;
writel(data, reg);
@@ -283,12 +674,135 @@ static int rockchip_pinctrl_set_pull(struct rockchip_pin_bank *bank,
return 0;
}
+static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
+ { 2, 4, 8, 12, -1, -1, -1, -1 },
+ { 3, 6, 9, 12, -1, -1, -1, -1 },
+ { 5, 10, 15, 20, -1, -1, -1, -1 },
+ { 4, 6, 8, 10, 12, 14, 16, 18 },
+ { 4, 7, 10, 13, 16, 19, 22, 26 }
+};
+
+#define RK3288_DRV_BITS_PER_PIN 2
+#define RK3399_DRV_3BITS_PER_PIN 3
+
+static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
+ int pin_num, int strength)
+{
+ struct rockchip_pinctrl *info = bank->drvdata;
+ struct rockchip_pin_ctrl *ctrl = info->ctrl;
+ int ret, i;
+ void __iomem *reg;
+ u32 data, rmask, rmask_bits, temp, val;
+ u8 bit;
+ int drv_type = bank->drv[pin_num / 8].drv_type;
+
+ if (!ctrl->drv_calc_reg)
+ return -ENOTSUPP;
+
+ dev_dbg(info->pctl_dev.dev, "setting drive of GPIO%d-%d to %d\n",
+ bank->bank_num, pin_num, strength);
+
+ ctrl->drv_calc_reg(bank, pin_num, &reg, &bit);
+ if (ctrl->type == RK3568) {
+ rmask_bits = RK3568_DRV_BITS_PER_PIN;
+ ret = (1 << (strength + 1)) - 1;
+ goto config;
+ }
+
+ ret = -EINVAL;
+ for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[drv_type]); i++) {
+ if (rockchip_perpin_drv_list[drv_type][i] == strength) {
+ ret = i;
+ break;
+ } else if (rockchip_perpin_drv_list[drv_type][i] < 0) {
+ ret = rockchip_perpin_drv_list[drv_type][i];
+ break;
+ }
+ }
+
+ if (ret < 0) {
+ dev_err(info->pctl_dev.dev, "unsupported driver strength %d\n",
+ strength);
+ return ret;
+ }
+
+ switch (drv_type) {
+ case DRV_TYPE_IO_1V8_3V0_AUTO:
+ case DRV_TYPE_IO_3V3_ONLY:
+ rmask_bits = RK3399_DRV_3BITS_PER_PIN;
+ switch (bit) {
+ case 0 ... 12:
+ /* regular case, nothing to do */
+ break;
+ case 15:
+ /*
+ * drive-strength offset is special, as it is spread
+ * over 2 registers, the bit data[15] contains bit 0
+ * of the value while temp[1:0] contains bits 2 and 1
+ */
+ data = (ret & 0x1) << 15;
+ temp = (ret >> 0x1) & 0x3;
+
+ rmask = BIT(15) | BIT(31);
+ data |= BIT(31);
+
+ val = readl(reg);
+ val &= ~rmask;
+ val |= data & rmask;
+ writel(val, reg);
+
+ rmask = 0x3 | (0x3 << 16);
+ temp |= (0x3 << 16);
+ reg += 0x4;
+
+ val = readl(reg);
+ val &= ~rmask;
+ val |= temp & rmask;
+ writel(val, reg);
+
+ return ret;
+ case 18 ... 21:
+ /* setting fully enclosed in the second register */
+ reg += 4;
+ bit -= 16;
+ break;
+ default:
+ dev_err(info->pctl_dev.dev, "unsupported bit: %d for pinctrl drive type: %d\n",
+ bit, drv_type);
+ return -EINVAL;
+ }
+ break;
+ case DRV_TYPE_IO_DEFAULT:
+ case DRV_TYPE_IO_1V8_OR_3V0:
+ case DRV_TYPE_IO_1V8_ONLY:
+ rmask_bits = RK3288_DRV_BITS_PER_PIN;
+ break;
+ default:
+ dev_err(info->pctl_dev.dev, "unsupported pinctrl drive type: %d\n",
+ drv_type);
+ return -EINVAL;
+ }
+
+config:
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << rmask_bits) - 1) << (bit + 16);
+ rmask = data | (data >> 16);
+ data |= (ret << bit);
+
+ val = readl(reg);
+ val &= ~rmask;
+ val |= data & rmask;
+ writel(val, reg);
+
+ return ret;
+}
+
static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
struct device_node *np)
{
struct rockchip_pinctrl *info = to_rockchip_pinctrl(pdev);
const __be32 *list;
- int i, size;
+ int i, size, ret;
int bank_num, pin_num, func;
/*
@@ -307,6 +821,7 @@ static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
const __be32 *phandle;
struct device_node *np_config;
struct rockchip_pin_bank *bank;
+ u32 drive_strength;
bank_num = be32_to_cpu(*list++);
pin_num = be32_to_cpu(*list++);
@@ -321,6 +836,10 @@ static int rockchip_pinctrl_set_state(struct pinctrl_device *pdev,
rockchip_pinctrl_set_func(bank, pin_num, func);
rockchip_pinctrl_set_pull(bank, pin_num,
parse_bias_config(np_config));
+
+ ret = of_property_read_u32(np_config, "drive-strength", &drive_strength);
+ if (!ret)
+ rockchip_set_drive_perpin(bank, pin_num, drive_strength);
}
return 0;
@@ -342,8 +861,8 @@ static int rockchip_get_bank_data(struct rockchip_pin_bank *bank,
res = request_iomem_region(dev_name(dev), node_res.start, node_res.end);
if (IS_ERR(res)) {
- dev_err(dev, "cannot request iomem region %08x\n",
- node_res.start);
+ dev_err(dev, "cannot request iomem region %pa\n",
+ &node_res.start);
return PTR_ERR(res);
}
@@ -373,7 +892,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
struct rockchip_pin_ctrl *ctrl;
struct rockchip_pin_bank *bank;
char *name;
- int i;
+ int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j;
match = of_match_node(rockchip_pinctrl_dt_match, node);
ctrl = (struct rockchip_pin_ctrl *)match->data;
@@ -395,11 +914,91 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(
}
}
+ grf_offs = ctrl->grf_mux_offset;
+ pmu_offs = ctrl->pmu_mux_offset;
+ drv_pmu_offs = ctrl->pmu_drv_offset;
+ drv_grf_offs = ctrl->grf_drv_offset;
bank = ctrl->pin_banks;
for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
+ int bank_pins = 0;
+
bank->drvdata = d;
bank->pin_base = ctrl->nr_pins;
ctrl->nr_pins += bank->nr_pins;
+
+ /* calculate iomux and drv offsets */
+ for (j = 0; j < 4; j++) {
+ struct rockchip_iomux *iom = &bank->iomux[j];
+ struct rockchip_drv *drv = &bank->drv[j];
+ int inc;
+
+ if (bank_pins >= bank->nr_pins)
+ break;
+
+ /* preset iomux offset value, set new start value */
+ if (iom->offset >= 0) {
+ if (iom->type & IOMUX_SOURCE_PMU)
+ pmu_offs = iom->offset;
+ else
+ grf_offs = iom->offset;
+ } else { /* set current iomux offset */
+ iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+ pmu_offs : grf_offs;
+ }
+
+ /* preset drv offset value, set new start value */
+ if (drv->offset >= 0) {
+ if (iom->type & IOMUX_SOURCE_PMU)
+ drv_pmu_offs = drv->offset;
+ else
+ drv_grf_offs = drv->offset;
+ } else { /* set current drv offset */
+ drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
+ drv_pmu_offs : drv_grf_offs;
+ }
+
+ dev_dbg(dev, "bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
+ i, j, iom->offset, drv->offset);
+
+ /*
+ * Increase offset according to iomux width.
+ * 4bit iomux'es are spread over two registers.
+ */
+ inc = (iom->type & (IOMUX_WIDTH_4BIT |
+ IOMUX_WIDTH_3BIT |
+ IOMUX_WIDTH_2BIT)) ? 8 : 4;
+ if (iom->type & IOMUX_SOURCE_PMU)
+ pmu_offs += inc;
+ else
+ grf_offs += inc;
+
+ /*
+ * Increase offset according to drv width.
+ * 3bit drive-strenth'es are spread over two registers.
+ */
+ if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
+ (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
+ inc = 8;
+ else
+ inc = 4;
+
+ if (iom->type & IOMUX_SOURCE_PMU)
+ drv_pmu_offs += inc;
+ else
+ drv_grf_offs += inc;
+
+ bank_pins += 8;
+ }
+
+ /* calculate the per-bank route_mask */
+ for (j = 0; j < ctrl->niomux_routes; j++) {
+ int pin = 0;
+
+ if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
+ pin = ctrl->iomux_routes[j].pin;
+ bank->route_mask |= BIT(pin);
+ }
+ }
}
return ctrl;
@@ -411,6 +1010,8 @@ static int rockchip_pinctrl_probe(struct device_d *dev)
struct rockchip_pin_ctrl *ctrl;
int ret;
+ of_platform_populate(dev->device_node, NULL, NULL);
+
info = xzalloc(sizeof(struct rockchip_pinctrl));
ctrl = rockchip_pinctrl_get_soc_data(info, dev);
@@ -462,7 +1063,7 @@ static struct rockchip_pin_ctrl rk2928_pin_ctrl = {
.pin_banks = rk2928_pin_banks,
.nr_banks = ARRAY_SIZE(rk2928_pin_banks),
.type = RK2928,
- .mux_offset = 0xa8,
+ .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
};
@@ -479,7 +1080,7 @@ static struct rockchip_pin_ctrl rk3066a_pin_ctrl = {
.pin_banks = rk3066a_pin_banks,
.nr_banks = ARRAY_SIZE(rk3066a_pin_banks),
.type = RK2928,
- .mux_offset = 0xa8,
+ .grf_mux_offset = 0xa8,
.pull_calc_reg = rk2928_calc_pull_reg_and_bit,
};
@@ -494,11 +1095,11 @@ static struct rockchip_pin_ctrl rk3066b_pin_ctrl = {
.pin_banks = rk3066b_pin_banks,
.nr_banks = ARRAY_SIZE(rk3066b_pin_banks),
.type = RK3066B,
- .mux_offset = 0x60,
+ .grf_mux_offset = 0x60,
};
static struct rockchip_pin_bank rk3188_pin_banks[] = {
- PIN_BANK(0, 32, "gpio0"),
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_GPIO_ONLY, 0, 0, 0),
PIN_BANK(1, 32, "gpio1"),
PIN_BANK(2, 32, "gpio2"),
PIN_BANK(3, 32, "gpio3"),
@@ -508,10 +1109,146 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
.pin_banks = rk3188_pin_banks,
.nr_banks = ARRAY_SIZE(rk3188_pin_banks),
.type = RK3188,
- .mux_offset = 0x60,
+ .grf_mux_offset = 0x60,
+ .iomux_routes = rk3188_mux_route_data,
+ .niomux_routes = ARRAY_SIZE(rk3188_mux_route_data),
.pull_calc_reg = rk3188_calc_pull_reg_and_bit,
};
+static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+ RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */
+ RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */
+ RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */
+ RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */
+ RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */
+ RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */
+ RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */
+ RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */
+ RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */
+ RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */
+ RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */
+ RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */
+ RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */
+ RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */
+ RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */
+ RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */
+ RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */
+ RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */
+ RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */
+ RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */
+ RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */
+ RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */
+ RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */
+ RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */
+ RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */
+ RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */
+ RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */
+ RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */
+ RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */
+ RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */
+ RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */
+};
+
+static struct rockchip_pin_bank rk3568_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+ IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
+ PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT),
+ PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT),
+ PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT),
+ PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT),
+};
+
+static struct rockchip_pin_ctrl rk3568_pin_ctrl = {
+ .pin_banks = rk3568_pin_banks,
+ .nr_banks = ARRAY_SIZE(rk3568_pin_banks),
+ .label = "RK3568-GPIO",
+ .type = RK3568,
+ .grf_mux_offset = 0x0,
+ .pmu_mux_offset = 0x0,
+ .grf_drv_offset = 0x0200,
+ .pmu_drv_offset = 0x0070,
+ .iomux_routes = rk3568_mux_route_data,
+ .niomux_routes = ARRAY_SIZE(rk3568_mux_route_data),
+ .pull_calc_reg = rk3568_calc_pull_reg_and_bit,
+ .drv_calc_reg = rk3568_calc_drv_reg_and_bit,
+};
+
static struct of_device_id rockchip_pinctrl_dt_match[] = {
{
.compatible = "rockchip,rk2928-pinctrl",
@@ -528,7 +1265,12 @@ static struct of_device_id rockchip_pinctrl_dt_match[] = {
{
.compatible = "rockchip,rk3188-pinctrl",
.data = &rk3188_pin_ctrl,
- }, {
+ },
+ {
+ .compatible = "rockchip,rk3568-pinctrl",
+ .data = &rk3568_pin_ctrl
+ },
+ {
/* sentinel */
}
};
@@ -539,4 +1281,4 @@ static struct driver_d rockchip_pinctrl_driver = {
.of_compatible = DRV_OF_COMPAT(rockchip_pinctrl_dt_match),
};
-console_platform_driver(rockchip_pinctrl_driver);
+core_platform_driver(rockchip_pinctrl_driver);