uboot/drivers/pinctrl/rockchip/pinctrl_rk3128.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Pinctrl driver for Rockchip 3128 SoCs
   4 * (C) Copyright 2017 Rockchip Electronics Co., Ltd
   5 */
   6
   7#include <common.h>
   8#include <dm.h>
   9#include <errno.h>
  10#include <syscon.h>
  11#include <asm/io.h>
  12#include <asm/arch/clock.h>
  13#include <asm/arch/grf_rk3128.h>
  14#include <asm/arch/hardware.h>
  15#include <asm/arch/periph.h>
  16#include <dm/pinctrl.h>
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20struct rk3128_pinctrl_priv {
  21        struct rk3128_grf *grf;
  22};
  23
  24static void pinctrl_rk3128_i2c_config(struct rk3128_grf *grf, int i2c_id)
  25{
  26        switch (i2c_id) {
  27        case PERIPH_ID_I2C0:
  28                rk_clrsetreg(&grf->gpio0a_iomux,
  29                             GPIO0A1_MASK | GPIO0A0_MASK,
  30                             GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
  31                             GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
  32
  33                break;
  34        case PERIPH_ID_I2C1:
  35                rk_clrsetreg(&grf->gpio0a_iomux,
  36                             GPIO0A3_MASK | GPIO0A2_MASK,
  37                             GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
  38                             GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
  39                break;
  40        case PERIPH_ID_I2C2:
  41                rk_clrsetreg(&grf->gpio2c_iomux2,
  42                             GPIO2C5_MASK | GPIO2C4_MASK,
  43                             GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
  44                             GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
  45                break;
  46        case PERIPH_ID_I2C3:
  47                rk_clrsetreg(&grf->gpio0a_iomux,
  48                             GPIO0A7_MASK | GPIO0A6_MASK,
  49                             GPIO0A7_I2C3_SDA << GPIO0A7_SHIFT |
  50                             GPIO0A6_I2C3_SCL << GPIO0A6_SHIFT);
  51
  52                break;
  53        }
  54}
  55
  56static void pinctrl_rk3128_sdmmc_config(struct rk3128_grf *grf, int mmc_id)
  57{
  58        switch (mmc_id) {
  59        case PERIPH_ID_EMMC:
  60                rk_clrsetreg(&grf->gpio1d_iomux, 0xffff,
  61                             GPIO1D7_EMMC_D7 << GPIO1D7_SHIFT |
  62                             GPIO1D6_EMMC_D6 << GPIO1D6_SHIFT |
  63                             GPIO1D5_EMMC_D5 << GPIO1D5_SHIFT |
  64                             GPIO1D4_EMMC_D4 << GPIO1D4_SHIFT |
  65                             GPIO1D3_EMMC_D3 << GPIO1D3_SHIFT |
  66                             GPIO1D2_EMMC_D2 << GPIO1D2_SHIFT |
  67                             GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
  68                             GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
  69                rk_clrsetreg(&grf->gpio2a_iomux,
  70                             GPIO2A5_MASK | GPIO2A7_MASK,
  71                             GPIO2A5_EMMC_PWREN << GPIO2A5_SHIFT |
  72                             GPIO2A7_EMMC_CLKOUT << GPIO2A7_SHIFT);
  73                break;
  74        case PERIPH_ID_SDCARD:
  75                rk_clrsetreg(&grf->gpio1c_iomux, 0x0fff,
  76                             GPIO1C5_MMC0_D3 << GPIO1C5_SHIFT |
  77                             GPIO1C4_MMC0_D2 << GPIO1C4_SHIFT |
  78                             GPIO1C3_MMC0_D1 << GPIO1C3_SHIFT |
  79                             GPIO1C2_MMC0_D0 << GPIO1C2_SHIFT |
  80                             GPIO1C1_MMC0_DETN << GPIO1C1_SHIFT |
  81                             GPIO1C0_MMC0_CLKOUT << GPIO1C0_SHIFT);
  82                break;
  83        }
  84}
  85
  86static int rk3128_pinctrl_request(struct udevice *dev, int func, int flags)
  87{
  88        struct rk3128_pinctrl_priv *priv = dev_get_priv(dev);
  89
  90        debug("%s: func=%x, flags=%x\n", __func__, func, flags);
  91        switch (func) {
  92        case PERIPH_ID_I2C0:
  93        case PERIPH_ID_I2C1:
  94        case PERIPH_ID_I2C2:
  95        case PERIPH_ID_I2C3:
  96                pinctrl_rk3128_i2c_config(priv->grf, func);
  97                break;
  98        case PERIPH_ID_SDMMC0:
  99        case PERIPH_ID_SDMMC1:
 100                pinctrl_rk3128_sdmmc_config(priv->grf, func);
 101                break;
 102        default:
 103                return -EINVAL;
 104        }
 105
 106        return 0;
 107}
 108
 109static int rk3128_pinctrl_get_periph_id(struct udevice *dev,
 110                                        struct udevice *periph)
 111{
 112        u32 cell[3];
 113        int ret;
 114
 115        ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 116                                   "interrupts", cell, ARRAY_SIZE(cell));
 117        if (ret < 0)
 118                return -EINVAL;
 119
 120        switch (cell[1]) {
 121        case 14:
 122                return PERIPH_ID_SDCARD;
 123        case 16:
 124                return PERIPH_ID_EMMC;
 125        case 20:
 126                return PERIPH_ID_UART0;
 127        case 21:
 128                return PERIPH_ID_UART1;
 129        case 22:
 130                return PERIPH_ID_UART2;
 131        case 23:
 132                return PERIPH_ID_SPI0;
 133        case 24:
 134                return PERIPH_ID_I2C0;
 135        case 25:
 136                return PERIPH_ID_I2C1;
 137        case 26:
 138                return PERIPH_ID_I2C2;
 139        case 27:
 140                return PERIPH_ID_I2C3;
 141        case 30:
 142                return PERIPH_ID_PWM0;
 143        }
 144        return -ENOENT;
 145}
 146
 147static int rk3128_pinctrl_set_state_simple(struct udevice *dev,
 148                                           struct udevice *periph)
 149{
 150        int func;
 151
 152        func = rk3128_pinctrl_get_periph_id(dev, periph);
 153        if (func < 0)
 154                return func;
 155        return rk3128_pinctrl_request(dev, func, 0);
 156}
 157
 158static struct pinctrl_ops rk3128_pinctrl_ops = {
 159        .set_state_simple       = rk3128_pinctrl_set_state_simple,
 160        .request        = rk3128_pinctrl_request,
 161        .get_periph_id  = rk3128_pinctrl_get_periph_id,
 162};
 163
 164static int rk3128_pinctrl_probe(struct udevice *dev)
 165{
 166        struct rk3128_pinctrl_priv *priv = dev_get_priv(dev);
 167
 168        priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 169        debug("%s: grf=%p\n", __func__, priv->grf);
 170        return 0;
 171}
 172
 173static const struct udevice_id rk3128_pinctrl_ids[] = {
 174        { .compatible = "rockchip,rk3128-pinctrl" },
 175        { }
 176};
 177
 178U_BOOT_DRIVER(pinctrl_rk3128) = {
 179        .name           = "pinctrl_rk3128",
 180        .id             = UCLASS_PINCTRL,
 181        .of_match       = rk3128_pinctrl_ids,
 182        .priv_auto_alloc_size = sizeof(struct rk3128_pinctrl_priv),
 183        .ops            = &rk3128_pinctrl_ops,
 184        .bind           = dm_scan_fdt_dev,
 185        .probe          = rk3128_pinctrl_probe,
 186};
 187