/* * Copyright (c) 2006-2023, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-11-25 GuEe-GUI first version */ #include #include #define DBG_TAG "pinctrl.bcm2712" #define DBG_LVL DBG_INFO #include #define BCM2712_PULL_NONE 0 #define BCM2712_PULL_DOWN 1 #define BCM2712_PULL_UP 2 #define BCM2712_PULL_MASK 0x3 #define BCM2712_FSEL_COUNT 9 #define BCM2712_FSEL_MASK 0xf #define REG_BIT_INVALID 0xffff #define BIT_TO_REG(b) (((b) >> 5) << 2) #define BIT_TO_SHIFT(b) ((b) & 0x1f) #define GPIO_REGS(n, mr, mb, pr, pb) [n] = { ((mr)*4)*8 + (mb)*4, ((pr)*4)*8 + (pb)*2 } #define EMMC_REGS(n, r, b) [n] = { 0, ((r)*4)*8 + (b)*2 } #define AGPIO_REGS(n, mr, mb, pr, pb) [n] = { ((mr)*4)*8 + (mb)*4, ((pr)*4)*8 + (pb)*2 } #define SGPIO_REGS(n, mr, mb) [n+32] = { ((mr)*4)*8 + (mb)*4, REG_BIT_INVALID } #define GPIO_PIN(a) { .number = a, .name = "gpio" #a } #define AGPIO_PIN(a) { .number = a, .name = "aon_gpio" #a } #define SGPIO_PIN(a) { .number = a+32, .name = "aon_sgpio" #a } enum bcm2712_funcs { func_gpio, func_alt1, func_alt2, func_alt3, func_alt4, func_alt5, func_alt6, func_alt7, func_alt8, func_aon_cpu_standbyb, func_aon_fp_4sec_resetb, func_aon_gpclk, func_aon_pwm, func_arm_jtag, func_aud_fs_clk0, func_avs_pmu_bsc, func_bsc_m0, func_bsc_m1, func_bsc_m2, func_bsc_m3, func_clk_observe, func_ctl_hdmi_5v, func_enet0, func_enet0_mii, func_enet0_rgmii, func_ext_sc_clk, func_fl0, func_fl1, func_gpclk0, func_gpclk1, func_gpclk2, func_hdmi_tx0_auto_i2c, func_hdmi_tx0_bsc, func_hdmi_tx1_auto_i2c, func_hdmi_tx1_bsc, func_i2s_in, func_i2s_out, func_ir_in, func_mtsif, func_mtsif_alt, func_mtsif_alt1, func_pdm, func_pkt, func_pm_led_out, func_sc0, func_sd0, func_sd2, func_sd_card_a, func_sd_card_b, func_sd_card_c, func_sd_card_d, func_sd_card_e, func_sd_card_f, func_sd_card_g, func_spdif_out, func_spi_m, func_spi_s, func_sr_edm_sense, func_te0, func_te1, func_tsio, func_uart0, func_uart1, func_uart2, func_usb_pwr, func_usb_vbus, func_uui, func_vc_i2c0, func_vc_i2c3, func_vc_i2c4, func_vc_i2c5, func_vc_i2csl, func_vc_pcm, func_vc_pwm0, func_vc_pwm1, func_vc_spi0, func_vc_spi3, func_vc_spi4, func_vc_spi5, func_vc_uart0, func_vc_uart2, func_vc_uart3, func_vc_uart4, func__, func_count = func__, }; struct bcm2712_pin_desc { rt_uint32_t number; const char *name; }; struct bcm2712_pin_funcs { #define PIN(i, f1, f2, f3, f4, f5, f6, f7, f8) \ [i] = { \ .funcs = { \ func_##f1, \ func_##f2, \ func_##f3, \ func_##f4, \ func_##f5, \ func_##f6, \ func_##f7, \ func_##f8, \ }, \ } rt_uint8_t funcs[BCM2712_FSEL_COUNT - 1]; }; struct bcm2712_pin_regs { rt_uint16_t mux_bit; rt_uint16_t pad_bit; }; struct bcm2712_pinctrl_soc_data { rt_size_t num_pins; const struct bcm2712_pin_desc *desc; const struct bcm2712_pin_funcs *funcs; const struct bcm2712_pin_regs *regs; }; struct bcm2712_pinctrl { struct rt_device_pin parent; const struct bcm2712_pinctrl_soc_data *soc_data; void *base; struct rt_spinlock lock; }; #define raw_to_bcm2712_pinctrl(raw) rt_container_of(raw, struct bcm2712_pinctrl, parent) static const char * const bcm2712_func_names[] = { #define FUNC_NAME(name) [func_##name] = #name FUNC_NAME(gpio), FUNC_NAME(alt1), FUNC_NAME(alt2), FUNC_NAME(alt3), FUNC_NAME(alt4), FUNC_NAME(alt5), FUNC_NAME(alt6), FUNC_NAME(alt7), FUNC_NAME(alt8), FUNC_NAME(aon_cpu_standbyb), FUNC_NAME(aon_fp_4sec_resetb), FUNC_NAME(aon_gpclk), FUNC_NAME(aon_pwm), FUNC_NAME(arm_jtag), FUNC_NAME(aud_fs_clk0), FUNC_NAME(avs_pmu_bsc), FUNC_NAME(bsc_m0), FUNC_NAME(bsc_m1), FUNC_NAME(bsc_m2), FUNC_NAME(bsc_m3), FUNC_NAME(clk_observe), FUNC_NAME(ctl_hdmi_5v), FUNC_NAME(enet0), FUNC_NAME(enet0_mii), FUNC_NAME(enet0_rgmii), FUNC_NAME(ext_sc_clk), FUNC_NAME(fl0), FUNC_NAME(fl1), FUNC_NAME(gpclk0), FUNC_NAME(gpclk1), FUNC_NAME(gpclk2), FUNC_NAME(hdmi_tx0_auto_i2c), FUNC_NAME(hdmi_tx0_bsc), FUNC_NAME(hdmi_tx1_auto_i2c), FUNC_NAME(hdmi_tx1_bsc), FUNC_NAME(i2s_in), FUNC_NAME(i2s_out), FUNC_NAME(ir_in), FUNC_NAME(mtsif), FUNC_NAME(mtsif_alt), FUNC_NAME(mtsif_alt1), FUNC_NAME(pdm), FUNC_NAME(pkt), FUNC_NAME(pm_led_out), FUNC_NAME(sc0), FUNC_NAME(sd0), FUNC_NAME(sd2), FUNC_NAME(sd_card_a), FUNC_NAME(sd_card_b), FUNC_NAME(sd_card_c), FUNC_NAME(sd_card_d), FUNC_NAME(sd_card_e), FUNC_NAME(sd_card_f), FUNC_NAME(sd_card_g), FUNC_NAME(spdif_out), FUNC_NAME(spi_m), FUNC_NAME(spi_s), FUNC_NAME(sr_edm_sense), FUNC_NAME(te0), FUNC_NAME(te1), FUNC_NAME(tsio), FUNC_NAME(uart0), FUNC_NAME(uart1), FUNC_NAME(uart2), FUNC_NAME(usb_pwr), FUNC_NAME(usb_vbus), FUNC_NAME(uui), FUNC_NAME(vc_i2c0), FUNC_NAME(vc_i2c3), FUNC_NAME(vc_i2c4), FUNC_NAME(vc_i2c5), FUNC_NAME(vc_i2csl), FUNC_NAME(vc_pcm), FUNC_NAME(vc_pwm0), FUNC_NAME(vc_pwm1), FUNC_NAME(vc_spi0), FUNC_NAME(vc_spi3), FUNC_NAME(vc_spi4), FUNC_NAME(vc_spi5), FUNC_NAME(vc_uart0), FUNC_NAME(vc_uart2), FUNC_NAME(vc_uart3), FUNC_NAME(vc_uart4), #undef FUNC_NAME }; rt_inline rt_uint32_t bcm2712_reg_rd(struct bcm2712_pinctrl *pc, int reg) { return HWREG32(pc->base + reg); } rt_inline void bcm2712_reg_wr(struct bcm2712_pinctrl *pc, int reg, rt_uint32_t val) { HWREG32(pc->base + reg) = val; } static void bcm2712_pinctrl_fsel_set(struct bcm2712_pinctrl *pc, rt_ubase_t pin, enum bcm2712_funcs func) { int fsel, cur; const rt_uint8_t *pin_funcs; rt_uint32_t bit = pc->soc_data->regs[pin].mux_bit, val; if (!bit || func >= func_count) { return; } fsel = BCM2712_FSEL_COUNT; if (func >= BCM2712_FSEL_COUNT) { /* Convert to an fsel number */ pin_funcs = pc->soc_data->funcs[pin].funcs; for (int i = 1; i < BCM2712_FSEL_COUNT; ++i) { if (pin_funcs[i - 1] == func) { fsel = i; break; } } } else { fsel = (enum bcm2712_funcs)func; } if (fsel >= BCM2712_FSEL_COUNT) { return; } val = bcm2712_reg_rd(pc, BIT_TO_REG(bit)); cur = (val >> BIT_TO_SHIFT(bit)) & BCM2712_FSEL_MASK; if (cur != fsel) { val &= ~(BCM2712_FSEL_MASK << BIT_TO_SHIFT(bit)); val |= fsel << BIT_TO_SHIFT(bit); bcm2712_reg_wr(pc, BIT_TO_REG(bit), val); } } static void bcm2712_pull_config_set(struct bcm2712_pinctrl *pc, rt_ubase_t pin, rt_uint32_t arg) { rt_uint32_t bit = pc->soc_data->regs[pin].pad_bit, val; if (bit == REG_BIT_INVALID) { return; } val = bcm2712_reg_rd(pc, BIT_TO_REG(bit)); val &= ~(BCM2712_PULL_MASK << BIT_TO_SHIFT(bit)); val |= (arg << BIT_TO_SHIFT(bit)); bcm2712_reg_wr(pc, BIT_TO_REG(bit), val); } static const struct rt_pin_ctrl_conf_params bcm2712_conf_params[] = { { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, }; static rt_err_t bcm2712_pinctrl_confs_apply_once(struct bcm2712_pinctrl *pc, struct rt_ofw_node *np) { rt_err_t err = RT_EOK; rt_ubase_t pin; const char *string; struct rt_ofw_prop *prop; enum bcm2712_funcs func = func_count; const struct rt_pin_ctrl_conf_params *conf = RT_NULL; if (rt_ofw_prop_read_string(np, "function", &string)) { return -RT_EINVAL; } for (int i = 0; i < RT_ARRAY_SIZE(bcm2712_func_names); ++i) { if (!rt_strcmp(string, bcm2712_func_names[i])) { func = (enum bcm2712_funcs)i; break; } } if (func == func_count) { return -RT_EINVAL; } for (int i = 0; i < RT_ARRAY_SIZE(bcm2712_conf_params); ++i) { if (rt_ofw_prop_read_bool(np, bcm2712_conf_params[i].propname)) { conf = &bcm2712_conf_params[i]; break; } } rt_ofw_foreach_prop_string(np, "pins", prop, string) { pin = pc->soc_data->num_pins; for (int i = 0; i < pc->soc_data->num_pins; ++i) { if (!rt_strcmp(pc->soc_data->desc[i].name, string)) { pin = pc->soc_data->desc[i].number; break; } } if (pin == pc->soc_data->num_pins) { err = -RT_EINVAL; break; } bcm2712_pinctrl_fsel_set(pc, pin, func); if (conf) { switch (conf->param) { case PIN_CONFIG_BIAS_DISABLE: bcm2712_pull_config_set(pc, pin, BCM2712_PULL_NONE); break; case PIN_CONFIG_BIAS_PULL_DOWN: bcm2712_pull_config_set(pc, pin, BCM2712_PULL_DOWN); break; case PIN_CONFIG_BIAS_PULL_UP: bcm2712_pull_config_set(pc, pin, BCM2712_PULL_UP); break; default: err = -RT_ENOSYS; break; } } } return err; } static rt_err_t bcm2712_pinctrl_confs_apply(struct rt_device *device, void *fw_conf_np) { rt_err_t err; rt_bool_t stage2 = RT_FALSE; struct rt_ofw_node *conf_np = fw_conf_np, *child; struct bcm2712_pinctrl *pc = raw_to_bcm2712_pinctrl(device); rt_hw_spin_lock(&pc->lock.lock); rt_ofw_foreach_child_node(conf_np, child) { stage2 = RT_TRUE; if ((err = bcm2712_pinctrl_confs_apply_once(pc, child))) { goto _unlock; } } if (!stage2) { err = bcm2712_pinctrl_confs_apply_once(pc, conf_np); } _unlock: rt_hw_spin_unlock(&pc->lock.lock); return err; } static const struct rt_pin_ops bcm2712_pinctrl_ops = { .pin_ctrl_confs_apply = bcm2712_pinctrl_confs_apply, }; static rt_err_t bcm2712_pinctrl_probe(struct rt_platform_device *pdev) { rt_err_t err; struct rt_device *dev = &pdev->parent; struct bcm2712_pinctrl *pc = rt_calloc(1, sizeof(*pc)); if (!pc) { return -RT_ENOMEM; } pc->soc_data = pdev->id->data; if (!(pc->base = rt_dm_dev_iomap(dev, 0))) { err = -RT_EIO; goto _fail; } rt_spin_lock_init(&pc->lock); pc->parent.ops = &bcm2712_pinctrl_ops; rt_ofw_data(dev->ofw_node) = &pc->parent; return RT_EOK; _fail: rt_free(pc); return err; } static const struct bcm2712_pin_desc bcm2712_c0_gpio_pins[] = { GPIO_PIN(0), GPIO_PIN(1), GPIO_PIN(2), GPIO_PIN(3), GPIO_PIN(4), GPIO_PIN(5), GPIO_PIN(6), GPIO_PIN(7), GPIO_PIN(8), GPIO_PIN(9), GPIO_PIN(10), GPIO_PIN(11), GPIO_PIN(12), GPIO_PIN(13), GPIO_PIN(14), GPIO_PIN(15), GPIO_PIN(16), GPIO_PIN(17), GPIO_PIN(18), GPIO_PIN(19), GPIO_PIN(20), GPIO_PIN(21), GPIO_PIN(22), GPIO_PIN(23), GPIO_PIN(24), GPIO_PIN(25), GPIO_PIN(26), GPIO_PIN(27), GPIO_PIN(28), GPIO_PIN(29), GPIO_PIN(30), GPIO_PIN(31), GPIO_PIN(32), GPIO_PIN(33), GPIO_PIN(34), GPIO_PIN(35), GPIO_PIN(36), GPIO_PIN(37), GPIO_PIN(38), GPIO_PIN(39), GPIO_PIN(40), GPIO_PIN(41), GPIO_PIN(42), GPIO_PIN(43), GPIO_PIN(44), GPIO_PIN(45), GPIO_PIN(46), GPIO_PIN(47), GPIO_PIN(48), GPIO_PIN(49), GPIO_PIN(50), GPIO_PIN(51), GPIO_PIN(52), GPIO_PIN(53), { 54, "emmc_cmd" }, { 55, "emmc_ds" }, { 56, "emmc_clk" }, { 57, "emmc_dat0" }, { 58, "emmc_dat1" }, { 59, "emmc_dat2" }, { 60, "emmc_dat3" }, { 61, "emmc_dat4" }, { 62, "emmc_dat5" }, { 63, "emmc_dat6" }, { 64, "emmc_dat7" }, }; static const struct bcm2712_pin_funcs bcm2712_c0_gpio_pin_funcs[] = { PIN(0, bsc_m3, vc_i2c0, gpclk0, enet0, vc_pwm1, vc_spi0, ir_in, _), PIN(1, bsc_m3, vc_i2c0, gpclk1, enet0, vc_pwm1, sr_edm_sense, vc_spi0, vc_uart3), PIN(2, pdm, i2s_in, gpclk2, vc_spi4, pkt, vc_spi0, vc_uart3, _), PIN(3, pdm, i2s_in, vc_spi4, pkt, vc_spi0, vc_uart3, _, _), PIN(4, pdm, i2s_in, arm_jtag, vc_spi4, pkt, vc_spi0, vc_uart3, _), PIN(5, pdm, vc_i2c3, arm_jtag, sd_card_e, vc_spi4, pkt, vc_pcm, vc_i2c5), PIN(6, pdm, vc_i2c3, arm_jtag, sd_card_e, vc_spi4, pkt, vc_pcm, vc_i2c5), PIN(7, i2s_out, spdif_out, arm_jtag, sd_card_e, vc_i2c3, enet0_rgmii, vc_pcm, vc_spi4), PIN(8, i2s_out, aud_fs_clk0, arm_jtag, sd_card_e, vc_i2c3, enet0_mii, vc_pcm, vc_spi4), PIN(9, i2s_out, aud_fs_clk0, arm_jtag, sd_card_e, enet0_mii, sd_card_c, vc_spi4, _), PIN(10, bsc_m3, mtsif_alt1, i2s_in, i2s_out, vc_spi5, enet0_mii, sd_card_c, vc_spi4), PIN(11, bsc_m3, mtsif_alt1, i2s_in, i2s_out, vc_spi5, enet0_mii, sd_card_c, vc_spi4), PIN(12, spi_s, mtsif_alt1, i2s_in, i2s_out, vc_spi5, vc_i2csl, sd0, sd_card_d), PIN(13, spi_s, mtsif_alt1, i2s_out, usb_vbus, vc_spi5, vc_i2csl, sd0, sd_card_d), PIN(14, spi_s, vc_i2csl, enet0_rgmii, arm_jtag, vc_spi5, vc_pwm0, vc_i2c4, sd_card_d), PIN(15, spi_s, vc_i2csl, vc_spi3, arm_jtag, vc_pwm0, vc_i2c4, gpclk0, _), PIN(16, sd_card_b, i2s_out, vc_spi3, i2s_in, sd0, enet0_rgmii, gpclk1, _), PIN(17, sd_card_b, i2s_out, vc_spi3, i2s_in, ext_sc_clk, sd0, enet0_rgmii, gpclk2), PIN(18, sd_card_b, i2s_out, vc_spi3, i2s_in, sd0, enet0_rgmii, vc_pwm1, _), PIN(19, sd_card_b, usb_pwr, vc_spi3, pkt, spdif_out, sd0, ir_in, vc_pwm1), PIN(20, sd_card_b, uui, vc_uart0, arm_jtag, uart2, usb_pwr, vc_pcm, vc_uart4), PIN(21, usb_pwr, uui, vc_uart0, arm_jtag, uart2, sd_card_b, vc_pcm, vc_uart4), PIN(22, usb_pwr, enet0, vc_uart0, mtsif, uart2, usb_vbus, vc_pcm, vc_i2c5), PIN(23, usb_vbus, enet0, vc_uart0, mtsif, uart2, i2s_out, vc_pcm, vc_i2c5), PIN(24, mtsif, pkt, uart0, enet0_rgmii, enet0_rgmii, vc_i2c4, vc_uart3, _), PIN(25, mtsif, pkt, sc0, uart0, enet0_rgmii, enet0_rgmii, vc_i2c4, vc_uart3), PIN(26, mtsif, pkt, sc0, uart0, enet0_rgmii, vc_uart4, vc_spi5, _), PIN(27, mtsif, pkt, sc0, uart0, enet0_rgmii, vc_uart4, vc_spi5, _), PIN(28, mtsif, pkt, sc0, enet0_rgmii, vc_uart4, vc_spi5, _, _), PIN(29, mtsif, pkt, sc0, enet0_rgmii, vc_uart4, vc_spi5, _, _), PIN(30, mtsif, pkt, sc0, sd2, enet0_rgmii, gpclk0, vc_pwm0, _), PIN(31, mtsif, pkt, sc0, sd2, enet0_rgmii, vc_spi3, vc_pwm0, _), PIN(32, mtsif, pkt, sc0, sd2, enet0_rgmii, vc_spi3, vc_uart3, _), PIN(33, mtsif, pkt, sd2, enet0_rgmii, vc_spi3, vc_uart3, _, _), PIN(34, mtsif, pkt, ext_sc_clk, sd2, enet0_rgmii, vc_spi3, vc_i2c5, _), PIN(35, mtsif, pkt, sd2, enet0_rgmii, vc_spi3, vc_i2c5, _, _), PIN(36, sd0, mtsif, sc0, i2s_in, vc_uart3, vc_uart2, _, _), PIN(37, sd0, mtsif, sc0, vc_spi0, i2s_in, vc_uart3, vc_uart2, _), PIN(38, sd0, mtsif_alt, sc0, vc_spi0, i2s_in, vc_uart3, vc_uart2, _), PIN(39, sd0, mtsif_alt, sc0, vc_spi0, vc_uart3, vc_uart2, _, _), PIN(40, sd0, mtsif_alt, sc0, vc_spi0, bsc_m3, _, _, _), PIN(41, sd0, mtsif_alt, sc0, vc_spi0, bsc_m3, _, _, _), PIN(42, vc_spi0, mtsif_alt, vc_i2c0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m), PIN(43, vc_spi0, mtsif_alt, vc_i2c0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m), PIN(44, vc_spi0, mtsif_alt, enet0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m), PIN(45, vc_spi0, mtsif_alt, enet0, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m), PIN(46, vc_spi0, mtsif_alt, sd_card_a, mtsif_alt1, arm_jtag, pdm, spi_m, _), PIN(47, enet0, mtsif_alt, i2s_out, mtsif_alt1, arm_jtag, _, _, _), PIN(48, sc0, usb_pwr, spdif_out, mtsif, _, _, _, _), PIN(49, sc0, usb_pwr, aud_fs_clk0, mtsif, _, _, _, _), PIN(50, sc0, usb_vbus, sc0, _, _, _, _, _), PIN(51, sc0, enet0, sc0, sr_edm_sense, _, _, _, _), PIN(52, sc0, enet0, vc_pwm1, _, _, _, _, _), PIN(53, sc0, enet0_rgmii, ext_sc_clk, _, _, _, _, _), }; static const struct bcm2712_pin_regs bcm2712_c0_gpio_pin_regs[] = { GPIO_REGS(0, 0, 0, 7, 7), GPIO_REGS(1, 0, 1, 7, 8), GPIO_REGS(2, 0, 2, 7, 9), GPIO_REGS(3, 0, 3, 7, 10), GPIO_REGS(4, 0, 4, 7, 11), GPIO_REGS(5, 0, 5, 7, 12), GPIO_REGS(6, 0, 6, 7, 13), GPIO_REGS(7, 0, 7, 7, 14), GPIO_REGS(8, 1, 0, 8, 0), GPIO_REGS(9, 1, 1, 8, 1), GPIO_REGS(10, 1, 2, 8, 2), GPIO_REGS(11, 1, 3, 8, 3), GPIO_REGS(12, 1, 4, 8, 4), GPIO_REGS(13, 1, 5, 8, 5), GPIO_REGS(14, 1, 6, 8, 6), GPIO_REGS(15, 1, 7, 8, 7), GPIO_REGS(16, 2, 0, 8, 8), GPIO_REGS(17, 2, 1, 8, 9), GPIO_REGS(18, 2, 2, 8, 10), GPIO_REGS(19, 2, 3, 8, 11), GPIO_REGS(20, 2, 4, 8, 12), GPIO_REGS(21, 2, 5, 8, 13), GPIO_REGS(22, 2, 6, 8, 14), GPIO_REGS(23, 2, 7, 9, 0), GPIO_REGS(24, 3, 0, 9, 1), GPIO_REGS(25, 3, 1, 9, 2), GPIO_REGS(26, 3, 2, 9, 3), GPIO_REGS(27, 3, 3, 9, 4), GPIO_REGS(28, 3, 4, 9, 5), GPIO_REGS(29, 3, 5, 9, 6), GPIO_REGS(30, 3, 6, 9, 7), GPIO_REGS(31, 3, 7, 9, 8), GPIO_REGS(32, 4, 0, 9, 9), GPIO_REGS(33, 4, 1, 9, 10), GPIO_REGS(34, 4, 2, 9, 11), GPIO_REGS(35, 4, 3, 9, 12), GPIO_REGS(36, 4, 4, 9, 13), GPIO_REGS(37, 4, 5, 9, 14), GPIO_REGS(38, 4, 6, 10, 0), GPIO_REGS(39, 4, 7, 10, 1), GPIO_REGS(40, 5, 0, 10, 2), GPIO_REGS(41, 5, 1, 10, 3), GPIO_REGS(42, 5, 2, 10, 4), GPIO_REGS(43, 5, 3, 10, 5), GPIO_REGS(44, 5, 4, 10, 6), GPIO_REGS(45, 5, 5, 10, 7), GPIO_REGS(46, 5, 6, 10, 8), GPIO_REGS(47, 5, 7, 10, 9), GPIO_REGS(48, 6, 0, 10, 10), GPIO_REGS(49, 6, 1, 10, 11), GPIO_REGS(50, 6, 2, 10, 12), GPIO_REGS(51, 6, 3, 10, 13), GPIO_REGS(52, 6, 4, 10, 14), GPIO_REGS(53, 6, 5, 11, 0), EMMC_REGS(54, 11, 1), /* EMMC_CMD */ EMMC_REGS(55, 11, 2), /* EMMC_DS */ EMMC_REGS(56, 11, 3), /* EMMC_CLK */ EMMC_REGS(57, 11, 4), /* EMMC_DAT0 */ EMMC_REGS(58, 11, 5), /* EMMC_DAT1 */ EMMC_REGS(59, 11, 6), /* EMMC_DAT2 */ EMMC_REGS(60, 11, 7), /* EMMC_DAT3 */ EMMC_REGS(61, 11, 8), /* EMMC_DAT4 */ EMMC_REGS(62, 11, 9), /* EMMC_DAT5 */ EMMC_REGS(63, 11, 10), /* EMMC_DAT6 */ EMMC_REGS(64, 11, 11), /* EMMC_DAT7 */ }; static struct bcm2712_pinctrl_soc_data bcm2712_c0_data = { .num_pins = RT_ARRAY_SIZE(bcm2712_c0_gpio_pins), .desc = bcm2712_c0_gpio_pins, .funcs = bcm2712_c0_gpio_pin_funcs, .regs = bcm2712_c0_gpio_pin_regs, }; static struct bcm2712_pin_desc bcm2712_c0_aon_gpio_pins[] = { AGPIO_PIN(0), AGPIO_PIN(1), AGPIO_PIN(2), AGPIO_PIN(3), AGPIO_PIN(4), AGPIO_PIN(5), AGPIO_PIN(6), AGPIO_PIN(7), AGPIO_PIN(8), AGPIO_PIN(9), AGPIO_PIN(10), AGPIO_PIN(11), AGPIO_PIN(12), AGPIO_PIN(13), AGPIO_PIN(14), AGPIO_PIN(15), AGPIO_PIN(16), SGPIO_PIN(0), SGPIO_PIN(1), SGPIO_PIN(2), SGPIO_PIN(3), SGPIO_PIN(4), SGPIO_PIN(5), }; static const struct bcm2712_pin_funcs bcm2712_c0_aon_gpio_pin_funcs[] = { PIN(0, ir_in, vc_spi0, vc_uart3, vc_i2c3, te0, vc_i2c0, _, _), PIN(1, vc_pwm0, vc_spi0, vc_uart3, vc_i2c3, te1, aon_pwm, vc_i2c0, vc_pwm1), PIN(2, vc_pwm0, vc_spi0, vc_uart3, ctl_hdmi_5v, fl0, aon_pwm, ir_in, vc_pwm1), PIN(3, ir_in, vc_spi0, vc_uart3, aon_fp_4sec_resetb, fl1, sd_card_g, aon_gpclk, _), PIN(4, gpclk0, vc_spi0, vc_i2csl, aon_gpclk, pm_led_out, aon_pwm, sd_card_g, vc_pwm0), PIN(5, gpclk1, ir_in, vc_i2csl, clk_observe, aon_pwm, sd_card_g, vc_pwm0, _), PIN(6, uart1, vc_uart4, gpclk2, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _), PIN(7, uart1, vc_uart4, gpclk0, aon_pwm, vc_uart0, vc_spi3, _, _), PIN(8, uart1, vc_uart4, vc_i2csl, ctl_hdmi_5v, vc_uart0, vc_spi3, _, _), PIN(9, uart1, vc_uart4, vc_i2csl, aon_pwm, vc_uart0, vc_spi3, _, _), PIN(10, tsio, ctl_hdmi_5v, sc0, spdif_out, vc_spi5, usb_pwr, aon_gpclk, sd_card_f), PIN(11, tsio, uart0, sc0, aud_fs_clk0, vc_spi5, usb_vbus, vc_uart2, sd_card_f), PIN(12, tsio, uart0, vc_uart0, tsio, vc_spi5, usb_pwr, vc_uart2, sd_card_f), PIN(13, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3), PIN(14, bsc_m1, uart0, vc_uart0, uui, vc_spi5, arm_jtag, vc_uart2, vc_i2c3), PIN(15, ir_in, aon_fp_4sec_resetb, vc_uart0, pm_led_out, ctl_hdmi_5v, aon_pwm, aon_gpclk, _), PIN(16, aon_cpu_standbyb, gpclk0, pm_led_out, ctl_hdmi_5v, vc_pwm0, usb_pwr, aud_fs_clk0, _), }; static const struct bcm2712_pin_regs bcm2712_c0_aon_gpio_pin_regs[] = { AGPIO_REGS(0, 3, 0, 6, 10), AGPIO_REGS(1, 3, 1, 6, 11), AGPIO_REGS(2, 3, 2, 6, 12), AGPIO_REGS(3, 3, 3, 6, 13), AGPIO_REGS(4, 3, 4, 6, 14), AGPIO_REGS(5, 3, 5, 7, 0), AGPIO_REGS(6, 3, 6, 7, 1), AGPIO_REGS(7, 3, 7, 7, 2), AGPIO_REGS(8, 4, 0, 7, 3), AGPIO_REGS(9, 4, 1, 7, 4), AGPIO_REGS(10, 4, 2, 7, 5), AGPIO_REGS(11, 4, 3, 7, 6), AGPIO_REGS(12, 4, 4, 7, 7), AGPIO_REGS(13, 4, 5, 7, 8), AGPIO_REGS(14, 4, 6, 7, 9), AGPIO_REGS(15, 4, 7, 7, 10), AGPIO_REGS(16, 5, 0, 7, 11), SGPIO_REGS(0, 0, 0), SGPIO_REGS(1, 0, 1), SGPIO_REGS(2, 0, 2), SGPIO_REGS(3, 0, 3), SGPIO_REGS(4, 1, 0), SGPIO_REGS(5, 2, 0), }; static struct bcm2712_pinctrl_soc_data bcm2712_c0_aon_data = { .num_pins = RT_ARRAY_SIZE(bcm2712_c0_aon_gpio_pins), .desc = bcm2712_c0_aon_gpio_pins, .funcs = bcm2712_c0_aon_gpio_pin_funcs, .regs = bcm2712_c0_aon_gpio_pin_regs, }; static const struct bcm2712_pin_desc bcm2712_d0_gpio_pins[] = { GPIO_PIN(1), GPIO_PIN(2), GPIO_PIN(3), GPIO_PIN(4), GPIO_PIN(10), GPIO_PIN(11), GPIO_PIN(12), GPIO_PIN(13), GPIO_PIN(14), GPIO_PIN(15), GPIO_PIN(18), GPIO_PIN(19), GPIO_PIN(20), GPIO_PIN(21), GPIO_PIN(22), GPIO_PIN(23), GPIO_PIN(24), GPIO_PIN(25), GPIO_PIN(26), GPIO_PIN(27), GPIO_PIN(28), GPIO_PIN(29), GPIO_PIN(30), GPIO_PIN(31), GPIO_PIN(32), GPIO_PIN(33), GPIO_PIN(34), GPIO_PIN(35), }; static const struct bcm2712_pin_funcs bcm2712_d0_gpio_pin_funcs[] = { PIN(1, vc_i2c0, usb_pwr, gpclk0, sd_card_e, vc_spi3, sr_edm_sense, vc_spi0, vc_uart0), PIN(2, vc_i2c0, usb_pwr, gpclk1, sd_card_e, vc_spi3, clk_observe, vc_spi0, vc_uart0), PIN(3, vc_i2c3, usb_vbus, gpclk2, sd_card_e, vc_spi3, vc_spi0, vc_uart0, _), PIN(4, vc_i2c3, vc_pwm1, vc_spi3, sd_card_e, vc_spi3, vc_spi0, vc_uart0, _), PIN(10, bsc_m3, vc_pwm1, vc_spi3, sd_card_e, vc_spi3, gpclk0, _, _), PIN(11, bsc_m3, vc_spi3, clk_observe, sd_card_c, gpclk1, _, _, _), PIN(12, spi_s, vc_spi3, sd_card_c, sd_card_d, _, _, _, _), PIN(13, spi_s, vc_spi3, sd_card_c, sd_card_d, _, _, _, _), PIN(14, spi_s, uui, arm_jtag, vc_pwm0, vc_i2c0, sd_card_d, _, _), PIN(15, spi_s, uui, arm_jtag, vc_pwm0, vc_i2c0, gpclk0, _, _), PIN(18, sd_card_f, vc_pwm1, _, _, _, _, _, _), PIN(19, sd_card_f, usb_pwr, vc_pwm1, _, _, _, _, _), PIN(20, vc_i2c3, uui, vc_uart0, arm_jtag, vc_uart2, _, _, _), PIN(21, vc_i2c3, uui, vc_uart0, arm_jtag, vc_uart2, _, _, _), PIN(22, sd_card_f, vc_uart0, vc_i2c3, _, _, _, _, _), PIN(23, vc_uart0, vc_i2c3, _, _, _, _, _, _), PIN(24, sd_card_b, vc_spi0, arm_jtag, uart0, usb_pwr, vc_uart2, vc_uart0, _), PIN(25, sd_card_b, vc_spi0, arm_jtag, uart0, usb_pwr, vc_uart2, vc_uart0, _), PIN(26, sd_card_b, vc_spi0, arm_jtag, uart0, usb_vbus, vc_uart2, vc_spi0, _), PIN(27, sd_card_b, vc_spi0, arm_jtag, uart0, vc_uart2, vc_spi0, _, _), PIN(28, sd_card_b, vc_spi0, arm_jtag, vc_i2c0, vc_spi0, _, _, _), PIN(29, arm_jtag, vc_i2c0, vc_spi0, _, _, _, _, _), PIN(30, sd2, gpclk0, vc_pwm0, _, _, _, _, _), PIN(31, sd2, vc_spi3, vc_pwm0, _, _, _, _, _), PIN(32, sd2, vc_spi3, vc_uart3, _, _, _, _, _), PIN(33, sd2, vc_spi3, vc_uart3, _, _, _, _, _), PIN(34, sd2, vc_spi3, vc_i2c5, _, _, _, _, _), PIN(35, sd2, vc_spi3, vc_i2c5, _, _, _, _, _), }; static const struct bcm2712_pin_regs bcm2712_d0_gpio_pin_regs[] = { GPIO_REGS(1, 0, 0, 4, 5), GPIO_REGS(2, 0, 1, 4, 6), GPIO_REGS(3, 0, 2, 4, 7), GPIO_REGS(4, 0, 3, 4, 8), GPIO_REGS(10, 0, 4, 4, 9), GPIO_REGS(11, 0, 5, 4, 10), GPIO_REGS(12, 0, 6, 4, 11), GPIO_REGS(13, 0, 7, 4, 12), GPIO_REGS(14, 1, 0, 4, 13), GPIO_REGS(15, 1, 1, 4, 14), GPIO_REGS(18, 1, 2, 5, 0), GPIO_REGS(19, 1, 3, 5, 1), GPIO_REGS(20, 1, 4, 5, 2), GPIO_REGS(21, 1, 5, 5, 3), GPIO_REGS(22, 1, 6, 5, 4), GPIO_REGS(23, 1, 7, 5, 5), GPIO_REGS(24, 2, 0, 5, 6), GPIO_REGS(25, 2, 1, 5, 7), GPIO_REGS(26, 2, 2, 5, 8), GPIO_REGS(27, 2, 3, 5, 9), GPIO_REGS(28, 2, 4, 5, 10), GPIO_REGS(29, 2, 5, 5, 11), GPIO_REGS(30, 2, 6, 5, 12), GPIO_REGS(31, 2, 7, 5, 13), GPIO_REGS(32, 3, 0, 5, 14), GPIO_REGS(33, 3, 1, 6, 0), GPIO_REGS(34, 3, 2, 6, 1), GPIO_REGS(35, 3, 3, 6, 2), }; static struct bcm2712_pinctrl_soc_data bcm2712_d0_data = { .num_pins = RT_ARRAY_SIZE(bcm2712_d0_gpio_pins), .desc = bcm2712_d0_gpio_pins, .funcs = bcm2712_d0_gpio_pin_funcs, .regs = bcm2712_d0_gpio_pin_regs, }; static struct bcm2712_pin_desc bcm2712_d0_aon_gpio_pins[] = { AGPIO_PIN(0), AGPIO_PIN(1), AGPIO_PIN(2), AGPIO_PIN(3), AGPIO_PIN(4), AGPIO_PIN(5), AGPIO_PIN(6), AGPIO_PIN(8), AGPIO_PIN(9), AGPIO_PIN(12), AGPIO_PIN(13), AGPIO_PIN(14), SGPIO_PIN(0), SGPIO_PIN(1), SGPIO_PIN(2), SGPIO_PIN(3), SGPIO_PIN(4), SGPIO_PIN(5), }; static const struct bcm2712_pin_funcs bcm2712_d0_aon_gpio_pin_funcs[] = { PIN(0, ir_in, vc_spi0, vc_uart0, vc_i2c3, uart0, vc_i2c0, _, _), PIN(1, vc_pwm0, vc_spi0, vc_uart0, vc_i2c3, uart0, aon_pwm, vc_i2c0, vc_pwm1), PIN(2, vc_pwm0, vc_spi0, vc_uart0, ctl_hdmi_5v, uart0, aon_pwm, ir_in, vc_pwm1), PIN(3, ir_in, vc_spi0, vc_uart0, uart0, sd_card_g, aon_gpclk, _, _), PIN(4, gpclk0, vc_spi0, pm_led_out, aon_pwm, sd_card_g, vc_pwm0, _, _), PIN(5, gpclk1, ir_in, aon_pwm, sd_card_g, vc_pwm0, _, _, _), PIN(6, uart1, vc_uart2, ctl_hdmi_5v, gpclk2, vc_spi3, _, _, _), PIN(7, _, _, _, _, _, _, _, _), PIN(8, uart1, vc_uart2, ctl_hdmi_5v, vc_spi0, vc_spi3, _, _, _), PIN(9, uart1, vc_uart2, vc_uart0, aon_pwm, vc_spi0, vc_uart2, vc_spi3, _), PIN(10, _, _, _, _, _, _, _, _), PIN(11, _, _, _, _, _, _, _, _), PIN(12, uart1, vc_uart2, vc_uart0, vc_spi0, usb_pwr, vc_uart2, vc_spi3, _), PIN(13, bsc_m1, vc_uart0, uui, vc_spi0, arm_jtag, vc_uart2, vc_i2c3, _), PIN(14, bsc_m1, aon_gpclk, vc_uart0, uui, vc_spi0, arm_jtag, vc_uart2, vc_i2c3), }; static const struct bcm2712_pin_regs bcm2712_d0_aon_gpio_pin_regs[] = { AGPIO_REGS(0, 3, 0, 5, 9), AGPIO_REGS(1, 3, 1, 5, 10), AGPIO_REGS(2, 3, 2, 5, 11), AGPIO_REGS(3, 3, 3, 5, 12), AGPIO_REGS(4, 3, 4, 5, 13), AGPIO_REGS(5, 3, 5, 5, 14), AGPIO_REGS(6, 3, 6, 6, 0), AGPIO_REGS(8, 3, 7, 6, 1), AGPIO_REGS(9, 4, 0, 6, 2), AGPIO_REGS(12, 4, 1, 6, 3), AGPIO_REGS(13, 4, 2, 6, 4), AGPIO_REGS(14, 4, 3, 6, 5), SGPIO_REGS(0, 0, 0), SGPIO_REGS(1, 0, 1), SGPIO_REGS(2, 0, 2), SGPIO_REGS(3, 0, 3), SGPIO_REGS(4, 1, 0), SGPIO_REGS(5, 2, 0), }; static struct bcm2712_pinctrl_soc_data bcm2712_d0_aon_data = { .num_pins = RT_ARRAY_SIZE(bcm2712_d0_aon_gpio_pins), .desc = bcm2712_d0_aon_gpio_pins, .funcs = bcm2712_d0_aon_gpio_pin_funcs, .regs = bcm2712_d0_aon_gpio_pin_regs, }; static const struct rt_ofw_node_id bcm2712_pinctrl_ofw_ids[] = { { .compatible = "brcm,bcm2712-pinctrl", .data = &bcm2712_c0_data }, { .compatible = "brcm,bcm2712-aon-pinctrl", .data = &bcm2712_c0_aon_data }, { .compatible = "brcm,bcm2712c0-pinctrl", .data = &bcm2712_c0_data }, { .compatible = "brcm,bcm2712c0-aon-pinctrl", .data = &bcm2712_c0_aon_data }, { .compatible = "brcm,bcm2712d0-pinctrl", .data = &bcm2712_d0_data }, { .compatible = "brcm,bcm2712d0-aon-pinctrl", .data = &bcm2712_d0_aon_data }, { /* sentinel */ } }; static struct rt_platform_driver bcm2712_pinctrl_driver = { .name = "pinctrl-bcm2712", .ids = bcm2712_pinctrl_ofw_ids, .probe = bcm2712_pinctrl_probe, }; static int bcm2712_pinctrl_register(void) { rt_platform_driver_register(&bcm2712_pinctrl_driver); return 0; } INIT_SUBSYS_EXPORT(bcm2712_pinctrl_register);