avionic design with actual uboot and tooling

submodule of avionic design uboot bootloader and with included tools to
get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
2026-03-03 21:46:32 +02:00
parent fe3ba02c96
commit 68d74d3181
11967 changed files with 2221897 additions and 0 deletions

View File

@@ -0,0 +1,168 @@
#
# PINCTRL infrastructure and drivers
#
menu "Pin controllers"
config PINCTRL
bool "Support pin controllers"
depends on DM
help
This enables the basic support for pinctrl framework. You may want
to enable some more options depending on what you want to do.
config PINCTRL_FULL
bool "Support full pin controllers"
depends on PINCTRL && OF_CONTROL
default y
help
This provides Linux-compatible device tree interface for the pinctrl
subsystem. This feature depends on device tree configuration because
it parses a device tree to look for the pinctrl device which the
peripheral device is associated with.
If this option is disabled (it is the only possible choice for non-DT
boards), the pinctrl core provides no systematic mechanism for
identifying peripheral devices, applying needed pinctrl settings.
It is totally up to the implementation of each low-level driver.
You can save memory footprint in return for some limitations.
config PINCTRL_GENERIC
bool "Support generic pin controllers"
depends on PINCTRL_FULL
default y
help
Say Y here if you want to use the pinctrl subsystem through the
generic DT interface. If enabled, some functions become available
to parse common properties such as "pins", "groups", "functions" and
some pin configuration parameters. It would be easier if you only
need the generic DT interface for pin muxing and pin configuration.
If you need to handle vendor-specific DT properties, you can disable
this option and implement your own set_state callback in the pinctrl
operations.
config PINMUX
bool "Support pin multiplexing controllers"
depends on PINCTRL_GENERIC
default y
help
This option enables pin multiplexing through the generic pinctrl
framework. Most SoCs have their own own multiplexing arrangement
where a single pin can be used for several functions. An SoC pinctrl
driver allows the required function to be selected for each pin.
The driver is typically controlled by the device tree.
config PINCONF
bool "Support pin configuration controllers"
depends on PINCTRL_GENERIC
help
This option enables pin configuration through the generic pinctrl
framework.
config SPL_PINCTRL
bool "Support pin controlloers in SPL"
depends on SPL && SPL_DM
help
This option is an SPL-variant of the PINCTRL option.
See the help of PINCTRL for details.
config SPL_PINCTRL_FULL
bool "Support full pin controllers in SPL"
depends on SPL_PINCTRL && SPL_OF_CONTROL
default y
help
This option is an SPL-variant of the PINCTRL_FULL option.
See the help of PINCTRL_FULL for details.
config SPL_PINCTRL_GENERIC
bool "Support generic pin controllers in SPL"
depends on SPL_PINCTRL_FULL
default y
help
This option is an SPL-variant of the PINCTRL_GENERIC option.
See the help of PINCTRL_GENERIC for details.
config SPL_PINMUX
bool "Support pin multiplexing controllers in SPL"
depends on SPL_PINCTRL_GENERIC
default y
help
This option is an SPL-variant of the PINMUX option.
See the help of PINMUX for details.
The pinctrl subsystem can add a substantial overhead to the SPL
image since it typically requires quite a few tables either in the
driver or in the device tree. If this is acceptable and you need
to adjust pin multiplexing in SPL in order to boot into U-Boot,
enable this option. You will need to enable device tree in SPL
for this to work.
config SPL_PINCONF
bool "Support pin configuration controllers in SPL"
depends on SPL_PINCTRL_GENERIC
help
This option is an SPL-variant of the PINCONF option.
See the help of PINCONF for details.
if PINCTRL || SPL_PINCTRL
config AR933X_PINCTRL
bool "QCA/Athores ar933x pin control driver"
depends on DM && SOC_AR933X
help
Support pin multiplexing control on QCA/Athores ar933x SoCs.
The driver is controlled by a device tree node which contains
both the GPIO definitions and pin control functions for each
available multiplex function.
config QCA953X_PINCTRL
bool "QCA/Athores qca953x pin control driver"
depends on DM && SOC_QCA953X
help
Support pin multiplexing control on QCA/Athores qca953x SoCs.
The driver is controlled by a device tree node which contains
both the GPIO definitions and pin control functions for each
available multiplex function.
config ROCKCHIP_PINCTRL
bool "Rockchip pin control driver"
depends on DM
help
Support pin multiplexing control on Rockchip SoCs. The driver is
controlled by a device tree node which contains both the GPIO
definitions and pin control functions for each available multiplex
function.
config ROCKCHIP_3036_PINCTRL
bool "Rockchip rk3036 pin control driver"
depends on DM
help
Support pin multiplexing control on Rockchip rk3036 SoCs. The driver is
controlled by a device tree node which contains both the GPIO
definitions and pin control functions for each available multiplex
function.
config PINCTRL_SANDBOX
bool "Sandbox pinctrl driver"
depends on SANDBOX
help
This enables pinctrl driver for sandbox. Currently, this driver
actually does nothing but print debug messages when pinctrl
operations are invoked.
config PIC32_PINCTRL
bool "Microchip PIC32 pin-control and pin-mux driver"
depends on DM && MACH_PIC32
default y
help
Supports individual pin selection and configuration for each remappable
peripheral available on Microchip PIC32 SoCs. This driver is controlled
by a device tree node which contains both GPIO defintion and pin control
functions.
endif
source "drivers/pinctrl/nxp/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
source "drivers/pinctrl/exynos/Kconfig"
endmenu

View File

@@ -0,0 +1,15 @@
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += pinctrl-uclass.o
obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC) += pinctrl-generic.o
obj-y += nxp/
obj-$(CONFIG_ARCH_ATH79) += ath79/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_PIC32_PINCTRL) += pinctrl_pic32.o
obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/

View File

@@ -0,0 +1,6 @@
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_AR933X_PINCTRL) += pinctrl_ar933x.o
obj-$(CONFIG_QCA953x_PINCTRL) += pinctrl_qca953x.o

View File

@@ -0,0 +1,136 @@
/*
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#include <dm/pinctrl.h>
#include <mach/ar71xx_regs.h>
DECLARE_GLOBAL_DATA_PTR;
enum periph_id {
PERIPH_ID_UART0,
PERIPH_ID_SPI0,
PERIPH_ID_NONE = -1,
};
struct ar933x_pinctrl_priv {
void __iomem *regs;
};
static void pinctrl_ar933x_spi_config(struct ar933x_pinctrl_priv *priv, int cs)
{
switch (cs) {
case 0:
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
AR933X_GPIO(4), AR933X_GPIO(3) |
AR933X_GPIO(5) | AR933X_GPIO(2));
setbits_be32(priv->regs + AR71XX_GPIO_REG_FUNC,
AR933X_GPIO_FUNC_SPI_EN |
AR933X_GPIO_FUNC_RES_TRUE);
break;
}
}
static void pinctrl_ar933x_uart_config(struct ar933x_pinctrl_priv *priv, int uart_id)
{
switch (uart_id) {
case PERIPH_ID_UART0:
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
AR933X_GPIO(9), AR933X_GPIO(10));
setbits_be32(priv->regs + AR71XX_GPIO_REG_FUNC,
AR933X_GPIO_FUNC_UART_EN |
AR933X_GPIO_FUNC_RES_TRUE);
break;
}
}
static int ar933x_pinctrl_request(struct udevice *dev, int func, int flags)
{
struct ar933x_pinctrl_priv *priv = dev_get_priv(dev);
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
switch (func) {
case PERIPH_ID_SPI0:
pinctrl_ar933x_spi_config(priv, flags);
break;
case PERIPH_ID_UART0:
pinctrl_ar933x_uart_config(priv, func);
break;
default:
return -EINVAL;
}
return 0;
}
static int ar933x_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
u32 cell[2];
int ret;
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
switch (cell[0]) {
case 128:
return PERIPH_ID_UART0;
case 129:
return PERIPH_ID_SPI0;
}
return -ENOENT;
}
static int ar933x_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int func;
func = ar933x_pinctrl_get_periph_id(dev, periph);
if (func < 0)
return func;
return ar933x_pinctrl_request(dev, func, 0);
}
static struct pinctrl_ops ar933x_pinctrl_ops = {
.set_state_simple = ar933x_pinctrl_set_state_simple,
.request = ar933x_pinctrl_request,
.get_periph_id = ar933x_pinctrl_get_periph_id,
};
static int ar933x_pinctrl_probe(struct udevice *dev)
{
struct ar933x_pinctrl_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
addr = dev_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->regs = map_physmem(addr,
AR71XX_GPIO_SIZE,
MAP_NOCACHE);
return 0;
}
static const struct udevice_id ar933x_pinctrl_ids[] = {
{ .compatible = "qca,ar933x-pinctrl" },
{ }
};
U_BOOT_DRIVER(pinctrl_ar933x) = {
.name = "pinctrl_ar933x",
.id = UCLASS_PINCTRL,
.of_match = ar933x_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct ar933x_pinctrl_priv),
.ops = &ar933x_pinctrl_ops,
.probe = ar933x_pinctrl_probe,
};

View File

@@ -0,0 +1,156 @@
/*
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#include <dm/pinctrl.h>
#include <mach/ar71xx_regs.h>
DECLARE_GLOBAL_DATA_PTR;
enum periph_id {
PERIPH_ID_UART0,
PERIPH_ID_SPI0,
PERIPH_ID_NONE = -1,
};
struct qca953x_pinctrl_priv {
void __iomem *regs;
};
static void pinctrl_qca953x_spi_config(struct qca953x_pinctrl_priv *priv, int cs)
{
switch (cs) {
case 0:
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
QCA953X_GPIO(5) | QCA953X_GPIO(6) |
QCA953X_GPIO(7), QCA953X_GPIO(8));
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC1,
QCA953X_GPIO_MUX_MASK(8) |
QCA953X_GPIO_MUX_MASK(16) |
QCA953X_GPIO_MUX_MASK(24),
(QCA953X_GPIO_OUT_MUX_SPI_CS0 << 8) |
(QCA953X_GPIO_OUT_MUX_SPI_CLK << 16) |
(QCA953X_GPIO_OUT_MUX_SPI_MOSI << 24));
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
QCA953X_GPIO_MUX_MASK(0),
QCA953X_GPIO_IN_MUX_SPI_DATA_IN);
setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
QCA953X_GPIO(8));
break;
}
}
static void pinctrl_qca953x_uart_config(struct qca953x_pinctrl_priv *priv, int uart_id)
{
switch (uart_id) {
case PERIPH_ID_UART0:
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
QCA953X_GPIO(9), QCA953X_GPIO(10));
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC2,
QCA953X_GPIO_MUX_MASK(16),
QCA953X_GPIO_OUT_MUX_UART0_SOUT << 16);
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
QCA953X_GPIO_MUX_MASK(8),
QCA953X_GPIO_IN_MUX_UART0_SIN << 8);
setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
QCA953X_GPIO(10));
break;
}
}
static int qca953x_pinctrl_request(struct udevice *dev, int func, int flags)
{
struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
switch (func) {
case PERIPH_ID_SPI0:
pinctrl_qca953x_spi_config(priv, flags);
break;
case PERIPH_ID_UART0:
pinctrl_qca953x_uart_config(priv, func);
break;
default:
return -EINVAL;
}
return 0;
}
static int qca953x_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
u32 cell[2];
int ret;
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
switch (cell[0]) {
case 128:
return PERIPH_ID_UART0;
case 129:
return PERIPH_ID_SPI0;
}
return -ENOENT;
}
static int qca953x_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int func;
func = qca953x_pinctrl_get_periph_id(dev, periph);
if (func < 0)
return func;
return qca953x_pinctrl_request(dev, func, 0);
}
static struct pinctrl_ops qca953x_pinctrl_ops = {
.set_state_simple = qca953x_pinctrl_set_state_simple,
.request = qca953x_pinctrl_request,
.get_periph_id = qca953x_pinctrl_get_periph_id,
};
static int qca953x_pinctrl_probe(struct udevice *dev)
{
struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
addr = dev_get_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->regs = map_physmem(addr,
AR71XX_GPIO_SIZE,
MAP_NOCACHE);
return 0;
}
static const struct udevice_id qca953x_pinctrl_ids[] = {
{ .compatible = "qca,qca953x-pinctrl" },
{ }
};
U_BOOT_DRIVER(pinctrl_qca953x) = {
.name = "pinctrl_qca953x",
.id = UCLASS_PINCTRL,
.of_match = qca953x_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct qca953x_pinctrl_priv),
.ops = &qca953x_pinctrl_ops,
.probe = qca953x_pinctrl_probe,
};

View File

@@ -0,0 +1,10 @@
config PINCTRL_EXYNOS
bool
config PINCTRL_EXYNOS7420
bool "Samsung Exynos7420 pinctrl driver"
depends on ARCH_EXYNOS && PINCTRL_FULL
select PINCTRL_EXYNOS
help
Support pin multiplexing and pin configuration control on
Samsung's Exynos7420 SoC.

View File

@@ -0,0 +1,9 @@
#
# Copyright (C) 2016 Samsung Electronics
# Thomas Abraham <thomas.ab@samsung.com>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_PINCTRL_EXYNOS) += pinctrl-exynos.o
obj-$(CONFIG_PINCTRL_EXYNOS7420) += pinctrl-exynos7420.o

View File

@@ -0,0 +1,141 @@
/*
* Exynos pinctrl driver common code.
* Copyright (C) 2016 Samsung Electronics
* Thomas Abraham <thomas.ab@samsung.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#include "pinctrl-exynos.h"
DECLARE_GLOBAL_DATA_PTR;
/**
* exynos_pinctrl_setup_peri: setup pinctrl for a peripheral.
* conf: soc specific pin configuration data array
* num_conf: number of configurations in the conf array.
* base: base address of the pin controller.
*/
void exynos_pinctrl_setup_peri(struct exynos_pinctrl_config_data *conf,
unsigned int num_conf, unsigned long base)
{
unsigned int idx, val;
for (idx = 0; idx < num_conf; idx++) {
val = readl(base + conf[idx].offset);
val &= ~(conf[idx].mask);
val |= conf[idx].value;
writel(val, base + conf[idx].offset);
}
}
/* given a pin-name, return the address of pin config registers */
static unsigned long pin_to_bank_base(struct udevice *dev, const char *pin_name,
u32 *pin)
{
struct exynos_pinctrl_priv *priv = dev_get_priv(dev);
const struct samsung_pin_ctrl *pin_ctrl = priv->pin_ctrl;
const struct samsung_pin_bank_data *bank_data = pin_ctrl->pin_banks;
u32 nr_banks = pin_ctrl->nr_banks, idx = 0;
char bank[10];
/*
* The format of the pin name is <bank name>-<pin_number>.
* Example: gpa0-4 (gpa0 is the bank name and 4 is the pin number.
*/
while (pin_name[idx] != '-') {
bank[idx] = pin_name[idx];
idx++;
}
bank[idx] = '\0';
*pin = pin_name[++idx] - '0';
/* lookup the pin bank data using the pin bank name */
for (idx = 0; idx < nr_banks; idx++)
if (!strcmp(bank, bank_data[idx].name))
break;
return priv->base + bank_data[idx].offset;
}
/**
* exynos_pinctrl_set_state: configure a pin state.
* dev: the pinctrl device to be configured.
* config: the state to be configured.
*/
int exynos_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
const void *fdt = gd->fdt_blob;
int node = config->of_offset;
unsigned int count, idx, pin_num, ret;
unsigned int pinfunc, pinpud, pindrv;
unsigned long reg, value;
const char *name;
/*
* refer to the following document for the pinctrl bindings
* linux/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
*/
count = fdt_count_strings(fdt, node, "samsung,pins");
if (count <= 0)
return -EINVAL;
pinfunc = fdtdec_get_int(fdt, node, "samsung,pin-function", -1);
pinpud = fdtdec_get_int(fdt, node, "samsung,pin-pud", -1);
pindrv = fdtdec_get_int(fdt, node, "samsung,pin-drv", -1);
for (idx = 0; idx < count; idx++) {
ret = fdt_get_string_index(fdt, node, "samsung,pins",
idx, &name);
if (ret < 0)
continue;
reg = pin_to_bank_base(dev, name, &pin_num);
if (pinfunc != -1) {
value = readl(reg + PIN_CON);
value &= ~(0xf << (pin_num << 2));
value |= (pinfunc << (pin_num << 2));
writel(value, reg + PIN_CON);
}
if (pinpud != -1) {
value = readl(reg + PIN_PUD);
value &= ~(0x3 << (pin_num << 1));
value |= (pinpud << (pin_num << 1));
writel(value, reg + PIN_PUD);
}
if (pindrv != -1) {
value = readl(reg + PIN_DRV);
value &= ~(0x3 << (pin_num << 1));
value |= (pindrv << (pin_num << 1));
writel(value, reg + PIN_DRV);
}
}
return 0;
}
int exynos_pinctrl_probe(struct udevice *dev)
{
struct exynos_pinctrl_priv *priv;
fdt_addr_t base;
priv = dev_get_priv(dev);
if (!priv)
return -EINVAL;
base = dev_get_addr(dev);
if (base == FDT_ADDR_T_NONE)
return -EINVAL;
priv->base = base;
priv->pin_ctrl = (struct samsung_pin_ctrl *)dev_get_driver_data(dev) +
dev->req_seq;
return 0;
}

View File

@@ -0,0 +1,77 @@
/*
* Exynos pinctrl driver header.
* Copyright (C) 2016 Samsung Electronics
* Thomas Abraham <thomas.ab@samsung.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __PINCTRL_EXYNOS_H_
#define __PINCTRL_EXYNOS__H_
#define PIN_CON 0x00 /* Offset of pin function register */
#define PIN_DAT 0x04 /* Offset of pin data register */
#define PIN_PUD 0x08 /* Offset of pin pull up/down config register */
#define PIN_DRV 0x0C /* Offset of pin drive strength register */
/**
* struct samsung_pin_bank_data: represent a controller pin-bank data.
* @offset: starting offset of the pin-bank registers.
* @nr_pins: number of pins included in this bank.
* @name: name to be prefixed for each pin in this pin bank.
*/
struct samsung_pin_bank_data {
u32 offset;
u8 nr_pins;
const char *name;
};
#define EXYNOS_PIN_BANK(pins, reg, id) \
{ \
.offset = reg, \
.nr_pins = pins, \
.name = id \
}
/**
* struct samsung_pin_ctrl: represent a pin controller.
* @pin_banks: list of pin banks included in this controller.
* @nr_banks: number of pin banks.
*/
struct samsung_pin_ctrl {
const struct samsung_pin_bank_data *pin_banks;
u32 nr_banks;
};
/**
* struct exynos_pinctrl_priv: exynos pin controller driver private data
* @pin_ctrl: pin controller bank information.
* @base: base address of the pin controller instance.
* @num_banks: number of pin banks included in the pin controller.
*/
struct exynos_pinctrl_priv {
const struct samsung_pin_ctrl *pin_ctrl;
unsigned long base;
int num_banks;
};
/**
* struct exynos_pinctrl_config_data: configuration for a peripheral.
* @offset: offset of the config registers in the controller.
* @mask: value of the register to be masked with.
* @value: new value to be programmed.
*/
struct exynos_pinctrl_config_data {
const unsigned int offset;
const unsigned int mask;
const unsigned int value;
};
void exynos_pinctrl_setup_peri(struct exynos_pinctrl_config_data *conf,
unsigned int num_conf, unsigned long base);
int exynos_pinctrl_set_state(struct udevice *dev,
struct udevice *config);
int exynos_pinctrl_probe(struct udevice *dev);
#endif /* __PINCTRL_EXYNOS_H_ */

