pinctrl_rv1108.c 4.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
/*
 * (C) Copyright 2016 Rockchip Electronics Co., Ltd
 * Author: Andy Yan <andy.yan@rock-chips.com>
 * SPDX-License-Identifier:     GPL-2.0+
 */
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/grf_rv1108.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <dm/pinctrl.h>

DECLARE_GLOBAL_DATA_PTR;

struct rv1108_pinctrl_priv {
	struct rv1108_grf *grf;
};

static void pinctrl_rv1108_uart_config(struct rv1108_grf *grf, int uart_id)
{
	switch (uart_id) {
	case PERIPH_ID_UART0:
		rk_clrsetreg(&grf->gpio3a_iomux,
			     GPIO3A6_MASK | GPIO3A5_MASK,
			     GPIO3A6_UART1_SOUT << GPIO3A6_SHIFT |
			     GPIO3A5_UART1_SIN << GPIO3A5_SHIFT);
		break;
	case PERIPH_ID_UART1:
		rk_clrsetreg(&grf->gpio1d_iomux,
			     GPIO1D3_MASK | GPIO1D2_MASK | GPIO1D1_MASK |
			     GPIO1D0_MASK,
			     GPIO1D3_UART0_SOUT << GPIO1D3_SHIFT |
			     GPIO1D2_UART0_SIN << GPIO1D2_SHIFT |
			     GPIO1D1_UART0_RTSN << GPIO1D1_SHIFT |
			     GPIO1D0_UART0_CTSN << GPIO1D0_SHIFT);
		break;
	case PERIPH_ID_UART2:
		rk_clrsetreg(&grf->gpio2d_iomux,
			     GPIO2D2_MASK | GPIO2D1_MASK,
			     GPIO2D2_UART2_SOUT_M0 << GPIO2D2_SHIFT |
			     GPIO2D1_UART2_SIN_M0 << GPIO2D1_SHIFT);
		break;
	}
}

static void pinctrl_rv1108_gmac_config(struct rv1108_grf *grf, int func)
{
	rk_clrsetreg(&grf->gpio1b_iomux,
		     GPIO1B7_MASK | GPIO1B6_MASK | GPIO1B5_MASK |
		     GPIO1B4_MASK | GPIO1B3_MASK | GPIO1B2_MASK,
		     GPIO1B7_GMAC_RXDV << GPIO1B7_SHIFT |
		     GPIO1B6_GMAC_RXD1 << GPIO1B6_SHIFT |
		     GPIO1B5_GMAC_RXD0 << GPIO1B5_SHIFT |
		     GPIO1B4_GMAC_TXEN << GPIO1B4_SHIFT |
		     GPIO1B3_GMAC_TXD1 << GPIO1B3_SHIFT |
		     GPIO1B2_GMAC_TXD0 << GPIO1B2_SHIFT);
	rk_clrsetreg(&grf->gpio1c_iomux,
		     GPIO1C5_MASK | GPIO1C4_MASK |
		     GPIO1C3_MASK | GPIO1C2_MASK,
		     GPIO1C5_GMAC_CLK << GPIO1C5_SHIFT |
		     GPIO1C4_GMAC_MDC << GPIO1C4_SHIFT |
		     GPIO1C3_GMAC_MDIO << GPIO1C3_SHIFT |
		     GPIO1C2_GMAC_RXER << GPIO1C2_SHIFT);
	writel(0xffff57f5, &grf->gpio1b_drv);
}

static void pinctrl_rv1108_sfc_config(struct rv1108_grf *grf)
{
	rk_clrsetreg(&grf->gpio2a_iomux, GPIO2A3_MASK | GPIO2A2_MASK |
		     GPIO2A1_MASK | GPIO2A0_MASK,
		     GPIO2A3_SFC_HOLD_IO3 << GPIO2A3_SHIFT |
		     GPIO2A2_SFC_WP_IO2 << GPIO2A2_SHIFT |
		     GPIO2A1_SFC_SO_IO1 << GPIO2A1_SHIFT |
		     GPIO2A0_SFC_SI_IO0 << GPIO2A0_SHIFT);
	rk_clrsetreg(&grf->gpio2b_iomux, GPIO2B7_MASK | GPIO2B4_MASK,
		     GPIO2B7_SFC_CLK << GPIO2B7_SHIFT |
		     GPIO2B4_SFC_CSN0 << GPIO2B4_SHIFT);
}

static int rv1108_pinctrl_request(struct udevice *dev, int func, int flags)
{
	struct rv1108_pinctrl_priv *priv = dev_get_priv(dev);

	switch (func) {
	case PERIPH_ID_UART0:
	case PERIPH_ID_UART1:
	case PERIPH_ID_UART2:
		pinctrl_rv1108_uart_config(priv->grf, func);
		break;
	case PERIPH_ID_GMAC:
		pinctrl_rv1108_gmac_config(priv->grf, func);
	case PERIPH_ID_SFC:
		pinctrl_rv1108_sfc_config(priv->grf);
	default:
		return -EINVAL;
	}

	return 0;
}

static int rv1108_pinctrl_get_periph_id(struct udevice *dev,
					struct udevice *periph)
{
	u32 cell[3];
	int ret;

111
	ret = dev_read_u32_array(periph, "interrupts", cell, ARRAY_SIZE(cell));
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
	if (ret < 0)
		return -EINVAL;

	switch (cell[1]) {
	case 11:
		return PERIPH_ID_SDCARD;
	case 13:
		return PERIPH_ID_EMMC;
	case 19:
		return PERIPH_ID_GMAC;
	case 30:
		return PERIPH_ID_I2C0;
	case 31:
		return PERIPH_ID_I2C1;
	case 32:
		return PERIPH_ID_I2C2;
	case 39:
		return PERIPH_ID_PWM0;
	case 44:
		return PERIPH_ID_UART0;
	case 45:
		return PERIPH_ID_UART1;
	case 46:
		return PERIPH_ID_UART2;
	case 56:
		return PERIPH_ID_SFC;
	}

	return -ENOENT;
}

static int rv1108_pinctrl_set_state_simple(struct udevice *dev,
					   struct udevice *periph)
{
	int func;

	func = rv1108_pinctrl_get_periph_id(dev, periph);
	if (func < 0)
		return func;

	return rv1108_pinctrl_request(dev, func, 0);
}

static struct pinctrl_ops rv1108_pinctrl_ops = {
	.set_state_simple	= rv1108_pinctrl_set_state_simple,
	.request		= rv1108_pinctrl_request,
	.get_periph_id		= rv1108_pinctrl_get_periph_id,
};

static int rv1108_pinctrl_probe(struct udevice *dev)
{
	struct rv1108_pinctrl_priv *priv = dev_get_priv(dev);

	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);

	return 0;
}

static const struct udevice_id rv1108_pinctrl_ids[] = {
	{.compatible = "rockchip,rv1108-pinctrl" },
	{ }
};

U_BOOT_DRIVER(pinctrl_rv1108) = {
	.name           = "pinctrl_rv1108",
	.id             = UCLASS_PINCTRL,
	.of_match       = rv1108_pinctrl_ids,
	.priv_auto_alloc_size = sizeof(struct rv1108_pinctrl_priv),
	.ops            = &rv1108_pinctrl_ops,
	.bind           = dm_scan_fdt_dev,
	.probe          = rv1108_pinctrl_probe,
};