uboot/drivers/pinctrl/rockchip/pinctrl_rk3036.c
<<
>>
Prefs
   1/*
   2 * Pinctrl driver for Rockchip 3036 SoCs
   3 * (C) Copyright 2015 Rockchip Electronics Co., Ltd
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <errno.h>
  11#include <syscon.h>
  12#include <asm/io.h>
  13#include <asm/arch/clock.h>
  14#include <asm/arch/grf_rk3036.h>
  15#include <asm/arch/hardware.h>
  16#include <asm/arch/periph.h>
  17#include <dm/pinctrl.h>
  18
  19DECLARE_GLOBAL_DATA_PTR;
  20
  21struct rk3036_pinctrl_priv {
  22        struct rk3036_grf *grf;
  23};
  24
  25static void pinctrl_rk3036_pwm_config(struct rk3036_grf *grf, int pwm_id)
  26{
  27        switch (pwm_id) {
  28        case PERIPH_ID_PWM0:
  29                rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK,
  30                             GPIO0D2_PWM0 << GPIO0D2_SHIFT);
  31                break;
  32        case PERIPH_ID_PWM1:
  33                rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK,
  34                             GPIO0A0_PWM1 << GPIO0A0_SHIFT);
  35                break;
  36        case PERIPH_ID_PWM2:
  37                rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK,
  38                             GPIO0A1_PWM2 << GPIO0A1_SHIFT);
  39                break;
  40        case PERIPH_ID_PWM3:
  41                rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK,
  42                             GPIO0D3_PWM3 << GPIO0D3_SHIFT);
  43                break;
  44        default:
  45                debug("pwm id = %d iomux error!\n", pwm_id);
  46                break;
  47        }
  48}
  49
  50static void pinctrl_rk3036_i2c_config(struct rk3036_grf *grf, int i2c_id)
  51{
  52        switch (i2c_id) {
  53        case PERIPH_ID_I2C0:
  54                rk_clrsetreg(&grf->gpio0a_iomux,
  55                             GPIO0A1_MASK | GPIO0A0_MASK,
  56                             GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
  57                             GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
  58
  59                break;
  60        case PERIPH_ID_I2C1:
  61                rk_clrsetreg(&grf->gpio0a_iomux,
  62                             GPIO0A3_MASK | GPIO0A2_MASK,
  63                             GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
  64                             GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
  65                break;
  66        case PERIPH_ID_I2C2:
  67                rk_clrsetreg(&grf->gpio2c_iomux,
  68                             GPIO2C5_MASK | GPIO2C4_MASK,
  69                             GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
  70                             GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
  71
  72                break;
  73        }
  74}
  75
  76static void pinctrl_rk3036_spi_config(struct rk3036_grf *grf, int cs)
  77{
  78        switch (cs) {
  79        case 0:
  80                rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D6_MASK,
  81                             GPIO1D6_SPI_CSN0 << GPIO1D6_SHIFT);
  82                break;
  83        case 1:
  84                rk_clrsetreg(&grf->gpio1d_iomux, GPIO1D7_MASK,
  85                             GPIO1D7_SPI_CSN1 << GPIO1D7_SHIFT);
  86                break;
  87        }
  88        rk_clrsetreg(&grf->gpio1d_iomux,
  89                     GPIO1D5_MASK | GPIO1D4_MASK,
  90                     GPIO1D5_SPI_TXD << GPIO1D5_SHIFT |
  91                     GPIO1D4_SPI_RXD << GPIO1D4_SHIFT);
  92
  93        rk_clrsetreg(&grf->gpio2a_iomux, GPIO2A0_MASK,
  94                     GPIO2A0_SPI_CLK << GPIO2A0_SHIFT);
  95}
  96
  97static void pinctrl_rk3036_uart_config(struct rk3036_grf *grf, int uart_id)
  98{
  99        switch (uart_id) {
 100        case PERIPH_ID_UART0:
 101                rk_clrsetreg(&grf->gpio0c_iomux,
 102                             GPIO0C3_MASK | GPIO0C2_MASK |
 103                             GPIO0C1_MASK |  GPIO0C0_MASK,
 104                             GPIO0C3_UART0_CTSN << GPIO0C3_SHIFT |
 105                             GPIO0C2_UART0_RTSN << GPIO0C2_SHIFT |
 106                             GPIO0C1_UART0_SIN << GPIO0C1_SHIFT |
 107                             GPIO0C0_UART0_SOUT << GPIO0C0_SHIFT);
 108                break;
 109        case PERIPH_ID_UART1:
 110                rk_clrsetreg(&grf->gpio2c_iomux,
 111                             GPIO2C7_MASK | GPIO2C6_MASK,
 112                             GPIO2C7_UART1_SOUT << GPIO2C7_SHIFT |
 113                             GPIO2C6_UART1_SIN << GPIO2C6_SHIFT);
 114                break;
 115        case PERIPH_ID_UART2:
 116                rk_clrsetreg(&grf->gpio1c_iomux,
 117                             GPIO1C3_MASK | GPIO1C2_MASK,
 118                             GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
 119                             GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
 120                break;
 121        }
 122}
 123
 124static void pinctrl_rk3036_sdmmc_config(struct rk3036_grf *grf, int mmc_id)
 125{
 126        switch (mmc_id) {
 127        case PERIPH_ID_EMMC:
 128                rk_clrsetreg(&grf->gpio1d_iomux, 0xffff,
 129                             GPIO1D7_EMMC_D7 << GPIO1D7_SHIFT |
 130                             GPIO1D6_EMMC_D6 << GPIO1D6_SHIFT |
 131                             GPIO1D5_EMMC_D5 << GPIO1D5_SHIFT |
 132                             GPIO1D4_EMMC_D4 << GPIO1D4_SHIFT |
 133                             GPIO1D3_EMMC_D3 << GPIO1D3_SHIFT |
 134                             GPIO1D2_EMMC_D2 << GPIO1D2_SHIFT |
 135                             GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
 136                             GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
 137                rk_clrsetreg(&grf->gpio2a_iomux,
 138                             GPIO2A4_MASK | GPIO2A1_MASK,
 139                             GPIO2A4_EMMC_CMD << GPIO2A4_SHIFT |
 140                             GPIO2A1_EMMC_CLKOUT << GPIO2A1_SHIFT);
 141                break;
 142        case PERIPH_ID_SDCARD:
 143                rk_clrsetreg(&grf->gpio1c_iomux, 0xffff,
 144                             GPIO1C5_MMC0_D3 << GPIO1C5_SHIFT |
 145                             GPIO1C4_MMC0_D2 << GPIO1C4_SHIFT |
 146                             GPIO1C3_MMC0_D1 << GPIO1C3_SHIFT |
 147                             GPIO1C2_MMC0_D0 << GPIO1C2_SHIFT |
 148                             GPIO1C1_MMC0_DETN << GPIO1C1_SHIFT |
 149                             GPIO1C0_MMC0_CLKOUT << GPIO1C0_SHIFT);
 150                break;
 151        }
 152}
 153
 154static int rk3036_pinctrl_request(struct udevice *dev, int func, int flags)
 155{
 156        struct rk3036_pinctrl_priv *priv = dev_get_priv(dev);
 157
 158        debug("%s: func=%x, flags=%x\n", __func__, func, flags);
 159        switch (func) {
 160        case PERIPH_ID_PWM0:
 161        case PERIPH_ID_PWM1:
 162        case PERIPH_ID_PWM2:
 163        case PERIPH_ID_PWM3:
 164                pinctrl_rk3036_pwm_config(priv->grf, func);
 165                break;
 166        case PERIPH_ID_I2C0:
 167        case PERIPH_ID_I2C1:
 168        case PERIPH_ID_I2C2:
 169                pinctrl_rk3036_i2c_config(priv->grf, func);
 170                break;
 171        case PERIPH_ID_SPI0:
 172                pinctrl_rk3036_spi_config(priv->grf, flags);
 173                break;
 174        case PERIPH_ID_UART0:
 175        case PERIPH_ID_UART1:
 176        case PERIPH_ID_UART2:
 177                pinctrl_rk3036_uart_config(priv->grf, func);
 178                break;
 179        case PERIPH_ID_SDMMC0:
 180        case PERIPH_ID_SDMMC1:
 181                pinctrl_rk3036_sdmmc_config(priv->grf, func);
 182                break;
 183        default:
 184                return -EINVAL;
 185        }
 186
 187        return 0;
 188}
 189
 190static int rk3036_pinctrl_get_periph_id(struct udevice *dev,
 191                                        struct udevice *periph)
 192{
 193        u32 cell[3];
 194        int ret;
 195
 196        ret = dev_read_u32_array(periph, "interrupts", cell, ARRAY_SIZE(cell));
 197        if (ret < 0)
 198                return -EINVAL;
 199
 200        switch (cell[1]) {
 201        case 14:
 202                return PERIPH_ID_SDCARD;
 203        case 16:
 204                return PERIPH_ID_EMMC;
 205        case 20:
 206                return PERIPH_ID_UART0;
 207        case 21:
 208                return PERIPH_ID_UART1;
 209        case 22:
 210                return PERIPH_ID_UART2;
 211        case 23:
 212                return PERIPH_ID_SPI0;
 213        case 24:
 214                return PERIPH_ID_I2C0;
 215        case 25:
 216                return PERIPH_ID_I2C1;
 217        case 26:
 218                return PERIPH_ID_I2C2;
 219        case 30:
 220                return PERIPH_ID_PWM0;
 221        }
 222        return -ENOENT;
 223}
 224
 225static int rk3036_pinctrl_set_state_simple(struct udevice *dev,
 226                                           struct udevice *periph)
 227{
 228        int func;
 229
 230        func = rk3036_pinctrl_get_periph_id(dev, periph);
 231        if (func < 0)
 232                return func;
 233        return rk3036_pinctrl_request(dev, func, 0);
 234}
 235
 236static struct pinctrl_ops rk3036_pinctrl_ops = {
 237        .set_state_simple       = rk3036_pinctrl_set_state_simple,
 238        .request        = rk3036_pinctrl_request,
 239        .get_periph_id  = rk3036_pinctrl_get_periph_id,
 240};
 241
 242static int rk3036_pinctrl_probe(struct udevice *dev)
 243{
 244        struct rk3036_pinctrl_priv *priv = dev_get_priv(dev);
 245
 246        priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
 247        debug("%s: grf=%p\n", __func__, priv->grf);
 248        return 0;
 249}
 250
 251static const struct udevice_id rk3036_pinctrl_ids[] = {
 252        { .compatible = "rockchip,rk3036-pinctrl" },
 253        { }
 254};
 255
 256U_BOOT_DRIVER(pinctrl_rk3036) = {
 257        .name           = "pinctrl_rk3036",
 258        .id             = UCLASS_PINCTRL,
 259        .of_match       = rk3036_pinctrl_ids,
 260        .priv_auto_alloc_size = sizeof(struct rk3036_pinctrl_priv),
 261        .ops            = &rk3036_pinctrl_ops,
 262        .bind           = dm_scan_fdt_dev,
 263        .probe          = rk3036_pinctrl_probe,
 264};
 265