Merge branch 'master' of git://git.denx.de/u-boot-sh
- Various pinctrl / gpio fixes for R-Car
This commit is contained in:
commit
44237e272f
@ -13,6 +13,9 @@ config RCAR_GEN3
|
||||
select ARM64
|
||||
select PHY
|
||||
select CMD_CACHE
|
||||
select PINCTRL
|
||||
select PINCONF
|
||||
select PINCTRL_PFC
|
||||
imply CMD_FS_UUID
|
||||
imply CMD_GPT
|
||||
imply CMD_UUID
|
||||
|
@ -43,17 +43,37 @@ int board_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the firmware passed a device tree use it for U-Boot DRAM setup.
|
||||
*/
|
||||
extern u64 rcar_atf_boot_args[];
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
if (fdtdec_setup_mem_size_base() != 0)
|
||||
return -EINVAL;
|
||||
const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]);
|
||||
const void *blob;
|
||||
|
||||
return 0;
|
||||
/* Check if ATF passed us DTB. If not, fall back to builtin DTB. */
|
||||
if (fdt_magic(atf_fdt_blob) == FDT_MAGIC)
|
||||
blob = atf_fdt_blob;
|
||||
else
|
||||
blob = gd->fdt_blob;
|
||||
|
||||
return fdtdec_setup_mem_size_base_fdt(blob);
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
fdtdec_setup_memory_banksize();
|
||||
const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]);
|
||||
const void *blob;
|
||||
|
||||
/* Check if ATF passed us DTB. If not, fall back to builtin DTB. */
|
||||
if (fdt_magic(atf_fdt_blob) == FDT_MAGIC)
|
||||
blob = atf_fdt_blob;
|
||||
else
|
||||
blob = gd->fdt_blob;
|
||||
|
||||
fdtdec_setup_memory_banksize_fdt(blob);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -69,17 +69,37 @@ int board_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the firmware passed a device tree use it for U-Boot DRAM setup.
|
||||
*/
|
||||
extern u64 rcar_atf_boot_args[];
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
if (fdtdec_setup_mem_size_base() != 0)
|
||||
return -EINVAL;
|
||||
const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]);
|
||||
const void *blob;
|
||||
|
||||
return 0;
|
||||
/* Check if ATF passed us DTB. If not, fall back to builtin DTB. */
|
||||
if (fdt_magic(atf_fdt_blob) == FDT_MAGIC)
|
||||
blob = atf_fdt_blob;
|
||||
else
|
||||
blob = gd->fdt_blob;
|
||||
|
||||
return fdtdec_setup_mem_size_base_fdt(blob);
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
fdtdec_setup_memory_banksize();
|
||||
const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]);
|
||||
const void *blob;
|
||||
|
||||
/* Check if ATF passed us DTB. If not, fall back to builtin DTB. */
|
||||
if (fdt_magic(atf_fdt_blob) == FDT_MAGIC)
|
||||
blob = atf_fdt_blob;
|
||||
else
|
||||
blob = gd->fdt_blob;
|
||||
|
||||
fdtdec_setup_memory_banksize_fdt(blob);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -68,17 +68,37 @@ int board_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the firmware passed a device tree use it for U-Boot DRAM setup.
|
||||
*/
|
||||
extern u64 rcar_atf_boot_args[];
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
if (fdtdec_setup_mem_size_base() != 0)
|
||||
return -EINVAL;
|
||||
const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]);
|
||||
const void *blob;
|
||||
|
||||
return 0;
|
||||
/* Check if ATF passed us DTB. If not, fall back to builtin DTB. */
|
||||
if (fdt_magic(atf_fdt_blob) == FDT_MAGIC)
|
||||
blob = atf_fdt_blob;
|
||||
else
|
||||
blob = gd->fdt_blob;
|
||||
|
||||
return fdtdec_setup_mem_size_base_fdt(blob);
|
||||
}
|
||||
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
fdtdec_setup_memory_banksize();
|
||||
const void *atf_fdt_blob = (const void *)(rcar_atf_boot_args[1]);
|
||||
const void *blob;
|
||||
|
||||
/* Check if ATF passed us DTB. If not, fall back to builtin DTB. */
|
||||
if (fdt_magic(atf_fdt_blob) == FDT_MAGIC)
|
||||
blob = atf_fdt_blob;
|
||||
else
|
||||
blob = gd->fdt_blob;
|
||||
|
||||
fdtdec_setup_memory_banksize_fdt(blob);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
24
cmd/clk.c
24
cmd/clk.c
@ -17,6 +17,7 @@ int __weak soc_clk_dump(void)
|
||||
struct uclass *uc;
|
||||
struct clk clk;
|
||||
int ret;
|
||||
ulong rate;
|
||||
|
||||
/* Device addresses start at 1 */
|
||||
ret = uclass_get(UCLASS_CLK, &uc);
|
||||
@ -26,20 +27,23 @@ int __weak soc_clk_dump(void)
|
||||
uclass_foreach_dev(dev, uc) {
|
||||
memset(&clk, 0, sizeof(clk));
|
||||
ret = device_probe(dev);
|
||||
if (ret) {
|
||||
printf("%-30.30s : ? Hz\n", dev->name);
|
||||
continue;
|
||||
}
|
||||
if (ret)
|
||||
goto noclk;
|
||||
|
||||
ret = clk_request(dev, &clk);
|
||||
if (ret) {
|
||||
printf("%-30.30s : ? Hz\n", dev->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%-30.30s : %lu Hz\n", dev->name, clk_get_rate(&clk));
|
||||
if (ret)
|
||||
goto noclk;
|
||||
|
||||
rate = clk_get_rate(&clk);
|
||||
clk_free(&clk);
|
||||
|
||||
if (rate == -ENODEV)
|
||||
goto noclk;
|
||||
|
||||
printf("%-30.30s : %lu Hz\n", dev->name, rate);
|
||||
continue;
|
||||
noclk:
|
||||
printf("%-30.30s : ? Hz\n", dev->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -26,7 +26,7 @@ static void print_mmcinfo(struct mmc *mmc)
|
||||
|
||||
printf("Bus Speed: %d\n", mmc->clock);
|
||||
#if CONFIG_IS_ENABLED(MMC_VERBOSE)
|
||||
printf("Mode : %s\n", mmc_mode_name(mmc->selected_mode));
|
||||
printf("Mode: %s\n", mmc_mode_name(mmc->selected_mode));
|
||||
mmc_dump_capabilities("card capabilities", mmc->card_caps);
|
||||
mmc_dump_capabilities("host capabilities", mmc->host_caps);
|
||||
#endif
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -70,6 +70,13 @@ struct pinconf_param {
|
||||
* @set_state_simple: do needed pinctrl operations for a peripherl @periph.
|
||||
* (necessary for pinctrl_simple)
|
||||
* @get_pin_muxing: display the muxing of a given pin.
|
||||
* @gpio_request_enable: requests and enables GPIO on a certain pin.
|
||||
* Implement this only if you can mux every pin individually as GPIO. The
|
||||
* affected GPIO range is passed along with an offset(pin number) into that
|
||||
* specific GPIO range - function selectors and pin groups are orthogonal
|
||||
* to this, the core will however make sure the pins do not collide.
|
||||
* @gpio_disable_free: free up GPIO muxing on a certain pin, the reverse of
|
||||
* @gpio_request_enable
|
||||
*/
|
||||
struct pinctrl_ops {
|
||||
int (*get_pins_count)(struct udevice *dev);
|
||||
@ -151,6 +158,24 @@ struct pinctrl_ops {
|
||||
*/
|
||||
int (*get_pin_muxing)(struct udevice *dev, unsigned int selector,
|
||||
char *buf, int size);
|
||||
|
||||
/**
|
||||
* gpio_request_enable: requests and enables GPIO on a certain pin.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*gpio_request_enable)(struct udevice *dev, unsigned int selector);
|
||||
|
||||
/**
|
||||
* gpio_disable_free: free up GPIO muxing on a certain pin.
|
||||
*
|
||||
* @dev: Pinctrl device to use
|
||||
* @selector: Pin selector
|
||||
* return 0 if OK, -ve on error
|
||||
*/
|
||||
int (*gpio_disable_free)(struct udevice *dev, unsigned int selector);
|
||||
};
|
||||
|
||||
#define pinctrl_get_ops(dev) ((struct pinctrl_ops *)(dev)->driver->ops)
|
||||
@ -407,4 +432,23 @@ int pinctrl_get_pins_count(struct udevice *dev);
|
||||
*/
|
||||
int pinctrl_get_pin_name(struct udevice *dev, int selector, char *buf,
|
||||
int size);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#endif /* __PINCTRL_H */
|
||||
|
Loading…
Reference in New Issue
Block a user