View File

@@ -0,0 +1,120 @@
/*
* Exynos7420 pinctrl driver.
* Copyright (C) 2016 Samsung Electronics
* Thomas Abraham <thomas.ab@samsung.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include <fdtdec.h>
#include <asm/arch/pinmux.h>
#include "pinctrl-exynos.h"
DECLARE_GLOBAL_DATA_PTR;
#define GPD1_OFFSET 0xc0
static struct exynos_pinctrl_config_data serial2_conf[] = {
{
.offset = GPD1_OFFSET + PIN_CON,
.mask = 0x00ff0000,
.value = 0x00220000,
}, {
.offset = GPD1_OFFSET + PIN_PUD,
.mask = 0x00000f00,
.value = 0x00000f00,
},
};
static int exynos7420_pinctrl_request(struct udevice *dev, int peripheral,
int flags)
{
struct exynos_pinctrl_priv *priv = dev_get_priv(dev);
unsigned long base = priv->base;
switch (PERIPH_ID_UART2) {
case PERIPH_ID_UART2:
exynos_pinctrl_setup_peri(serial2_conf,
ARRAY_SIZE(serial2_conf), base);
break;
default:
return -ENODEV;
}
return 0;
}
static struct pinctrl_ops exynos7420_pinctrl_ops = {
.set_state = exynos_pinctrl_set_state,
.request = exynos7420_pinctrl_request,
};
/* pin banks of Exynos7420 pin-controller - BUS0 */
static const struct samsung_pin_bank_data exynos7420_pin_banks0[] = {
EXYNOS_PIN_BANK(5, 0x000, "gpb0"),
EXYNOS_PIN_BANK(8, 0x020, "gpc0"),
EXYNOS_PIN_BANK(2, 0x040, "gpc1"),
EXYNOS_PIN_BANK(6, 0x060, "gpc2"),
EXYNOS_PIN_BANK(8, 0x080, "gpc3"),
EXYNOS_PIN_BANK(4, 0x0a0, "gpd0"),
EXYNOS_PIN_BANK(6, 0x0c0, "gpd1"),
EXYNOS_PIN_BANK(8, 0x0e0, "gpd2"),
EXYNOS_PIN_BANK(5, 0x100, "gpd4"),
EXYNOS_PIN_BANK(4, 0x120, "gpd5"),
EXYNOS_PIN_BANK(6, 0x140, "gpd6"),
EXYNOS_PIN_BANK(3, 0x160, "gpd7"),
EXYNOS_PIN_BANK(2, 0x180, "gpd8"),
EXYNOS_PIN_BANK(2, 0x1a0, "gpg0"),
EXYNOS_PIN_BANK(4, 0x1c0, "gpg3"),
};
/* pin banks of Exynos7420 pin-controller - FSYS0 */
static const struct samsung_pin_bank_data exynos7420_pin_banks1[] = {
EXYNOS_PIN_BANK(7, 0x000, "gpr4"),
};
/* pin banks of Exynos7420 pin-controller - FSYS1 */
static const struct samsung_pin_bank_data exynos7420_pin_banks2[] = {
EXYNOS_PIN_BANK(4, 0x000, "gpr0"),
EXYNOS_PIN_BANK(8, 0x020, "gpr1"),
EXYNOS_PIN_BANK(5, 0x040, "gpr2"),
EXYNOS_PIN_BANK(8, 0x060, "gpr3"),
};
const struct samsung_pin_ctrl exynos7420_pin_ctrl[] = {
{
/* pin-controller instance BUS0 data */
.pin_banks = exynos7420_pin_banks0,
.nr_banks = ARRAY_SIZE(exynos7420_pin_banks0),
}, {
/* pin-controller instance FSYS0 data */
.pin_banks = exynos7420_pin_banks1,
.nr_banks = ARRAY_SIZE(exynos7420_pin_banks1),
}, {
/* pin-controller instance FSYS1 data */
.pin_banks = exynos7420_pin_banks2,
.nr_banks = ARRAY_SIZE(exynos7420_pin_banks2),
},
};
static const struct udevice_id exynos7420_pinctrl_ids[] = {
{ .compatible = "samsung,exynos7420-pinctrl",
.data = (ulong)exynos7420_pin_ctrl },
{ }
};
U_BOOT_DRIVER(pinctrl_exynos7420) = {
.name = "pinctrl_exynos7420",
.id = UCLASS_PINCTRL,
.of_match = exynos7420_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct exynos_pinctrl_priv),
.ops = &exynos7420_pinctrl_ops,
.probe = exynos_pinctrl_probe,
.flags = DM_FLAG_PRE_RELOC
};

View File

@@ -0,0 +1,30 @@
config PINCTRL_IMX
bool
config PINCTRL_IMX6
bool "IMX6 pinctrl driver"
depends on ARCH_MX6 && PINCTRL_FULL
select DEVRES
select PINCTRL_IMX
help
Say Y here to enable the imx6 pinctrl driver
This provides a simple pinctrl driver for i.MX6 SoC familiy,
i.MX6DQ/SL/SX/UL/DQP. This feature depends on device tree
configuration. This driver is different from the linux one,
this is a simple implementation, only parses the 'fsl,pins'
property and configure related registers.
config PINCTRL_IMX7
bool "IMX7 pinctrl driver"
depends on ARCH_MX7 && PINCTRL_FULL
select DEVRES
select PINCTRL_IMX
help
Say Y here to enable the imx7 pinctrl driver
This provides a simple pinctrl driver for i.MX7 SoC familiy,
i.MX7D. This feature depends on device tree
configuration. This driver is different from the linux one,
this is a simple implementation, only parses the 'fsl,pins'
property and configure related registers.

View File

@@ -0,0 +1,3 @@
obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
obj-$(CONFIG_PINCTRL_IMX6) += pinctrl-imx6.o
obj-$(CONFIG_PINCTRL_IMX7) += pinctrl-imx7.o

View File

