Skip to content
Snippets Groups Projects
Commit 1ccd3f14 authored by Tom Rini's avatar Tom Rini
Browse files
parents 6417572e 079b54f2
No related branches found
No related tags found
No related merge requests found
......@@ -43,6 +43,7 @@ CONFIG_NETDEVICES=y
CONFIG_SMC911X=y
CONFIG_SMC911X_BASE=0x0
CONFIG_SMC911X_32_BIT=y
CONFIG_PINCONF=y
CONFIG_SYSRESET=y
CONFIG_SYSRESET_PSCI=y
CONFIG_USB=y
......
......@@ -16,11 +16,42 @@
#define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000
#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700
#define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x1800
#define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x1900
#define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x1980
#define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00
#define UNIPHIER_PINCTRL_IECTRL 0x1d00
static const char *uniphier_pinctrl_dummy_name = "_dummy";
static int uniphier_pinctrl_get_pins_count(struct udevice *dev)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
int pins_count = priv->socdata->pins_count;
/*
* We do not list all pins in the pin table to save memory footprint.
* Report the max pin number + 1 to fake the framework.
*/
return pins[pins_count - 1].number + 1;
}
static const char *uniphier_pinctrl_get_pin_name(struct udevice *dev,
unsigned int selector)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
int pins_count = priv->socdata->pins_count;
int i;
for (i = 0; i < pins_count; i++)
if (pins[i].number == selector)
return pins[i].name;
return uniphier_pinctrl_dummy_name;
}
static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
......@@ -113,10 +144,25 @@ static const struct pinconf_param uniphier_pinconf_params[] = {
{ "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-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
{ "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
{ "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
};
static const struct uniphier_pinctrl_pin *
uniphier_pinctrl_pin_get(struct uniphier_pinctrl_priv *priv, unsigned int pin)
{
const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
int pins_count = priv->socdata->pins_count;
int i;
for (i = 0; i < pins_count; i++)
if (pins[i].number == pin)
return &pins[i];
return NULL;
}
static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
unsigned int param, unsigned int arg)
{
......@@ -157,8 +203,88 @@ static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
return 0;
}
static int uniphier_pinconf_set_one(struct udevice *dev, unsigned int pin,
unsigned int param, unsigned int arg)
static const unsigned int uniphier_pinconf_drv_strengths_1bit[] = {
4, 8,
};
static const unsigned int uniphier_pinconf_drv_strengths_2bit[] = {
8, 12, 16, 20,
};
static const unsigned int uniphier_pinconf_drv_strengths_3bit[] = {
4, 5, 7, 9, 11, 12, 14, 16,
};
static int uniphier_pinconf_drive_set(struct udevice *dev, unsigned int pin,
unsigned int strength)
{
struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
const struct uniphier_pinctrl_pin *desc;
const unsigned int *strengths;
unsigned int base, stride, width, drvctrl, reg, shift;
u32 val, mask, tmp;
desc = uniphier_pinctrl_pin_get(priv, pin);
if (WARN_ON(!desc))
return -EINVAL;
switch (uniphier_pin_get_drv_type(desc->data)) {
case UNIPHIER_PIN_DRV_1BIT:
strengths = uniphier_pinconf_drv_strengths_1bit;
base = UNIPHIER_PINCTRL_DRVCTRL_BASE;
stride = 1;
width = 1;
break;
case UNIPHIER_PIN_DRV_2BIT:
strengths = uniphier_pinconf_drv_strengths_2bit;
base = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
stride = 2;
width = 2;
break;
case UNIPHIER_PIN_DRV_3BIT:
strengths = uniphier_pinconf_drv_strengths_3bit;
base = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
stride = 4;
width = 3;
break;
default:
/* drive strength control is not supported for this pin */
return -EINVAL;
}
drvctrl = uniphier_pin_get_drvctrl(desc->data);
drvctrl *= stride;
reg = base + drvctrl / 32 * 4;
shift = drvctrl % 32;
mask = (1U << width) - 1;
for (val = 0; val <= mask; val++) {
if (strengths[val] > strength)
break;
}
if (val == 0) {
dev_err(dev, "unsupported drive strength %u mA for pin %s\n",
strength, desc->name);
return -EINVAL;
}
if (!mask)
return 0;
val--;
tmp = readl(priv->base + reg);
tmp &= ~(mask << shift);
tmp |= (mask & val) << shift;
writel(tmp, priv->base + reg);
return 0;
}
static int uniphier_pinconf_set(struct udevice *dev, unsigned int pin,
unsigned int param, unsigned int arg)
{
int ret;
......@@ -169,11 +295,14 @@ static int uniphier_pinconf_set_one(struct udevice *dev, unsigned int pin,
case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
ret = uniphier_pinconf_bias_set(dev, pin, param, arg);
break;
case PIN_CONFIG_DRIVE_STRENGTH:
ret = uniphier_pinconf_drive_set(dev, pin, arg);
break;
case PIN_CONFIG_INPUT_ENABLE:
ret = uniphier_pinconf_input_enable(dev, pin, arg);
break;
default:
printf("unsupported configuration parameter %u\n", param);
dev_err(dev, "unsupported configuration parameter %u\n", param);
return -EINVAL;
}
......@@ -190,7 +319,7 @@ static int uniphier_pinconf_group_set(struct udevice *dev,
int i, ret;
for (i = 0; i < grp->num_pins; i++) {
ret = uniphier_pinconf_set_one(dev, grp->pins[i], param, arg);
ret = uniphier_pinconf_set(dev, grp->pins[i], param, arg);
if (ret)
return ret;
}
......@@ -268,6 +397,8 @@ static int uniphier_pinmux_group_set(struct udevice *dev,
}
const struct pinctrl_ops uniphier_pinctrl_ops = {
.get_pins_count = uniphier_pinctrl_get_pins_count,
.get_pin_name = uniphier_pinctrl_get_pin_name,
.get_groups_count = uniphier_pinctrl_get_groups_count,
.get_group_name = uniphier_pinctrl_get_group_name,
.get_functions_count = uniphier_pinmux_get_functions_count,
......@@ -276,6 +407,7 @@ const struct pinctrl_ops uniphier_pinctrl_ops = {
#if CONFIG_IS_ENABLED(PINCONF)
.pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params),
.pinconf_params = uniphier_pinconf_params,
.pinconf_set = uniphier_pinconf_set,
.pinconf_group_set = uniphier_pinconf_group_set,
#endif
.set_state = pinctrl_generic_set_state,
......
......@@ -10,6 +10,15 @@
#include "pinctrl-uniphier.h"
static const struct uniphier_pinctrl_pin uniphier_ld20_pins[] = {
UNIPHIER_PINCTRL_PIN(40, "RGMII_TXCLK", 28, UNIPHIER_PIN_DRV_3BIT),
UNIPHIER_PINCTRL_PIN(41, "RGMII_TXD0", 29, UNIPHIER_PIN_DRV_3BIT),
UNIPHIER_PINCTRL_PIN(42, "RGMII_TXD1", 30, UNIPHIER_PIN_DRV_3BIT),
UNIPHIER_PINCTRL_PIN(43, "RGMII_TXD2", 31, UNIPHIER_PIN_DRV_3BIT),
UNIPHIER_PINCTRL_PIN(44, "RGMII_TXD3", 32, UNIPHIER_PIN_DRV_3BIT),
UNIPHIER_PINCTRL_PIN(45, "RGMII_TXCTL", 33, UNIPHIER_PIN_DRV_3BIT),
};
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};
......@@ -102,6 +111,8 @@ static const char * const uniphier_ld20_functions[] = {
};
static struct uniphier_pinctrl_socdata uniphier_ld20_pinctrl_socdata = {
.pins = uniphier_ld20_pins,
.pins_count = ARRAY_SIZE(uniphier_ld20_pins),
.groups = uniphier_ld20_groups,
.groups_count = ARRAY_SIZE(uniphier_ld20_groups),
.functions = uniphier_ld20_functions,
......
......@@ -10,17 +10,6 @@
#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};
......@@ -134,8 +123,6 @@ static const char * const uniphier_ld6b_functions[] = {
};
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,
......
......@@ -8,15 +8,48 @@
#define __PINCTRL_UNIPHIER_H__
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/build_bug.h>
#include <linux/kernel.h>
#include <linux/types.h>
#define UNIPHIER_PIN_ATTR_PACKED(iectrl) (iectrl)
/* drive strength control register number */
#define UNIPHIER_PIN_DRVCTRL_SHIFT 0
#define UNIPHIER_PIN_DRVCTRL_BITS 9
#define UNIPHIER_PIN_DRVCTRL_MASK ((1U << (UNIPHIER_PIN_DRVCTRL_BITS)) \
- 1)
/* drive control type */
#define UNIPHIER_PIN_DRV_TYPE_SHIFT ((UNIPHIER_PIN_DRVCTRL_SHIFT) + \
(UNIPHIER_PIN_DRVCTRL_BITS))
#define UNIPHIER_PIN_DRV_TYPE_BITS 2
#define UNIPHIER_PIN_DRV_TYPE_MASK ((1U << (UNIPHIER_PIN_DRV_TYPE_BITS)) \
- 1)
/* drive control type */
enum uniphier_pin_drv_type {
UNIPHIER_PIN_DRV_1BIT, /* 2 level control: 4/8 mA */
UNIPHIER_PIN_DRV_2BIT, /* 4 level control: 8/12/16/20 mA */
UNIPHIER_PIN_DRV_3BIT, /* 8 level control: 4/5/7/9/11/12/14/16 mA */
};
#define UNIPHIER_PIN_DRVCTRL(x) \
(((x) & (UNIPHIER_PIN_DRVCTRL_MASK)) << (UNIPHIER_PIN_DRVCTRL_SHIFT))
#define UNIPHIER_PIN_DRV_TYPE(x) \
(((x) & (UNIPHIER_PIN_DRV_TYPE_MASK)) << (UNIPHIER_PIN_DRV_TYPE_SHIFT))
static inline unsigned int uniphier_pin_get_iectrl(unsigned long data)
#define UNIPHIER_PIN_ATTR_PACKED(drvctrl, drv_type) \
UNIPHIER_PIN_DRVCTRL(drvctrl) | \
UNIPHIER_PIN_DRV_TYPE(drv_type)
static inline unsigned int uniphier_pin_get_drvctrl(unsigned int data)
{
return data;
return (data >> UNIPHIER_PIN_DRVCTRL_SHIFT) & UNIPHIER_PIN_DRVCTRL_MASK;
}
static inline unsigned int uniphier_pin_get_drv_type(unsigned int data)
{
return (data >> UNIPHIER_PIN_DRV_TYPE_SHIFT) &
UNIPHIER_PIN_DRV_TYPE_MASK;
}
/**
......@@ -27,7 +60,8 @@ static inline unsigned int uniphier_pin_get_iectrl(unsigned long data)
*/
struct uniphier_pinctrl_pin {
unsigned number;
unsigned long data;
const char *name;
unsigned int data;
};
/**
......@@ -72,10 +106,11 @@ struct uniphier_pinctrl_socdata {
#define UNIPHIER_PINCTRL_CAPS_MUX_4BIT BIT(0)
};
#define UNIPHIER_PINCTRL_PIN(a, b) \
#define UNIPHIER_PINCTRL_PIN(a, b, c, d) \
{ \
.number = a, \
.data = UNIPHIER_PIN_ATTR_PACKED(b), \
.name = b, \
.data = UNIPHIER_PIN_ATTR_PACKED(c, d), \
}
#define __UNIPHIER_PINCTRL_GROUP(grp) \
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment