static int meson_ee_gpio_irq_type(struct irq_data *irqd, unsigned int type)
{
struct meson_domain *domain = to_meson_domain(irqd->chip_data);
+ struct meson_bank *bank;
struct irq_data *parent_data;
unsigned long flags;
unsigned int trigger_type[2];
unsigned int gpio_virq;
unsigned char cnt;
unsigned char pin;
+ unsigned char irq_pin;
+ int ret;
type = type & IRQ_TYPE_SENSE_MASK;
/*the gpio hwirq eqaul to gpio offset in gpio chip*/
pin = domain->data->pin_base + irqd->hwirq;
+ ret = meson_get_bank(domain, pin, &bank);
+ if (ret)
+ return ret;
+
+ if (bank->irq < 0)
+ return -EINVAL;
+
+ irq_pin = bank->irq + pin - bank->first;
+
/*set pin select register*/
start_bit = (cnt & 3) << 3;
regmap_update_bits(domain->reg_irq,
(cnt < 4)?(GPIO_IRQ_MUX_0_3 * 4):(GPIO_IRQ_MUX_4_7 * 4),
0xff << start_bit,
- pin << start_bit);
+ irq_pin << start_bit);
/**
*TODO: support to configure the filter registers by
* the func interface.
static int meson_ao_gpio_irq_type(struct irq_data *irqd, unsigned int type)
{
struct meson_domain *domain = to_meson_domain(irqd->chip_data);
+ struct meson_bank *bank;
struct irq_data *parent_data;
unsigned long flags;
unsigned int trigger_type[2];
unsigned int gpio_virq;
unsigned char cnt;
unsigned char pin;
+ unsigned char irq_pin;
+ int ret;
type = type & IRQ_TYPE_SENSE_MASK;
/*the gpio hwirq eqaul to gpio offset in gpio chip*/
pin = domain->data->pin_base + irqd->hwirq;
+ ret = meson_get_bank(domain, pin, &bank);
+ if (ret)
+ return ret;
+
+ if (bank->irq < 0)
+ return -EINVAL;
+
+ irq_pin = bank->irq + pin - bank->first;
+
/*set pin select register*/
start_bit = cnt << 2;
regmap_update_bits(domain->reg_irq, 0,
0xf << start_bit,
- pin << start_bit);
+ irq_pin << start_bit);
/**
*TODO: support to configure the filter registers by
* the func interface.
.pinmux_type = PINMUX_V1,
.pinctrl_data = &meson_gxl_periphs_pinctrl_data,
.irq_chip = &meson_ee_gpio_irq_chip,
+ .init = meson_gxl_periphs_init,
};
struct meson_pinctrl_private meson_gxl_aobus = {
.pinmux_type = PINMUX_V1,
.pinctrl_data = &meson_gxl_aobus_pinctrl_data,
.irq_chip = &meson_ao_gpio_irq_chip,
+ .init = meson_gxl_aobus_init,
};
struct meson_pinctrl_private meson_m8b_cbus = {
.pinmux_type = PINMUX_V1,
.pinctrl_data = &meson8b_cbus_pinctrl_data,
.irq_chip = &meson_ee_gpio_irq_chip,
+ .init = NULL,
};
struct meson_pinctrl_private meson_m8b_aobus = {
.pinmux_type = PINMUX_V1,
.pinctrl_data = &meson8b_aobus_pinctrl_data,
.irq_chip = &meson_ao_gpio_irq_chip,
+ .init = NULL,
};
struct meson_pinctrl_private meson_axg_periphs = {
.pinmux_type = PINMUX_V2,
.pinctrl_data = &meson_axg_periphs_pinctrl_data,
.irq_chip = &meson_ee_gpio_irq_chip,
+ .init = NULL,
};
struct meson_pinctrl_private meson_axg_aobus = {
.pinmux_type = PINMUX_V2,
.pinctrl_data = &meson_axg_aobus_pinctrl_data,
.irq_chip = &meson_ao_gpio_irq_chip,
+ .init = meson_axg_aobus_init,
};
static const struct of_device_id meson_pinctrl_dt_match[] = {
return ret;
}
+ if (priv->init)
+ priv->init(pc);
+
meson_irq_setup(pc, priv->irq_chip);
return 0;
* @name: bank name
* @first: first pin of the bank
* @last: last pin of the bank
+ * @irq: irq base number of the bank
* @regs: array of register descriptors
*
* A bank represents a set of pins controlled by a contiguous set of
const char *name;
unsigned int first;
unsigned int last;
+ int irq;
struct meson_reg_desc regs[NUM_REG];
};
unsigned int num_funcs;
};
-struct meson_pinctrl_private {
- unsigned char pinmux_type;
- struct meson_pinctrl_data *pinctrl_data;
- struct irq_chip *irq_chip;
-};
-
struct meson_pinctrl {
struct device *dev;
struct pinctrl_dev *pcdev;
struct meson_domain *domain;
};
+struct meson_pinctrl_private {
+ unsigned char pinmux_type;
+ struct meson_pinctrl_data *pinctrl_data;
+ struct irq_chip *irq_chip;
+ int (*init)(struct meson_pinctrl *pc);
+};
+
struct meson_desc_function {
const char *name;
unsigned char muxval;
PINMUX_MAX,
};
+#define CMD_TEST_N_DIR 0x82000046
+#define TEST_N_OUTPUT 1
+
#define PIN(x, b) (b + x)
#define MESON_MUX_V2_MASK(x) (0xf << x)
#define MESON_MUX_V2_VAL(y, x) ((y & 0xf) << x)
.num_groups = ARRAY_SIZE(fn ## _groups), \
}
-#define BANK(n, f, l, per, peb, pr, pb, dr, db, or, ob, ir, ib) \
+#define BANK(n, f, l, i, per, peb, pr, pb, dr, db, or, ob, ir, ib)\
{ \
.name = n, \
.first = f, \
.last = l, \
+ .irq = i, \
.regs = { \
[REG_PULLEN] = { per, peb }, \
[REG_PULL] = { pr, pb }, \
extern struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data;
extern struct meson_pinctrl_data meson_axg_periphs_pinctrl_data;
extern struct meson_pinctrl_data meson_axg_aobus_pinctrl_data;
+
+extern int meson_gxl_aobus_init(struct meson_pinctrl *pc);
+extern int meson_gxl_periphs_init(struct meson_pinctrl *pc);
+extern int meson_axg_aobus_init(struct meson_pinctrl *pc);
};
static struct meson_bank meson8b_cbus_banks[] = {
- /* name first last pullen pull dir out in */
- BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_21, EE_OFF),
+ /* name first last irq pullen pull dir out in */
+ BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_21, EE_OFF), 97,
4, 0, 4, 0, 0, 0, 1, 0, 2, 0),
- BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF),
+ BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_16, EE_OFF), 80,
3, 0, 3, 0, 3, 0, 4, 0, 5, 0),
- BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF),
+ BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 50,
0, 0, 0, 0, 6, 0, 7, 0, 8, 0),
- BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF),
+ BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF), 14,
1, 16, 1, 16, 9, 19, 10, 19, 11, 19),
- BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF),
+ BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 43,
2, 20, 2, 20, 0, 22, 1, 22, 2, 22),
- BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_18, EE_OFF),
+ BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_18, EE_OFF), 24,
2, 0, 2, 0, 9, 0, 10, 0, 11, 0),
- BANK("DIF", PIN(DIF_0_P, EE_OFF), PIN(DIF_4_N, EE_OFF),
+ BANK("DIF", PIN(DIF_0_P, EE_OFF), PIN(DIF_4_N, EE_OFF), -1,
5, 8, 5, 8, 12, 12, 13, 12, 14, 12),
};
static struct meson_bank meson8b_aobus_banks[] = {
- /* name first last pullen pull dir out in */
- BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0),
+ /* name first last irq pullen pull dir out in */
+ BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), -1,
0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
};
*/
#include <dt-bindings/gpio/mesonaxg-gpio.h>
+#include <linux/arm-smccc.h>
#include "pinctrl-meson.h"
-#define EE_OFF 14
+#define EE_OFF 15
static const struct meson_desc_pin mesonaxg_periphs_pins[] = {
MESON_PINCTRL_PIN(MESON_PIN(GPIOZ_0, EE_OFF), 0x2, 0,
MESON_FUNCTION(0x2, "gen_clk_ao"), /*GEN_CLK_AO */
MESON_FUNCTION(0x3, "pwm_ao_c"), /*PWMAO_C */
MESON_FUNCTION(0x4, "gen_clk")), /*GEN_CLK_EE*/
+ MESON_PINCTRL_PIN(MESON_PIN(GPIO_TEST_N, 0), 0x1, 24,
+ MESON_FUNCTION(0x0, "gpio_ao")),
};
static struct meson_bank mesonaxg_periphs_banks[] = {
- /* name first last pullen pull dir out in */
- BANK("A", PIN(GPIOA_0, EE_OFF), PIN(GPIOA_20, EE_OFF),
+ /* name first last irq pullen pull dir out in */
+ BANK("A", PIN(GPIOA_0, EE_OFF), PIN(GPIOA_20, EE_OFF), 40,
0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
- BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_15, EE_OFF),
+ BANK("Y", PIN(GPIOY_0, EE_OFF), PIN(GPIOY_15, EE_OFF), 84,
1, 0, 1, 0, 3, 0, 4, 0, 5, 0),
- BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF),
+ BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_22, EE_OFF), 61,
2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
- BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_10, EE_OFF),
+ BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_10, EE_OFF), 14,
3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
- BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_14, EE_OFF),
+ BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_14, EE_OFF), 25,
4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
};
+/* TEST_N is special pin, only used as gpio output at present.
+ * the direction control bit from AO_SEC_REG0 bit[0], it
+ * configured to output when pinctrl driver is initialized.
+ * to make the api of gpiolib work well, the reserved bit(bit[14])
+ * seen as direction control bit.
+ *
+ * AO_GPIO_O_EN_N 0x09<<2=0x24 bit[31] output level
+ * AO_GPIO_I 0x0a<<2=0x28 bit[31] input level
+ * AO_SEC_REG0 0x50<<2=0x140 bit[0] input enable
+ * AO_RTI_PULL_UP_REG 0x0b<<2=0x2c bit[14] pull-up/down
+ * AO_RTI_PULL_UP_REG 0x0b<<2=0x2c bit[30] pull-up enable
+ */
static struct meson_bank mesonaxg_aobus_banks[] = {
- /* name first last pullen pull dir out in */
- BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0),
+ /* name first last irq pullen pull dir out in */
+ BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_13, 0), 0,
0, 16, 0, 0, 0, 0, 0, 16, 1, 0),
+ BANK("TEST", PIN(GPIO_TEST_N, 0), PIN(GPIO_TEST_N, 0), -1,
+ 0, 30, 0, 14, 0, 14, 0, 31, 1, 31),
};
static struct meson_domain_data mesonaxg_periphs_domain_data = {
.name = "periphs-banks",
.banks = mesonaxg_periphs_banks,
.num_banks = ARRAY_SIZE(mesonaxg_periphs_banks),
- .pin_base = 14,
+ .pin_base = 15,
.num_pins = 85,
};
.banks = mesonaxg_aobus_banks,
.num_banks = ARRAY_SIZE(mesonaxg_aobus_banks),
.pin_base = 0,
- .num_pins = 14,
+ .num_pins = 15,
};
struct meson_pinctrl_data meson_axg_periphs_pinctrl_data = {
.domain_data = &mesonaxg_aobus_domain_data,
.num_pins = ARRAY_SIZE(mesonaxg_aobus_pins),
};
+
+int meson_axg_aobus_init(struct meson_pinctrl *pc)
+{
+ struct arm_smccc_res res;
+ /*set TEST_N to output*/
+ arm_smccc_smc(CMD_TEST_N_DIR, TEST_N_OUTPUT, 0, 0, 0, 0, 0, 0, &res);
+
+ return 0;
+}
*/
#include "pinctrl-meson.h"
+#include <linux/arm-smccc.h>
#include <dt-bindings/gpio/gxl.h>
-#define EE_OFF 10
+#define EE_OFF 11
+#define HHI_XTAL_DIVN_CNTL_GPIO (0xc883c000 + (0x2f << 2))
static const struct pinctrl_pin_desc meson_gxl_periphs_pins[] = {
MESON_PIN(GPIOZ_0, EE_OFF),
MESON_PIN(GPIOX_18, EE_OFF),
MESON_PIN(GPIOCLK_0, EE_OFF),
MESON_PIN(GPIOCLK_1, EE_OFF),
-
- MESON_PIN(GPIO_TEST_N, EE_OFF),
};
static const unsigned int emmc_nand_d07_pins[] = {
GPIO_GROUP(GPIOCLK_0, EE_OFF),
GPIO_GROUP(GPIOCLK_1, EE_OFF),
- GPIO_GROUP(GPIO_TEST_N, EE_OFF),
-
/* Bank X */
GROUP(uart_tx_a, 5, 19),
GROUP(uart_rx_a, 5, 18),
MESON_PIN(GPIOAO_7, 0),
MESON_PIN(GPIOAO_8, 0),
MESON_PIN(GPIOAO_9, 0),
+ MESON_PIN(GPIO_TEST_N, 0),
};
GPIO_GROUP(GPIOAO_7, 0),
GPIO_GROUP(GPIOAO_8, 0),
GPIO_GROUP(GPIOAO_9, 0),
+ GPIO_GROUP(GPIO_TEST_N, 0),
/* bank AO */
GROUP(uart_tx_ao_b_1, 0, 26),
"GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
"GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18",
- "GPIO_TEST_N",
+ "GPIOCLK_0", "GPIOCLK_1",
};
static const char * const emmc_groups[] = {
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
+ "GPIO_TEST_N",
};
static const char * const uart_ao_groups[] = {
FUNCTION(ao_cec),
};
+/*To use Bank CLK as normal pin, and have to set the register
+ *HHI_XTAL_DIVN_CNTL[0xc883c000 + (0x2f << 2)], as follows:
+ *
+ *bit[10] = 0
+ *bit[11] = 0
+ *bit[12] = 0
+ *
+ */
static struct meson_bank meson_gxl_periphs_banks[] = {
/* name first last pullen pull dir out in */
- BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_18, EE_OFF),
+ BANK("X", PIN(GPIOX_0, EE_OFF), PIN(GPIOX_18, EE_OFF), 89,
4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
- BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF),
+ BANK("DV", PIN(GPIODV_0, EE_OFF), PIN(GPIODV_29, EE_OFF), 59,
0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
- BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF),
+ BANK("H", PIN(GPIOH_0, EE_OFF), PIN(GPIOH_9, EE_OFF), 26,
1, 20, 1, 20, 3, 20, 4, 20, 5, 20),
- BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF),
+ BANK("Z", PIN(GPIOZ_0, EE_OFF), PIN(GPIOZ_15, EE_OFF), 10,
3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
- BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF),
+ BANK("CARD", PIN(CARD_0, EE_OFF), PIN(CARD_6, EE_OFF), 52,
2, 20, 2, 20, 6, 20, 7, 20, 8, 20),
- BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF),
+ BANK("BOOT", PIN(BOOT_0, EE_OFF), PIN(BOOT_15, EE_OFF), 36,
2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
- BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_1, EE_OFF),
+ BANK("CLK", PIN(GPIOCLK_0, EE_OFF), PIN(GPIOCLK_1, EE_OFF), 108,
3, 28, 3, 28, 9, 28, 10, 28, 11, 28),
};
+/* TEST_N is special pin, only used as gpio output at present.
+ * the direction control bit from AO_SEC_REG0 bit[0], it
+ * configured to output when pinctrl driver is initialized.
+ * to make the api of gpiolib work well, the reserved bit(bit[14])
+ * seen as direction control bit.
+ *
+ * AO_GPIO_O_EN_N 0x09<<2=0x24 bit[31] output level
+ * AO_GPIO_I 0x0a<<2=0x28 bit[31] input level
+ * AO_SEC_REG0 0x50<<2=0x140 bit[0] input enable
+ * AO_RTI_PULL_UP_REG 0x0b<<2=0x2c bit[30] pull-up/down
+ * AO_RTI_PULL_UP_REG 0x0b<<2=0x2c bit[14] pull-up enable
+ */
static struct meson_bank meson_gxl_aobus_banks[] = {
/* name first last pullen pull dir out in */
- BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_9, 0),
+ BANK("AO", PIN(GPIOAO_0, 0), PIN(GPIOAO_9, 0), 0,
0, 0, 0, 16, 0, 0, 0, 16, 1, 0),
+ BANK("TEST", PIN(GPIO_TEST_N, 0), PIN(GPIO_TEST_N, 0), -1,
+ 0, 14, 0, 30, 0, 14, 0, 31, 1, 31),
};
static struct meson_domain_data meson_gxl_periphs_domain_data = {
.name = "periphs-banks",
.banks = meson_gxl_periphs_banks,
.num_banks = ARRAY_SIZE(meson_gxl_periphs_banks),
- .pin_base = 10,
- .num_pins = 101,
+ .pin_base = 11,
+ .num_pins = 100,
};
static struct meson_domain_data meson_gxl_aobus_domain_data = {
.banks = meson_gxl_aobus_banks,
.num_banks = ARRAY_SIZE(meson_gxl_aobus_banks),
.pin_base = 0,
- .num_pins = 10,
+ .num_pins = 11,
};
struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {
.num_groups = ARRAY_SIZE(meson_gxl_aobus_groups),
.num_funcs = ARRAY_SIZE(meson_gxl_aobus_functions),
};
+
+int meson_gxl_aobus_init(struct meson_pinctrl *pc)
+{
+ struct arm_smccc_res res;
+ /*set TEST_N to output*/
+ arm_smccc_smc(CMD_TEST_N_DIR, TEST_N_OUTPUT, 0, 0, 0, 0, 0, 0, &res);
+
+ return 0;
+}
+
+int meson_gxl_periphs_init(struct meson_pinctrl *pc)
+{
+ void __iomem *reg;
+
+ if (!request_mem_region(HHI_XTAL_DIVN_CNTL_GPIO, 4, "gpioclk")) {
+ dev_err(pc->dev, "could not get region 0x%x - 0x%x\n",
+ HHI_XTAL_DIVN_CNTL_GPIO,
+ HHI_XTAL_DIVN_CNTL_GPIO + 4);
+ return -EBUSY;
+ }
+
+ reg = ioremap(HHI_XTAL_DIVN_CNTL_GPIO, 4);
+ if (!reg) {
+ dev_err(pc->dev, "could not remap register memory\n");
+ return -ENOMEM;
+ }
+ writel(readl(reg) & (~(7 << 10)), reg);
+
+ iounmap(reg);
+ release_mem_region(HHI_XTAL_DIVN_CNTL_GPIO, 4);
+
+ return 0;
+}
#define GPIOAO_7 7
#define GPIOAO_8 8
#define GPIOAO_9 9
+#define GPIO_TEST_N 10
#define GPIOZ_0 0
#define GPIOZ_1 1
#define GPIOX_18 97
#define GPIOCLK_0 98
#define GPIOCLK_1 99
-#define GPIO_TEST_N 100
#define AO 0x10
#define AO2 0x11
#define GPIOAO_11 11
#define GPIOAO_12 12
#define GPIOAO_13 13
+#define GPIO_TEST_N 14
/* Second GPIO chip */
#define GPIOZ_0 0