@@ -0,0 +1,241 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <mapmem.h>
#include <linux/io.h>
#include <linux/err.h>
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
DECLARE_GLOBAL_DATA_PTR;
static int imx_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
struct imx_pinctrl_priv *priv = dev_get_priv(dev);
struct imx_pinctrl_soc_info *info = priv->info;
int node = config->of_offset;
const struct fdt_property *prop;
u32 *pin_data;
int npins, size, pin_size;
int mux_reg, conf_reg, input_reg, input_val, mux_mode, config_val;
int i, j = 0;
dev_dbg(dev, "%s: %s\n", __func__, config->name);
if (info->flags & SHARE_MUX_CONF_REG)
pin_size = SHARE_FSL_PIN_SIZE;
else
pin_size = FSL_PIN_SIZE;
prop = fdt_getprop(gd->fdt_blob, node, "fsl,pins", &size);
if (!prop) {
dev_err(dev, "No fsl,pins property in node %s\n", config->name);
return -EINVAL;
}
if (!size || size % pin_size) {
dev_err(dev, "Invalid fsl,pins property in node %s\n",
config->name);
return -EINVAL;
}
pin_data = devm_kzalloc(dev, size, 0);
if (!pin_data)
return -ENOMEM;
if (fdtdec_get_int_array(gd->fdt_blob, node, "fsl,pins",
pin_data, size >> 2)) {
dev_err(dev, "Error reading pin data.\n");
return -EINVAL;
}
npins = size / pin_size;
/*
* Refer to linux documentation for details:
* Documentation/devicetree/bindings/pinctrl/fsl,imx-pinctrl.txt
*/
for (i = 0; i < npins; i++) {
mux_reg = pin_data[j++];
if (!(info->flags & ZERO_OFFSET_VALID) && !mux_reg)
mux_reg = -1;
if (info->flags & SHARE_MUX_CONF_REG) {
conf_reg = mux_reg;
} else {
conf_reg = pin_data[j++];
if (!(info->flags & ZERO_OFFSET_VALID) && !conf_reg)
conf_reg = -1;
}
if ((mux_reg == -1) || (conf_reg == -1)) {
dev_err(dev, "Error mux_reg or conf_reg\n");
return -EINVAL;
}
input_reg = pin_data[j++];
mux_mode = pin_data[j++];
input_val = pin_data[j++];
config_val = pin_data[j++];
dev_dbg(dev, "mux_reg 0x%x, conf_reg 0x%x, input_reg 0x%x, "
"mux_mode 0x%x, input_val 0x%x, config_val 0x%x\n",
mux_reg, conf_reg, input_reg, mux_mode, input_val,
config_val);
if (config_val & IMX_PAD_SION)
mux_mode |= IOMUXC_CONFIG_SION;
config_val &= ~IMX_PAD_SION;
/* Set Mux */
if (info->flags & SHARE_MUX_CONF_REG) {
clrsetbits_le32(info->base + mux_reg, 0x7 << 20,
mux_mode << 20);
} else {
writel(mux_mode, info->base + mux_reg);
}
dev_dbg(dev, "write mux: offset 0x%x val 0x%x\n", mux_reg,
mux_mode);
/*
* Set select input
*
* If the select input value begins with 0xff, it's a quirky
* select input and the value should be interpreted as below.
* 31 23 15 7 0
* | 0xff | shift | width | select |
* It's used to work around the problem that the select
* input for some pin is not implemented in the select
* input register but in some general purpose register.
* We encode the select input value, width and shift of
* the bit field into input_val cell of pin function ID
* in device tree, and then decode them here for setting
* up the select input bits in general purpose register.
*/
if (input_val >> 24 == 0xff) {
u32 val = input_val;
u8 select = val & 0xff;
u8 width = (val >> 8) & 0xff;
u8 shift = (val >> 16) & 0xff;
u32 mask = ((1 << width) - 1) << shift;
/*
* The input_reg[i] here is actually some IOMUXC general
* purpose register, not regular select input register.
*/
val = readl(info->base + input_reg);
val &= ~mask;
val |= select << shift;
writel(val, info->base + input_reg);
} else if (input_reg) {
/*
* Regular select input register can never be at offset
* 0, and we only print register value for regular case.
*/
if (info->input_sel_base)
writel(input_val, info->input_sel_base +
input_reg);
else
writel(input_val, info->base + input_reg);
dev_dbg(dev, "select_input: offset 0x%x val 0x%x\n",
input_reg, input_val);
}
/* Set config */
if (!(config_val & IMX_NO_PAD_CTL)) {
if (info->flags & SHARE_MUX_CONF_REG) {
clrsetbits_le32(info->base + conf_reg, 0xffff,
config_val);
} else {
writel(config_val, info->base + conf_reg);
}
dev_dbg(dev, "write config: offset 0x%x val 0x%x\n",
conf_reg, config_val);
}
}
return 0;
}
const struct pinctrl_ops imx_pinctrl_ops = {
.set_state = imx_pinctrl_set_state,
};
int imx_pinctrl_probe(struct udevice *dev,
struct imx_pinctrl_soc_info *info)
{
struct imx_pinctrl_priv *priv = dev_get_priv(dev);
int node = dev->of_offset, ret;
struct fdtdec_phandle_args arg;
fdt_addr_t addr;
fdt_size_t size;
if (!info) {
dev_err(dev, "wrong pinctrl info\n");
return -EINVAL;
}
priv->dev = dev;
priv->info = info;
addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
info->base = map_sysmem(addr, size);
if (!info->base)
return -ENOMEM;
priv->info = info;
/*
* Refer to linux documentation for details:
* Documentation/devicetree/bindings/pinctrl/fsl,imx7d-pinctrl.txt
*/
if (fdtdec_get_bool(gd->fdt_blob, node, "fsl,input-sel")) {
ret = fdtdec_parse_phandle_with_args(gd->fdt_blob,
node, "fsl,input-sel",
NULL, 0, 0, &arg);
if (ret) {
dev_err(dev, "iomuxc fsl,input-sel property not found\n");
return -EINVAL;
}
addr = fdtdec_get_addr_size(gd->fdt_blob, arg.node, "reg",
&size);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
info->input_sel_base = map_sysmem(addr, size);
if (!info->input_sel_base)
return -ENOMEM;
}
dev_info(dev, "initialized IMX pinctrl driver\n");
return 0;
}
int imx_pinctrl_remove(struct udevice *dev)
{
struct imx_pinctrl_priv *priv = dev_get_priv(dev);
struct imx_pinctrl_soc_info *info = priv->info;
if (info->input_sel_base)
unmap_sysmem(info->input_sel_base);
if (info->base)
unmap_sysmem(info->base);
return 0;
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __DRIVERS_PINCTRL_IMX_H
#define __DRIVERS_PINCTRL_IMX_H
/**
* @base: the address to the controller in virtual memory
* @input_sel_base: the address of the select input in virtual memory.
* @flags: flags specific for each soc
*/
struct imx_pinctrl_soc_info {
void __iomem *base;
void __iomem *input_sel_base;
unsigned int flags;
};
/**
* @dev: a pointer back to containing device
* @info: the soc info
*/
struct imx_pinctrl_priv {
struct udevice *dev;
struct imx_pinctrl_soc_info *info;
};
extern const struct pinctrl_ops imx_pinctrl_ops;
#define IMX_NO_PAD_CTL 0x80000000 /* no pin config need */
#define IMX_PAD_SION 0x40000000 /* set SION */
/*
* Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and
* 1 u32 CONFIG, so 24 types in total for each pin.
*/
#define FSL_PIN_SIZE 24
#define SHARE_FSL_PIN_SIZE 20
#define SHARE_MUX_CONF_REG 0x1
#define ZERO_OFFSET_VALID 0x2
#define IOMUXC_CONFIG_SION (0x1 << 4)
int imx_pinctrl_probe(struct udevice *dev, struct imx_pinctrl_soc_info *info);
int imx_pinctrl_remove(struct udevice *dev);
#endif /* __DRIVERS_PINCTRL_IMX_H */

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx6_pinctrl_soc_info;
static int imx6_pinctrl_probe(struct udevice *dev)
{
struct imx_pinctrl_soc_info *info =
(struct imx_pinctrl_soc_info *)dev_get_driver_data(dev);
return imx_pinctrl_probe(dev, info);
}
static const struct udevice_id imx6_pinctrl_match[] = {
{ .compatible = "fsl,imx6q-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6dl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6sl-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6sx-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ .compatible = "fsl,imx6ul-iomuxc", .data = (ulong)&imx6_pinctrl_soc_info },
{ /* sentinel */ }
};
U_BOOT_DRIVER(imx6_pinctrl) = {
.name = "imx6-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(imx6_pinctrl_match),
.probe = imx6_pinctrl_probe,
.remove = imx_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
.ops = &imx_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2016 Peng Fan <van.freenix@gmail.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-imx.h"
static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info;
static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = {
.flags = ZERO_OFFSET_VALID,
};
static int imx7_pinctrl_probe(struct udevice *dev)
{
struct imx_pinctrl_soc_info *info =
(struct imx_pinctrl_soc_info *)dev_get_driver_data(dev);
return imx_pinctrl_probe(dev, info);
}
static const struct udevice_id imx7_pinctrl_match[] = {
{ .compatible = "fsl,imx7d-iomuxc", .data = (ulong)&imx7_pinctrl_soc_info },
{ .compatible = "fsl,imx7d-iomuxc-lpsr", .data = (ulong)&imx7_lpsr_pinctrl_soc_info },
{ /* sentinel */ }
};
U_BOOT_DRIVER(imx7_pinctrl) = {
.name = "imx7-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(imx7_pinctrl_match),
.probe = imx7_pinctrl_probe,
.remove = imx_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct imx_pinctrl_priv),
.ops = &imx_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -0,0 +1,359 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <linux/compat.h>
#include <dm/device.h>
#include <dm/pinctrl.h>
DECLARE_GLOBAL_DATA_PTR;
/**
* pinctrl_pin_name_to_selector() - return the pin selector for a pin
*
* @dev: pin controller device
* @pin: the pin name to look up
* @return: pin selector, or negative error code on failure
*/
static int pinctrl_pin_name_to_selector(struct udevice *dev, const char *pin)
{
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
unsigned npins, selector;
if (!ops->get_pins_count || !ops->get_pin_name) {
dev_dbg(dev, "get_pins_count or get_pin_name missing\n");
return -ENOSYS;
}
npins = ops->get_pins_count(dev);
/* See if this pctldev has this pin */
for (selector = 0; selector < npins; selector++) {
const char *pname = ops->get_pin_name(dev, selector);
if (!strcmp(pin, pname))
return selector;
}
return -ENOSYS;
}
/**
* pinctrl_group_name_to_selector() - return the group selector for a group
*
* @dev: pin controller device
* @group: the pin group name to look up
* @return: pin group selector, or negative error code on failure
*/
static int pinctrl_group_name_to_selector(struct udevice *dev,
const char *group)
{
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
unsigned ngroups, selector;
if (!ops->get_groups_count || !ops->get_group_name) {
dev_dbg(dev, "get_groups_count or get_group_name missing\n");
return -ENOSYS;
}
ngroups = ops->get_groups_count(dev);
/* See if this pctldev has this group */
for (selector = 0; selector < ngroups; selector++) {
const char *gname = ops->get_group_name(dev, selector);
if (!strcmp(group, gname))
return selector;
}
return -ENOSYS;
}
#if CONFIG_IS_ENABLED(PINMUX)
/**
* pinmux_func_name_to_selector() - return the function selector for a function
*
* @dev: pin controller device
* @function: the function name to look up
* @return: function selector, or negative error code on failure
*/
static int pinmux_func_name_to_selector(struct udevice *dev,
const char *function)
{
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
unsigned nfuncs, selector = 0;
if (!ops->get_functions_count || !ops->get_function_name) {
dev_dbg(dev,
"get_functions_count or get_function_name missing\n");
return -ENOSYS;
}
nfuncs = ops->get_functions_count(dev);
/* See if this pctldev has this function */
for (selector = 0; selector < nfuncs; selector++) {
const char *fname = ops->get_function_name(dev, selector);
if (!strcmp(function, fname))
return selector;
}
return -ENOSYS;
}
/**
* pinmux_enable_setting() - enable pin-mux setting for a certain pin/group
*
* @dev: pin controller device
* @is_group: target of operation (true: pin group, false: pin)
* @selector: pin selector or group selector, depending on @is_group
* @func_selector: function selector
* @return: 0 on success, or negative error code on failure
*/
static int pinmux_enable_setting(struct udevice *dev, bool is_group,
unsigned selector, unsigned func_selector)
{
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
if (is_group) {
if (!ops->pinmux_group_set) {
dev_dbg(dev, "pinmux_group_set op missing\n");
return -ENOSYS;
}
return ops->pinmux_group_set(dev, selector, func_selector);
} else {
if (!ops->pinmux_set) {
dev_dbg(dev, "pinmux_set op missing\n");
return -ENOSYS;
}
return ops->pinmux_set(dev, selector, func_selector);
}
}
#else
static int pinmux_func_name_to_selector(struct udevice *dev,
const char *function)
{
return 0;
}
static int pinmux_enable_setting(struct udevice *dev, bool is_group,
unsigned selector, unsigned func_selector)
{
return 0;
}
#endif
#if CONFIG_IS_ENABLED(PINCONF)
/**
* pinconf_prop_name_to_param() - return parameter ID for a property name
*
* @dev: pin controller device
* @property: property name in DTS, such as "bias-pull-up", "slew-rate", etc.
* @default_value: return default value in case no value is specified in DTS
* @return: return pamater ID, or negative error code on failure
*/
static int pinconf_prop_name_to_param(struct udevice *dev,
const char *property, u32 *default_value)
{
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
const struct pinconf_param *p, *end;
if (!ops->pinconf_num_params || !ops->pinconf_params) {
dev_dbg(dev, "pinconf_num_params or pinconf_params missing\n");
return -ENOSYS;
}
p = ops->pinconf_params;
end = p + ops->pinconf_num_params;
/* See if this pctldev supports this parameter */
for (; p < end; p++) {
if (!strcmp(property, p->property)) {
*default_value = p->default_value;
return p->param;
}
}
return -ENOSYS;
}
/**
* pinconf_enable_setting() - apply pin configuration for a certain pin/group
*
* @dev: pin controller device
* @is_group: target of operation (true: pin group, false: pin)
* @selector: pin selector or group selector, depending on @is_group
* @param: configuration paramter
* @argument: argument taken by some configuration parameters
* @return: 0 on success, or negative error code on failure
*/
static int pinconf_enable_setting(struct udevice *dev, bool is_group,
unsigned selector, unsigned param,
u32 argument)
{
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
if (is_group) {
if (!ops->pinconf_group_set) {
dev_dbg(dev, "pinconf_group_set op missing\n");
return -ENOSYS;
}
return ops->pinconf_group_set(dev, selector, param,
argument);
} else {
if (!ops->pinconf_set) {
dev_dbg(dev, "pinconf_set op missing\n");
return -ENOSYS;
}
return ops->pinconf_set(dev, selector, param, argument);
}
}
#else
static int pinconf_prop_name_to_param(struct udevice *dev,
const char *property, u32 *default_value)
{
return -ENOSYS;
}
static int pinconf_enable_setting(struct udevice *dev, bool is_group,
unsigned selector, unsigned param,
u32 argument)
{
return 0;
}
#endif
/**
* pinctrl_generic_set_state_one() - set state for a certain pin/group
* Apply all pin multiplexing and pin configurations specified by @config
* for a given pin or pin group.
*
* @dev: pin controller device
* @config: pseudo device pointing to config node
* @is_group: target of operation (true: pin group, false: pin)
* @selector: pin selector or group selector, depending on @is_group
* @return: 0 on success, or negative error code on failure
*/
static int pinctrl_generic_set_state_one(struct udevice *dev,
struct udevice *config,
bool is_group, unsigned selector)
{
const void *fdt = gd->fdt_blob;
int node_offset = config->of_offset;
const char *propname;
const void *value;
int prop_offset, len, func_selector, param, ret;
u32 arg, default_val;
for (prop_offset = fdt_first_property_offset(fdt, node_offset);
prop_offset > 0;
prop_offset = fdt_next_property_offset(fdt, prop_offset)) {
value = fdt_getprop_by_offset(fdt, prop_offset,
&propname, &len);
if (!value)
return -EINVAL;
if (!strcmp(propname, "function")) {
func_selector = pinmux_func_name_to_selector(dev,
value);
if (func_selector < 0)
return func_selector;
ret = pinmux_enable_setting(dev, is_group,
selector,
func_selector);
} else {
param = pinconf_prop_name_to_param(dev, propname,
&default_val);
if (param < 0)
continue; /* just skip unknown properties */
if (len >= sizeof(fdt32_t))
arg = fdt32_to_cpu(*(fdt32_t *)value);
else
arg = default_val;
ret = pinconf_enable_setting(dev, is_group,
selector, param, arg);
}
if (ret)
return ret;
}
return 0;
}
/**
* pinctrl_generic_set_state_subnode() - apply all settings in config node
*
* @dev: pin controller device
* @config: pseudo device pointing to config node
* @return: 0 on success, or negative error code on failure
*/
static int pinctrl_generic_set_state_subnode(struct udevice *dev,
struct udevice *config)
{
const void *fdt = gd->fdt_blob;
int node = config->of_offset;
const char *subnode_target_type = "pins";
bool is_group = false;
const char *name;
int strings_count, selector, i, ret;
strings_count = fdt_count_strings(fdt, node, subnode_target_type);
if (strings_count < 0) {
subnode_target_type = "groups";
is_group = true;
strings_count = fdt_count_strings(fdt, node,
subnode_target_type);
if (strings_count < 0)
return -EINVAL;
}
for (i = 0; i < strings_count; i++) {
ret = fdt_get_string_index(fdt, node, subnode_target_type,
i, &name);
if (ret < 0)
return -EINVAL;
if (is_group)
selector = pinctrl_group_name_to_selector(dev, name);
else
selector = pinctrl_pin_name_to_selector(dev, name);
if (selector < 0)
return selector;
ret = pinctrl_generic_set_state_one(dev, config,
is_group, selector);
if (ret)
return ret;
}
return 0;
}
int pinctrl_generic_set_state(struct udevice *dev, struct udevice *config)
{
struct udevice *child;
int ret;
ret = pinctrl_generic_set_state_subnode(dev, config);
if (ret)
return ret;
for (device_find_first_child(config, &child);
child;
device_find_next_child(&child)) {
ret = pinctrl_generic_set_state_subnode(dev, child);
if (ret)
return ret;
}
return 0;
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
/* #define DEBUG */
#include <common.h>
#include <dm/device.h>
#include <dm/pinctrl.h>
static const char * const sandbox_pins[] = {
"SCL",
"SDA",
"TX",
"RX",
};
static const char * const sandbox_groups[] = {
"i2c",
"serial_a",
"serial_b",
"spi",
};
static const char * const sandbox_functions[] = {
"i2c",
"serial",
"spi",
};
static const struct pinconf_param sandbox_conf_params[] = {
{ "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
{ "bias-high-impedance", PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0 },
{ "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
{ "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
{ "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
{ "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
{ "drive-open-drain", PIN_CONFIG_DRIVE_OPEN_DRAIN, 0 },
{ "drive-open-source", PIN_CONFIG_DRIVE_OPEN_SOURCE, 0 },
{ "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
};
static int sandbox_get_pins_count(struct udevice *dev)
{
return ARRAY_SIZE(sandbox_pins);
}
static const char *sandbox_get_pin_name(struct udevice *dev, unsigned selector)
{
return sandbox_pins[selector];
}
static int sandbox_get_groups_count(struct udevice *dev)
{
return ARRAY_SIZE(sandbox_groups);
}
static const char *sandbox_get_group_name(struct udevice *dev,
unsigned selector)
{
return sandbox_groups[selector];
}
static int sandbox_get_functions_count(struct udevice *dev)
{
return ARRAY_SIZE(sandbox_functions);
}
static const char *sandbox_get_function_name(struct udevice *dev,
unsigned selector)
{
return sandbox_functions[selector];
}
static int sandbox_pinmux_set(struct udevice *dev, unsigned pin_selector,
unsigned func_selector)
{
debug("sandbox pinmux: pin = %d (%s), function = %d (%s)\n",
pin_selector, sandbox_get_pin_name(dev, pin_selector),
func_selector, sandbox_get_function_name(dev, func_selector));
return 0;
}
static int sandbox_pinmux_group_set(struct udevice *dev,
unsigned group_selector,
unsigned func_selector)
{
debug("sandbox pinmux: group = %d (%s), function = %d (%s)\n",
group_selector, sandbox_get_group_name(dev, group_selector),
func_selector, sandbox_get_function_name(dev, func_selector));
return 0;
}
static int sandbox_pinconf_set(struct udevice *dev, unsigned pin_selector,
unsigned param, unsigned argument)
{
debug("sandbox pinconf: pin = %d (%s), param = %d, arg = %d\n",
pin_selector, sandbox_get_pin_name(dev, pin_selector),
param, argument);
return 0;
}
static int sandbox_pinconf_group_set(struct udevice *dev,
unsigned group_selector,
unsigned param, unsigned argument)
{
debug("sandbox pinconf: group = %d (%s), param = %d, arg = %d\n",
group_selector, sandbox_get_group_name(dev, group_selector),
param, argument);
return 0;
}
const struct pinctrl_ops sandbox_pinctrl_ops = {
.get_pins_count = sandbox_get_pins_count,
.get_pin_name = sandbox_get_pin_name,
.get_groups_count = sandbox_get_groups_count,
.get_group_name = sandbox_get_group_name,
.get_functions_count = sandbox_get_functions_count,
.get_function_name = sandbox_get_function_name,
.pinmux_set = sandbox_pinmux_set,
.pinmux_group_set = sandbox_pinmux_group_set,
.pinconf_num_params = ARRAY_SIZE(sandbox_conf_params),
.pinconf_params = sandbox_conf_params,
.pinconf_set = sandbox_pinconf_set,
.pinconf_group_set = sandbox_pinconf_group_set,
.set_state = pinctrl_generic_set_state,
};
static const struct udevice_id sandbox_pinctrl_match[] = {
{ .compatible = "sandbox,pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(sandbox_pinctrl) = {
.name = "sandbox_pinctrl",
.id = UCLASS_PINCTRL,
.of_match = sandbox_pinctrl_match,
.ops = &sandbox_pinctrl_ops,
};

View File

@@ -0,0 +1,292 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <libfdt.h>
#include <linux/err.h>
#include <linux/list.h>
#include <dm/device.h>
#include <dm/lists.h>
#include <dm/pinctrl.h>
#include <dm/uclass.h>
DECLARE_GLOBAL_DATA_PTR;
int pinctrl_decode_pin_config(const void *blob, int node)
{
int flags = 0;
if (fdtdec_get_bool(blob, node, "bias-pull-up"))
flags |= 1 << PIN_CONFIG_BIAS_PULL_UP;
else if (fdtdec_get_bool(blob, node, "bias-pull-down"))
flags |= 1 << PIN_CONFIG_BIAS_PULL_DOWN;
return flags;
}
#if CONFIG_IS_ENABLED(PINCTRL_FULL)
/**
* pinctrl_config_one() - apply pinctrl settings for a single node
*
* @config: pin configuration node
* @return: 0 on success, or negative error code on failure
*/
static int pinctrl_config_one(struct udevice *config)
{
struct udevice *pctldev;
const struct pinctrl_ops *ops;
pctldev = config;
for (;;) {
pctldev = dev_get_parent(pctldev);
if (!pctldev) {
dev_err(config, "could not find pctldev\n");
return -EINVAL;
}
if (pctldev->uclass->uc_drv->id == UCLASS_PINCTRL)
break;
}
ops = pinctrl_get_ops(pctldev);
return ops->set_state(pctldev, config);
}
/**
* pinctrl_select_state_full() - full implementation of pinctrl_select_state
*
* @dev: peripheral device
* @statename: state name, like "default"
* @return: 0 on success, or negative error code on failure
*/
static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
{
const void *fdt = gd->fdt_blob;
int node = dev->of_offset;
char propname[32]; /* long enough */
const fdt32_t *list;
uint32_t phandle;
int config_node;
struct udevice *config;
int state, size, i, ret;
state = fdt_find_string(fdt, node, "pinctrl-names", statename);
if (state < 0) {
char *end;
/*
* If statename is not found in "pinctrl-names",
* assume statename is just the integer state ID.
*/
state = simple_strtoul(statename, &end, 10);
if (*end)
return -EINVAL;
}
snprintf(propname, sizeof(propname), "pinctrl-%d", state);
list = fdt_getprop(fdt, node, propname, &size);
if (!list)
return -EINVAL;
size /= sizeof(*list);
for (i = 0; i < size; i++) {
phandle = fdt32_to_cpu(*list++);
config_node = fdt_node_offset_by_phandle(fdt, phandle);
if (config_node < 0) {
dev_err(dev, "prop %s index %d invalid phandle\n",
propname, i);
return -EINVAL;
}
ret = uclass_get_device_by_of_offset(UCLASS_PINCONFIG,
config_node, &config);
if (ret)
return ret;
ret = pinctrl_config_one(config);
if (ret)
return ret;
}
return 0;
}
/**
* pinconfig_post-bind() - post binding for PINCONFIG uclass
* Recursively bind its children as pinconfig devices.
*
* @dev: pinconfig device
* @return: 0 on success, or negative error code on failure
*/
static int pinconfig_post_bind(struct udevice *dev)
{
const void *fdt = gd->fdt_blob;
int offset = dev->of_offset;
bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
const char *name;
int ret;
for (offset = fdt_first_subnode(fdt, offset);
offset > 0;
offset = fdt_next_subnode(fdt, offset)) {
if (pre_reloc_only &&
!fdt_getprop(fdt, offset, "u-boot,dm-pre-reloc", NULL))
continue;
/*
* If this node has "compatible" property, this is not
* a pin configuration node, but a normal device. skip.
*/
fdt_get_property(fdt, offset, "compatible", &ret);
if (ret >= 0)
continue;
if (ret != -FDT_ERR_NOTFOUND)
return ret;
name = fdt_get_name(fdt, offset, NULL);
if (!name)
return -EINVAL;
ret = device_bind_driver_to_node(dev, "pinconfig", name,
offset, NULL);
if (ret)
return ret;
}
return 0;
}
UCLASS_DRIVER(pinconfig) = {
.id = UCLASS_PINCONFIG,
.post_bind = pinconfig_post_bind,
.name = "pinconfig",
};
U_BOOT_DRIVER(pinconfig_generic) = {
.name = "pinconfig",
.id = UCLASS_PINCONFIG,
};
#else
static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
{
return -ENODEV;
}
static int pinconfig_post_bind(struct udevice *dev)
{
return 0;
}
#endif
/**
* pinctrl_select_state_simple() - simple implementation of pinctrl_select_state
*
* @dev: peripheral device
* @return: 0 on success, or negative error code on failure
*/
static int pinctrl_select_state_simple(struct udevice *dev)
{
struct udevice *pctldev;
struct pinctrl_ops *ops;
int ret;
/*
* For simplicity, assume the first device of PINCTRL uclass
* is the correct one. This is most likely OK as there is
* usually only one pinctrl device on the system.
*/
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev);
if (ret)
return ret;
ops = pinctrl_get_ops(pctldev);
if (!ops->set_state_simple) {
dev_dbg(dev, "set_state_simple op missing\n");
return -ENOSYS;
}
return ops->set_state_simple(pctldev, dev);
}
int pinctrl_select_state(struct udevice *dev, const char *statename)
{
/*
* Try full-implemented pinctrl first.
* If it fails or is not implemented, try simple one.
*/
if (pinctrl_select_state_full(dev, statename))
return pinctrl_select_state_simple(dev);
return 0;
}
int pinctrl_request(struct udevice *dev, int func, int flags)
{
struct pinctrl_ops *ops = pinctrl_get_ops(dev);
if (!ops->request)
return -ENOSYS;
return ops->request(dev, func, flags);
}
int pinctrl_request_noflags(struct udevice *dev, int func)
{
return pinctrl_request(dev, func, 0);
}
int pinctrl_get_periph_id(struct udevice *dev, struct udevice *periph)
{
struct pinctrl_ops *ops = pinctrl_get_ops(dev);
if (!ops->get_periph_id)
return -ENOSYS;
return ops->get_periph_id(dev, periph);
}
int pinctrl_get_gpio_mux(struct udevice *dev, int banknum, int index)
{
struct pinctrl_ops *ops = pinctrl_get_ops(dev);
if (!ops->get_gpio_mux)
return -ENOSYS;
return ops->get_gpio_mux(dev, banknum, index);
}
/**
* pinconfig_post-bind() - post binding for PINCTRL uclass
* Recursively bind child nodes as pinconfig devices in case of full pinctrl.
*
* @dev: pinctrl device
* @return: 0 on success, or negative error code on failure
*/
static int pinctrl_post_bind(struct udevice *dev)
{
const struct pinctrl_ops *ops = pinctrl_get_ops(dev);
if (!ops) {
dev_dbg(dev, "ops is not set. Do not bind.\n");
return -EINVAL;
}
/*
* If set_state callback is set, we assume this pinctrl driver is the
* full implementation. In this case, its child nodes should be bound
* so that peripheral devices can easily search in parent devices
* during later DT-parsing.
*/
if (ops->set_state)
return pinconfig_post_bind(dev);
return 0;
}
UCLASS_DRIVER(pinctrl) = {
.id = UCLASS_PINCTRL,
.post_bind = pinctrl_post_bind,
.flags = DM_UC_FLAG_SEQ_ALIAS,
.name = "pinctrl",
};

View File

@@ -0,0 +1,363 @@
/*
* Pinctrl driver for Microchip PIC32 SoCs
* Copyright (c) 2015 Microchip Technology Inc.
* Written by Purna Chandra Mandal <purna.mandal@microchip.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/io.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include <mach/pic32.h>
DECLARE_GLOBAL_DATA_PTR;
/* PIC32 has 10 peripheral ports with 16 pins each.
* Ports are marked PORTA-PORTK or PORT0-PORT9.
*/
enum {
PIC32_PORT_A = 0,
PIC32_PORT_B = 1,
PIC32_PORT_C = 2,
PIC32_PORT_D = 3,
PIC32_PORT_E = 4,
PIC32_PORT_F = 5,
PIC32_PORT_G = 6,
PIC32_PORT_H = 7,
PIC32_PORT_J = 8, /* no PORT_I */
PIC32_PORT_K = 9,
PIC32_PINS_PER_PORT = 16,
};
#define PIN_CONFIG_PIC32_DIGITAL (PIN_CONFIG_END + 1)
#define PIN_CONFIG_PIC32_ANALOG (PIN_CONFIG_END + 2)
/* pin configuration descriptor */
struct pic32_pin_config {
u16 port; /* port number */
u16 pin; /* pin number in the port */
u32 config; /* one of PIN_CONFIG_* */
};
#define PIN_CONFIG(_prt, _pin, _cfg) \
{.port = (_prt), .pin = (_pin), .config = (_cfg), }
/* In PIC32 muxing is performed at pin-level through two
* different set of registers - one set for input functions,
* and other for output functions.
* Pin configuration is handled through port register.
*/
/* Port control registers */
struct pic32_reg_port {
struct pic32_reg_atomic ansel;
struct pic32_reg_atomic tris;
struct pic32_reg_atomic port;
struct pic32_reg_atomic lat;
struct pic32_reg_atomic odc;
struct pic32_reg_atomic cnpu;
struct pic32_reg_atomic cnpd;
struct pic32_reg_atomic cncon;
struct pic32_reg_atomic unused[8];
};
/* Input function mux registers */
struct pic32_reg_in_mux {
u32 unused0;
u32 int1[4];
u32 unused1;
u32 t2ck[8];
u32 ic1[9];
u32 unused2;
u32 ocfar;
u32 unused3;
u32 u1rx;
u32 u1cts;
u32 u2rx;
u32 u2cts;
u32 u3rx;
u32 u3cts;
u32 u4rx;
u32 u4cts;
u32 u5rx;
u32 u5cts;
u32 u6rx;
u32 u6cts;
u32 unused4;
u32 sdi1;
u32 ss1;
u32 unused5;
u32 sdi2;
u32 ss2;
u32 unused6;
u32 sdi3;
u32 ss3;
u32 unused7;
u32 sdi4;
u32 ss4;
u32 unused8;
u32 sdi5;
u32 ss5;
u32 unused9;
u32 sdi6;
u32 ss6;
u32 c1rx;
u32 c2rx;
u32 refclki1;
u32 refclki2;
u32 refclki3;
u32 refclki4;
};
/* output mux register offset */
#define PPS_OUT(__port, __pin) \
(((__port) * PIC32_PINS_PER_PORT + (__pin)) << 2)
struct pic32_pinctrl_priv {
struct pic32_reg_in_mux *mux_in; /* mux input function */
struct pic32_reg_port *pinconf; /* pin configuration*/
void __iomem *mux_out; /* mux output function */
};
enum {
PERIPH_ID_UART1,
PERIPH_ID_UART2,
PERIPH_ID_ETH,
PERIPH_ID_USB,
PERIPH_ID_SDHCI,
PERIPH_ID_I2C1,
PERIPH_ID_I2C2,
PERIPH_ID_SPI1,
PERIPH_ID_SPI2,
PERIPH_ID_SQI,
};
static int pic32_pinconfig_one(struct pic32_pinctrl_priv *priv,
u32 port_nr, u32 pin, u32 param)
{
struct pic32_reg_port *port;
port = &priv->pinconf[port_nr];
switch (param) {
case PIN_CONFIG_PIC32_DIGITAL:
writel(BIT(pin), &port->ansel.clr);
break;
case PIN_CONFIG_PIC32_ANALOG:
writel(BIT(pin), &port->ansel.set);
break;
case PIN_CONFIG_INPUT_ENABLE:
writel(BIT(pin), &port->tris.set);
break;
case PIN_CONFIG_OUTPUT:
writel(BIT(pin), &port->tris.clr);
break;
case PIN_CONFIG_BIAS_PULL_UP:
writel(BIT(pin), &port->cnpu.set);
break;
case PIN_CONFIG_BIAS_PULL_DOWN:
writel(BIT(pin), &port->cnpd.set);
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
writel(BIT(pin), &port->odc.set);
break;
default:
break;
}
return 0;
}
static int pic32_pinconfig_set(struct pic32_pinctrl_priv *priv,
const struct pic32_pin_config *list, int count)
{
int i;
for (i = 0 ; i < count; i++)
pic32_pinconfig_one(priv, list[i].port,
list[i].pin, list[i].config);
return 0;
}
static void pic32_eth_pin_config(struct udevice *dev)
{
struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
const struct pic32_pin_config configs[] = {
/* EMDC - D11 */
PIN_CONFIG(PIC32_PORT_D, 11, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_D, 11, PIN_CONFIG_OUTPUT),
/* ETXEN */
PIN_CONFIG(PIC32_PORT_D, 6, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_D, 6, PIN_CONFIG_OUTPUT),
/* ECRSDV */
PIN_CONFIG(PIC32_PORT_H, 13, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_H, 13, PIN_CONFIG_INPUT_ENABLE),
/* ERXD0 */
PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_INPUT_ENABLE),
PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_BIAS_PULL_DOWN),
/* ERXD1 */
PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_INPUT_ENABLE),
PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_BIAS_PULL_DOWN),
/* EREFCLK */
PIN_CONFIG(PIC32_PORT_J, 11, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_J, 11, PIN_CONFIG_INPUT_ENABLE),
/* ETXD1 */
PIN_CONFIG(PIC32_PORT_J, 9, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_J, 9, PIN_CONFIG_OUTPUT),
/* ETXD0 */
PIN_CONFIG(PIC32_PORT_J, 8, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_J, 8, PIN_CONFIG_OUTPUT),
/* EMDIO */
PIN_CONFIG(PIC32_PORT_J, 1, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_J, 1, PIN_CONFIG_INPUT_ENABLE),
/* ERXERR */
PIN_CONFIG(PIC32_PORT_F, 3, PIN_CONFIG_PIC32_DIGITAL),
PIN_CONFIG(PIC32_PORT_F, 3, PIN_CONFIG_INPUT_ENABLE),
};
pic32_pinconfig_set(priv, configs, ARRAY_SIZE(configs));
}
static int pic32_pinctrl_request(struct udevice *dev, int func, int flags)
{
struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
switch (func) {
case PERIPH_ID_UART2:
/* PPS for U2 RX/TX */
writel(0x02, priv->mux_out + PPS_OUT(PIC32_PORT_G, 9));
writel(0x05, &priv->mux_in->u2rx); /* B0 */
/* set digital mode */
pic32_pinconfig_one(priv, PIC32_PORT_G, 9,
PIN_CONFIG_PIC32_DIGITAL);
pic32_pinconfig_one(priv, PIC32_PORT_B, 0,
PIN_CONFIG_PIC32_DIGITAL);
break;
case PERIPH_ID_ETH:
pic32_eth_pin_config(dev);
break;
default:
debug("%s: unknown-unhandled case\n", __func__);
break;
}
return 0;
}
static int pic32_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
int ret;
u32 cell[2];
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
/* interrupt number */
switch (cell[0]) {
case 112 ... 114:
return PERIPH_ID_UART1;
case 145 ... 147:
return PERIPH_ID_UART2;
case 109 ... 111:
return PERIPH_ID_SPI1;
case 142 ... 144:
return PERIPH_ID_SPI2;
case 115 ... 117:
return PERIPH_ID_I2C1;
case 148 ... 150:
return PERIPH_ID_I2C2;
case 132 ... 133:
return PERIPH_ID_USB;
case 169:
return PERIPH_ID_SQI;
case 191:
return PERIPH_ID_SDHCI;
case 153:
return PERIPH_ID_ETH;
default:
break;
}
return -ENOENT;
}
static int pic32_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int func;
debug("%s: periph %s\n", __func__, periph->name);
func = pic32_pinctrl_get_periph_id(dev, periph);
if (func < 0)
return func;
return pic32_pinctrl_request(dev, func, 0);
}
static struct pinctrl_ops pic32_pinctrl_ops = {
.set_state_simple = pic32_pinctrl_set_state_simple,
.request = pic32_pinctrl_request,
.get_periph_id = pic32_pinctrl_get_periph_id,
};
static int pic32_pinctrl_probe(struct udevice *dev)
{
struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
struct fdt_resource res;
void *fdt = (void *)gd->fdt_blob;
int node = dev->of_offset;
int ret;
ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
"ppsin", &res);
if (ret < 0) {
printf("pinctrl: resource \"ppsin\" not found\n");
return ret;
}
priv->mux_in = ioremap(res.start, fdt_resource_size(&res));
ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
"ppsout", &res);
if (ret < 0) {
printf("pinctrl: resource \"ppsout\" not found\n");
return ret;
}
priv->mux_out = ioremap(res.start, fdt_resource_size(&res));
ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
"port", &res);
if (ret < 0) {
printf("pinctrl: resource \"port\" not found\n");
return ret;
}
priv->pinconf = ioremap(res.start, fdt_resource_size(&res));
return 0;
}
static int pic32_pinctrl_bind(struct udevice *dev)
{
/* scan child GPIO banks */
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
static const struct udevice_id pic32_pinctrl_ids[] = {
{ .compatible = "microchip,pic32mzda-pinctrl" },
{ }
};
U_BOOT_DRIVER(pinctrl_pic32) = {
.name = "pinctrl_pic32",
.id = UCLASS_PINCTRL,
.of_match = pic32_pinctrl_ids,
.ops = &pic32_pinctrl_ops,
.probe = pic32_pinctrl_probe,
.bind = pic32_pinctrl_bind,
.priv_auto_alloc_size = sizeof(struct pic32_pinctrl_priv),
};

View File

@@ -0,0 +1,9 @@
#
# Copyright (c) 2015 Google, Inc
# Written by Simon Glass <sjg@chromium.org>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_ROCKCHIP_PINCTRL) += pinctrl_rk3288.o
obj-$(CONFIG_ROCKCHIP_3036_PINCTRL) += pinctrl_rk3036.o

View File

@@ -0,0 +1,284 @@
/*
* Pinctrl driver for Rockchip 3036 SoCs
* (C) Copyright 2015 Rockchip Electronics Co., Ltd
*
* 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_rk3036.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
struct rk3036_pinctrl_priv {
struct rk3036_grf *grf;
};
static void pinctrl_rk3036_pwm_config(struct rk3036_grf *grf, int pwm_id)
{
switch (pwm_id) {
case PERIPH_ID_PWM0:
rk_clrsetreg(&grf->gpio0d_iomux, GPIO0D2_MASK << GPIO0D2_SHIFT,
GPIO0D2_PWM0 << GPIO0D2_SHIFT);
break;
case PERIPH_ID_PWM1:
rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A0_MASK << GPIO0A0_SHIFT,
GPIO0A0_PWM1 << GPIO0A0_SHIFT);
break;
case PERIPH_ID_PWM2:
rk_clrsetreg(&grf->gpio0a_iomux, GPIO0A1_MASK << GPIO0A1_SHIFT,
GPIO0A1_PWM2 << GPIO0A1_SHIFT);
break;
case PERIPH_ID_PWM3:
rk_clrsetreg(&grf->gpio0a_iomux, GPIO0D3_MASK << GPIO0D3_SHIFT,
GPIO0D3_PWM3 << GPIO0D3_SHIFT);
break;
default:
debug("pwm id = %d iomux error!\n", pwm_id);
break;
}
}
static void pinctrl_rk3036_i2c_config(struct rk3036_grf *grf, int i2c_id)
{
switch (i2c_id) {
case PERIPH_ID_I2C0:
rk_clrsetreg(&grf->gpio0a_iomux,
GPIO0A1_MASK << GPIO0A1_SHIFT |
GPIO0A0_MASK << GPIO0A0_SHIFT,
GPIO0A1_I2C0_SDA << GPIO0A1_SHIFT |
GPIO0A0_I2C0_SCL << GPIO0A0_SHIFT);
break;
case PERIPH_ID_I2C1:
rk_clrsetreg(&grf->gpio0a_iomux,
GPIO0A3_MASK << GPIO0A3_SHIFT |
GPIO0A2_MASK << GPIO0A2_SHIFT,
GPIO0A3_I2C1_SDA << GPIO0A3_SHIFT |
GPIO0A2_I2C1_SCL << GPIO0A2_SHIFT);
break;
case PERIPH_ID_I2C2:
rk_clrsetreg(&grf->gpio2c_iomux,
GPIO2C5_MASK << GPIO2C5_SHIFT |
GPIO2C4_MASK << GPIO2C4_SHIFT,
GPIO2C5_I2C2_SCL << GPIO2C5_SHIFT |
GPIO2C4_I2C2_SDA << GPIO2C4_SHIFT);
break;
}
}
static void pinctrl_rk3036_spi_config(struct rk3036_grf *grf, int cs)
{
switch (cs) {
case 0:
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D6_MASK << GPIO1D6_SHIFT,
GPIO1D6_SPI_CSN0 << GPIO1D6_SHIFT);
break;
case 1:
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D7_MASK << GPIO1D7_SHIFT,
GPIO1D7_SPI_CSN1 << GPIO1D7_SHIFT);
break;
}
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D5_MASK << GPIO1D5_SHIFT |
GPIO1D4_MASK << GPIO1D4_SHIFT,
GPIO1D5_SPI_TXD << GPIO1D5_SHIFT |
GPIO1D4_SPI_RXD << GPIO1D4_SHIFT);
rk_clrsetreg(&grf->gpio2a_iomux,
GPIO2A0_MASK << GPIO2A0_SHIFT,
GPIO2A0_SPI_CLK << GPIO2A0_SHIFT);
}
static void pinctrl_rk3036_uart_config(struct rk3036_grf *grf, int uart_id)
{
switch (uart_id) {
case PERIPH_ID_UART0:
rk_clrsetreg(&grf->gpio0c_iomux,
GPIO0C3_MASK << GPIO0C3_SHIFT |
GPIO0C2_MASK << GPIO0C2_SHIFT |
GPIO0C1_MASK << GPIO0C1_SHIFT |
GPIO0C0_MASK << GPIO0C0_SHIFT,
GPIO0C3_UART0_CTSN << GPIO0C3_SHIFT |
GPIO0C2_UART0_RTSN << GPIO0C2_SHIFT |
GPIO0C1_UART0_SIN << GPIO0C1_SHIFT |
GPIO0C0_UART0_SOUT << GPIO0C0_SHIFT);
break;
case PERIPH_ID_UART1:
rk_clrsetreg(&grf->gpio2c_iomux,
GPIO2C7_MASK << GPIO2C7_SHIFT |
GPIO2C6_MASK << GPIO2C6_SHIFT,
GPIO2C7_UART1_SOUT << GPIO2C7_SHIFT |
GPIO2C6_UART1_SIN << GPIO2C6_SHIFT);
break;
case PERIPH_ID_UART2:
rk_clrsetreg(&grf->gpio1c_iomux,
GPIO1C3_MASK << GPIO1C3_SHIFT |
GPIO1C2_MASK << GPIO1C2_SHIFT,
GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
break;
}
}
static void pinctrl_rk3036_sdmmc_config(struct rk3036_grf *grf, int mmc_id)
{
switch (mmc_id) {
case PERIPH_ID_EMMC:
rk_clrsetreg(&grf->gpio1d_iomux, 0xffff,
GPIO1D7_EMMC_D7 << GPIO1D7_SHIFT |
GPIO1D6_EMMC_D6 << GPIO1D6_SHIFT |
GPIO1D5_EMMC_D5 << GPIO1D5_SHIFT |
GPIO1D4_EMMC_D4 << GPIO1D4_SHIFT |
GPIO1D3_EMMC_D3 << GPIO1D3_SHIFT |
GPIO1D2_EMMC_D2 << GPIO1D2_SHIFT |
GPIO1D1_EMMC_D1 << GPIO1D1_SHIFT |
GPIO1D0_EMMC_D0 << GPIO1D0_SHIFT);
rk_clrsetreg(&grf->gpio2a_iomux,
GPIO2A4_MASK << GPIO2A4_SHIFT |
GPIO2A1_MASK << GPIO2A1_SHIFT,
GPIO2A4_EMMC_CMD << GPIO2A4_SHIFT |
GPIO2A1_EMMC_CLKOUT << GPIO2A1_SHIFT);
break;
case PERIPH_ID_SDCARD:
rk_clrsetreg(&grf->gpio1c_iomux, 0xffff,
GPIO1C5_MMC0_D3 << GPIO1C5_SHIFT |
GPIO1C4_MMC0_D2 << GPIO1C4_SHIFT |
GPIO1C3_MMC0_D1 << GPIO1C3_SHIFT |
GPIO1C2_MMC0_D0 << GPIO1C2_SHIFT |
GPIO1C1_MMC0_DETN << GPIO1C1_SHIFT |
GPIO1C0_MMC0_CLKOUT << GPIO1C0_SHIFT);
break;
}
}
static int rk3036_pinctrl_request(struct udevice *dev, int func, int flags)
{
struct rk3036_pinctrl_priv *priv = dev_get_priv(dev);
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
switch (func) {
case PERIPH_ID_PWM0:
case PERIPH_ID_PWM1:
case PERIPH_ID_PWM2:
case PERIPH_ID_PWM3:
pinctrl_rk3036_pwm_config(priv->grf, func);
break;
case PERIPH_ID_I2C0:
case PERIPH_ID_I2C1:
case PERIPH_ID_I2C2:
pinctrl_rk3036_i2c_config(priv->grf, func);
break;
case PERIPH_ID_SPI0:
pinctrl_rk3036_spi_config(priv->grf, flags);
break;
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
case PERIPH_ID_UART2:
pinctrl_rk3036_uart_config(priv->grf, func);
break;
case PERIPH_ID_SDMMC0:
case PERIPH_ID_SDMMC1:
pinctrl_rk3036_sdmmc_config(priv->grf, func);
break;
default:
return -EINVAL;
}
return 0;
}
static int rk3036_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
u32 cell[3];
int ret;
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
switch (cell[1]) {
case 14:
return PERIPH_ID_SDCARD;
case 16:
return PERIPH_ID_EMMC;
case 20:
return PERIPH_ID_UART0;
case 21:
return PERIPH_ID_UART1;
case 22:
return PERIPH_ID_UART2;
case 23:
return PERIPH_ID_SPI0;
case 24:
return PERIPH_ID_I2C0;
case 25:
return PERIPH_ID_I2C1;
case 26:
return PERIPH_ID_I2C2;
case 30:
return PERIPH_ID_PWM0;
}
return -ENOENT;
}
static int rk3036_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int func;
func = rk3036_pinctrl_get_periph_id(dev, periph);
if (func < 0)
return func;
return rk3036_pinctrl_request(dev, func, 0);
}
static struct pinctrl_ops rk3036_pinctrl_ops = {
.set_state_simple = rk3036_pinctrl_set_state_simple,
.request = rk3036_pinctrl_request,
.get_periph_id = rk3036_pinctrl_get_periph_id,
};
static int rk3036_pinctrl_bind(struct udevice *dev)
{
/* scan child GPIO banks */
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
static int rk3036_pinctrl_probe(struct udevice *dev)
{
struct rk3036_pinctrl_priv *priv = dev_get_priv(dev);
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
debug("%s: grf=%p\n", __func__, priv->grf);
return 0;
}
static const struct udevice_id rk3036_pinctrl_ids[] = {
{ .compatible = "rockchip,rk3036-pinctrl" },
{ }
};
U_BOOT_DRIVER(pinctrl_rk3036) = {
.name = "pinctrl_rk3036",
.id = UCLASS_PINCTRL,
.of_match = rk3036_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct rk3036_pinctrl_priv),
.ops = &rk3036_pinctrl_ops,
.bind = rk3036_pinctrl_bind,
.probe = rk3036_pinctrl_probe,
};

View File

@@ -0,0 +1,729 @@
/*
* Pinctrl driver for Rockchip SoCs
* Copyright (c) 2015 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* 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_rk3288.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3288.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
DECLARE_GLOBAL_DATA_PTR;
struct rk3288_pinctrl_priv {
struct rk3288_grf *grf;
struct rk3288_pmu *pmu;
int num_banks;
};
/**
* Encode variants of iomux registers into a type variable
*/
#define IOMUX_GPIO_ONLY BIT(0)
#define IOMUX_WIDTH_4BIT BIT(1)
#define IOMUX_SOURCE_PMU BIT(2)
#define IOMUX_UNROUTED BIT(3)
/**
* @type: iomux variant using IOMUX_* constants
* @offset: if initialized to -1 it will be autocalculated, by specifying
* an initial offset value the relevant source offset can be reset
* to a new value for autocalculating the following iomux registers.
*/
struct rockchip_iomux {
u8 type;
s16 offset;
};
/**
* @reg: register offset of the gpio bank
* @nr_pins: number of pins in this bank
* @bank_num: number of the bank, to account for holes
* @name: name of the bank
* @iomux: array describing the 4 iomux sources of the bank
*/
struct rockchip_pin_bank {
u16 reg;
u8 nr_pins;
u8 bank_num;
char *name;
struct rockchip_iomux iomux[4];
};
#define PIN_BANK(id, pins, label) \
{ \
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
.iomux = { \
{ .offset = -1 }, \
{ .offset = -1 }, \
{ .offset = -1 }, \
{ .offset = -1 }, \
}, \
}
#define PIN_BANK_IOMUX_FLAGS(id, pins, label, iom0, iom1, iom2, iom3) \
{ \
.bank_num = id, \
.nr_pins = pins, \
.name = label, \
.iomux = { \
{ .type = iom0, .offset = -1 }, \
{ .type = iom1, .offset = -1 }, \
{ .type = iom2, .offset = -1 }, \
{ .type = iom3, .offset = -1 }, \
}, \
}
#ifndef CONFIG_SPL_BUILD
static struct rockchip_pin_bank rk3288_pin_banks[] = {
PIN_BANK_IOMUX_FLAGS(0, 24, "gpio0", IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
IOMUX_SOURCE_PMU,
IOMUX_UNROUTED
),
PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_UNROUTED,
IOMUX_UNROUTED,
IOMUX_UNROUTED,
0
),
PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, IOMUX_UNROUTED),
PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, IOMUX_WIDTH_4BIT),
PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
IOMUX_WIDTH_4BIT,
0,
0
),
PIN_BANK_IOMUX_FLAGS(5, 32, "gpio5", IOMUX_UNROUTED,
0,
0,
IOMUX_UNROUTED
),
PIN_BANK_IOMUX_FLAGS(6, 32, "gpio6", 0, 0, 0, IOMUX_UNROUTED),
PIN_BANK_IOMUX_FLAGS(7, 32, "gpio7", 0,
0,
IOMUX_WIDTH_4BIT,
IOMUX_UNROUTED
),
PIN_BANK(8, 16, "gpio8"),
};
#endif
static void pinctrl_rk3288_pwm_config(struct rk3288_grf *grf, int pwm_id)
{
switch (pwm_id) {
case PERIPH_ID_PWM0:
rk_clrsetreg(&grf->gpio7a_iomux, GPIO7A0_MASK << GPIO7A0_SHIFT,
GPIO7A0_PWM_0 << GPIO7A0_SHIFT);
break;
case PERIPH_ID_PWM1:
rk_clrsetreg(&grf->gpio7a_iomux, GPIO7A1_MASK << GPIO7A1_SHIFT,
GPIO7A1_PWM_1 << GPIO7A1_SHIFT);
break;
case PERIPH_ID_PWM2:
rk_clrsetreg(&grf->gpio7a_iomux, GPIO7C6_MASK << GPIO7C6_SHIFT,
GPIO7C6_PWM_2 << GPIO7C6_SHIFT);
break;
case PERIPH_ID_PWM3:
rk_clrsetreg(&grf->gpio7a_iomux, GPIO7C7_MASK << GPIO7C6_SHIFT,
GPIO7C7_PWM_3 << GPIO7C7_SHIFT);
break;
default:
debug("pwm id = %d iomux error!\n", pwm_id);
break;
}
}
static void pinctrl_rk3288_i2c_config(struct rk3288_grf *grf,
struct rk3288_pmu *pmu, int i2c_id)
{
switch (i2c_id) {
case PERIPH_ID_I2C0:
clrsetbits_le32(&pmu->gpio0_iomux[PMU_GPIO0_B],
GPIO0_B7_MASK << GPIO0_B7_SHIFT,
GPIO0_B7_I2C0PMU_SDA << GPIO0_B7_SHIFT);
clrsetbits_le32(&pmu->gpio0_iomux[PMU_GPIO0_C],
GPIO0_C0_MASK << GPIO0_C0_SHIFT,
GPIO0_C0_I2C0PMU_SCL << GPIO0_C0_SHIFT);
break;
#ifndef CONFIG_SPL_BUILD
case PERIPH_ID_I2C1:
rk_clrsetreg(&grf->gpio8a_iomux,
GPIO8A4_MASK << GPIO8A4_SHIFT |
GPIO8A5_MASK << GPIO8A5_SHIFT,
GPIO8A4_I2C2SENSOR_SDA << GPIO8A4_SHIFT |
GPIO8A5_I2C2SENSOR_SCL << GPIO8A5_SHIFT);
break;
case PERIPH_ID_I2C2:
rk_clrsetreg(&grf->gpio6b_iomux,
GPIO6B1_MASK << GPIO6B1_SHIFT |
GPIO6B2_MASK << GPIO6B2_SHIFT,
GPIO6B1_I2C1AUDIO_SDA << GPIO6B1_SHIFT |
GPIO6B2_I2C1AUDIO_SCL << GPIO6B2_SHIFT);
break;
case PERIPH_ID_I2C3:
rk_clrsetreg(&grf->gpio2c_iomux,
GPIO2C1_MASK << GPIO2C1_SHIFT |
GPIO2C0_MASK << GPIO2C0_SHIFT,
GPIO2C1_I2C3CAM_SDA << GPIO2C1_SHIFT |
GPIO2C0_I2C3CAM_SCL << GPIO2C0_SHIFT);
break;
case PERIPH_ID_I2C4:
rk_clrsetreg(&grf->gpio7cl_iomux,
GPIO7C1_MASK << GPIO7C1_SHIFT |
GPIO7C2_MASK << GPIO7C2_SHIFT,
GPIO7C1_I2C4TP_SDA << GPIO7C1_SHIFT |
GPIO7C2_I2C4TP_SCL << GPIO7C2_SHIFT);
break;
case PERIPH_ID_I2C5:
rk_clrsetreg(&grf->gpio7cl_iomux,
GPIO7C3_MASK << GPIO7C3_SHIFT,
GPIO7C3_I2C5HDMI_SDA << GPIO7C3_SHIFT);
rk_clrsetreg(&grf->gpio7ch_iomux,
GPIO7C4_MASK << GPIO7C4_SHIFT,
GPIO7C4_I2C5HDMI_SCL << GPIO7C4_SHIFT);
break;
#endif
default:
debug("i2c id = %d iomux error!\n", i2c_id);
break;
}
}
#ifndef CONFIG_SPL_BUILD
static void pinctrl_rk3288_lcdc_config(struct rk3288_grf *grf, int lcd_id)
{
switch (lcd_id) {
case PERIPH_ID_LCDC0:
rk_clrsetreg(&grf->gpio1d_iomux,
GPIO1D3_MASK << GPIO1D0_SHIFT |
GPIO1D2_MASK << GPIO1D2_SHIFT |
GPIO1D1_MASK << GPIO1D1_SHIFT |
GPIO1D0_MASK << GPIO1D0_SHIFT,
GPIO1D3_LCDC0_DCLK << GPIO1D3_SHIFT |
GPIO1D2_LCDC0_DEN << GPIO1D2_SHIFT |
GPIO1D1_LCDC0_VSYNC << GPIO1D1_SHIFT |
GPIO1D0_LCDC0_HSYNC << GPIO1D0_SHIFT);
break;
default:
debug("lcdc id = %d iomux error!\n", lcd_id);
break;
}
}
#endif
static int pinctrl_rk3288_spi_config(struct rk3288_grf *grf,
enum periph_id spi_id, int cs)
{
switch (spi_id) {
#ifndef CONFIG_SPL_BUILD
case PERIPH_ID_SPI0:
switch (cs) {
case 0:
rk_clrsetreg(&grf->gpio5b_iomux,
GPIO5B5_MASK << GPIO5B5_SHIFT,
GPIO5B5_SPI0_CSN0 << GPIO5B5_SHIFT);
break;
case 1:
rk_clrsetreg(&grf->gpio5c_iomux,
GPIO5C0_MASK << GPIO5C0_SHIFT,
GPIO5C0_SPI0_CSN1 << GPIO5C0_SHIFT);
break;
default:
goto err;
}
rk_clrsetreg(&grf->gpio5b_iomux,
GPIO5B7_MASK << GPIO5B7_SHIFT |
GPIO5B6_MASK << GPIO5B6_SHIFT |
GPIO5B4_MASK << GPIO5B4_SHIFT,
GPIO5B7_SPI0_RXD << GPIO5B7_SHIFT |
GPIO5B6_SPI0_TXD << GPIO5B6_SHIFT |
GPIO5B4_SPI0_CLK << GPIO5B4_SHIFT);
break;
case PERIPH_ID_SPI1:
if (cs != 0)
goto err;
rk_clrsetreg(&grf->gpio7b_iomux,
GPIO7B6_MASK << GPIO7B6_SHIFT |
GPIO7B7_MASK << GPIO7B7_SHIFT |
GPIO7B5_MASK << GPIO7B5_SHIFT |
GPIO7B4_MASK << GPIO7B4_SHIFT,
GPIO7B6_SPI1_RXD << GPIO7B6_SHIFT |
GPIO7B7_SPI1_TXD << GPIO7B7_SHIFT |
GPIO7B5_SPI1_CSN0 << GPIO7B5_SHIFT |
GPIO7B4_SPI1_CLK << GPIO7B4_SHIFT);
break;
#endif
case PERIPH_ID_SPI2:
switch (cs) {
case 0:
rk_clrsetreg(&grf->gpio8a_iomux,
GPIO8A7_MASK << GPIO8A7_SHIFT,
GPIO8A7_SPI2_CSN0 << GPIO8A7_SHIFT);
break;
case 1:
rk_clrsetreg(&grf->gpio8a_iomux,
GPIO8A3_MASK << GPIO8A3_SHIFT,
GPIO8A3_SPI2_CSN1 << GPIO8A3_SHIFT);
break;
default:
goto err;
}
rk_clrsetreg(&grf->gpio8b_iomux,
GPIO8B1_MASK << GPIO8B1_SHIFT |
GPIO8B0_MASK << GPIO8B0_SHIFT,
GPIO8B1_SPI2_TXD << GPIO8B1_SHIFT |
GPIO8B0_SPI2_RXD << GPIO8B0_SHIFT);
rk_clrsetreg(&grf->gpio8a_iomux,
GPIO8A6_MASK << GPIO8A6_SHIFT,
GPIO8A6_SPI2_CLK << GPIO8A6_SHIFT);
break;
default:
goto err;
}
return 0;
err:
debug("rkspi: periph%d cs=%d not supported", spi_id, cs);
return -ENOENT;
}
static void pinctrl_rk3288_uart_config(struct rk3288_grf *grf, int uart_id)
{
switch (uart_id) {
#ifndef CONFIG_SPL_BUILD
case PERIPH_ID_UART_BT:
rk_clrsetreg(&grf->gpio4c_iomux,
GPIO4C3_MASK << GPIO4C3_SHIFT |
GPIO4C2_MASK << GPIO4C2_SHIFT |
GPIO4C1_MASK << GPIO4C1_SHIFT |
GPIO4C0_MASK << GPIO4C0_SHIFT,
GPIO4C3_UART0BT_RTSN << GPIO4C3_SHIFT |
GPIO4C2_UART0BT_CTSN << GPIO4C2_SHIFT |
GPIO4C1_UART0BT_SOUT << GPIO4C1_SHIFT |
GPIO4C0_UART0BT_SIN << GPIO4C0_SHIFT);
break;
case PERIPH_ID_UART_BB:
rk_clrsetreg(&grf->gpio5b_iomux,
GPIO5B3_MASK << GPIO5B3_SHIFT |
GPIO5B2_MASK << GPIO5B2_SHIFT |
GPIO5B1_MASK << GPIO5B1_SHIFT |
GPIO5B0_MASK << GPIO5B0_SHIFT,
GPIO5B3_UART1BB_RTSN << GPIO5B3_SHIFT |
GPIO5B2_UART1BB_CTSN << GPIO5B2_SHIFT |
GPIO5B1_UART1BB_SOUT << GPIO5B1_SHIFT |
GPIO5B0_UART1BB_SIN << GPIO5B0_SHIFT);
break;
#endif
case PERIPH_ID_UART_DBG:
rk_clrsetreg(&grf->gpio7ch_iomux,
GPIO7C7_MASK << GPIO7C7_SHIFT |
GPIO7C6_MASK << GPIO7C6_SHIFT,
GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
break;
#ifndef CONFIG_SPL_BUILD
case PERIPH_ID_UART_GPS:
rk_clrsetreg(&grf->gpio7b_iomux,
GPIO7B2_MASK << GPIO7B2_SHIFT |
GPIO7B1_MASK << GPIO7B1_SHIFT |
GPIO7B0_MASK << GPIO7B0_SHIFT,
GPIO7B2_UART3GPS_RTSN << GPIO7B2_SHIFT |
GPIO7B1_UART3GPS_CTSN << GPIO7B1_SHIFT |
GPIO7B0_UART3GPS_SOUT << GPIO7B0_SHIFT);
rk_clrsetreg(&grf->gpio7a_iomux,
GPIO7A7_MASK << GPIO7A7_SHIFT,
GPIO7A7_UART3GPS_SIN << GPIO7A7_SHIFT);
break;
case PERIPH_ID_UART_EXP:
rk_clrsetreg(&grf->gpio5b_iomux,
GPIO5B5_MASK << GPIO5B5_SHIFT |
GPIO5B4_MASK << GPIO5B4_SHIFT |
GPIO5B6_MASK << GPIO5B6_SHIFT |
GPIO5B7_MASK << GPIO5B7_SHIFT,
GPIO5B5_UART4EXP_RTSN << GPIO5B5_SHIFT |
GPIO5B4_UART4EXP_CTSN << GPIO5B4_SHIFT |
GPIO5B6_UART4EXP_SOUT << GPIO5B6_SHIFT |
GPIO5B7_UART4EXP_SIN << GPIO5B7_SHIFT);
break;
#endif
default:
debug("uart id = %d iomux error!\n", uart_id);
break;
}
}
static void pinctrl_rk3288_sdmmc_config(struct rk3288_grf *grf, int mmc_id)
{
switch (mmc_id) {
case PERIPH_ID_EMMC:
rk_clrsetreg(&grf->gpio3a_iomux, 0xffff,
GPIO3A7_EMMC_DATA7 << GPIO3A7_SHIFT |
GPIO3A6_EMMC_DATA6 << GPIO3A6_SHIFT |
GPIO3A5_EMMC_DATA5 << GPIO3A5_SHIFT |
GPIO3A4_EMMC_DATA4 << GPIO3A4_SHIFT |
GPIO3A3_EMMC_DATA3 << GPIO3A3_SHIFT |
GPIO3A2_EMMC_DATA2 << GPIO3A2_SHIFT |
GPIO3A1_EMMC_DATA1 << GPIO3A1_SHIFT |
GPIO3A0_EMMC_DATA0 << GPIO3A0_SHIFT);
rk_clrsetreg(&grf->gpio3b_iomux, GPIO3B1_MASK << GPIO3B1_SHIFT,
GPIO3B1_EMMC_PWREN << GPIO3B1_SHIFT);
rk_clrsetreg(&grf->gpio3c_iomux,
GPIO3C0_MASK << GPIO3C0_SHIFT,
GPIO3C0_EMMC_CMD << GPIO3C0_SHIFT);
break;
case PERIPH_ID_SDCARD:
rk_clrsetreg(&grf->gpio6c_iomux, 0xffff,
GPIO6C6_SDMMC0_DECTN << GPIO6C6_SHIFT |
GPIO6C5_SDMMC0_CMD << GPIO6C5_SHIFT |
GPIO6C4_SDMMC0_CLKOUT << GPIO6C4_SHIFT |
GPIO6C3_SDMMC0_DATA3 << GPIO6C3_SHIFT |
GPIO6C2_SDMMC0_DATA2 << GPIO6C2_SHIFT |
GPIO6C1_SDMMC0_DATA1 << GPIO6C1_SHIFT |
GPIO6C0_SDMMC0_DATA0 << GPIO6C0_SHIFT);
/* use sdmmc0 io, disable JTAG function */
rk_clrsetreg(&grf->soc_con0, 1 << GRF_FORCE_JTAG_SHIFT, 0);
break;
default:
debug("mmc id = %d iomux error!\n", mmc_id);
break;
}
}
#ifndef CONFIG_SPL_BUILD
static void pinctrl_rk3288_hdmi_config(struct rk3288_grf *grf, int hdmi_id)
{
switch (hdmi_id) {
case PERIPH_ID_HDMI:
rk_clrsetreg(&grf->gpio7cl_iomux, GPIO7C3_MASK << GPIO7C3_SHIFT,
GPIO7C3_EDPHDMII2C_SDA << GPIO7C3_SHIFT);
rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C4_MASK << GPIO7C4_SHIFT,
GPIO7C4_EDPHDMII2C_SCL << GPIO7C4_SHIFT);
break;
default:
debug("hdmi id = %d iomux error!\n", hdmi_id);
break;
}
}
#endif
static int rk3288_pinctrl_request(struct udevice *dev, int func, int flags)
{
struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
switch (func) {
case PERIPH_ID_PWM0:
case PERIPH_ID_PWM1:
case PERIPH_ID_PWM2:
case PERIPH_ID_PWM3:
case PERIPH_ID_PWM4:
pinctrl_rk3288_pwm_config(priv->grf, func);
break;
case PERIPH_ID_I2C0:
case PERIPH_ID_I2C1:
case PERIPH_ID_I2C2:
case PERIPH_ID_I2C3:
case PERIPH_ID_I2C4:
case PERIPH_ID_I2C5:
pinctrl_rk3288_i2c_config(priv->grf, priv->pmu, func);
break;
case PERIPH_ID_SPI0:
case PERIPH_ID_SPI1:
case PERIPH_ID_SPI2:
pinctrl_rk3288_spi_config(priv->grf, func, flags);
break;
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
case PERIPH_ID_UART2:
case PERIPH_ID_UART3:
case PERIPH_ID_UART4:
pinctrl_rk3288_uart_config(priv->grf, func);
break;
#ifndef CONFIG_SPL_BUILD
case PERIPH_ID_LCDC0:
case PERIPH_ID_LCDC1:
pinctrl_rk3288_lcdc_config(priv->grf, func);
break;
case PERIPH_ID_HDMI:
pinctrl_rk3288_hdmi_config(priv->grf, func);
break;
#endif
case PERIPH_ID_SDMMC0:
case PERIPH_ID_SDMMC1:
pinctrl_rk3288_sdmmc_config(priv->grf, func);
break;
default:
return -EINVAL;
}
return 0;
}
static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
struct udevice *periph)
{
u32 cell[3];
int ret;
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
"interrupts", cell, ARRAY_SIZE(cell));
if (ret < 0)
return -EINVAL;
switch (cell[1]) {
case 44:
return PERIPH_ID_SPI0;
case 45:
return PERIPH_ID_SPI1;
case 46:
return PERIPH_ID_SPI2;
case 60:
return PERIPH_ID_I2C0;
case 62: /* Note strange order */
return PERIPH_ID_I2C1;
case 61:
return PERIPH_ID_I2C2;
case 63:
return PERIPH_ID_I2C3;
case 64:
return PERIPH_ID_I2C4;
case 65:
return PERIPH_ID_I2C5;
case 103:
return PERIPH_ID_HDMI;
}
return -ENOENT;
}
static int rk3288_pinctrl_set_state_simple(struct udevice *dev,
struct udevice *periph)
{
int func;
func = rk3288_pinctrl_get_periph_id(dev, periph);
if (func < 0)
return func;
return rk3288_pinctrl_request(dev, func, 0);
}
#ifndef CONFIG_SPL_BUILD
int rk3288_pinctrl_get_pin_info(struct rk3288_pinctrl_priv *priv,
int banknum, int ind, u32 **addrp, uint *shiftp,
uint *maskp)
{
struct rockchip_pin_bank *bank = &rk3288_pin_banks[banknum];
uint muxnum;
u32 *addr;
for (muxnum = 0; muxnum < 4; muxnum++) {
struct rockchip_iomux *mux = &bank->iomux[muxnum];
if (ind >= 8) {
ind -= 8;
continue;
}
if (mux->type & IOMUX_SOURCE_PMU)
addr = priv->pmu->gpio0_iomux;
else
addr = (u32 *)priv->grf - 4;
addr += mux->offset;
*shiftp = ind & 7;
if (mux->type & IOMUX_WIDTH_4BIT) {
*maskp = 0xf;
*shiftp *= 4;
if (*shiftp >= 16) {
*shiftp -= 16;
addr++;
}
} else {
*maskp = 3;
*shiftp *= 2;
}
debug("%s: addr=%p, mask=%x, shift=%x\n", __func__, addr,
*maskp, *shiftp);
*addrp = addr;
return 0;
}
return -EINVAL;
}
static int rk3288_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
int index)
{
struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
uint shift;
uint mask;
u32 *addr;
int ret;
ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
&mask);
if (ret)
return ret;
return (readl(addr) & mask) >> shift;
}
static int rk3288_pinctrl_set_pins(struct udevice *dev, int banknum, int index,
int muxval, int flags)
{
struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
uint shift, ind = index;
uint mask;
u32 *addr;
int ret;
debug("%s: %x %x %x %x\n", __func__, banknum, index, muxval, flags);
ret = rk3288_pinctrl_get_pin_info(priv, banknum, index, &addr, &shift,
&mask);
if (ret)
return ret;
rk_clrsetreg(addr, mask << shift, muxval << shift);
/* Handle pullup/pulldown */
if (flags) {
uint val = 0;
if (flags & (1 << PIN_CONFIG_BIAS_PULL_UP))
val = 1;
else if (flags & (1 << PIN_CONFIG_BIAS_PULL_DOWN))
val = 2;
shift = (index & 7) * 2;
ind = index >> 3;
if (banknum == 0)
addr = &priv->pmu->gpio0pull[ind];
else
addr = &priv->grf->gpio1_p[banknum - 1][ind];
debug("%s: addr=%p, val=%x, shift=%x\n", __func__, addr, val,
shift);
rk_clrsetreg(addr, 3 << shift, val << shift);
}
return 0;
}
static int rk3288_pinctrl_set_state(struct udevice *dev, struct udevice *config)
{
const void *blob = gd->fdt_blob;
int pcfg_node, ret, flags, count, i;
u32 cell[60], *ptr;
debug("%s: %s %s\n", __func__, dev->name, config->name);
ret = fdtdec_get_int_array_count(blob, config->of_offset,
"rockchip,pins", cell,
ARRAY_SIZE(cell));
if (ret < 0) {
debug("%s: bad array %d\n", __func__, ret);
return -EINVAL;
}
count = ret;
for (i = 0, ptr = cell; i < count; i += 4, ptr += 4) {
pcfg_node = fdt_node_offset_by_phandle(blob, ptr[3]);
if (pcfg_node < 0)
return -EINVAL;
flags = pinctrl_decode_pin_config(blob, pcfg_node);
if (flags < 0)
return flags;
ret = rk3288_pinctrl_set_pins(dev, ptr[0], ptr[1], ptr[2],
flags);
if (ret)
return ret;
}
return 0;
}
#endif
static struct pinctrl_ops rk3288_pinctrl_ops = {
#ifndef CONFIG_SPL_BUILD
.set_state = rk3288_pinctrl_set_state,
.get_gpio_mux = rk3288_pinctrl_get_gpio_mux,
#endif
.set_state_simple = rk3288_pinctrl_set_state_simple,
.request = rk3288_pinctrl_request,
.get_periph_id = rk3288_pinctrl_get_periph_id,
};
static int rk3288_pinctrl_bind(struct udevice *dev)
{
/* scan child GPIO banks */
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
#ifndef CONFIG_SPL_BUILD
static int rk3288_pinctrl_parse_tables(struct rk3288_pinctrl_priv *priv,
struct rockchip_pin_bank *banks,
int count)
{
struct rockchip_pin_bank *bank;
uint reg, muxnum, banknum;
reg = 0;
for (banknum = 0; banknum < count; banknum++) {
bank = &banks[banknum];
bank->reg = reg;
debug("%s: bank %d, reg %x\n", __func__, banknum, reg * 4);
for (muxnum = 0; muxnum < 4; muxnum++) {
struct rockchip_iomux *mux = &bank->iomux[muxnum];
if (!(mux->type & IOMUX_UNROUTED))
mux->offset = reg;
if (mux->type & IOMUX_WIDTH_4BIT)
reg += 2;
else
reg += 1;
}
}
return 0;
}
#endif
static int rk3288_pinctrl_probe(struct udevice *dev)
{
struct rk3288_pinctrl_priv *priv = dev_get_priv(dev);
int ret = 0;
priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
debug("%s: grf=%p, pmu=%p\n", __func__, priv->grf, priv->pmu);
#ifndef CONFIG_SPL_BUILD
ret = rk3288_pinctrl_parse_tables(priv, rk3288_pin_banks,
ARRAY_SIZE(rk3288_pin_banks));
#endif
return ret;
}
static const struct udevice_id rk3288_pinctrl_ids[] = {
{ .compatible = "rockchip,rk3288-pinctrl" },
{ }
};
U_BOOT_DRIVER(pinctrl_rk3288) = {
.name = "pinctrl_rk3288",
.id = UCLASS_PINCTRL,
.of_match = rk3288_pinctrl_ids,
.priv_auto_alloc_size = sizeof(struct rk3288_pinctrl_priv),
.ops = &rk3288_pinctrl_ops,
.bind = rk3288_pinctrl_bind,
.probe = rk3288_pinctrl_probe,
};

View File

@@ -0,0 +1,54 @@
if ARCH_UNIPHIER
config PINCTRL_UNIPHIER
bool
config PINCTRL_UNIPHIER_LD4
bool "UniPhier PH1-LD4 SoC pinctrl driver"
depends on ARCH_UNIPHIER_LD4
default y
select PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_PRO4
bool "UniPhier PH1-Pro4 SoC pinctrl driver"
depends on ARCH_UNIPHIER_PRO4
default y
select PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_SLD8
bool "UniPhier PH1-sLD8 SoC pinctrl driver"
depends on ARCH_UNIPHIER_SLD8
default y
select PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_PRO5
bool "UniPhier PH1-Pro5 SoC pinctrl driver"
depends on ARCH_UNIPHIER_PRO5
default y
select PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_PXS2
bool "UniPhier ProXstream2 SoC pinctrl driver"
depends on ARCH_UNIPHIER_PXS2
default y
select PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_LD6B
bool "UniPhier PH1-LD6b SoC pinctrl driver"
depends on ARCH_UNIPHIER_LD6B
default y
select PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_LD11
bool "UniPhier PH1-LD11 SoC pinctrl driver"
depends on ARCH_UNIPHIER_LD11
default y
select PINCTRL_UNIPHIER
config PINCTRL_UNIPHIER_LD20
bool "UniPhier PH1-LD20 SoC pinctrl driver"
depends on ARCH_UNIPHIER_LD20
default y
select PINCTRL_UNIPHIER
endif

View File

@@ -0,0 +1,14 @@
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += pinctrl-uniphier-core.o
obj-$(CONFIG_PINCTRL_UNIPHIER_LD4) += pinctrl-uniphier-ld4.o
obj-$(CONFIG_PINCTRL_UNIPHIER_PRO4) += pinctrl-uniphier-pro4.o
obj-$(CONFIG_PINCTRL_UNIPHIER_SLD8) += pinctrl-uniphier-sld8.o
obj-$(CONFIG_PINCTRL_UNIPHIER_PRO5) += pinctrl-uniphier-pro5.o
obj-$(CONFIG_PINCTRL_UNIPHIER_PXS2) += pinctrl-uniphier-pxs2.o
obj-$(CONFIG_PINCTRL_UNIPHIER_LD6B) += pinctrl-uniphier-ld6b.o
obj-$(CONFIG_PINCTRL_UNIPHIER_LD11) += pinctrl-uniphier-ld11.o
obj-$(CONFIG_PINCTRL_UNIPHIER_LD20) += pinctrl-uniphier-ld20.o

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <mapmem.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/sizes.h>
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const char *uniphier_pinctrl_dummy_name = "_dummy";
static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
return priv->socdata->groups_count;
}
static const char *uniphier_pinctrl_get_group_name(struct udevice *dev,
unsigned selector)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
if (!priv->socdata->groups[selector].name)
return uniphier_pinctrl_dummy_name;
return priv->socdata->groups[selector].name;
}
static int uniphier_pinmux_get_functions_count(struct udevice *dev)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
return priv->socdata->functions_count;
}
static const char *uniphier_pinmux_get_function_name(struct udevice *dev,
unsigned selector)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
if (!priv->socdata->functions[selector])
return uniphier_pinctrl_dummy_name;
return priv->socdata->functions[selector];
}
static void uniphier_pinconf_input_enable_perpin(struct udevice *dev,
unsigned pin)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
unsigned reg;
u32 mask, tmp;
reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4;
mask = BIT(pin % 32);
tmp = readl(priv->base + reg);
tmp |= mask;
writel(tmp, priv->base + reg);
}
static void uniphier_pinconf_input_enable_legacy(struct udevice *dev,
unsigned pin)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
int pins_count = priv->socdata->pins_count;
const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
int i;
for (i = 0; i < pins_count; i++) {
if (pins[i].number == pin) {
unsigned int iectrl;
u32 tmp;
iectrl = uniphier_pin_get_iectrl(pins[i].data);
tmp = readl(priv->base + UNIPHIER_PINCTRL_IECTRL);
tmp |= 1 << iectrl;
writel(tmp, priv->base + UNIPHIER_PINCTRL_IECTRL);
}
}
}
static void uniphier_pinconf_input_enable(struct udevice *dev, unsigned pin)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
uniphier_pinconf_input_enable_perpin(dev, pin);
else
uniphier_pinconf_input_enable_legacy(dev, pin);
}
static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
int muxval)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
unsigned mux_bits, reg_stride, reg, reg_end, shift, mask;
bool load_pinctrl;
u32 tmp;
/* some pins need input-enabling */
uniphier_pinconf_input_enable(dev, pin);
if (muxval < 0)
return; /* dedicated pin; nothing to do for pin-mux */
if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
/*
* Mode offset bit
* Normal 4 * n shift+3:shift
* Debug 4 * n shift+7:shift+4
*/
mux_bits = 4;
reg_stride = 8;
load_pinctrl = true;
} else {
/*
* Mode offset bit
* Normal 8 * n shift+3:shift
* Debug 8 * n + 4 shift+3:shift
*/
mux_bits = 8;
reg_stride = 4;
load_pinctrl = false;
}
reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
reg_end = reg + reg_stride;
shift = pin * mux_bits % 32;
mask = (1U << mux_bits) - 1;
/*
* If reg_stride is greater than 4, the MSB of each pinsel shall be
* stored in the offset+4.
*/
for (; reg < reg_end; reg += 4) {
tmp = readl(priv->base + reg);
tmp &= ~(mask << shift);
tmp |= (mask & muxval) << shift;
writel(tmp, priv->base + reg);
muxval >>= mux_bits;
}
if (load_pinctrl)
writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX);
}
static int uniphier_pinmux_group_set(struct udevice *dev,
unsigned group_selector,
unsigned func_selector)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
const struct uniphier_pinctrl_group *grp =
&priv->socdata->groups[group_selector];
int i;
for (i = 0; i < grp->num_pins; i++)
uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]);
return 0;
}
const struct pinctrl_ops uniphier_pinctrl_ops = {
.get_groups_count = uniphier_pinctrl_get_groups_count,
.get_group_name = uniphier_pinctrl_get_group_name,
.get_functions_count = uniphier_pinmux_get_functions_count,
.get_function_name = uniphier_pinmux_get_function_name,
.pinmux_group_set = uniphier_pinmux_group_set,
.set_state = pinctrl_generic_set_state,
};
int uniphier_pinctrl_probe(struct udevice *dev,
struct uniphier_pinctrl_socdata *socdata)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
fdt_addr_t addr;
addr = dev_get_addr(dev->parent);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->base = map_sysmem(addr, SZ_4K);
if (!priv->base)
return -ENOMEM;
priv->socdata = socdata;
return 0;
}
int uniphier_pinctrl_remove(struct udevice *dev)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
unmap_sysmem(priv->base);
return 0;
}

View File

@@ -0,0 +1,107 @@
/*
* Copyright (C) 2016 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const unsigned emmc_pins[] = {18, 19, 20, 21, 22, 23, 24, 25};
static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned emmc_dat8_pins[] = {26, 27, 28, 29};
static const int emmc_dat8_muxvals[] = {0, 0, 0, 0};
static const unsigned ether_rmii_pins[] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17};
static const int ether_rmii_muxvals[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
static const unsigned i2c0_pins[] = {63, 64};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {65, 66};
static const int i2c1_muxvals[] = {0, 0};
static const unsigned i2c3_pins[] = {67, 68};
static const int i2c3_muxvals[] = {1, 1};
static const unsigned i2c4_pins[] = {61, 62};
static const int i2c4_muxvals[] = {1, 1};
static const unsigned nand_pins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17};
static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned uart0_pins[] = {54, 55};
static const int uart0_muxvals[] = {0, 0};
static const unsigned uart1_pins[] = {58, 59};
static const int uart1_muxvals[] = {1, 1};
static const unsigned uart2_pins[] = {90, 91};
static const int uart2_muxvals[] = {1, 1};
static const unsigned uart3_pins[] = {94, 95};
static const int uart3_muxvals[] = {1, 1};
static const unsigned usb0_pins[] = {46, 47};
static const int usb0_muxvals[] = {0, 0};
static const unsigned usb1_pins[] = {48, 49};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {50, 51};
static const int usb2_muxvals[] = {0, 0};
static const struct uniphier_pinctrl_group uniphier_ld11_groups[] = {
UNIPHIER_PINCTRL_GROUP(emmc),
UNIPHIER_PINCTRL_GROUP(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(ether_rmii),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(i2c4),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart3),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
};
static const char * const uniphier_ld11_functions[] = {
UNIPHIER_PINMUX_FUNCTION(emmc),
UNIPHIER_PINMUX_FUNCTION(ether_rmii),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(i2c4),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION_SPL(uart3),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
};
static struct uniphier_pinctrl_socdata uniphier_ld11_pinctrl_socdata = {
.groups = uniphier_ld11_groups,
.groups_count = ARRAY_SIZE(uniphier_ld11_groups),
.functions = uniphier_ld11_functions,
.functions_count = ARRAY_SIZE(uniphier_ld11_functions),
.caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL,
};
static int uniphier_ld11_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_ld11_pinctrl_socdata);
}
static const struct udevice_id uniphier_ld11_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld11-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_ld11_pinctrl) = {
.name = "uniphier-ld11-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_ld11_pinctrl_match),
.probe = uniphier_ld11_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
};

View File

@@ -0,0 +1,121 @@
/*
* Copyright (C) 2016 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const unsigned emmc_pins[] = {18, 19, 20, 21, 22, 23, 24, 25};
static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned emmc_dat8_pins[] = {26, 27, 28, 29};
static const int emmc_dat8_muxvals[] = {0, 0, 0, 0};
static const unsigned ether_rgmii_pins[] = {30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45};
static const int ether_rgmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
static const unsigned ether_rmii_pins[] = {30, 31, 32, 33, 34, 35, 36, 37, 39,
41, 42, 45};
static const int ether_rmii_muxvals[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
static const unsigned i2c0_pins[] = {63, 64};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {65, 66};
static const int i2c1_muxvals[] = {0, 0};
static const unsigned i2c3_pins[] = {67, 68};
static const int i2c3_muxvals[] = {1, 1};
static const unsigned i2c4_pins[] = {61, 62};
static const int i2c4_muxvals[] = {1, 1};
static const unsigned nand_pins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17};
static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned sd_pins[] = {10, 11, 12, 13, 14, 15, 16, 17};
static const int sd_muxvals[] = {3, 3, 3, 3, 3, 3, 3, 3}; /* No SDVOLC */
static const unsigned uart0_pins[] = {54, 55};
static const int uart0_muxvals[] = {0, 0};
static const unsigned uart1_pins[] = {58, 59};
static const int uart1_muxvals[] = {1, 1};
static const unsigned uart2_pins[] = {90, 91};
static const int uart2_muxvals[] = {1, 1};
static const unsigned uart3_pins[] = {94, 95};
static const int uart3_muxvals[] = {1, 1};
static const unsigned usb0_pins[] = {46, 47};
static const int usb0_muxvals[] = {0, 0};
static const unsigned usb1_pins[] = {48, 49};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {50, 51};
static const int usb2_muxvals[] = {0, 0};
static const unsigned usb3_pins[] = {52, 53};
static const int usb3_muxvals[] = {0, 0};
static const struct uniphier_pinctrl_group uniphier_ld20_groups[] = {
UNIPHIER_PINCTRL_GROUP(emmc),
UNIPHIER_PINCTRL_GROUP(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(ether_rgmii),
UNIPHIER_PINCTRL_GROUP(ether_rmii),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(i2c4),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP(sd),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart3),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
UNIPHIER_PINCTRL_GROUP(usb3),
};
static const char * const uniphier_ld20_functions[] = {
UNIPHIER_PINMUX_FUNCTION(emmc),
UNIPHIER_PINMUX_FUNCTION(ether_rgmii),
UNIPHIER_PINMUX_FUNCTION(ether_rmii),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(i2c4),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION(sd),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION_SPL(uart3),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
UNIPHIER_PINMUX_FUNCTION(usb3),
};
static struct uniphier_pinctrl_socdata uniphier_ld20_pinctrl_socdata = {
.groups = uniphier_ld20_groups,
.groups_count = ARRAY_SIZE(uniphier_ld20_groups),
.functions = uniphier_ld20_functions,
.functions_count = ARRAY_SIZE(uniphier_ld20_functions),
.caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL,
};
static int uniphier_ld20_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_ld20_pinctrl_socdata);
}
static const struct udevice_id uniphier_ld20_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld20-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_ld20_pinctrl) = {
.name = "uniphier-ld20-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_ld20_pinctrl_match),
.probe = uniphier_ld20_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
};

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const struct uniphier_pinctrl_pin uniphier_ld4_pins[] = {
UNIPHIER_PINCTRL_PIN(53, 0),
UNIPHIER_PINCTRL_PIN(54, 0),
UNIPHIER_PINCTRL_PIN(55, 0),
UNIPHIER_PINCTRL_PIN(56, 0),
UNIPHIER_PINCTRL_PIN(67, 0),
UNIPHIER_PINCTRL_PIN(68, 0),
UNIPHIER_PINCTRL_PIN(69, 0),
UNIPHIER_PINCTRL_PIN(70, 0),
UNIPHIER_PINCTRL_PIN(85, 0),
UNIPHIER_PINCTRL_PIN(88, 0),
UNIPHIER_PINCTRL_PIN(156, 0),
};
static const unsigned emmc_pins[] = {21, 22, 23, 24, 25, 26, 27};
static const int emmc_muxvals[] = {0, 1, 1, 1, 1, 1, 1};
static const unsigned emmc_dat8_pins[] = {28, 29, 30, 31};
static const int emmc_dat8_muxvals[] = {1, 1, 1, 1};
static const unsigned ether_mii_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 136, 137, 138, 139, 140,
141, 142};
static const int ether_mii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 4, 4, 4, 4, 4};
static const unsigned ether_rmii_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43};
static const int ether_rmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned i2c0_pins[] = {102, 103};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {104, 105};
static const int i2c1_muxvals[] = {0, 0};
static const unsigned i2c2_pins[] = {108, 109};
static const int i2c2_muxvals[] = {2, 2};
static const unsigned i2c3_pins[] = {108, 109};
static const int i2c3_muxvals[] = {3, 3};
static const unsigned nand_pins[] = {24, 25, 26, 27, 28, 29, 30, 31, 158, 159,
160, 161, 162, 163, 164};
static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned nand_cs1_pins[] = {22, 23};
static const int nand_cs1_muxvals[] = {0, 0};
static const unsigned sd_pins[] = {44, 45, 46, 47, 48, 49, 50, 51, 52};
static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned uart0_pins[] = {85, 88};
static const int uart0_muxvals[] = {1, 1};
static const unsigned uart1_pins[] = {155, 156};
static const int uart1_muxvals[] = {13, 13};
static const unsigned uart1b_pins[] = {69, 70};
static const int uart1b_muxvals[] = {23, 23};
static const unsigned uart2_pins[] = {128, 129};
static const int uart2_muxvals[] = {13, 13};
static const unsigned uart3_pins[] = {110, 111};
static const int uart3_muxvals[] = {1, 1};
static const unsigned usb0_pins[] = {53, 54};
static const int usb0_muxvals[] = {0, 0};
static const unsigned usb1_pins[] = {55, 56};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {155, 156};
static const int usb2_muxvals[] = {4, 4};
static const unsigned usb2b_pins[] = {67, 68};
static const int usb2b_muxvals[] = {23, 23};
static const struct uniphier_pinctrl_group uniphier_ld4_groups[] = {
UNIPHIER_PINCTRL_GROUP_SPL(emmc),
UNIPHIER_PINCTRL_GROUP_SPL(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(ether_mii),
UNIPHIER_PINCTRL_GROUP(ether_rmii),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c2),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP(nand_cs1),
UNIPHIER_PINCTRL_GROUP(sd),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart1b),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart3),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
UNIPHIER_PINCTRL_GROUP(usb2b),
};
static const char * const uniphier_ld4_functions[] = {
UNIPHIER_PINMUX_FUNCTION_SPL(emmc),
UNIPHIER_PINMUX_FUNCTION(ether_mii),
UNIPHIER_PINMUX_FUNCTION(ether_rmii),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c2),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION(sd),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION_SPL(uart3),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
};
static struct uniphier_pinctrl_socdata uniphier_ld4_pinctrl_socdata = {
.pins = uniphier_ld4_pins,
.pins_count = ARRAY_SIZE(uniphier_ld4_pins),
.groups = uniphier_ld4_groups,
.groups_count = ARRAY_SIZE(uniphier_ld4_groups),
.functions = uniphier_ld4_functions,
.functions_count = ARRAY_SIZE(uniphier_ld4_functions),
};
static int uniphier_ld4_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_ld4_pinctrl_socdata);
}
static const struct udevice_id uniphier_ld4_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld4-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_ld4_pinctrl) = {
.name = "uniphier-ld4-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_ld4_pinctrl_match),
.probe = uniphier_ld4_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
};

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const struct uniphier_pinctrl_pin uniphier_ld6b_pins[] = {
UNIPHIER_PINCTRL_PIN(113, 0),
UNIPHIER_PINCTRL_PIN(114, 0),
UNIPHIER_PINCTRL_PIN(115, 0),
UNIPHIER_PINCTRL_PIN(116, 0),
UNIPHIER_PINCTRL_PIN(217, 0),
UNIPHIER_PINCTRL_PIN(218, 0),
UNIPHIER_PINCTRL_PIN(219, 0),
UNIPHIER_PINCTRL_PIN(220, 0),
};
static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42};
static const int emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46};
static const int emmc_dat8_muxvals[] = {1, 1, 1, 1};
static const unsigned ether_rgmii_pins[] = {143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156,
157, 158};
static const int ether_rgmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
static const unsigned ether_rmii_pins[] = {143, 144, 145, 146, 147, 148, 149,
150, 152, 154, 155, 158};
static const int ether_rmii_muxvals[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1};
static const unsigned i2c0_pins[] = {109, 110};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {111, 112};
static const int i2c1_muxvals[] = {0, 0};
static const unsigned i2c2_pins[] = {115, 116};
static const int i2c2_muxvals[] = {1, 1};
static const unsigned i2c3_pins[] = {118, 119};
static const int i2c3_muxvals[] = {1, 1};
static const unsigned nand_pins[] = {30, 31, 32, 33, 34, 35, 36, 39, 40, 41,
42, 43, 44, 45, 46};
static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned nand_cs1_pins[] = {37, 38};
static const int nand_cs1_muxvals[] = {0, 0};
static const unsigned sd_pins[] = {47, 48, 49, 50, 51, 52, 53, 54, 55};
static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned uart0_pins[] = {135, 136};
static const int uart0_muxvals[] = {3, 3};
static const unsigned uart0b_pins[] = {11, 12};
static const int uart0b_muxvals[] = {2, 2};
static const unsigned uart1_pins[] = {115, 116};
static const int uart1_muxvals[] = {0, 0};
static const unsigned uart1b_pins[] = {113, 114};
static const int uart1b_muxvals[] = {1, 1};
static const unsigned uart2_pins[] = {113, 114};
static const int uart2_muxvals[] = {2, 2};
static const unsigned uart2b_pins[] = {86, 87};
static const int uart2b_muxvals[] = {1, 1};
static const unsigned usb0_pins[] = {56, 57};
static const int usb0_muxvals[] = {0, 0};
static const unsigned usb1_pins[] = {58, 59};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {60, 61};
static const int usb2_muxvals[] = {0, 0};
static const unsigned usb3_pins[] = {62, 63};
static const int usb3_muxvals[] = {0, 0};
static const struct uniphier_pinctrl_group uniphier_ld6b_groups[] = {
UNIPHIER_PINCTRL_GROUP_SPL(emmc),
UNIPHIER_PINCTRL_GROUP_SPL(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(ether_rgmii),
UNIPHIER_PINCTRL_GROUP(ether_rmii),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c2),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP(nand_cs1),
UNIPHIER_PINCTRL_GROUP(sd),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart0b),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart1b),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart2b),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
UNIPHIER_PINCTRL_GROUP(usb3),
};
static const char * const uniphier_ld6b_functions[] = {
UNIPHIER_PINMUX_FUNCTION_SPL(emmc),
UNIPHIER_PINMUX_FUNCTION(ether_rgmii),
UNIPHIER_PINMUX_FUNCTION(ether_rmii),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c2),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION(sd),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
UNIPHIER_PINMUX_FUNCTION(usb3),
};
static struct uniphier_pinctrl_socdata uniphier_ld6b_pinctrl_socdata = {
.pins = uniphier_ld6b_pins,
.pins_count = ARRAY_SIZE(uniphier_ld6b_pins),
.groups = uniphier_ld6b_groups,
.groups_count = ARRAY_SIZE(uniphier_ld6b_groups),
.functions = uniphier_ld6b_functions,
.functions_count = ARRAY_SIZE(uniphier_ld6b_functions),
};
static int uniphier_ld6b_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_ld6b_pinctrl_socdata);
}
static const struct udevice_id uniphier_ld6b_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-ld6b-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_ld6b_pinctrl) = {
.name = "uniphier-ld6b-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_ld6b_pinctrl_match),
.probe = uniphier_ld6b_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
};

