Merge branch 'master' of git://git.denx.de/u-boot-sh

- Various pinctrl / gpio fixes for R-Car
This commit is contained in:
Tom Rini
2019-05-06 07:18:51 -04:00
12 changed files with 290 additions and 39 deletions

View File

@@ -6,6 +6,7 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <dm/pinctrl.h>
#include <errno.h>
#include <asm/gpio.h>
#include <asm/io.h>
@@ -117,19 +118,17 @@ static int rcar_gpio_get_function(struct udevice *dev, unsigned offset)
static int rcar_gpio_request(struct udevice *dev, unsigned offset,
const char *label)
{
struct rcar_gpio_priv *priv = dev_get_priv(dev);
struct udevice *pctldev;
int ret;
return pinctrl_gpio_request(dev, offset);
}
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pctldev);
if (ret)
return ret;
return sh_pfc_config_mux_for_gpio(pctldev, priv->pfc_offset + offset);
static int rcar_gpio_free(struct udevice *dev, unsigned offset)
{
return pinctrl_gpio_free(dev, offset);
}
static const struct dm_gpio_ops rcar_gpio_ops = {
.request = rcar_gpio_request,
.free = rcar_gpio_free,
.direction_input = rcar_gpio_direction_input,
.direction_output = rcar_gpio_direction_output,
.get_value = rcar_gpio_get_value,

View File

@@ -46,6 +46,8 @@
#define CSR_OPS 0x0000000F
#define CSR_OPS_CONFIG BIT(1)
#define APSR_TDM BIT(14)
#define TCCR_TSRQ0 BIT(0)
#define RFLR_RFL_MIN 0x05EE
@@ -389,9 +391,14 @@ static int ravb_dmac_init(struct udevice *dev)
/* FIFO size set */
writel(0x00222210, eth->iobase + RAVB_REG_TGC);
/* Delay CLK: 2ns */
if (pdata->max_speed == 1000)
writel(BIT(14), eth->iobase + RAVB_REG_APSR);
/* Delay CLK: 2ns (not applicable on R-Car E3/D3) */
if ((rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77990) ||
(rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77995))
return 0;
if ((pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
(pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID))
writel(APSR_TDM, eth->iobase + RAVB_REG_APSR);
return 0;
}

View File

@@ -172,6 +172,102 @@ static int pinconfig_post_bind(struct udevice *dev)
}
#endif
static int
pinctrl_gpio_get_pinctrl_and_offset(struct udevice *dev, unsigned offset,
struct udevice **pctldev,
unsigned int *pin_selector)
{
struct ofnode_phandle_args args;
unsigned gpio_offset, pfc_base, pfc_pins;
int ret;
ret = dev_read_phandle_with_args(dev, "gpio-ranges", NULL, 3,
0, &args);
if (ret) {
dev_dbg(dev, "%s: dev_read_phandle_with_args: err=%d\n",
__func__, ret);
return ret;
}
ret = uclass_get_device_by_ofnode(UCLASS_PINCTRL,
args.node, pctldev);
if (ret) {
dev_dbg(dev,
"%s: uclass_get_device_by_of_offset failed: err=%d\n",
__func__, ret);
return ret;
}
gpio_offset = args.args[0];
pfc_base = args.args[1];
pfc_pins = args.args[2];
if (offset < gpio_offset || offset > gpio_offset + pfc_pins) {
dev_dbg(dev,
"%s: GPIO can not be mapped to pincontrol pin\n",
__func__);
return -EINVAL;
}
offset -= gpio_offset;
offset += pfc_base;
*pin_selector = offset;
return 0;
}
/**
* pinctrl_gpio_request() - request a single pin to be used as GPIO
*
* @dev: GPIO peripheral device
* @offset: the GPIO pin offset from the GPIO controller
* @return: 0 on success, or negative error code on failure
*/
int pinctrl_gpio_request(struct udevice *dev, unsigned offset)
{
const struct pinctrl_ops *ops;
struct udevice *pctldev;
unsigned int pin_selector;
int ret;
ret = pinctrl_gpio_get_pinctrl_and_offset(dev, offset,
&pctldev, &pin_selector);
if (ret)
return ret;
ops = pinctrl_get_ops(pctldev);
if (!ops || !ops->gpio_request_enable)
return -ENOTSUPP;
return ops->gpio_request_enable(pctldev, pin_selector);
}
/**
* pinctrl_gpio_free() - free a single pin used as GPIO
*
* @dev: GPIO peripheral device
* @offset: the GPIO pin offset from the GPIO controller
* @return: 0 on success, or negative error code on failure
*/
int pinctrl_gpio_free(struct udevice *dev, unsigned offset)
{
const struct pinctrl_ops *ops;
struct udevice *pctldev;
unsigned int pin_selector;
int ret;
ret = pinctrl_gpio_get_pinctrl_and_offset(dev, offset,
&pctldev, &pin_selector);
if (ret)
return ret;
ops = pinctrl_get_ops(pctldev);
if (!ops || !ops->gpio_disable_free)
return -ENOTSUPP;
return ops->gpio_disable_free(pctldev, pin_selector);
}
/**
* pinctrl_select_state_simple() - simple implementation of pinctrl_select_state
*

View File

@@ -459,7 +459,44 @@ static const char *sh_pfc_pinctrl_get_function_name(struct udevice *dev,
return priv->pfc.info->functions[selector].name;
}
int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector)
static int sh_pfc_gpio_request_enable(struct udevice *dev,
unsigned pin_selector)
{
struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
struct sh_pfc_pinctrl *pmx = &priv->pmx;
struct sh_pfc *pfc = &priv->pfc;
struct sh_pfc_pin_config *cfg;
const struct sh_pfc_pin *pin = NULL;
int i, ret, idx;
for (i = 1; i < pfc->info->nr_pins; i++) {
if (priv->pfc.info->pins[i].pin != pin_selector)
continue;
pin = &priv->pfc.info->pins[i];
break;
}
if (!pin)
return -EINVAL;
idx = sh_pfc_get_pin_index(pfc, pin->pin);
cfg = &pmx->configs[idx];
if (cfg->type != PINMUX_TYPE_NONE)
return -EBUSY;
ret = sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
if (ret)
return ret;
cfg->type = PINMUX_TYPE_GPIO;
return 0;
}
static int sh_pfc_gpio_disable_free(struct udevice *dev,
unsigned pin_selector)
{
struct sh_pfc_pinctrl_priv *priv = dev_get_priv(dev);
struct sh_pfc_pinctrl *pmx = &priv->pmx;
@@ -482,10 +519,9 @@ int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector)
idx = sh_pfc_get_pin_index(pfc, pin->pin);
cfg = &pmx->configs[idx];
if (cfg->type != PINMUX_TYPE_NONE)
return -EBUSY;
cfg->type = PINMUX_TYPE_NONE;
return sh_pfc_config_mux(pfc, pin->enum_id, PINMUX_TYPE_GPIO);
return 0;
}
static int sh_pfc_pinctrl_pin_set(struct udevice *dev, unsigned pin_selector,
@@ -746,6 +782,9 @@ static struct pinctrl_ops sh_pfc_pinctrl_ops = {
.pinmux_set = sh_pfc_pinctrl_pin_set,
.pinmux_group_set = sh_pfc_pinctrl_group_set,
.set_state = pinctrl_generic_set_state,
.gpio_request_enable = sh_pfc_gpio_request_enable,
.gpio_disable_free = sh_pfc_gpio_disable_free,
};
static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx)

View File

@@ -275,7 +275,6 @@ void sh_pfc_write(struct sh_pfc *pfc, u32 reg, u32 data);
const struct pinmux_bias_reg *
sh_pfc_pin_to_bias_reg(const struct sh_pfc *pfc, unsigned int pin,
unsigned int *bit);
int sh_pfc_config_mux_for_gpio(struct udevice *dev, unsigned pin_selector);
extern const struct sh_pfc_soc_info r8a7790_pinmux_info;
extern const struct sh_pfc_soc_info r8a7791_pinmux_info;