View File

@@ -0,0 +1,150 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const struct uniphier_pinctrl_pin uniphier_pro4_pins[] = {
};
static const unsigned emmc_pins[] = {40, 41, 42, 43, 51, 52, 53};
static const int emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
static const unsigned emmc_dat8_pins[] = {44, 45, 46, 47};
static const int emmc_dat8_muxvals[] = {1, 1, 1, 1};
static const unsigned ether_mii_pins[] = {160, 161, 162, 163, 164, 165, 166,
167, 168, 169, 170, 171, 172, 173,
174, 175, 176, 177, 178, 179};
static const int ether_mii_muxvals[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0};
static const unsigned ether_rgmii_pins[] = {160, 161, 162, 163, 164, 165, 167,
168, 169, 170, 171, 172, 176, 177,
178, 179};
static const int ether_rgmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
static const unsigned ether_rmii_pins[] = {160, 161, 162, 165, 168, 169, 172,
173, 176, 177, 178, 179};
static const int ether_rmii_muxvals[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned ether_rmiib_pins[] = {161, 162, 165, 167, 168, 169, 172,
173, 176, 177, 178, 179};
static const int ether_rmiib_muxvals[] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned i2c0_pins[] = {142, 143};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {144, 145};
static const int i2c1_muxvals[] = {0, 0};
static const unsigned i2c2_pins[] = {146, 147};
static const int i2c2_muxvals[] = {0, 0};
static const unsigned i2c3_pins[] = {148, 149};
static const int i2c3_muxvals[] = {0, 0};
static const unsigned i2c6_pins[] = {308, 309};
static const int i2c6_muxvals[] = {6, 6};
static const unsigned nand_pins[] = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54};
static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned nand_cs1_pins[] = {131, 132};
static const int nand_cs1_muxvals[] = {1, 1};
static const unsigned sd_pins[] = {150, 151, 152, 153, 154, 155, 156, 157, 158};
static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326,
327};
static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned uart0_pins[] = {127, 128};
static const int uart0_muxvals[] = {0, 0};
static const unsigned uart1_pins[] = {129, 130};
static const int uart1_muxvals[] = {0, 0};
static const unsigned uart2_pins[] = {131, 132};
static const int uart2_muxvals[] = {0, 0};
static const unsigned uart3_pins[] = {88, 89};
static const int uart3_muxvals[] = {2, 2};
static const unsigned usb0_pins[] = {180, 181};
static const int usb0_muxvals[] = {0, 0};
static const unsigned usb1_pins[] = {182, 183};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {184, 185};
static const int usb2_muxvals[] = {0, 0};
static const unsigned usb3_pins[] = {186, 187};
static const int usb3_muxvals[] = {0, 0};
static const struct uniphier_pinctrl_group uniphier_pro4_groups[] = {
UNIPHIER_PINCTRL_GROUP_SPL(emmc),
UNIPHIER_PINCTRL_GROUP_SPL(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(ether_mii),
UNIPHIER_PINCTRL_GROUP(ether_rgmii),
UNIPHIER_PINCTRL_GROUP(ether_rmii),
UNIPHIER_PINCTRL_GROUP(ether_rmiib),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c2),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(i2c6),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP(nand_cs1),
UNIPHIER_PINCTRL_GROUP(sd),
UNIPHIER_PINCTRL_GROUP(sd1),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart3),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
UNIPHIER_PINCTRL_GROUP(usb3),
};
static const char * const uniphier_pro4_functions[] = {
UNIPHIER_PINMUX_FUNCTION_SPL(emmc),
UNIPHIER_PINMUX_FUNCTION(ether_mii),
UNIPHIER_PINMUX_FUNCTION(ether_rgmii),
UNIPHIER_PINMUX_FUNCTION(ether_rmii),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c2),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(i2c6),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION(sd),
UNIPHIER_PINMUX_FUNCTION(sd1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION_SPL(uart3),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
UNIPHIER_PINMUX_FUNCTION(usb3),
};
static struct uniphier_pinctrl_socdata uniphier_pro4_pinctrl_socdata = {
.pins = uniphier_pro4_pins,
.pins_count = ARRAY_SIZE(uniphier_pro4_pins),
.groups = uniphier_pro4_groups,
.groups_count = ARRAY_SIZE(uniphier_pro4_groups),
.functions = uniphier_pro4_functions,
.functions_count = ARRAY_SIZE(uniphier_pro4_functions),
.caps = UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE,
};
static int uniphier_pro4_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_pro4_pinctrl_socdata);
}
static const struct udevice_id uniphier_pro4_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-pro4-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_pro4_pinctrl) = {
.name = "uniphier-pro4-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_pro4_pinctrl_match),
.probe = uniphier_pro4_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -0,0 +1,141 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const struct uniphier_pinctrl_pin uniphier_pro5_pins[] = {
UNIPHIER_PINCTRL_PIN(47, 0),
UNIPHIER_PINCTRL_PIN(48, 0),
UNIPHIER_PINCTRL_PIN(49, 0),
UNIPHIER_PINCTRL_PIN(50, 0),
UNIPHIER_PINCTRL_PIN(53, 0),
UNIPHIER_PINCTRL_PIN(54, 0),
UNIPHIER_PINCTRL_PIN(87, 0),
UNIPHIER_PINCTRL_PIN(88, 0),
UNIPHIER_PINCTRL_PIN(101, 0),
UNIPHIER_PINCTRL_PIN(102, 0),
};
static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42};
static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0};
static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46};
static const int emmc_dat8_muxvals[] = {0, 0, 0, 0};
static const unsigned i2c0_pins[] = {112, 113};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {114, 115};
static const int i2c1_muxvals[] = {0, 0};
static const unsigned i2c2_pins[] = {116, 117};
static const int i2c2_muxvals[] = {0, 0};
static const unsigned i2c3_pins[] = {118, 119};
static const int i2c3_muxvals[] = {0, 0};
static const unsigned i2c5_pins[] = {87, 88};
static const int i2c5_muxvals[] = {2, 2};
static const unsigned i2c5b_pins[] = {196, 197};
static const int i2c5b_muxvals[] = {2, 2};
static const unsigned i2c5c_pins[] = {215, 216};
static const int i2c5c_muxvals[] = {2, 2};
static const unsigned i2c6_pins[] = {101, 102};
static const int i2c6_muxvals[] = {2, 2};
static const unsigned nand_pins[] = {19, 20, 21, 22, 23, 24, 25, 28, 29, 30,
31, 32, 33, 34, 35};
static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned nand_cs1_pins[] = {26, 27};
static const int nand_cs1_muxvals[] = {0, 0};
static const unsigned sd_pins[] = {250, 251, 252, 253, 254, 255, 256, 257, 258};
static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned uart0_pins[] = {47, 48};
static const int uart0_muxvals[] = {0, 0};
static const unsigned uart0b_pins[] = {227, 228};
static const int uart0b_muxvals[] = {3, 3};
static const unsigned uart1_pins[] = {49, 50};
static const int uart1_muxvals[] = {0, 0};
static const unsigned uart2_pins[] = {51, 52};
static const int uart2_muxvals[] = {0, 0};
static const unsigned uart3_pins[] = {53, 54};
static const int uart3_muxvals[] = {0, 0};
static const unsigned usb0_pins[] = {124, 125};
static const int usb0_muxvals[] = {0, 0};
static const unsigned usb1_pins[] = {126, 127};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {128, 129};
static const int usb2_muxvals[] = {0, 0};
static const struct uniphier_pinctrl_group uniphier_pro5_groups[] = {
UNIPHIER_PINCTRL_GROUP_SPL(emmc),
UNIPHIER_PINCTRL_GROUP_SPL(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c2),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(i2c5),
UNIPHIER_PINCTRL_GROUP(i2c5b),
UNIPHIER_PINCTRL_GROUP(i2c5c),
UNIPHIER_PINCTRL_GROUP(i2c6),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP(nand_cs1),
UNIPHIER_PINCTRL_GROUP(sd),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart0b),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart3),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
};
static const char * const uniphier_pro5_functions[] = {
UNIPHIER_PINMUX_FUNCTION_SPL(emmc),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c2),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(i2c5),
UNIPHIER_PINMUX_FUNCTION(i2c6),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION(sd),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION_SPL(uart3),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
};
static struct uniphier_pinctrl_socdata uniphier_pro5_pinctrl_socdata = {
.pins = uniphier_pro5_pins,
.pins_count = ARRAY_SIZE(uniphier_pro5_pins),
.groups = uniphier_pro5_groups,
.groups_count = ARRAY_SIZE(uniphier_pro5_groups),
.functions = uniphier_pro5_functions,
.functions_count = ARRAY_SIZE(uniphier_pro5_functions),
.caps = UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE,
};
static int uniphier_pro5_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_pro5_pinctrl_socdata);
}
static const struct udevice_id uniphier_pro5_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-pro5-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_pro5_pinctrl) = {
.name = "uniphier-pro5-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_pro5_pinctrl_match),
.probe = uniphier_pro5_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View File

@@ -0,0 +1,153 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const struct uniphier_pinctrl_pin uniphier_pxs2_pins[] = {
UNIPHIER_PINCTRL_PIN(113, 0),
UNIPHIER_PINCTRL_PIN(114, 0),
UNIPHIER_PINCTRL_PIN(115, 0),
UNIPHIER_PINCTRL_PIN(116, 0),
};
static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42};
static const int emmc_muxvals[] = {9, 9, 9, 9, 9, 9, 9};
static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46};
static const int emmc_dat8_muxvals[] = {9, 9, 9, 9};
static const unsigned ether_mii_pins[] = {143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156,
158, 159, 199, 200, 201, 202};
static const int ether_mii_muxvals[] = {8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 12, 12, 12, 12};
static const unsigned ether_rgmii_pins[] = {143, 144, 145, 146, 147, 148, 149,
150, 151, 152, 153, 154, 155, 156,
157, 158};
static const int ether_rgmii_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8};
static const unsigned ether_rmii_pins[] = {143, 144, 145, 146, 147, 148, 149,
150, 152, 154, 155, 158};
static const int ether_rmii_muxvals[] = {8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9};
static const unsigned i2c0_pins[] = {109, 110};
static const int i2c0_muxvals[] = {8, 8};
static const unsigned i2c1_pins[] = {111, 112};
static const int i2c1_muxvals[] = {8, 8};
static const unsigned i2c2_pins[] = {171, 172};
static const int i2c2_muxvals[] = {8, 8};
static const unsigned i2c3_pins[] = {159, 160};
static const int i2c3_muxvals[] = {8, 8};
static const unsigned i2c5_pins[] = {183, 184};
static const int i2c5_muxvals[] = {11, 11};
static const unsigned i2c6_pins[] = {185, 186};
static const int i2c6_muxvals[] = {11, 11};
static const unsigned nand_pins[] = {30, 31, 32, 33, 34, 35, 36, 39, 40, 41,
42, 43, 44, 45, 46};
static const int nand_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
static const unsigned nand_cs1_pins[] = {37, 38};
static const int nand_cs1_muxvals[] = {8, 8};
static const unsigned sd_pins[] = {47, 48, 49, 50, 51, 52, 53, 54, 55};
static const int sd_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8};
static const unsigned uart0_pins[] = {217, 218};
static const int uart0_muxvals[] = {8, 8};
static const unsigned uart0b_pins[] = {179, 180};
static const int uart0b_muxvals[] = {10, 10};
static const unsigned uart1_pins[] = {115, 116};
static const int uart1_muxvals[] = {8, 8};
static const unsigned uart2_pins[] = {113, 114};
static const int uart2_muxvals[] = {8, 8};
static const unsigned uart3_pins[] = {219, 220};
static const int uart3_muxvals[] = {8, 8};
static const unsigned uart3b_pins[] = {181, 182};
static const int uart3b_muxvals[] = {10, 10};
static const unsigned usb0_pins[] = {56, 57};
static const int usb0_muxvals[] = {8, 8};
static const unsigned usb1_pins[] = {58, 59};
static const int usb1_muxvals[] = {8, 8};
static const unsigned usb2_pins[] = {60, 61};
static const int usb2_muxvals[] = {8, 8};
static const unsigned usb3_pins[] = {62, 63};
static const int usb3_muxvals[] = {8, 8};
static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
UNIPHIER_PINCTRL_GROUP_SPL(emmc),
UNIPHIER_PINCTRL_GROUP_SPL(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(ether_mii),
UNIPHIER_PINCTRL_GROUP(ether_rgmii),
UNIPHIER_PINCTRL_GROUP(ether_rmii),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c2),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(i2c5),
UNIPHIER_PINCTRL_GROUP(i2c6),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP(nand_cs1),
UNIPHIER_PINCTRL_GROUP(sd),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart0b),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart3),
UNIPHIER_PINCTRL_GROUP_SPL(uart3b),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
UNIPHIER_PINCTRL_GROUP(usb3),
};
static const char * const uniphier_pxs2_functions[] = {
UNIPHIER_PINMUX_FUNCTION_SPL(emmc),
UNIPHIER_PINMUX_FUNCTION(ether_mii),
UNIPHIER_PINMUX_FUNCTION(ether_rgmii),
UNIPHIER_PINMUX_FUNCTION(ether_rmii),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c2),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(i2c5),
UNIPHIER_PINMUX_FUNCTION(i2c6),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION(sd),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION_SPL(uart3),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
UNIPHIER_PINMUX_FUNCTION(usb3),
};
static struct uniphier_pinctrl_socdata uniphier_pxs2_pinctrl_socdata = {
.pins = uniphier_pxs2_pins,
.pins_count = ARRAY_SIZE(uniphier_pxs2_pins),
.groups = uniphier_pxs2_groups,
.groups_count = ARRAY_SIZE(uniphier_pxs2_groups),
.functions = uniphier_pxs2_functions,
.functions_count = ARRAY_SIZE(uniphier_pxs2_functions),
};
static int uniphier_pxs2_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_pxs2_pinctrl_socdata);
}
static const struct udevice_id uniphier_pxs2_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-pxs2-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_pxs2_pinctrl) = {
.name = "uniphier-pxs2-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_pxs2_pinctrl_match),
.probe = uniphier_pxs2_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
};

View File

@@ -0,0 +1,149 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <dm/device.h>
#include <dm/pinctrl.h>
#include "pinctrl-uniphier.h"
static const struct uniphier_pinctrl_pin uniphier_sld8_pins[] = {
UNIPHIER_PINCTRL_PIN(32, 8),
UNIPHIER_PINCTRL_PIN(33, 8),
UNIPHIER_PINCTRL_PIN(34, 8),
UNIPHIER_PINCTRL_PIN(35, 8),
UNIPHIER_PINCTRL_PIN(36, 8),
UNIPHIER_PINCTRL_PIN(37, 8),
UNIPHIER_PINCTRL_PIN(38, 8),
UNIPHIER_PINCTRL_PIN(39, 8),
UNIPHIER_PINCTRL_PIN(40, 9),
UNIPHIER_PINCTRL_PIN(41, 0),
UNIPHIER_PINCTRL_PIN(42, 0),
UNIPHIER_PINCTRL_PIN(43, 0),
UNIPHIER_PINCTRL_PIN(44, 0),
UNIPHIER_PINCTRL_PIN(70, 0),
UNIPHIER_PINCTRL_PIN(71, 0),
UNIPHIER_PINCTRL_PIN(102, 10),
UNIPHIER_PINCTRL_PIN(103, 10),
UNIPHIER_PINCTRL_PIN(104, 11),
UNIPHIER_PINCTRL_PIN(105, 11),
UNIPHIER_PINCTRL_PIN(108, 13),
UNIPHIER_PINCTRL_PIN(109, 13),
UNIPHIER_PINCTRL_PIN(112, 0),
UNIPHIER_PINCTRL_PIN(113, 0),
UNIPHIER_PINCTRL_PIN(114, 0),
UNIPHIER_PINCTRL_PIN(115, 0),
};
static const unsigned emmc_pins[] = {21, 22, 23, 24, 25, 26, 27};
static const int emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
static const unsigned emmc_dat8_pins[] = {28, 29, 30, 31};
static const int emmc_dat8_muxvals[] = {1, 1, 1, 1};
static const unsigned ether_mii_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14,
61, 63, 64, 65, 66, 67, 68};
static const int ether_mii_muxvals[] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 27, 27, 27, 27, 27, 27, 27};
static const unsigned ether_rmii_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13,
14};
static const int ether_rmii_muxvals[] = {13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13};
static const unsigned i2c0_pins[] = {102, 103};
static const int i2c0_muxvals[] = {0, 0};
static const unsigned i2c1_pins[] = {104, 105};
static const int i2c1_muxvals[] = {0, 0};
static const unsigned i2c2_pins[] = {108, 109};
static const int i2c2_muxvals[] = {2, 2};
static const unsigned i2c3_pins[] = {108, 109};
static const int i2c3_muxvals[] = {3, 3};
static const unsigned nand_pins[] = {15, 16, 17, 18, 19, 20, 21, 24, 25, 26,
27, 28, 29, 30, 31};
static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned nand_cs1_pins[] = {22, 23};
static const int nand_cs1_muxvals[] = {0, 0};
static const unsigned sd_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, 40};
static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
static const unsigned uart0_pins[] = {70, 71};
static const int uart0_muxvals[] = {3, 3};
static const unsigned uart1_pins[] = {114, 115};
static const int uart1_muxvals[] = {0, 0};
static const unsigned uart2_pins[] = {112, 113};
static const int uart2_muxvals[] = {1, 1};
static const unsigned uart3_pins[] = {110, 111};
static const int uart3_muxvals[] = {1, 1};
static const unsigned usb0_pins[] = {41, 42};
static const int usb0_muxvals[] = {0, 0};
static const unsigned usb1_pins[] = {43, 44};
static const int usb1_muxvals[] = {0, 0};
static const unsigned usb2_pins[] = {114, 115};
static const int usb2_muxvals[] = {1, 1};
static const struct uniphier_pinctrl_group uniphier_sld8_groups[] = {
UNIPHIER_PINCTRL_GROUP_SPL(emmc),
UNIPHIER_PINCTRL_GROUP_SPL(emmc_dat8),
UNIPHIER_PINCTRL_GROUP(ether_mii),
UNIPHIER_PINCTRL_GROUP(ether_rmii),
UNIPHIER_PINCTRL_GROUP(i2c0),
UNIPHIER_PINCTRL_GROUP(i2c1),
UNIPHIER_PINCTRL_GROUP(i2c2),
UNIPHIER_PINCTRL_GROUP(i2c3),
UNIPHIER_PINCTRL_GROUP(nand),
UNIPHIER_PINCTRL_GROUP(nand_cs1),
UNIPHIER_PINCTRL_GROUP(sd),
UNIPHIER_PINCTRL_GROUP_SPL(uart0),
UNIPHIER_PINCTRL_GROUP_SPL(uart1),
UNIPHIER_PINCTRL_GROUP_SPL(uart2),
UNIPHIER_PINCTRL_GROUP_SPL(uart3),
UNIPHIER_PINCTRL_GROUP(usb0),
UNIPHIER_PINCTRL_GROUP(usb1),
UNIPHIER_PINCTRL_GROUP(usb2),
};
static const char * const uniphier_sld8_functions[] = {
UNIPHIER_PINMUX_FUNCTION_SPL(emmc),
UNIPHIER_PINMUX_FUNCTION(ether_mii),
UNIPHIER_PINMUX_FUNCTION(ether_rmii),
UNIPHIER_PINMUX_FUNCTION(i2c0),
UNIPHIER_PINMUX_FUNCTION(i2c1),
UNIPHIER_PINMUX_FUNCTION(i2c2),
UNIPHIER_PINMUX_FUNCTION(i2c3),
UNIPHIER_PINMUX_FUNCTION(nand),
UNIPHIER_PINMUX_FUNCTION(sd),
UNIPHIER_PINMUX_FUNCTION_SPL(uart0),
UNIPHIER_PINMUX_FUNCTION_SPL(uart1),
UNIPHIER_PINMUX_FUNCTION_SPL(uart2),
UNIPHIER_PINMUX_FUNCTION_SPL(uart3),
UNIPHIER_PINMUX_FUNCTION(usb0),
UNIPHIER_PINMUX_FUNCTION(usb1),
UNIPHIER_PINMUX_FUNCTION(usb2),
};
static struct uniphier_pinctrl_socdata uniphier_sld8_pinctrl_socdata = {
.pins = uniphier_sld8_pins,
.pins_count = ARRAY_SIZE(uniphier_sld8_pins),
.groups = uniphier_sld8_groups,
.groups_count = ARRAY_SIZE(uniphier_sld8_groups),
.functions = uniphier_sld8_functions,
.functions_count = ARRAY_SIZE(uniphier_sld8_functions),
};
static int uniphier_sld8_pinctrl_probe(struct udevice *dev)
{
return uniphier_pinctrl_probe(dev, &uniphier_sld8_pinctrl_socdata);
}
static const struct udevice_id uniphier_sld8_pinctrl_match[] = {
{ .compatible = "socionext,uniphier-sld8-pinctrl" },
{ /* sentinel */ }
};
U_BOOT_DRIVER(uniphier_sld8_pinctrl) = {
.name = "uniphier-sld8-pinctrl",
.id = UCLASS_PINCTRL,
.of_match = of_match_ptr(uniphier_sld8_pinctrl_match),
.probe = uniphier_sld8_pinctrl_probe,
.remove = uniphier_pinctrl_remove,
.priv_auto_alloc_size = sizeof(struct uniphier_pinctrl_priv),
.ops = &uniphier_pinctrl_ops,
};

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __PINCTRL_UNIPHIER_H__
#define __PINCTRL_UNIPHIER_H__
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/types.h>
#define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000
#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700
#define UNIPHIER_PINCTRL_IECTRL 0x1d00
#define UNIPHIER_PIN_ATTR_PACKED(iectrl) (iectrl)
static inline unsigned int uniphier_pin_get_iectrl(unsigned long data)
{
return data;
}
/**
* struct uniphier_pinctrl_pin - pin data for UniPhier SoC
*
* @number: pin number
* @data: additional per-pin data
*/
struct uniphier_pinctrl_pin {
unsigned number;
unsigned long data;
};
/**
* struct uniphier_pinctrl_group - pin group data for UniPhier SoC
*
* @name: pin group name
* @pins: array of pins that belong to the group
* @num_pins: number of pins in the group
* @muxvals: array of values to be set to pinmux registers
*/
struct uniphier_pinctrl_group {
const char *name;
const unsigned *pins;
unsigned num_pins;
const int *muxvals;
};
/**
* struct uniphier_pinctrl_socdata - SoC data for UniPhier pin controller
*
* @pins: array of pin data
* @pins_count: number of pin data
* @groups: array of pin group data
* @groups_count: number of pin group data
* @functions: array of pinmux function names
* @functions_count: number of pinmux functions
* @mux_bits: bit width of each pinmux register
* @reg_stride: stride of pinmux register address
* @caps: SoC-specific capability flag
*/
struct uniphier_pinctrl_socdata {
const struct uniphier_pinctrl_pin *pins;
int pins_count;
const struct uniphier_pinctrl_group *groups;
int groups_count;
const char * const *functions;
int functions_count;
unsigned caps;
#define UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL BIT(1)
#define UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE BIT(0)
};
#define UNIPHIER_PINCTRL_PIN(a, b) \
{ \
.number = a, \
.data = UNIPHIER_PIN_ATTR_PACKED(b), \
}
#define __UNIPHIER_PINCTRL_GROUP(grp) \
{ \
.name = #grp, \
.pins = grp##_pins, \
.num_pins = ARRAY_SIZE(grp##_pins), \
.muxvals = grp##_muxvals + \
BUILD_BUG_ON_ZERO(ARRAY_SIZE(grp##_pins) != \
ARRAY_SIZE(grp##_muxvals)), \
}
#define __UNIPHIER_PINMUX_FUNCTION(func) #func
#ifdef CONFIG_SPL_BUILD
#define UNIPHIER_PINCTRL_GROUP(grp) { .name = NULL }
#define UNIPHIER_PINMUX_FUNCTION(func) NULL
#else
#define UNIPHIER_PINCTRL_GROUP(grp) __UNIPHIER_PINCTRL_GROUP(grp)
#define UNIPHIER_PINMUX_FUNCTION(func) __UNIPHIER_PINMUX_FUNCTION(func)
#endif
#define UNIPHIER_PINCTRL_GROUP_SPL(grp) __UNIPHIER_PINCTRL_GROUP(grp)
#define UNIPHIER_PINMUX_FUNCTION_SPL(func) __UNIPHIER_PINMUX_FUNCTION(func)
/**
* struct uniphier_pinctrl_priv - private data for UniPhier pinctrl driver
*
* @base: base address of the pinctrl device
* @socdata: SoC specific data
*/
struct uniphier_pinctrl_priv {
void __iomem *base;
struct uniphier_pinctrl_socdata *socdata;
};
extern const struct pinctrl_ops uniphier_pinctrl_ops;
int uniphier_pinctrl_probe(struct udevice *dev,
struct uniphier_pinctrl_socdata *socdata);
int uniphier_pinctrl_remove(struct udevice *dev);
#endif /* __PINCTRL_UNIPHIER_H__ */