diff options
Diffstat (limited to 'drivers')
88 files changed, 1581 insertions, 982 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index e8c9e0a326..0e5d97d166 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -16,6 +16,8 @@ source "drivers/crypto/Kconfig" source "drivers/demo/Kconfig" +source "drivers/ddr/fsl/Kconfig" + source "drivers/dfu/Kconfig" source "drivers/dma/Kconfig" diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c05ce2a9ef..335ef9e1d7 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -28,6 +28,13 @@ config CLK_BOSTON help Enable this to support the clocks +config CLK_ZYNQMP + bool "Enable clock driver support for ZynqMP" + depends on ARCH_ZYNQMP + help + This clock driver adds support for clock realted settings for + ZynqMP platform. + source "drivers/clk/tegra/Kconfig" source "drivers/clk/uniphier/Kconfig" source "drivers/clk/exynos/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 40a5e8cae8..f55348e8f1 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ obj-$(CONFIG_SANDBOX) += clk_sandbox.o obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o obj-$(CONFIG_MACH_PIC32) += clk_pic32.o +obj-$(CONFIG_CLK_ZYNQMP) += clk_zynqmp.o obj-y += tegra/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c new file mode 100644 index 0000000000..694274d991 --- /dev/null +++ b/drivers/clk/clk_zynqmp.c @@ -0,0 +1,241 @@ +/* + * ZynqMP clock driver + * + * Copyright (C) 2016 Xilinx, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/bitops.h> +#include <clk-uclass.h> +#include <dm/device.h> +#include <clk.h> + +#define ZYNQMP_GEM0_REF_CTRL 0xFF5E0050 +#define ZYNQMP_IOPLL_CTRL 0xFF5E0020 +#define ZYNQMP_RPLL_CTRL 0xFF5E0030 +#define ZYNQMP_DPLL_CTRL 0xFD1A002C +#define ZYNQMP_SIP_SVC_MMIO_WRITE 0xC2000013 +#define ZYNQMP_SIP_SVC_MMIO_WRITE 0xC2000013 +#define ZYNQMP_SIP_SVC_MMIO_WRITE 0xC2000013 +#define ZYNQMP_SIP_SVC_MMIO_READ 0xC2000014 +#define ZYNQMP_DIV_MAX_VAL 0x3F +#define ZYNQMP_DIV1_SHFT 8 +#define ZYNQMP_DIV1_SHFT 8 +#define ZYNQMP_DIV2_SHFT 16 +#define ZYNQMP_DIV_MASK 0x3F +#define ZYNQMP_PLL_CTRL_FBDIV_MASK 0x7F +#define ZYNQMP_PLL_CTRL_FBDIV_SHFT 8 +#define ZYNQMP_GEM_REF_CTRL_SRC_MASK 0x7 +#define ZYNQMP_GEM0_CLK_ID 45 +#define ZYNQMP_GEM1_CLK_ID 46 +#define ZYNQMP_GEM2_CLK_ID 47 +#define ZYNQMP_GEM3_CLK_ID 48 + +static unsigned long pss_ref_clk; + +static int zynqmp_calculate_divisors(unsigned long req_rate, + unsigned long parent_rate, + u32 *div1, u32 *div2) +{ + u32 req_div = 1; + u32 i; + + /* + * calculate two divisors to get + * required rate and each divisor + * should be less than 63 + */ + req_div = DIV_ROUND_UP(parent_rate, req_rate); + + for (i = 1; i <= req_div; i++) { + if ((req_div % i) == 0) { + *div1 = req_div / i; + *div2 = i; + if ((*div1 < ZYNQMP_DIV_MAX_VAL) && + (*div2 < ZYNQMP_DIV_MAX_VAL)) + return 0; + } + } + + return -1; +} + +static int zynqmp_get_periph_id(unsigned long id) +{ + int periph_id; + + switch (id) { + case ZYNQMP_GEM0_CLK_ID: + periph_id = 0; + break; + case ZYNQMP_GEM1_CLK_ID: + periph_id = 1; + break; + case ZYNQMP_GEM2_CLK_ID: + periph_id = 2; + break; + case ZYNQMP_GEM3_CLK_ID: + periph_id = 3; + break; + default: + printf("%s, Invalid clock id:%ld\n", __func__, id); + return -EINVAL; + } + + return periph_id; +} + +static int zynqmp_set_clk(unsigned long id, u32 div1, u32 div2) +{ + struct pt_regs regs; + ulong reg; + u32 mask, value; + + id = zynqmp_get_periph_id(id); + if (id < 0) + return -EINVAL; + + reg = (ulong)((u32 *)ZYNQMP_GEM0_REF_CTRL + id); + mask = (ZYNQMP_DIV_MASK << ZYNQMP_DIV1_SHFT) | + (ZYNQMP_DIV_MASK << ZYNQMP_DIV2_SHFT); + value = (div1 << ZYNQMP_DIV1_SHFT) | (div2 << ZYNQMP_DIV2_SHFT); + + debug("%s: reg:0x%lx, mask:0x%x, value:0x%x\n", __func__, reg, mask, + value); + + regs.regs[0] = ZYNQMP_SIP_SVC_MMIO_WRITE; + regs.regs[1] = ((u64)mask << 32) | reg; + regs.regs[2] = value; + regs.regs[3] = 0; + + smc_call(®s); + + return regs.regs[0]; +} + +static unsigned long zynqmp_clk_get_rate(struct clk *clk) +{ + struct pt_regs regs; + ulong reg; + unsigned long value; + int id; + + id = zynqmp_get_periph_id(clk->id); + if (id < 0) + return -EINVAL; + + reg = (ulong)((u32 *)ZYNQMP_GEM0_REF_CTRL + id); + + regs.regs[0] = ZYNQMP_SIP_SVC_MMIO_READ; + regs.regs[1] = reg; + regs.regs[2] = 0; + regs.regs[3] = 0; + + smc_call(®s); + + value = upper_32_bits(regs.regs[0]); + + value &= ZYNQMP_GEM_REF_CTRL_SRC_MASK; + + switch (value) { + case 0: + regs.regs[1] = ZYNQMP_IOPLL_CTRL; + break; + case 2: + regs.regs[1] = ZYNQMP_RPLL_CTRL; + break; + case 3: + regs.regs[1] = ZYNQMP_DPLL_CTRL; + break; + default: + return -EINVAL; + } + + regs.regs[0] = ZYNQMP_SIP_SVC_MMIO_READ; + regs.regs[2] = 0; + regs.regs[3] = 0; + + smc_call(®s); + + value = upper_32_bits(regs.regs[0]) & + (ZYNQMP_PLL_CTRL_FBDIV_MASK << + ZYNQMP_PLL_CTRL_FBDIV_SHFT); + value >>= ZYNQMP_PLL_CTRL_FBDIV_SHFT; + value *= pss_ref_clk; + + return value; +} + +static ulong zynqmp_clk_set_rate(struct clk *clk, unsigned long clk_rate) +{ + int ret; + u32 div1 = 0; + u32 div2 = 0; + unsigned long input_clk; + + input_clk = zynqmp_clk_get_rate(clk); + if (IS_ERR_VALUE(input_clk)) { + dev_err(dev, "failed to get input_clk\n"); + return -EINVAL; + } + + debug("%s: i/p CLK %ld, clk_rate:0x%ld\n", __func__, input_clk, + clk_rate); + + ret = zynqmp_calculate_divisors(clk_rate, input_clk, &div1, &div2); + if (ret) { + dev_err(dev, "failed to proper divisors\n"); + return -EINVAL; + } + + debug("%s: Div1:%d, Div2:%d\n", __func__, div1, div2); + + ret = zynqmp_set_clk(clk->id, div1, div2); + if (ret) { + dev_err(dev, "failed to set gem clk\n"); + return -EINVAL; + } + + return 0; +} + +static int zynqmp_clk_probe(struct udevice *dev) +{ + struct clk clk; + int ret; + + debug("%s\n", __func__); + ret = clk_get_by_name(dev, "pss_ref_clk", &clk); + if (ret < 0) { + dev_err(dev, "failed to get pss_ref_clk\n"); + return ret; + } + + pss_ref_clk = clk_get_rate(&clk); + if (IS_ERR_VALUE(pss_ref_clk)) { + dev_err(dev, "failed to get rate pss_ref_clk\n"); + return -EINVAL; + } + + return 0; +} + +static struct clk_ops zynqmp_clk_ops = { + .set_rate = zynqmp_clk_set_rate, + .get_rate = zynqmp_clk_get_rate, +}; + +static const struct udevice_id zynqmp_clk_ids[] = { + { .compatible = "xlnx,zynqmp-clkc" }, + { } +}; + +U_BOOT_DRIVER(zynqmp_clk) = { + .name = "zynqmp-clk", + .id = UCLASS_CLK, + .of_match = zynqmp_clk_ids, + .probe = zynqmp_clk_probe, + .ops = &zynqmp_clk_ops, +}; diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig index 86b2f2f7ac..31889598e8 100644 --- a/drivers/crypto/fsl/Kconfig +++ b/drivers/crypto/fsl/Kconfig @@ -4,3 +4,42 @@ config FSL_CAAM Enables the Freescale's Cryptographic Accelerator and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). The driver uses Job Ring as interface to communicate with CAAM. + +config SYS_FSL_HAS_SEC + bool + help + Enable Freescale Secure Boot and Trusted Architecture + +config SYS_FSL_SEC_COMPAT_2 + bool + help + Secure boot and trust architecture compatible version 2 + +config SYS_FSL_SEC_COMPAT_4 + bool + help + Secure boot and trust architecture compatible version 4 + +config SYS_FSL_SEC_COMPAT_5 + bool + help + Secure boot and trust architecture compatible version 5 + +config SYS_FSL_SEC_COMPAT_6 + bool + help + Secure boot and trust architecture compatible version 6 + +config SYS_FSL_SEC_BE + bool "Big-endian access to Freescale Secure Boot" + +config SYS_FSL_SEC_COMPAT + int "Freescale Secure Boot compatibility" + depends on SYS_FSL_HAS_SEC + default 2 if SYS_FSL_SEC_COMPAT_2 + default 4 if SYS_FSL_SEC_COMPAT_4 + default 5 if SYS_FSL_SEC_COMPAT_5 + default 6 if SYS_FSL_SEC_COMPAT_6 + +config SYS_FSL_SEC_LE + bool "Little-endian access to Freescale Secure Boot" diff --git a/drivers/ddr/fsl/Kconfig b/drivers/ddr/fsl/Kconfig new file mode 100644 index 0000000000..a3d2bd5fe6 --- /dev/null +++ b/drivers/ddr/fsl/Kconfig @@ -0,0 +1,172 @@ +config SYS_FSL_DDR + bool + help + Select Freescale General DDR driver, shared between most Freescale + PowerPC- based SoCs (such as mpc83xx, mpc85xx, mpc86xx) and ARM- + based Layerscape SoCs (such as ls2080a). + +config SYS_FSL_MMDC + bool + help + Select Freescale Multi Mode DDR controller (MMDC). + +config SYS_FSL_DDR_BE + bool + help + Access DDR registers in big-endian + +config SYS_FSL_DDR_LE + bool + help + Access DDR registers in little-endian + +menu "Freescale DDR controllers" + depends on SYS_FSL_DDR + +config SYS_NUM_DDR_CTLRS + int "Maximum DDR controllers" + default 3 if ARCH_LS2080A || \ + ARCH_T4240 + default 2 if ARCH_B4860 || \ + ARCH_BSC9132 || \ + ARCH_MPC8572 || \ + ARCH_MPC8641 || \ + ARCH_P4080 || \ + ARCH_P5020 || \ + ARCH_P5040 || \ + ARCH_T4160 + default 1 + +config SYS_FSL_DDR_VER + int + default 50 if SYS_FSL_DDR_VER_50 + default 47 if SYS_FSL_DDR_VER_47 + default 46 if SYS_FSL_DDR_VER_46 + default 44 if SYS_FSL_DDR_VER_44 + +config SYS_FSL_DDR_VER_50 + bool + +config SYS_FSL_DDR_VER_47 + bool + +config SYS_FSL_DDR_VER_46 + bool + +config SYS_FSL_DDR_VER_44 + bool + +config SYS_FSL_DDRC_GEN1 + bool + help + Enable Freescale DDR controller. + +config SYS_FSL_DDRC_GEN2 + bool + depends on !MPC86xx + help + Enable Freescale DDR2 controller. + +config SYS_FSL_DDRC_86XX_GEN2 + bool + depends on MPC86xx + help + Enable Freescale DDR2 controller for MPC86xx SoCs. + +config SYS_FSL_DDRC_GEN3 + bool + depends on PPC + help + Enable Freescale DDR3 controller for PowerPC SoCs. + +config SYS_FSL_DDRC_ARM_GEN3 + bool + depends on ARM + help + Enable Freescale DDR3 controller for ARM SoCs. + +config SYS_FSL_DDRC_GEN4 + bool + help + Enable Freescale DDR4 controller. + +config SYS_FSL_HAS_DDR4 + bool + +config SYS_FSL_HAS_DDR3 + bool + +config SYS_FSL_HAS_DDR2 + bool + +config SYS_FSL_HAS_DDR1 + bool + +choice + prompt "DDR technology" + default SYS_FSL_DDR4 if SYS_FSL_HAS_DDR4 + default SYS_FSL_DDR3 if SYS_FSL_HAS_DDR3 + default SYS_FSL_DDR2 if SYS_FSL_HAS_DDR2 + default SYS_FSL_DDR1 if SYS_FSL_HAS_DDR1 + +config SYS_FSL_DDR4 + bool "Freescale DDR4 controller" + depends on SYS_FSL_HAS_DDR4 + select SYS_FSL_DDRC_GEN4 + +config SYS_FSL_DDR3 + bool "Freescale DDR3 controller" + depends on SYS_FSL_HAS_DDR3 + select SYS_FSL_DDRC_GEN3 if PPC + select SYS_FSL_DDRC_ARM_GEN3 if ARM + +config SYS_FSL_DDR2 + bool "Freescale DDR2 controller" + depends on SYS_FSL_HAS_DDR2 + select SYS_FSL_DDRC_GEN2 if (!MPC86xx && !SYS_FSL_DDRC_GEN3) + select SYS_FSL_DDRC_86XX_GEN2 if MPC86xx + +config SYS_FSL_DDR1 + bool "Freescale DDR1 controller" + depends on SYS_FSL_HAS_DDR1 + select SYS_FSL_DDRC_GEN1 + +endchoice + +endmenu + +config SYS_FSL_ERRATUM_A008378 + bool + +config SYS_FSL_ERRATUM_A008511 + bool + +config SYS_FSL_ERRATUM_A009663 + bool + +config SYS_FSL_ERRATUM_A009801 + bool + +config SYS_FSL_ERRATUM_A009803 + bool + +config SYS_FSL_ERRATUM_A009942 + bool + +config SYS_FSL_ERRATUM_A010165 + bool + +config SYS_FSL_ERRATUM_NMG_DDR120 + bool + +config SYS_FSL_ERRATUM_DDR_115 + bool + +config SYS_FSL_ERRATUM_DDR111_DDR134 + bool + +config SYS_FSL_ERRATUM_DDR_A003 + bool + +config SYS_FSL_ERRATUM_DDR_A003474 + bool diff --git a/drivers/ddr/fsl/Makefile b/drivers/ddr/fsl/Makefile index 00dea428e3..7935f7d56f 100644 --- a/drivers/ddr/fsl/Makefile +++ b/drivers/ddr/fsl/Makefile @@ -30,7 +30,7 @@ obj-$(CONFIG_FSL_DDR_INTERACTIVE) += interactive.o obj-$(CONFIG_SYS_FSL_DDRC_GEN1) += mpc85xx_ddr_gen1.o obj-$(CONFIG_SYS_FSL_DDRC_GEN2) += mpc85xx_ddr_gen2.o obj-$(CONFIG_SYS_FSL_DDRC_GEN3) += mpc85xx_ddr_gen3.o -obj-$(CONFIG_SYS_FSL_DDR_86XX) += mpc86xx_ddr.o +obj-$(CONFIG_SYS_FSL_DDRC_86XX_GEN2) += mpc86xx_ddr.o obj-$(CONFIG_SYS_FSL_DDRC_ARM_GEN3) += arm_ddr_gen3.o obj-$(CONFIG_SYS_FSL_DDRC_GEN4) += fsl_ddr_gen4.o obj-$(CONFIG_SYS_FSL_MMDC) += fsl_mmdc.o diff --git a/drivers/ddr/fsl/arm_ddr_gen3.c b/drivers/ddr/fsl/arm_ddr_gen3.c index 7160da4ec8..5b7ced5949 100644 --- a/drivers/ddr/fsl/arm_ddr_gen3.c +++ b/drivers/ddr/fsl/arm_ddr_gen3.c @@ -40,17 +40,17 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; break; -#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; break; diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c index f7e87b8ee9..21687dd077 100644 --- a/drivers/ddr/fsl/ctrl_regs.c +++ b/drivers/ddr/fsl/ctrl_regs.c @@ -2318,17 +2318,17 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num, case 0: ddrc = (void *)CONFIG_SYS_FSL_DDR_ADDR; break; -#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) case 1: ddrc = (void *)CONFIG_SYS_FSL_DDR2_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) case 2: ddrc = (void *)CONFIG_SYS_FSL_DDR3_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) case 3: ddrc = (void *)CONFIG_SYS_FSL_DDR4_ADDR; break; diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c index dadcb3abc3..e0f9e2ca3d 100644 --- a/drivers/ddr/fsl/fsl_ddr_gen4.c +++ b/drivers/ddr/fsl/fsl_ddr_gen4.c @@ -68,17 +68,17 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; break; -#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; break; diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c index 49352b30fb..202ad138f9 100644 --- a/drivers/ddr/fsl/interactive.c +++ b/drivers/ddr/fsl/interactive.c @@ -763,7 +763,7 @@ static void fsl_ddr_regs_edit(fsl_ddr_info_t *pinfo, debug("fsl_ddr_regs_edit: ctrl_num = %u, " "regname = %s, value = %s\n", ctrl_num, regname, value_str); - if (ctrl_num > CONFIG_NUM_DDR_CONTROLLERS) + if (ctrl_num > CONFIG_SYS_NUM_DDR_CTLRS) return; ddr = &(pinfo->fsl_ddr_config_reg[ctrl_num]); @@ -1685,7 +1685,7 @@ static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, /* STEP 1: DIMM SPD data */ if (do_mask & STEP_GET_SPD) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) { if (!(ctrl_mask & (1 << i))) continue; @@ -1706,7 +1706,7 @@ static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, /* STEP 2: DIMM Parameters */ if (do_mask & STEP_COMPUTE_DIMM_PARMS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) { if (!(ctrl_mask & (1 << i))) continue; for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { @@ -1725,7 +1725,7 @@ static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, /* STEP 3: Common Parameters */ if (do_mask & STEP_COMPUTE_COMMON_PARMS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) { if (!(ctrl_mask & (1 << i))) continue; printf("\"lowest common\" DIMM parameters: " @@ -1739,7 +1739,7 @@ static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, /* STEP 4: User Configuration Options */ if (do_mask & STEP_GATHER_OPTS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) { if (!(ctrl_mask & (1 << i))) continue; printf("User Config Options: Controller=%u\n", i); @@ -1751,7 +1751,7 @@ static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, /* STEP 5: Address assignment */ if (do_mask & STEP_ASSIGN_ADDRESSES) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) { if (!(ctrl_mask & (1 << i))) continue; for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) { @@ -1766,7 +1766,7 @@ static void fsl_ddr_printinfo(const fsl_ddr_info_t *pinfo, /* STEP 6: computed controller register values */ if (do_mask & STEP_COMPUTE_REGS) { - for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) { + for (i = 0; i < CONFIG_SYS_NUM_DDR_CTLRS; i++) { if (!(ctrl_mask & (1 << i))) continue; printf("Computed Register Values: Controller=%u\n", i); diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 479184f4ed..159c22e18a 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -40,35 +40,35 @@ void fsl_ddr_set_intl3r(const unsigned int granule_size); #if defined(SPD_EEPROM_ADDRESS) || \ defined(SPD_EEPROM_ADDRESS1) || defined(SPD_EEPROM_ADDRESS2) || \ defined(SPD_EEPROM_ADDRESS3) || defined(SPD_EEPROM_ADDRESS4) -#if (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { +#if (CONFIG_SYS_NUM_DDR_CTLRS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +u8 spd_i2c_addr[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS, }; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { +#elif (CONFIG_SYS_NUM_DDR_CTLRS == 1) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ }; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { +#elif (CONFIG_SYS_NUM_DDR_CTLRS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +u8 spd_i2c_addr[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ }; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { +#elif (CONFIG_SYS_NUM_DDR_CTLRS == 2) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ [1][1] = SPD_EEPROM_ADDRESS4, /* controller 2 */ }; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { +#elif (CONFIG_SYS_NUM_DDR_CTLRS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 1) +u8 spd_i2c_addr[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ [1][0] = SPD_EEPROM_ADDRESS2, /* controller 2 */ [2][0] = SPD_EEPROM_ADDRESS3, /* controller 3 */ }; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) -u8 spd_i2c_addr[CONFIG_NUM_DDR_CONTROLLERS][CONFIG_DIMM_SLOTS_PER_CTLR] = { +#elif (CONFIG_SYS_NUM_DDR_CTLRS == 3) && (CONFIG_DIMM_SLOTS_PER_CTLR == 2) +u8 spd_i2c_addr[CONFIG_SYS_NUM_DDR_CTLRS][CONFIG_DIMM_SLOTS_PER_CTLR] = { [0][0] = SPD_EEPROM_ADDRESS1, /* controller 1 */ [0][1] = SPD_EEPROM_ADDRESS2, /* controller 1 */ [1][0] = SPD_EEPROM_ADDRESS3, /* controller 2 */ @@ -146,7 +146,7 @@ void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd, unsigned int i; unsigned int i2c_address = 0; - if (ctrl_num >= CONFIG_NUM_DDR_CONTROLLERS) { + if (ctrl_num >= CONFIG_SYS_NUM_DDR_CTLRS) { printf("%s unexpected ctrl_num = %u\n", __FUNCTION__, ctrl_num); return; } @@ -430,7 +430,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step, assert_reset = pinfo->board_need_mem_reset(); /* data bus width capacity adjust shift amount */ - unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS]; + unsigned int dbw_capacity_adjust[CONFIG_SYS_NUM_DDR_CTLRS]; for (i = first_ctrl; i <= last_ctrl; i++) dbw_capacity_adjust[i] = 0; @@ -720,7 +720,7 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) &pinfo->common_timing_params[i], law_memctl, i); } -#if CONFIG_NUM_DDR_CONTROLLERS > 3 +#if CONFIG_SYS_NUM_DDR_CTLRS > 3 else if (i == 2) { law_memctl = LAW_TRGT_IF_DDR_INTLV_34; fsl_ddr_set_lawbar( diff --git a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c index 1bfb9d4097..afbed598c8 100644 --- a/drivers/ddr/fsl/mpc85xx_ddr_gen3.c +++ b/drivers/ddr/fsl/mpc85xx_ddr_gen3.c @@ -44,17 +44,17 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs, case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; break; -#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; break; diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c index 793d12aabb..d6a8fcb216 100644 --- a/drivers/ddr/fsl/options.c +++ b/drivers/ddr/fsl/options.c @@ -1077,7 +1077,7 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm, * if CONFIG_SYS_FSL_DDR_INTLV_256B is defined, mandatory interleaving * with 256 Byte is enabled. */ -#if (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if (CONFIG_SYS_NUM_DDR_CTLRS > 1) if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf)) #ifdef CONFIG_SYS_FSL_DDR_INTLV_256B ; @@ -1107,39 +1107,39 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm, "ctlr_intlv", "cacheline", buf)) { popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : FSL_DDR_CACHE_LINE_INTERLEAVING; popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : 1; } else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", "page", buf)) { popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : FSL_DDR_PAGE_INTERLEAVING; popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : 1; } else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", "bank", buf)) { popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : FSL_DDR_BANK_INTERLEAVING; popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : 1; } else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", "superbank", buf)) { popts->memctl_interleaving_mode = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : FSL_DDR_SUPERBANK_INTERLEAVING; popts->memctl_interleaving = - ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ? + ((CONFIG_SYS_NUM_DDR_CTLRS == 3) && ctrl_num == 2) ? 0 : 1; -#if (CONFIG_NUM_DDR_CONTROLLERS == 3) +#if (CONFIG_SYS_NUM_DDR_CTLRS == 3) } else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", "3way_1KB", buf)) { @@ -1155,7 +1155,7 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm, "3way_8KB", buf)) { popts->memctl_interleaving_mode = FSL_DDR_3WAY_8KB_INTERLEAVING; -#elif (CONFIG_NUM_DDR_CONTROLLERS == 4) +#elif (CONFIG_SYS_NUM_DDR_CTLRS == 4) } else if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv", "4way_1KB", buf)) { @@ -1178,7 +1178,7 @@ unsigned int populate_memctl_options(const common_timing_params_t *common_dimm, } #endif /* CONFIG_SYS_FSL_DDR_INTLV_256B */ done: -#endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */ +#endif /* CONFIG_SYS_NUM_DDR_CTLRS > 1 */ if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) && (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) { /* test null first. if CONFIG_HWCONFIG is not defined, @@ -1356,10 +1356,10 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo) case FSL_DDR_PAGE_INTERLEAVING: case FSL_DDR_BANK_INTERLEAVING: case FSL_DDR_SUPERBANK_INTERLEAVING: -#if (3 == CONFIG_NUM_DDR_CONTROLLERS) +#if (3 == CONFIG_SYS_NUM_DDR_CTLRS) k = 2; #else - k = CONFIG_NUM_DDR_CONTROLLERS; + k = CONFIG_SYS_NUM_DDR_CTLRS; #endif break; case FSL_DDR_3WAY_1KB_INTERLEAVING: @@ -1369,7 +1369,7 @@ void check_interleaving_options(fsl_ddr_info_t *pinfo) case FSL_DDR_4WAY_4KB_INTERLEAVING: case FSL_DDR_4WAY_8KB_INTERLEAVING: default: - k = CONFIG_NUM_DDR_CONTROLLERS; + k = CONFIG_SYS_NUM_DDR_CTLRS; break; } debug("%d of %d controllers are interleaving.\n", j, k); diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c index 99777793a5..b58784be65 100644 --- a/drivers/ddr/fsl/util.c +++ b/drivers/ddr/fsl/util.c @@ -30,17 +30,17 @@ u32 fsl_ddr_get_version(unsigned int ctrl_num) case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; break; -#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; break; @@ -174,23 +174,23 @@ void print_ddr_info(unsigned int start_ctrl) struct ccsr_ddr __iomem *ddr = (struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR); -#if defined(CONFIG_E6500) && (CONFIG_NUM_DDR_CONTROLLERS == 3) +#if defined(CONFIG_E6500) && (CONFIG_SYS_NUM_DDR_CTLRS == 3) u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004); #endif -#if (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if (CONFIG_SYS_NUM_DDR_CTLRS > 1) uint32_t cs0_config = ddr_in32(&ddr->cs0_config); #endif uint32_t sdram_cfg = ddr_in32(&ddr->sdram_cfg); int cas_lat; -#if CONFIG_NUM_DDR_CONTROLLERS >= 2 +#if CONFIG_SYS_NUM_DDR_CTLRS >= 2 if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) || (start_ctrl == 1)) { ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR; sdram_cfg = ddr_in32(&ddr->sdram_cfg); } #endif -#if CONFIG_NUM_DDR_CONTROLLERS >= 3 +#if CONFIG_SYS_NUM_DDR_CTLRS >= 3 if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) || (start_ctrl == 2)) { ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR; @@ -246,7 +246,7 @@ void print_ddr_info(unsigned int start_ctrl) else puts(", ECC off)"); -#if (CONFIG_NUM_DDR_CONTROLLERS == 3) +#if (CONFIG_SYS_NUM_DDR_CTLRS == 3) #ifdef CONFIG_E6500 if (*mcintl3r & 0x80000000) { puts("\n"); @@ -268,7 +268,7 @@ void print_ddr_info(unsigned int start_ctrl) } #endif #endif -#if (CONFIG_NUM_DDR_CONTROLLERS >= 2) +#if (CONFIG_SYS_NUM_DDR_CTLRS >= 2) if ((cs0_config & 0x20000000) && (start_ctrl == 0)) { puts("\n"); puts(" DDR Controller Interleaving Mode: "); @@ -337,8 +337,8 @@ void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl, { unsigned int i; u32 ddrc_debug20; - u32 ddrc_debug2[CONFIG_NUM_DDR_CONTROLLERS] = {}; - u32 *ddrc_debug2_p[CONFIG_NUM_DDR_CONTROLLERS] = {}; + u32 ddrc_debug2[CONFIG_SYS_NUM_DDR_CTLRS] = {}; + u32 *ddrc_debug2_p[CONFIG_SYS_NUM_DDR_CTLRS] = {}; struct ccsr_ddr __iomem *ddr; for (i = first_ctrl; i <= last_ctrl; i++) { @@ -346,17 +346,17 @@ void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl, case 0: ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR; break; -#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1) +#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1) case 1: ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2) +#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2) case 2: ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR; break; #endif -#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3) +#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3) case 3: ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR; break; diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index ef889ea4e6..2ff716c252 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -38,11 +38,6 @@ #define CONFIG_SYS_FPGA_PROG_TIME (CONFIG_SYS_HZ * 4) /* 4 s */ #endif -static int zynq_info(xilinx_desc *desc) -{ - return FPGA_SUCCESS; -} - #define DUMMY_WORD 0xffffffff /* Xilinx binary format header */ @@ -481,16 +476,9 @@ static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize, } #endif -static int zynq_dump(xilinx_desc *desc, const void *buf, size_t bsize) -{ - return FPGA_FAIL; -} - struct xilinx_fpga_op zynq_op = { .load = zynq_load, #if defined(CONFIG_CMD_FPGA_LOADFS) .loadfs = zynq_loadfs, #endif - .dump = zynq_dump, - .info = zynq_info, }; diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index f49f60bb37..ef85a70ed3 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -366,6 +366,7 @@ static const struct dm_i2c_ops cdns_i2c_ops = { static const struct udevice_id cdns_i2c_of_match[] = { { .compatible = "cdns,i2c-r1p10" }, + { .compatible = "cdns,i2c-r1p14" }, { /* end of table */ } }; diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 2ba1254d70..9ed8da39ef 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -68,15 +68,86 @@ config ATMEL_SDHCI It is compliant with the SD Host Controller Standard V3.0 specification. -config ROCKCHIP_DWMMC +config MMC_DAVINCI + bool "TI DAVINCI Multimedia Card Interface support" + depends on ARCH_DAVINCI + default y + help + This selects the TI DAVINCI Multimedia card Interface. + If you have an DAVINCI board with a Multimedia Card slot, + say Y here. If unsure, say N. + +config MMC_DW + bool "Synopsys DesignWare Memory Card Interface" + help + This selects support for the Synopsys DesignWare Mobile Storage IP + block, this provides host support for SD and MMC interfaces, in both + PIO, internal DMA mode and external DMA mode. + +config MMC_DW_EXYNOS + bool "Exynos specific extensions for Synopsys DW Memory Card Interface" + depends on ARCH_EXYNOS + depends on MMC_DW + default y + help + This selects support for Samsung Exynos SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Exynos4 and Exynos5 SoC's. + +config MMC_DW_K3 + bool "K3 specific extensions for Synopsys DW Memory Card Interface" + depends on MMC_DW + help + This selects support for Hisilicon K3 SoC specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Hisilicon K3 SoC's. + +config MMC_DW_ROCKCHIP bool "Rockchip SD/MMC controller support" depends on DM_MMC && OF_CONTROL + depends on MMC_DW help This enables support for the Rockchip SD/MMM controller, which is based on Designware IP. The device is compatible with at least SD 3.0, SDIO 3.0 and MMC 4.5 and supports common eMMC chips as well as removeable SD and micro-SD cards. +config MMC_DW_SOCFPGA + bool "SOCFPGA specific extensions for Synopsys DW Memory Card Interface" + depends on ARCH_SOCFPGA + depends on MMC_DW + default y + help + This selects support for Altera SOCFPGA specific extensions to the + Synopsys DesignWare Memory Card Interface driver. Select this option + for platforms based on Altera SOCFPGA. + +config MMC_MXC + bool "Freescale i.MX21/27/31 or MPC512x Multimedia Card support" + help + This selects the Freescale i.MX21, i.MX27, i.MX31 or MPC512x + Multimedia Card Interface. If you have an i.MX or MPC512x platform + with a Multimedia Card slot, say Y here. + + If unsure, say N. + +config MMC_MXS + bool "Freescale MXS Multimedia Card Interface support" + help + This selects the Freescale SSP MMC controller found on MXS based + platforms like mx23/28. + + If unsure, say N. + +config MMC_OMAP_HS + bool "TI OMAP High Speed Multimedia Card Interface support" + help + This selects the TI OMAP High Speed Multimedia card Interface. + If you have an omap2plus board with a Multimedia Card slot, + say Y here. + + If unsure, say N. + config SH_SDHI bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support" depends on RMOBILE @@ -107,8 +178,8 @@ config ROCKCHIP_SDHCI config MMC_UNIPHIER bool "UniPhier SD/MMC Host Controller support" depends on ARCH_UNIPHIER - depends on BLK - select DM_MMC_OPS + depends on BLK && DM_MMC_OPS + depends on OF_CONTROL help This selects support for the SD/MMC Host Controller on UniPhier SoCs. @@ -159,6 +230,18 @@ config MMC_SDHCI_BCM2835 If unsure, say N. +config MMC_SDHCI_CADENCE + bool "SDHCI support for the Cadence SD/SDIO/eMMC controller" + depends on BLK && DM_MMC_OPS + depends on MMC_SDHCI + depends on OF_CONTROL + help + This selects the Cadence SD/SDIO/eMMC driver. + + If you have a controller with this interface, say Y here. + + If unsure, say N. + config MMC_SDHCI_KONA bool "SDHCI support on Broadcom KONA platform" depends on MMC_SDHCI @@ -204,6 +287,36 @@ config MMC_SDHCI_SPEAR If unsure, say N. +config MMC_SDHCI_TEGRA + bool "SDHCI platform support for the Tegra SD/MMC Controller" + depends on TEGRA + default y + help + This selects the Tegra SD/MMC controller. If you have a Tegra + platform with SD or MMC devices, say Y here. + + If unsure, say N. + +config MMC_SUNXI + bool "Allwinner sunxi SD/MMC Host Controller support" + depends on ARCH_SUNXI && !UART0_PORT_F + default y + help + This selects support for the SD/MMC Host Controller on + Allwinner sunxi SoCs. + endif endmenu + +config SYS_FSL_ERRATUM_ESDHC111 + bool + +config SYS_FSL_ERRATUM_ESDHC13 + bool + +config SYS_FSL_ERRATUM_ESDHC135 + bool + +config SYS_FSL_ERRATUM_ESDHC_A001 + bool diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 2b136ea21e..4dca09c955 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -16,10 +16,13 @@ endif obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o obj-$(CONFIG_ATMEL_SDHCI) += atmel_sdhci.o obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o -obj-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o -obj-$(CONFIG_DWMMC) += dw_mmc.o -obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o -obj-$(CONFIG_HIKEY_DWMMC) += hi6220_dw_mmc.o +obj-$(CONFIG_MMC_DAVINCI) += davinci_mmc.o + +obj-$(CONFIG_MMC_DW) += dw_mmc.o +obj-$(CONFIG_MMC_DW_EXYNOS) += exynos_dw_mmc.o +obj-$(CONFIG_MMC_DW_K3) += hi6220_dw_mmc.o +obj-$(CONFIG_MMC_DW_ROCKCHIP) += rockchip_dw_mmc.o +obj-$(CONFIG_MMC_DW_SOCFPGA) += socfpga_dw_mmc.o obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o @@ -29,14 +32,12 @@ obj-$(CONFIG_GENERIC_MMC) += mmc_boot.o endif obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o -obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o -obj-$(CONFIG_MXC_MMC) += mxcmmc.o -obj-$(CONFIG_MXS_MMC) += mxsmmc.o -obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o +obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o +obj-$(CONFIG_MMC_MXC) += mxcmmc.o +obj-$(CONFIG_MMC_MXS) += mxsmmc.o obj-$(CONFIG_X86) += pci_mmc.o obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o -obj-$(CONFIG_ROCKCHIP_DWMMC) += rockchip_dw_mmc.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o obj-$(CONFIG_S3C_SDI) += s3c_sdi.o ifdef CONFIG_BLK @@ -46,9 +47,6 @@ endif endif obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_SH_SDHI) += sh_sdhi.o -obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o -obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o -obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o obj-$(CONFIG_ROCKCHIP_SDHCI) += rockchip_sdhci.o @@ -64,7 +62,12 @@ obj-$(CONFIG_MSM_SDHCI) += msm_sdhci.o # SDHCI obj-$(CONFIG_MMC_SDHCI) += sdhci.o obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o +obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o obj-$(CONFIG_MMC_SDHCI_KONA) += kona_sdhci.o obj-$(CONFIG_MMC_SDHCI_MV) += mv_sdhci.o obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o +obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o + +obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o +obj-$(CONFIG_MMC_UNIPHIER) += uniphier-sd.o diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index e64ac3c993..ddf8383f1c 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -275,7 +275,7 @@ static int mmc_host_reset(struct mmc *dev) return 0; } -static void host_set_ios(struct mmc *dev) +static int host_set_ios(struct mmc *dev) { struct pl180_mmc_host *host = dev->priv; u32 sdi_clkcr; @@ -333,6 +333,8 @@ static void host_set_ios(struct mmc *dev) writel(sdi_clkcr, &host->base->clock); udelay(CLK_CHANGE_DELAY); + + return 0; } static const struct mmc_ops arm_pl180_mmci_ops = { diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 993a00cdb1..1627dca3a1 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -234,7 +234,7 @@ static void sdh_set_clk(unsigned long clk) bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); } -static void bfin_sdh_set_ios(struct mmc *mmc) +static int bfin_sdh_set_ios(struct mmc *mmc) { u16 cfg = 0; u16 clk_ctl = 0; @@ -250,6 +250,8 @@ static void bfin_sdh_set_ios(struct mmc *mmc) } bfin_write_SDH_CLK_CTL(clk_ctl); sdh_set_clk(mmc->clock); + + return 0; } static int bfin_sdh_init(struct mmc *mmc) diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index b495c7564c..9edb668e14 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -348,7 +348,7 @@ static int dmmc_init(struct mmc *mmc) } /* Set buswidth or clock as indicated by the GENERIC_MMC framework */ -static void dmmc_set_ios(struct mmc *mmc) +static int dmmc_set_ios(struct mmc *mmc) { struct davinci_mmc *host = mmc->priv; struct davinci_mmc_regs *regs = host->reg_base; @@ -362,6 +362,8 @@ static void dmmc_set_ios(struct mmc *mmc) /* Set clock speed */ if (mmc->clock) dmmc_set_clock(mmc, mmc->clock); + + return 0; } static const struct mmc_ops dmmc_ops = { diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index d6ac46c1e0..700f764432 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -388,7 +388,7 @@ static int dwmci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); #else -static void dwmci_set_ios(struct mmc *mmc) +static int dwmci_set_ios(struct mmc *mmc) { #endif struct dwmci_host *host = (struct dwmci_host *)mmc->priv; @@ -421,9 +421,8 @@ static void dwmci_set_ios(struct mmc *mmc) if (host->clksel) host->clksel(host); -#ifdef CONFIG_DM_MMC_OPS + return 0; -#endif } static int dwmci_init(struct mmc *mmc) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 9796d39c65..7defeb4f2a 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -592,7 +592,7 @@ static void esdhc_clock_control(struct mmc *mmc, bool enable) } #endif -static void esdhc_set_ios(struct mmc *mmc) +static int esdhc_set_ios(struct mmc *mmc) { struct fsl_esdhc_priv *priv = mmc->priv; struct fsl_esdhc *regs = priv->esdhc_regs; @@ -614,6 +614,7 @@ static void esdhc_set_ios(struct mmc *mmc) else if (mmc->bus_width == 8) esdhc_setbits32(®s->proctl, PROCTL_DTW_8); + return 0; } static int esdhc_init(struct mmc *mmc) diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index e88c6322e9..652a718467 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -251,7 +251,7 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static void ftsdc010_set_ios(struct mmc *mmc) +static int ftsdc010_set_ios(struct mmc *mmc) { struct ftsdc010_chip *chip = mmc->priv; struct ftsdc010_mmc __iomem *regs = chip->regs; @@ -270,6 +270,8 @@ static void ftsdc010_set_ios(struct mmc *mmc) setbits_le32(®s->bwr, FTSDC010_BWR_MODE_1BIT); break; } + + return 0; } static int ftsdc010_init(struct mmc *mmc) diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index cca0b04a60..7dc4a5de74 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -336,7 +336,7 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) } /* Entered into mmc structure during driver init */ -static void mci_set_ios(struct mmc *mmc) +static int mci_set_ios(struct mmc *mmc) { struct atmel_mci_priv *priv = mmc->priv; atmel_mci_t *mci = priv->mci; @@ -370,6 +370,8 @@ static void mci_set_ios(struct mmc *mmc) writel(busw << 7 | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr); } + + return 0; } /* Entered into mmc structure during driver init */ diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index 25101179f6..a9d95fbd74 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -236,13 +236,14 @@ done: return ret; } -static void mmc_spi_set_ios(struct mmc *mmc) +static int mmc_spi_set_ios(struct mmc *mmc) { struct spi_slave *spi = mmc->priv; debug("%s: clock %u\n", __func__, mmc->clock); if (mmc->clock) spi_set_speed(spi, mmc->clock); + return 0; } static int mmc_spi_init_p(struct mmc *mmc) diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index a2792ac4ec..3c7fb2130e 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -316,12 +316,14 @@ static void mvebu_mmc_set_bus(unsigned int bus) mvebu_mmc_write(SDIO_HOST_CTRL, ctrl_reg); } -static void mvebu_mmc_set_ios(struct mmc *mmc) +static int mvebu_mmc_set_ios(struct mmc *mmc) { debug("%s: bus[%d] clock[%d]\n", DRIVER_NAME, mmc->bus_width, mmc->clock); mvebu_mmc_set_bus(mmc->bus_width); mvebu_mmc_set_clk(mmc->clock); + + return 0; } /* diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index 5a385a37f8..dcf17c5d60 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -448,7 +448,7 @@ static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios) writel((prescaler << 4) | divider, &host->base->clk_rate); } -static void mxcmci_set_ios(struct mmc *mmc) +static int mxcmci_set_ios(struct mmc *mmc) { struct mxcmci_host *host = mmc->priv; if (mmc->bus_width == 4) @@ -464,6 +464,8 @@ static void mxcmci_set_ios(struct mmc *mmc) } host->clock = mmc->clock; + + return 0; } static int mxcmci_init(struct mmc *mmc) diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 0896028403..fe1fe707a5 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -304,7 +304,7 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) return 0; } -static void mxsmmc_set_ios(struct mmc *mmc) +static int mxsmmc_set_ios(struct mmc *mmc) { struct mxsmmc_priv *priv = mmc->priv; struct mxs_ssp_regs *ssp_regs = priv->regs; @@ -331,6 +331,8 @@ static void mxsmmc_set_ios(struct mmc *mmc) debug("MMC%d: Set %d bits bus width\n", mmc->block_dev.devnum, mmc->bus_width); + + return 0; } static int mxsmmc_init(struct mmc *mmc) diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 0a1ee407a1..b3268467dc 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -511,7 +511,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, return 0; } -static void omap_hsmmc_set_ios(struct mmc *mmc) +static int omap_hsmmc_set_ios(struct mmc *mmc) { struct hsmmc *mmc_base; unsigned int dsor = 0; @@ -559,10 +559,12 @@ static void omap_hsmmc_set_ios(struct mmc *mmc) while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for ics!\n", __func__); - return; + return -ETIMEDOUT; } } writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); + + return 0; } #ifdef OMAP_HSMMC_USE_GPIO diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c index 2abf943bdb..c06364cfc1 100644 --- a/drivers/mmc/pic32_sdhci.c +++ b/drivers/mmc/pic32_sdhci.c @@ -15,6 +15,20 @@ DECLARE_GLOBAL_DATA_PTR; +static int pic32_sdhci_get_cd(struct sdhci_host *host) +{ + /* PIC32 SDHCI CD errata: + * - set CD_TEST and clear CD_TEST_INS bit + */ + sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL); + + return 0; +} + +static const struct sdhci_ops pic32_sdhci_ops = { + .get_cd = pic32_sdhci_get_cd, +}; + static int pic32_sdhci_probe(struct udevice *dev) { struct sdhci_host *host = dev_get_priv(dev); @@ -30,9 +44,10 @@ static int pic32_sdhci_probe(struct udevice *dev) host->ioaddr = ioremap(addr, size); host->name = dev->name; - host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_NO_CD; + host->quirks = SDHCI_QUIRK_NO_HISPD_BIT; host->bus_width = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 4); + host->ops = &pic32_sdhci_ops; ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clock-freq-min-max", f_min_max, 2); diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index a5462e2148..f627553cac 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -313,7 +313,7 @@ static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, return 0; } -static void pxa_mmc_set_ios(struct mmc *mmc) +static int pxa_mmc_set_ios(struct mmc *mmc) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; @@ -322,13 +322,13 @@ static void pxa_mmc_set_ios(struct mmc *mmc) if (!mmc->clock) { pxa_mmc_stop_clock(mmc); - return; + return 0; } /* PXA3xx can do 26MHz with special settings. */ if (mmc->clock == 26000000) { writel(0x7, ®s->clkrt); - return; + return 0; } /* Set clock to the card the usual way. */ @@ -342,6 +342,8 @@ static void pxa_mmc_set_ios(struct mmc *mmc) } writel(pxa_mmc_clock, ®s->clkrt); + + return 0; } static int pxa_mmc_init(struct mmc *mmc) diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c index c56e1a3a1c..e33e35e4fa 100644 --- a/drivers/mmc/rockchip_sdhci.c +++ b/drivers/mmc/rockchip_sdhci.c @@ -12,7 +12,9 @@ #include <libfdt.h> #include <malloc.h> #include <sdhci.h> +#include <clk.h> +DECLARE_GLOBAL_DATA_PTR; /* 400KHz is max freq for card ID etc. Use that as min */ #define EMMC_MIN_FREQ 400000 @@ -32,11 +34,24 @@ static int arasan_sdhci_probe(struct udevice *dev) struct rockchip_sdhc_plat *plat = dev_get_platdata(dev); struct rockchip_sdhc *prv = dev_get_priv(dev); struct sdhci_host *host = &prv->host; - int ret; + int max_frequency, ret; + struct clk clk; + + + max_frequency = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "max-frequency", 0); + ret = clk_get_by_index(dev, 0, &clk); + if (!ret) { + ret = clk_set_rate(&clk, max_frequency); + if (IS_ERR_VALUE(ret)) + printf("%s clk set rate fail!\n", __func__); + } else { + printf("%s fail to get clk\n", __func__); + } host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD; - ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ROCKCHIP_SDHCI_MAX_FREQ, + ret = sdhci_setup_cfg(&plat->cfg, host, max_frequency, EMMC_MIN_FREQ); host->mmc = &plat->mmc; diff --git a/drivers/mmc/s3c_sdi.c b/drivers/mmc/s3c_sdi.c index 1b8358a7bc..faf7b83a14 100644 --- a/drivers/mmc/s3c_sdi.c +++ b/drivers/mmc/s3c_sdi.c @@ -207,7 +207,7 @@ error: return ret; } -static void s3cmmc_set_ios(struct mmc *mmc) +static int s3cmmc_set_ios(struct mmc *mmc) { struct s3c24x0_sdi *sdi_regs = s3c24x0_get_base_sdi(); uint32_t divider = 0; @@ -215,7 +215,7 @@ static void s3cmmc_set_ios(struct mmc *mmc) wide_bus = (mmc->bus_width == 4); if (!mmc->clock) - return; + return 0; divider = DIV_ROUND_UP(get_PCLK(), mmc->clock); if (divider) @@ -223,6 +223,8 @@ static void s3cmmc_set_ios(struct mmc *mmc) writel(divider, &sdi_regs->sdipre); mdelay(125); + + return 0; } static int s3cmmc_init(struct mmc *mmc) diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index ac737e0f0f..1f1d2ed865 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -73,6 +73,17 @@ static void s5p_sdhci_set_control_reg(struct sdhci_host *host) sdhci_writel(host, ctrl, SDHCI_CONTROL2); } +static void s5p_set_clock(struct sdhci_host *host, u32 div) +{ + /* ToDo : Use the Clock Framework */ + set_mmc_clk(host->index, div); +} + +static const struct sdhci_ops s5p_sdhci_ops = { + .set_clock = &s5p_set_clock, + .set_control_reg = &s5p_sdhci_set_control_reg, +}; + static int s5p_sdhci_core_init(struct sdhci_host *host) { host->name = S5P_NAME; @@ -81,9 +92,7 @@ static int s5p_sdhci_core_init(struct sdhci_host *host) SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_USE_WIDE8; host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; - - host->set_control_reg = &s5p_sdhci_set_control_reg; - host->set_clock = set_mmc_clk; + host->ops = &s5p_sdhci_ops; if (host->bus_width == 8) host->host_caps |= MMC_MODE_8BIT; diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c new file mode 100644 index 0000000000..2253bbc518 --- /dev/null +++ b/drivers/mmc/sdhci-cadence.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <dm/device.h> +#include <mmc.h> +#include <sdhci.h> + +/* HRS - Host Register Set (specific to Cadence) */ +#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */ +#define SDHCI_CDNS_HRS04_ACK BIT(26) +#define SDHCI_CDNS_HRS04_RD BIT(25) +#define SDHCI_CDNS_HRS04_WR BIT(24) +#define SDHCI_CDNS_HRS04_RDATA_SHIFT 12 +#define SDHCI_CDNS_HRS04_WDATA_SHIFT 8 +#define SDHCI_CDNS_HRS04_ADDR_SHIFT 0 + +/* SRS - Slot Register Set (SDHCI-compatible) */ +#define SDHCI_CDNS_SRS_BASE 0x200 + +/* PHY */ +#define SDHCI_CDNS_PHY_DLY_SD_HS 0x00 +#define SDHCI_CDNS_PHY_DLY_SD_DEFAULT 0x01 +#define SDHCI_CDNS_PHY_DLY_UHS_SDR12 0x02 +#define SDHCI_CDNS_PHY_DLY_UHS_SDR25 0x03 +#define SDHCI_CDNS_PHY_DLY_UHS_SDR50 0x04 +#define SDHCI_CDNS_PHY_DLY_UHS_DDR50 0x05 +#define SDHCI_CDNS_PHY_DLY_EMMC_LEGACY 0x06 +#define SDHCI_CDNS_PHY_DLY_EMMC_SDR 0x07 +#define SDHCI_CDNS_PHY_DLY_EMMC_DDR 0x08 + +struct sdhci_cdns_plat { + struct mmc_config cfg; + struct mmc mmc; + void __iomem *hrs_addr; +}; + +static void sdhci_cdns_write_phy_reg(struct sdhci_cdns_plat *plat, + u8 addr, u8 data) +{ + void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS04; + u32 tmp; + + tmp = (data << SDHCI_CDNS_HRS04_WDATA_SHIFT) | + (addr << SDHCI_CDNS_HRS04_ADDR_SHIFT); + writel(tmp, reg); + + tmp |= SDHCI_CDNS_HRS04_WR; + writel(tmp, reg); + + tmp &= ~SDHCI_CDNS_HRS04_WR; + writel(tmp, reg); +} + +static void sdhci_cdns_phy_init(struct sdhci_cdns_plat *plat) +{ + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_SD_HS, 4); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_SD_DEFAULT, 4); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_EMMC_LEGACY, 9); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_EMMC_SDR, 2); + sdhci_cdns_write_phy_reg(plat, SDHCI_CDNS_PHY_DLY_EMMC_DDR, 3); +} + +static int sdhci_cdns_bind(struct udevice *dev) +{ + struct sdhci_cdns_plat *plat = dev_get_platdata(dev); + + return sdhci_bind(dev, &plat->mmc, &plat->cfg); +} + +static int sdhci_cdns_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct sdhci_cdns_plat *plat = dev_get_platdata(dev); + struct sdhci_host *host = dev_get_priv(dev); + fdt_addr_t base; + int ret; + + base = dev_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->hrs_addr = devm_ioremap(dev, base, SZ_1K); + if (!plat->hrs_addr) + return -ENOMEM; + + host->name = dev->name; + host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE; + host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD; + + sdhci_cdns_phy_init(plat); + + ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0); + if (ret) + return ret; + + upriv->mmc = &plat->mmc; + host->mmc = &plat->mmc; + host->mmc->priv = host; + + return sdhci_probe(dev); +} + +static const struct udevice_id sdhci_cdns_match[] = { + { .compatible = "socionext,uniphier-sd4hc" }, + { .compatible = "cdns,sd4hc" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sdhci_cdns) = { + .name = "sdhci-cdns", + .id = UCLASS_MMC, + .of_match = sdhci_cdns_match, + .bind = sdhci_cdns_bind, + .probe = sdhci_cdns_probe, + .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct sdhci_cdns_plat), + .ops = &sdhci_ops, +}; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index cbf5f56221..5b404ff4a3 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -359,8 +359,8 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) div >>= 1; } - if (host->set_clock) - host->set_clock(host->index, div); + if (host->ops && host->ops->set_clock) + host->ops->set_clock(host, div); clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) @@ -411,9 +411,6 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) return; } - if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) - sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); - pwr |= SDHCI_POWER_ON; sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); @@ -424,14 +421,14 @@ static int sdhci_set_ios(struct udevice *dev) { struct mmc *mmc = mmc_get_mmc_dev(dev); #else -static void sdhci_set_ios(struct mmc *mmc) +static int sdhci_set_ios(struct mmc *mmc) { #endif u32 ctrl; struct sdhci_host *host = mmc->priv; - if (host->set_control_reg) - host->set_control_reg(host); + if (host->ops && host->ops->set_control_reg) + host->ops->set_control_reg(host); if (mmc->clock != host->clock) sdhci_set_clock(mmc, mmc->clock); @@ -462,9 +459,8 @@ static void sdhci_set_ios(struct mmc *mmc) ctrl &= ~SDHCI_CTRL_HISPD; sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); -#ifdef CONFIG_DM_MMC_OPS + return 0; -#endif } static int sdhci_init(struct mmc *mmc) @@ -484,25 +480,8 @@ static int sdhci_init(struct mmc *mmc) sdhci_set_power(host, fls(mmc->cfg->voltages) - 1); - if (host->quirks & SDHCI_QUIRK_NO_CD) { -#if defined(CONFIG_PIC32_SDHCI) - /* PIC32 SDHCI CD errata: - * - set CD_TEST and clear CD_TEST_INS bit - */ - sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL); -#else - unsigned int status; - - sdhci_writeb(host, SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST, - SDHCI_HOST_CONTROL); - - status = sdhci_readl(host, SDHCI_PRESENT_STATE); - while ((!(status & SDHCI_CARD_PRESENT)) || - (!(status & SDHCI_CARD_STATE_STABLE)) || - (!(status & SDHCI_CARD_DETECT_PIN_LEVEL))) - status = sdhci_readl(host, SDHCI_PRESENT_STATE); -#endif - } + if (host->ops && host->ops->get_cd) + host->ops->get_cd(host); /* Enable only interrupts served by the SD controller */ sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK, @@ -593,27 +572,23 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, cfg->voltages |= host->voltages; cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; + + /* Since Host Controller Version3.0 */ if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { - if (caps & SDHCI_CAN_DO_8BIT) - cfg->host_caps |= MMC_MODE_8BIT; + if (!(caps & SDHCI_CAN_DO_8BIT)) + cfg->host_caps &= ~MMC_MODE_8BIT; + + /* Find out whether clock multiplier is supported */ + caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); + host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> + SDHCI_CLOCK_MUL_SHIFT; } if (host->host_caps) cfg->host_caps |= host->host_caps; - cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - /* - * In case of Host Controller v3.00, find out whether clock - * multiplier is supported. - */ - if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { - caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); - host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> - SDHCI_CLOCK_MUL_SHIFT; - } - return 0; } diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 69ded9ee2c..1ff59f06d5 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -539,7 +539,7 @@ static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static void sh_mmcif_set_ios(struct mmc *mmc) +static int sh_mmcif_set_ios(struct mmc *mmc) { struct sh_mmcif_host *host = mmc->priv; @@ -554,6 +554,8 @@ static void sh_mmcif_set_ios(struct mmc *mmc) host->bus_width = MMC_BUS_WIDTH_1; debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); + + return 0; } static int sh_mmcif_init(struct mmc *mmc) diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c index 78e2ef643c..25224e2e1d 100644 --- a/drivers/mmc/sh_sdhi.c +++ b/drivers/mmc/sh_sdhi.c @@ -608,14 +608,14 @@ static int sh_sdhi_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, return ret; } -static void sh_sdhi_set_ios(struct mmc *mmc) +static int sh_sdhi_set_ios(struct mmc *mmc) { int ret; struct sh_sdhi_host *host = mmc_priv(mmc); ret = sh_sdhi_clock_control(host, mmc->clock); if (ret) - return; + return -EINVAL; if (mmc->bus_width == 4) sh_sdhi_writew(host, SDHI_OPTION, ~OPT_BUS_WIDTH_1 & @@ -625,6 +625,8 @@ static void sh_sdhi_set_ios(struct mmc *mmc) sh_sdhi_readw(host, SDHI_OPTION)); debug("clock = %d, buswidth = %d\n", mmc->clock, mmc->bus_width); + + return 0; } static int sh_sdhi_initialize(struct mmc *mmc) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index b8716c93cb..fd3fc2af40 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -227,7 +227,7 @@ static int mmc_config_clock(struct mmc *mmc) return 0; } -static void sunxi_mmc_set_ios(struct mmc *mmc) +static int sunxi_mmc_set_ios(struct mmc *mmc) { struct sunxi_mmc_host *mmchost = mmc->priv; @@ -237,7 +237,7 @@ static void sunxi_mmc_set_ios(struct mmc *mmc) /* Change clock first */ if (mmc->clock && mmc_config_clock(mmc) != 0) { mmchost->fatal_err = 1; - return; + return -EINVAL; } /* Change bus width */ @@ -247,6 +247,8 @@ static void sunxi_mmc_set_ios(struct mmc *mmc) writel(0x1, &mmchost->reg->width); else writel(0x0, &mmchost->reg->width); + + return 0; } static int sunxi_mmc_core_init(struct mmc *mmc) diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 97b1154595..0211dc7b80 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -408,7 +408,7 @@ out: priv->clock = clock; } -static void tegra_mmc_set_ios(struct mmc *mmc) +static int tegra_mmc_set_ios(struct mmc *mmc) { struct tegra_mmc_priv *priv = mmc->priv; unsigned char ctrl; @@ -438,6 +438,8 @@ static void tegra_mmc_set_ios(struct mmc *mmc) writeb(ctrl, &priv->reg->hostctl); debug("mmc_set_ios: hostctl = %08X\n", ctrl); + + return 0; } static void tegra_mmc_pad_init(struct tegra_mmc_priv *priv) diff --git a/drivers/mtd/nand/mxs_nand_spl.c b/drivers/mtd/nand/mxs_nand_spl.c index ff28df4c19..b6c9208140 100644 --- a/drivers/mtd/nand/mxs_nand_spl.c +++ b/drivers/mtd/nand/mxs_nand_spl.c @@ -153,7 +153,7 @@ static int mxs_nand_init(void) nand_chip.numchips = 1; /* identify flash device */ - puts("NAND : "); + puts(": "); if (mxs_flash_ident(mtd)) { printf("Failed to identify\n"); return -1; diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index d1e1bdda28..f4f0de395b 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -656,14 +656,14 @@ static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data, struct nand_chip *chip = mtd_to_nand(mtd); struct omap_nand_info *info = nand_get_controller_data(chip); - count = decode_bch(info->control, NULL, 512, read_ecc, calc_ecc, - NULL, errloc); + count = decode_bch(info->control, NULL, SECTOR_BYTES, + read_ecc, calc_ecc, NULL, errloc); if (count > 0) { /* correct errors */ for (i = 0; i < count; i++) { /* correct data only, not ecc bytes */ - if (errloc[i] < 8*512) - data[errloc[i]/8] ^= 1 << (errloc[i] & 7); + if (errloc[i] < SECTOR_BYTES << 3) + data[errloc[i] >> 3] ^= 1 << (errloc[i] & 7); debug("corrected bitflip %u\n", errloc[i]); #ifdef DEBUG puts("read_ecc: "); diff --git a/drivers/mtd/spi/sunxi_spi_spl.c b/drivers/mtd/spi/sunxi_spi_spl.c index e70064c677..a24c115174 100644 --- a/drivers/mtd/spi/sunxi_spi_spl.c +++ b/drivers/mtd/spi/sunxi_spi_spl.c @@ -284,4 +284,4 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, return 0; } /* Use priorty 0 to override the default if it happens to be linked in */ -SPL_LOAD_IMAGE_METHOD("sunxi SPI" 0, BOOT_DEVICE_SPI, spl_spi_load_image); +SPL_LOAD_IMAGE_METHOD("sunxi SPI", 0, BOOT_DEVICE_SPI, spl_spi_load_image); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 929b9e273e..f52629fa53 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -215,4 +215,11 @@ config PIC32_ETH This driver implements 10/100 Mbps Ethernet and MAC layer for Microchip PIC32 microcontrollers. +config GMAC_ROCKCHIP + bool "Rockchip Synopsys Designware Ethernet MAC" + depends on DM_ETH && ETH_DESIGNWARE + help + This driver provides Rockchip SoCs network support based on the + Synopsys Designware driver. + endif # NETDEVICES diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 9a7bfc6d5b..2493a48b88 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_FTGMAC100) += ftgmac100.o obj-$(CONFIG_FTMAC110) += ftmac110.o obj-$(CONFIG_FTMAC100) += ftmac100.o obj-$(CONFIG_GRETH) += greth.o +obj-$(CONFIG_GMAC_ROCKCHIP) += gmac_rockchip.o obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o obj-$(CONFIG_LAN91C96) += lan91c96.o diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 9e6d726184..f242fc6b3f 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -230,14 +230,14 @@ static int _dw_write_hwaddr(struct dw_eth_dev *priv, u8 *mac_id) return 0; } -static void dw_adjust_link(struct eth_mac_regs *mac_p, - struct phy_device *phydev) +static int dw_adjust_link(struct dw_eth_dev *priv, struct eth_mac_regs *mac_p, + struct phy_device *phydev) { u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN; if (!phydev->link) { printf("%s: No link.\n", phydev->dev->name); - return; + return 0; } if (phydev->speed != 1000) @@ -256,6 +256,8 @@ static void dw_adjust_link(struct eth_mac_regs *mac_p, printf("Speed: %d, %s duplex%s\n", phydev->speed, (phydev->duplex) ? "full" : "half", (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); + + return 0; } static void _dw_eth_halt(struct dw_eth_dev *priv) @@ -269,7 +271,7 @@ static void _dw_eth_halt(struct dw_eth_dev *priv) phy_shutdown(priv->phydev); } -static int _dw_eth_init(struct dw_eth_dev *priv, u8 *enetaddr) +int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr) { struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; @@ -321,7 +323,16 @@ static int _dw_eth_init(struct dw_eth_dev *priv, u8 *enetaddr) return ret; } - dw_adjust_link(mac_p, priv->phydev); + ret = dw_adjust_link(priv, mac_p, priv->phydev); + if (ret) + return ret; + + return 0; +} + +int designware_eth_enable(struct dw_eth_dev *priv) +{ + struct eth_mac_regs *mac_p = priv->mac_regs_p; if (!priv->phydev->link) return -EIO; @@ -480,7 +491,13 @@ static int dw_phy_init(struct dw_eth_dev *priv, void *dev) #ifndef CONFIG_DM_ETH static int dw_eth_init(struct eth_device *dev, bd_t *bis) { - return _dw_eth_init(dev->priv, dev->enetaddr); + int ret; + + ret = designware_eth_init(dev->priv, dev->enetaddr); + if (!ret) + ret = designware_eth_enable(dev->priv); + + return ret; } static int dw_eth_send(struct eth_device *dev, void *packet, int length) @@ -571,40 +588,48 @@ int designware_initialize(ulong base_addr, u32 interface) static int designware_eth_start(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); + struct dw_eth_dev *priv = dev_get_priv(dev); + int ret; - return _dw_eth_init(dev->priv, pdata->enetaddr); + ret = designware_eth_init(priv, pdata->enetaddr); + if (ret) + return ret; + ret = designware_eth_enable(priv); + if (ret) + return ret; + + return 0; } -static int designware_eth_send(struct udevice *dev, void *packet, int length) +int designware_eth_send(struct udevice *dev, void *packet, int length) { struct dw_eth_dev *priv = dev_get_priv(dev); return _dw_eth_send(priv, packet, length); } -static int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp) +int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp) { struct dw_eth_dev *priv = dev_get_priv(dev); return _dw_eth_recv(priv, packetp); } -static int designware_eth_free_pkt(struct udevice *dev, uchar *packet, - int length) +int designware_eth_free_pkt(struct udevice *dev, uchar *packet, int length) { struct dw_eth_dev *priv = dev_get_priv(dev); return _dw_free_pkt(priv); } -static void designware_eth_stop(struct udevice *dev) +void designware_eth_stop(struct udevice *dev) { struct dw_eth_dev *priv = dev_get_priv(dev); return _dw_eth_halt(priv); } -static int designware_eth_write_hwaddr(struct udevice *dev) +int designware_eth_write_hwaddr(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct dw_eth_dev *priv = dev_get_priv(dev); @@ -628,7 +653,7 @@ static int designware_eth_bind(struct udevice *dev) return 0; } -static int designware_eth_probe(struct udevice *dev) +int designware_eth_probe(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct dw_eth_dev *priv = dev_get_priv(dev); @@ -678,7 +703,7 @@ static int designware_eth_remove(struct udevice *dev) return 0; } -static const struct eth_ops designware_eth_ops = { +const struct eth_ops designware_eth_ops = { .start = designware_eth_start, .send = designware_eth_send, .recv = designware_eth_recv, @@ -687,7 +712,7 @@ static const struct eth_ops designware_eth_ops = { .write_hwaddr = designware_eth_write_hwaddr, }; -static int designware_eth_ofdata_to_platdata(struct udevice *dev) +int designware_eth_ofdata_to_platdata(struct udevice *dev) { struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); #ifdef CONFIG_DM_GPIO diff --git a/drivers/net/designware.h b/drivers/net/designware.h index d345c5b0c3..7992d0ebee 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -245,10 +245,23 @@ struct dw_eth_dev { }; #ifdef CONFIG_DM_ETH +int designware_eth_ofdata_to_platdata(struct udevice *dev); +int designware_eth_probe(struct udevice *dev); +extern const struct eth_ops designware_eth_ops; + struct dw_eth_pdata { struct eth_pdata eth_pdata; u32 reset_delays[3]; }; + +int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr); +int designware_eth_enable(struct dw_eth_dev *priv); +int designware_eth_send(struct udevice *dev, void *packet, int length); +int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp); +int designware_eth_free_pkt(struct udevice *dev, uchar *packet, + int length); +void designware_eth_stop(struct udevice *dev); +int designware_eth_write_hwaddr(struct udevice *dev); #endif #endif diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index 08b3f27601..fa96bad902 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -26,8 +26,6 @@ obj-$(CONFIG_ARCH_P5020) += p5020.o obj-$(CONFIG_ARCH_P5040) += p5040.o obj-$(CONFIG_ARCH_T1040) += t1040.o obj-$(CONFIG_ARCH_T1042) += t1040.o -obj-$(CONFIG_PPC_T1020) += t1040.o -obj-$(CONFIG_PPC_T1022) += t1040.o obj-$(CONFIG_ARCH_T1023) += t1024.o obj-$(CONFIG_ARCH_T1024) += t1024.o obj-$(CONFIG_ARCH_T2080) += t2080.o diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c new file mode 100644 index 0000000000..5f833fa711 --- /dev/null +++ b/drivers/net/gmac_rockchip.c @@ -0,0 +1,154 @@ +/* + * (C) Copyright 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Rockchip GMAC ethernet IP driver for U-Boot + */ + +#include <common.h> +#include <dm.h> +#include <clk.h> +#include <phy.h> +#include <syscon.h> +#include <asm/io.h> +#include <asm/arch/periph.h> +#include <asm/arch/clock.h> +#include <asm/arch/grf_rk3288.h> +#include <dm/pinctrl.h> +#include <dt-bindings/clock/rk3288-cru.h> +#include "designware.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Platform data for the gmac + * + * dw_eth_pdata: Required platform data for designware driver (must be first) + */ +struct gmac_rockchip_platdata { + struct dw_eth_pdata dw_eth_pdata; + int tx_delay; + int rx_delay; +}; + +static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev) +{ + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + + pdata->tx_delay = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "tx-delay", 0x30); + pdata->rx_delay = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "rx-delay", 0x10); + + return designware_eth_ofdata_to_platdata(dev); +} + +static int gmac_rockchip_fix_mac_speed(struct dw_eth_dev *priv) +{ + struct rk3288_grf *grf; + int clk; + + switch (priv->phydev->speed) { + case 10: + clk = GMAC_CLK_SEL_2_5M; + break; + case 100: + clk = GMAC_CLK_SEL_25M; + break; + case 1000: + clk = GMAC_CLK_SEL_125M; + break; + default: + debug("Unknown phy speed: %d\n", priv->phydev->speed); + return -EINVAL; + } + + grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + rk_clrsetreg(&grf->soc_con1, + GMAC_CLK_SEL_MASK << GMAC_CLK_SEL_SHIFT, + clk << GMAC_CLK_SEL_SHIFT); + + return 0; +} + +static int gmac_rockchip_probe(struct udevice *dev) +{ + struct gmac_rockchip_platdata *pdata = dev_get_platdata(dev); + struct rk3288_grf *grf; + struct clk clk; + int ret; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return ret; + + /* Since mac_clk is fed by an external clock we can use 0 here */ + ret = clk_set_rate(&clk, 0); + if (ret) + return ret; + + /* Set to RGMII mode */ + grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + rk_clrsetreg(&grf->soc_con1, + RMII_MODE_MASK << RMII_MODE_SHIFT | + GMAC_PHY_INTF_SEL_MASK << GMAC_PHY_INTF_SEL_SHIFT, + GMAC_PHY_INTF_SEL_RGMII << GMAC_PHY_INTF_SEL_SHIFT); + + rk_clrsetreg(&grf->soc_con3, + RXCLK_DLY_ENA_GMAC_MASK << RXCLK_DLY_ENA_GMAC_SHIFT | + TXCLK_DLY_ENA_GMAC_MASK << TXCLK_DLY_ENA_GMAC_SHIFT | + CLK_RX_DL_CFG_GMAC_MASK << CLK_RX_DL_CFG_GMAC_SHIFT | + CLK_TX_DL_CFG_GMAC_MASK << CLK_TX_DL_CFG_GMAC_SHIFT, + RXCLK_DLY_ENA_GMAC_ENABLE << RXCLK_DLY_ENA_GMAC_SHIFT | + TXCLK_DLY_ENA_GMAC_ENABLE << TXCLK_DLY_ENA_GMAC_SHIFT | + pdata->rx_delay << CLK_RX_DL_CFG_GMAC_SHIFT | + pdata->tx_delay << CLK_TX_DL_CFG_GMAC_SHIFT); + + return designware_eth_probe(dev); +} + +static int gmac_rockchip_eth_start(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + struct dw_eth_dev *priv = dev_get_priv(dev); + int ret; + + ret = designware_eth_init(priv, pdata->enetaddr); + if (ret) + return ret; + ret = gmac_rockchip_fix_mac_speed(priv); + if (ret) + return ret; + ret = designware_eth_enable(priv); + if (ret) + return ret; + + return 0; +} + +const struct eth_ops gmac_rockchip_eth_ops = { + .start = gmac_rockchip_eth_start, + .send = designware_eth_send, + .recv = designware_eth_recv, + .free_pkt = designware_eth_free_pkt, + .stop = designware_eth_stop, + .write_hwaddr = designware_eth_write_hwaddr, +}; + +static const struct udevice_id rockchip_gmac_ids[] = { + { .compatible = "rockchip,rk3288-gmac" }, + { } +}; + +U_BOOT_DRIVER(eth_gmac_rockchip) = { + .name = "gmac_rockchip", + .id = UCLASS_ETH, + .of_match = rockchip_gmac_ids, + .ofdata_to_platdata = gmac_rockchip_ofdata_to_platdata, + .probe = gmac_rockchip_probe, + .ops = &gmac_rockchip_eth_ops, + .priv_auto_alloc_size = sizeof(struct dw_eth_dev), + .platdata_auto_alloc_size = sizeof(struct gmac_rockchip_platdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; diff --git a/drivers/net/phy/xilinx_phy.c b/drivers/net/phy/xilinx_phy.c index f3eaf2e97c..920bfcb380 100644 --- a/drivers/net/phy/xilinx_phy.c +++ b/drivers/net/phy/xilinx_phy.c @@ -101,11 +101,11 @@ static int xilinxphy_startup(struct phy_device *phydev) static int xilinxphy_of_init(struct phy_device *phydev) { - struct udevice *dev = (struct udevice *)&phydev->dev; u32 phytype; debug("%s\n", __func__); - phytype = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "phy-type", -1); + phytype = fdtdec_get_int(gd->fdt_blob, phydev->dev->of_offset, + "phy-type", -1); if (phytype == XAE_PHY_TYPE_1000BASE_X) phydev->flags |= XAE_PHY_TYPE_1000BASE_X; diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index d2e5e7c7cd..6dd87cf28f 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include <clk.h> #include <common.h> #include <dm.h> #include <net.h> @@ -181,35 +182,22 @@ struct zynq_gem_priv { struct phy_device *phydev; int phy_of_handle; struct mii_dev *bus; +#ifdef CONFIG_CLK_ZYNQMP + struct clk clk; +#endif }; -static inline int mdio_wait(struct zynq_gem_regs *regs) -{ - u32 timeout = 20000; - - /* Wait till MDIO interface is ready to accept a new transaction. */ - while (--timeout) { - if (readl(®s->nwsr) & ZYNQ_GEM_NWSR_MDIOIDLE_MASK) - break; - WATCHDOG_RESET(); - } - - if (!timeout) { - printf("%s: Timeout\n", __func__); - return 1; - } - - return 0; -} - static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum, u32 op, u16 *data) { u32 mgtcr; struct zynq_gem_regs *regs = priv->iobase; + int err; - if (mdio_wait(regs)) - return 1; + err = wait_for_bit(__func__, ®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK, + true, 20000, true); + if (err) + return err; /* Construct mgtcr mask for the operation */ mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op | @@ -219,8 +207,10 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum, /* Write mgtcr and wait for completion */ writel(mgtcr, ®s->phymntnc); - if (mdio_wait(regs)) - return 1; + err = wait_for_bit(__func__, ®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK, + true, 20000, true); + if (err) + return err; if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) *data = readl(®s->phymntnc); @@ -469,8 +459,14 @@ static int zynq_gem_init(struct udevice *dev) /* Change the rclk and clk only not using EMIO interface */ if (!priv->emio) +#ifndef CONFIG_CLK_ZYNQMP zynq_slcr_gem_clk_setup((ulong)priv->iobase != ZYNQ_GEM_BASEADDR0, clk_rate); +#else + ret = clk_set_rate(&priv->clk, clk_rate); + if (IS_ERR_VALUE(ret)) + return -1; +#endif setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_RXEN_MASK | ZYNQ_GEM_NWCTRL_TXEN_MASK); @@ -643,6 +639,14 @@ static int zynq_gem_probe(struct udevice *dev) priv->tx_bd = (struct emac_bd *)bd_space; priv->rx_bd = (struct emac_bd *)((ulong)bd_space + BD_SEPRN_SPACE); +#ifdef CONFIG_CLK_ZYNQMP + ret = clk_get_by_name(dev, "tx_clk", &priv->clk); + if (ret < 0) { + dev_err(dev, "failed to get clock\n"); + return -EINVAL; + } +#endif + priv->bus = mdio_alloc(); priv->bus->read = zynq_gem_miiphy_read; priv->bus->write = zynq_gem_miiphy_write; diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index ff2c37006e..275b29bc32 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -9,7 +9,7 @@ menuconfig PCI if PCI config DM_PCI - bool "Enable driver mode for PCI" + bool "Enable driver model for PCI" depends on DM help Use driver model for PCI. Driver model is the new method for diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c index 4ca39e6d98..0c46450d36 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c @@ -20,7 +20,7 @@ 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 int ether_rmii_muxvals[] = {0, 0, 0, 0, 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}; diff --git a/drivers/power/axp152.c b/drivers/power/axp152.c index cd07275d9f..c4b3fe58a6 100644 --- a/drivers/power/axp152.c +++ b/drivers/power/axp152.c @@ -75,7 +75,7 @@ int axp_init(void) return rc; if (ver != 0x05) - return -1; + return -EINVAL; return 0; } diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c index 731b75e50a..4b25ef2578 100644 --- a/drivers/power/axp209.c +++ b/drivers/power/axp209.c @@ -158,7 +158,7 @@ int axp_init(void) ver &= 0x0f; if (ver != 0x1) - return -1; + return -EINVAL; /* Mask all interrupts */ for (i = AXP209_IRQ_ENABLE1; i <= AXP209_IRQ_ENABLE5; i++) { diff --git a/drivers/power/battery/bat_trats2.c b/drivers/power/battery/bat_trats2.c index 57221adf81..6329e028b6 100644 --- a/drivers/power/battery/bat_trats2.c +++ b/drivers/power/battery/bat_trats2.c @@ -18,7 +18,7 @@ static int power_battery_charge(struct pmic *bat) struct power_battery *p_bat = bat->pbat; if (bat->chrg->chrg_state(p_bat->chrg, PMIC_CHARGER_ENABLE, 450)) - return -1; + return -EINVAL; return 0; } diff --git a/drivers/power/exynos-tmu.c b/drivers/power/exynos-tmu.c index b9968c25eb..6a662677a7 100644 --- a/drivers/power/exynos-tmu.c +++ b/drivers/power/exynos-tmu.c @@ -190,7 +190,7 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) COMPAT_SAMSUNG_EXYNOS_TMU); if (node < 0) { debug("EXYNOS_TMU: No node for tmu in device tree\n"); - return -1; + return -ENODEV; } /* @@ -202,7 +202,7 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) addr = fdtdec_get_addr(blob, node, "reg"); if (addr == FDT_ADDR_T_NONE) { debug("%s: Missing tmu-base\n", __func__); - return -1; + return -ENODEV; } info->tmu_base = (struct exynos5_tmu_reg *)addr; @@ -246,11 +246,11 @@ static int get_tmu_fdt_values(struct tmu_info *info, const void *blob) if (error) { debug("fail to get tmu node properties\n"); - return -1; + return -EINVAL; } #else /* Non DT support may never be added. Just in case */ - return -1; + return -ENODEV; #endif return 0; diff --git a/drivers/power/fuel_gauge/fg_max17042.c b/drivers/power/fuel_gauge/fg_max17042.c index 154ca6a695..e43349454d 100644 --- a/drivers/power/fuel_gauge/fg_max17042.c +++ b/drivers/power/fuel_gauge/fg_max17042.c @@ -199,7 +199,7 @@ static int power_update_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max17042 fuel gauge\n"); - return -1; + return -ENODEV; } ret |= pmic_reg_read(p, MAX17042_VFSOC, &val); @@ -224,7 +224,7 @@ static int power_check_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max17042 fuel gauge\n"); - return -1; + return -ENODEV; } ret |= pmic_reg_read(p, MAX17042_STATUS, &val); diff --git a/drivers/power/mfd/fg_max77693.c b/drivers/power/mfd/fg_max77693.c index 4519fed497..df1550816e 100644 --- a/drivers/power/mfd/fg_max77693.c +++ b/drivers/power/mfd/fg_max77693.c @@ -52,7 +52,7 @@ static int power_update_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max77693 fuel gauge\n"); - return -1; + return -ENODEV; } ret = max77693_get_soc(&pb->bat->state_of_chrg); @@ -74,7 +74,7 @@ static int power_check_battery(struct pmic *p, struct pmic *bat) if (pmic_probe(p)) { puts("Can't find max77693 fuel gauge\n"); - return -1; + return -ENODEV; } ret = pmic_reg_read(p, MAX77693_STATUS, &val); diff --git a/drivers/power/mfd/pmic_max77693.c b/drivers/power/mfd/pmic_max77693.c index 6b28e28b3f..c63390ed48 100644 --- a/drivers/power/mfd/pmic_max77693.c +++ b/drivers/power/mfd/pmic_max77693.c @@ -16,7 +16,7 @@ static int max77693_charger_state(struct pmic *p, int state, int current) unsigned int val; if (pmic_probe(p)) - return -1; + return -ENODEV; /* unlock write capability */ val = MAX77693_CHG_UNLOCK; @@ -27,13 +27,13 @@ static int max77693_charger_state(struct pmic *p, int state, int current) pmic_reg_read(p, MAX77693_CHG_CNFG_00, &val); val &= ~0x01; pmic_reg_write(p, MAX77693_CHG_CNFG_00, val); - return -1; + return -ENOTSUPP; } if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) { printf("%s: Wrong charge current: %d [mA]\n", __func__, current); - return -1; + return -EINVAL; } /* set charging current */ @@ -59,7 +59,7 @@ static int max77693_charger_bat_present(struct pmic *p) unsigned int val; if (pmic_probe(p)) - return -1; + return -ENODEV; pmic_reg_read(p, MAX77693_CHG_INT_OK, &val); diff --git a/drivers/power/palmas.c b/drivers/power/palmas.c index 4f9a62cb34..c813b21e6f 100644 --- a/drivers/power/palmas.c +++ b/drivers/power/palmas.c @@ -47,20 +47,23 @@ int palmas_mmc1_poweron_ldo(uint voltage) u8 val = 0; #if defined(CONFIG_DRA7XX) + int ret; /* * Currently valid for the dra7xx_evm board: * Set TPS659038 LDO1 to 3.0 V */ val = LDO_VOLT_3V0; - if (palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_VOLTAGE, val)) { + ret = palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_VOLTAGE, val); + if (ret) { printf("tps65903x: could not set LDO1 voltage.\n"); - return 1; + return ret; } /* TURN ON LDO1 */ val = RSC_MODE_SLEEP | RSC_MODE_ACTIVE; - if (palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_CTRL, val)) { + ret = palmas_i2c_write_u8(TPS65903X_CHIP_P1, LDO1_CTRL, val); + if (ret) { printf("tps65903x: could not turn on LDO1.\n"); - return 1; + return ret; } return 0; #else diff --git a/drivers/power/pmic/pmic_hi6553.c b/drivers/power/pmic/pmic_hi6553.c index 0af798753e..b2346b6b4d 100644 --- a/drivers/power/pmic/pmic_hi6553.c +++ b/drivers/power/pmic/pmic_hi6553.c @@ -26,7 +26,7 @@ void hi6553_writeb(u32 offset, uint8_t value) int pmic_reg_write(struct pmic *p, u32 reg, u32 val) { if (check_reg(p, reg)) - return -1; + return -EINVAL; hi6553_writeb(reg, (uint8_t)val); @@ -36,7 +36,7 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val) int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) { if (check_reg(p, reg)) - return -1; + return -EINVAL; *val = (u32)hi6553_readb(reg); diff --git a/drivers/power/pmic/pmic_max77686.c b/drivers/power/pmic/pmic_max77686.c index 93c8d2b155..8e653316d1 100644 --- a/drivers/power/pmic/pmic_max77686.c +++ b/drivers/power/pmic/pmic_max77686.c @@ -67,14 +67,14 @@ int max77686_set_ldo_voltage(struct pmic *p, int ldo, ulong uV) if (ldo < 1 || ldo > 26) { printf("%s: %d is wrong ldo number\n", __func__, ldo); - return -1; + return -EINVAL; } adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1; hex = max77686_ldo_volt2hex(ldo, uV); if (!hex) - return -1; + return -EINVAL; ret = pmic_reg_read(p, adr, &val); if (ret) @@ -120,7 +120,7 @@ int max77686_set_ldo_mode(struct pmic *p, int ldo, char opmode) if (ldo < 1 || 26 < ldo) { printf("%s: %d is wrong ldo number\n", __func__, ldo); - return -1; + return -EINVAL; } adr = MAX77686_REG_PMIC_LDO1CTRL1 + ldo - 1; @@ -161,7 +161,7 @@ int max77686_set_ldo_mode(struct pmic *p, int ldo, char opmode) if (mode == 0xff) { printf("%s: %d is not supported on LDO%d\n", __func__, opmode, ldo); - return -1; + return -ENOTSUPP; } ret = pmic_reg_read(p, adr, &val); @@ -182,7 +182,7 @@ int max77686_set_buck_mode(struct pmic *p, int buck, char opmode) size = ARRAY_SIZE(max77686_buck_addr); if (buck >= size) { printf("%s: %d is wrong buck number\n", __func__, buck); - return -1; + return -EINVAL; } adr = max77686_buck_addr[buck]; @@ -238,7 +238,7 @@ int max77686_set_buck_mode(struct pmic *p, int buck, char opmode) if (mode == 0xff) { printf("%s: %d is not supported on BUCK%d\n", __func__, opmode, buck); - return -1; + return -ENOTSUPP; } ret = pmic_reg_read(p, adr, &val); @@ -271,20 +271,20 @@ int pmic_init(unsigned char bus) if (node < 0) { debug("PMIC: No node for PMIC Chip in device tree\n"); debug("node = %d\n", node); - return -1; + return -ENODEV; } parent = fdt_parent_offset(blob, node); if (parent < 0) { debug("%s: Cannot find node parent\n", __func__); - return -1; + return -ENODEV; } /* tmp since p->bus is unsigned */ tmp = i2c_get_bus_num_fdt(parent); if (tmp < 0) { debug("%s: Cannot find I2C bus\n", __func__); - return -1; + return -ENODEV; } p->bus = tmp; p->hw.i2c.addr = fdtdec_get_int(blob, node, "reg", 9); diff --git a/drivers/power/pmic/pmic_max8997.c b/drivers/power/pmic/pmic_max8997.c index a36a9a08bf..32afb3f7d0 100644 --- a/drivers/power/pmic/pmic_max8997.c +++ b/drivers/power/pmic/pmic_max8997.c @@ -33,7 +33,7 @@ static int pmic_charger_state(struct pmic *p, int state, int current) u32 val = 0; if (pmic_probe(p)) - return -1; + return -ENODEV; if (state == PMIC_CHARGER_DISABLE) { puts("Disable the charger.\n"); @@ -41,13 +41,13 @@ static int pmic_charger_state(struct pmic *p, int state, int current) val &= ~(MBCHOSTEN | VCHGR_FC); pmic_reg_write(p, MAX8997_REG_MBCCTRL2, val); - return -1; + return -ENOTSUPP; } if (current < CHARGER_MIN_CURRENT || current > CHARGER_MAX_CURRENT) { printf("%s: Wrong charge current: %d [mA]\n", __func__, current); - return -1; + return -EINVAL; } fc = (current - CHARGER_MIN_CURRENT) / CHARGER_CURRENT_RESOLUTION; @@ -71,7 +71,7 @@ static int pmic_charger_bat_present(struct pmic *p) u32 val; if (pmic_probe(p)) - return -1; + return -ENODEV; pmic_reg_read(p, MAX8997_REG_STATUS4, &val); diff --git a/drivers/power/power_core.c b/drivers/power/power_core.c index fe1f316021..b72286d429 100644 --- a/drivers/power/power_core.c +++ b/drivers/power/power_core.c @@ -23,7 +23,7 @@ int check_reg(struct pmic *p, u32 reg) if (reg >= p->number_of_regs) { printf("<reg num> = %d is invalid. Should be less than %d\n", reg, p->number_of_regs); - return -1; + return -EINVAL; } return 0; @@ -34,7 +34,7 @@ int pmic_set_output(struct pmic *p, u32 reg, int out, int on) u32 val; if (pmic_reg_read(p, reg, &val)) - return -1; + return -ENOTSUPP; if (on) val |= out; @@ -42,7 +42,7 @@ int pmic_set_output(struct pmic *p, u32 reg, int out, int on) val &= ~out; if (pmic_reg_write(p, reg, val)) - return -1; + return -ENOTSUPP; return 0; } @@ -59,7 +59,7 @@ static int pmic_dump(struct pmic *p) if (!p) { puts("Wrong PMIC name!\n"); - return -1; + return -ENODEV; } pmic_show_info(p); diff --git a/drivers/power/power_i2c.c b/drivers/power/power_i2c.c index 0dcf9fe918..8a8ea10e33 100644 --- a/drivers/power/power_i2c.c +++ b/drivers/power/power_i2c.c @@ -21,7 +21,7 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val) unsigned char buf[4] = { 0 }; if (check_reg(p, reg)) - return -1; + return -EINVAL; I2C_SET_BUS(p->bus); @@ -51,27 +51,26 @@ int pmic_reg_write(struct pmic *p, u32 reg, u32 val) break; default: printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num); - return -1; + return -EINVAL; } - if (i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num)) - return -1; - - return 0; + return i2c_write(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num); } int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) { unsigned char buf[4] = { 0 }; u32 ret_val = 0; + int ret; if (check_reg(p, reg)) - return -1; + return -EINVAL; I2C_SET_BUS(p->bus); - if (i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num)) - return -1; + ret = i2c_read(pmic_i2c_addr, reg, 1, buf, pmic_i2c_tx_num); + if (ret) + return ret; switch (pmic_i2c_tx_num) { case 3: @@ -93,7 +92,7 @@ int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) break; default: printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num); - return -1; + return -EINVAL; } memcpy(val, &ret_val, sizeof(ret_val)); @@ -106,7 +105,7 @@ int pmic_probe(struct pmic *p) debug("Bus: %d PMIC:%s probed!\n", p->bus, p->name); if (i2c_probe(pmic_i2c_addr)) { printf("Can't find PMIC:%s\n", p->name); - return -1; + return -ENODEV; } return 0; diff --git a/drivers/power/power_spi.c b/drivers/power/power_spi.c index 1e554461f3..ef8531df0f 100644 --- a/drivers/power/power_spi.c +++ b/drivers/power/power_spi.c @@ -27,14 +27,14 @@ static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write) p->hw.spi.mode); if (!slave) - return -1; + return -ENODEV; } if (check_reg(p, reg)) - return -1; + return -EINVAL; if (spi_claim_bus(slave)) - return -1; + return -EBUSY; pmic_tx = p->hw.spi.prepare_tx(reg, val, write); @@ -59,21 +59,15 @@ static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write) err: spi_release_bus(slave); - return -1; + return -ENOTSUPP; } int pmic_reg_write(struct pmic *p, u32 reg, u32 val) { - if (pmic_reg(p, reg, &val, 1)) - return -1; - - return 0; + return pmic_reg(p, reg, &val, 1); } int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) { - if (pmic_reg(p, reg, val, 0)) - return -1; - - return 0; + return pmic_reg(p, reg, val, 0); } diff --git a/drivers/power/tps6586x.c b/drivers/power/tps6586x.c index 865098386d..f50c4d17ee 100644 --- a/drivers/power/tps6586x.c +++ b/drivers/power/tps6586x.c @@ -97,14 +97,14 @@ static int read_voltages(int *sm0, int *sm1) ctrl1 = tps6586x_read(SUPPLY_CONTROL1); ctrl2 = tps6586x_read(SUPPLY_CONTROL2); if (ctrl1 == -1 || ctrl2 == -1) - return -1; + return -ENOTSUPP; /* Figure out whether V1 or V2 is selected */ is_v2 = (ctrl1 | ctrl2) & CTRL_SM0_SUPPLY2; *sm0 = tps6586x_read(is_v2 ? SM0_VOLTAGE_V2 : SM0_VOLTAGE_V1); *sm1 = tps6586x_read(is_v2 ? SM1_VOLTAGE_V2 : SM1_VOLTAGE_V1); if (*sm0 == -1 || *sm1 == -1) - return -1; + return -ENOTSUPP; return 0; } @@ -129,7 +129,7 @@ static int set_voltage(int reg, int data, int rate) /* write v1, v2 and rate, then trigger */ if (tps6586x_write(reg, buff, 3) || tps6586x_write(SUPPLY_CONTROL1, &control_bit, 1)) - return -1; + return -ENOTSUPP; return 0; } @@ -177,7 +177,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate, /* get current voltage settings */ if (read_voltages(&sm0, &sm1)) { debug("%s: Cannot read voltage settings\n", __func__); - return -1; + return -EINVAL; } /* @@ -189,7 +189,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate, if (min_sm0_over_sm1 != -1 && sm0 < sm1 + min_sm0_over_sm1) { debug("%s: SM0 is %d, SM1 is %d, but min_sm0_over_sm1 is %d\n", __func__, sm0, sm1, min_sm0_over_sm1); - return -1; + return -EINVAL; } /* @@ -240,7 +240,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate, } debug("%d-%d %d-%d done\n", sm0, sm0_target, sm1, sm1_target); - return bad ? -1 : 0; + return bad ? -EINVAL : 0; } int tps6586x_init(struct udevice *dev) diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 57af1b56cb..cb79a01631 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -17,6 +17,10 @@ config RTC_PCF2127 bool "Enable PCF2127 driver" depends on DM_RTC help - Enable pcf2127 driver which provides rtc get and set function + The PCF2127 is a CMOS Real Time Clock (RTC) and calendar with an integrated + Temperature Compensated Crystal (Xtal) Oscillator (TCXO) and a 32.768 kHz quartz + crystal optimized for very high accuracy and very low power consumption. The PCF2127 + has a selectable I2C-bus or SPI-bus, a backup battery switch-over circuit, a + programmable watchdog function, a timestamp function, and many other features. endmenu diff --git a/drivers/rtc/pcf2127.c b/drivers/rtc/pcf2127.c index bc59c6cda3..dcf0340b4d 100644 --- a/drivers/rtc/pcf2127.c +++ b/drivers/rtc/pcf2127.c @@ -11,21 +11,21 @@ #include <i2c.h> #include <rtc.h> -#define PCF2127_REG_CTRL1 (0x00) -#define PCF2127_REG_CTRL2 (0x01) -#define PCF2127_REG_CTRL3 (0x02) -#define PCF2127_REG_SC (0x03) /* datetime */ -#define PCF2127_REG_MN (0x04) -#define PCF2127_REG_HR (0x05) -#define PCF2127_REG_DM (0x06) -#define PCF2127_REG_DW (0x07) -#define PCF2127_REG_MO (0x08) -#define PCF2127_REG_YR (0x09) +#define PCF2127_REG_CTRL1 0x00 +#define PCF2127_REG_CTRL2 0x01 +#define PCF2127_REG_CTRL3 0x02 +#define PCF2127_REG_SC 0x03 +#define PCF2127_REG_MN 0x04 +#define PCF2127_REG_HR 0x05 +#define PCF2127_REG_DM 0x06 +#define PCF2127_REG_DW 0x07 +#define PCF2127_REG_MO 0x08 +#define PCF2127_REG_YR 0x09 static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm) { uchar buf[8]; - int i = 0; + int i = 0, ret; /* start register address */ buf[i++] = PCF2127_REG_SC; @@ -44,21 +44,22 @@ static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm) buf[i++] = bin2bcd(tm->tm_year % 100); /* write register's data */ - if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0) - return -1; + ret = dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)); - return 0; + return ret; } static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm) { - int rel = 0; + int ret = 0; uchar buf[10] = { PCF2127_REG_CTRL1 }; - if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, 1) < 0) - return -1; - if (dm_i2c_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0) - return -1; + ret = dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, 1); + if (ret < 0) + return ret; + ret = dm_i2c_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)); + if (ret < 0) + return ret; if (buf[PCF2127_REG_CTRL3] & 0x04) puts("### Warning: RTC Low Voltage - date/time not reliable\n"); @@ -79,12 +80,13 @@ static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm) tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec); - return rel; + return ret; } static int pcf2127_rtc_reset(struct udevice *dev) { /*Doing nothing here*/ + return 0; } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b26ada38ad..b11f3ff89e 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -352,7 +352,7 @@ config ROCKCHIP_SERIAL depends on DM_SERIAL && SPL_OF_PLATDATA help Select this to enable a debug UART for Rockchip devices when using - CONFIG_OF_PLATDATA (i.e. a compiled-in device tree replacemenmt). + CONFIG_SPL_OF_PLATDATA (i.e. a compiled-in device tree replacemenmt). This uses the ns16550 driver, converting the platdata from of-platdata to the ns16550 format. diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index c1ce1580a2..896b093765 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -23,10 +23,8 @@ obj-$(CONFIG_BFIN_SPI) += bfin_spi.o obj-$(CONFIG_BFIN_SPI6XX) += bfin_spi6xx.o obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o obj-$(CONFIG_CF_SPI) += cf_spi.o -obj-$(CONFIG_CF_QSPI) += cf_qspi.o obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o obj-$(CONFIG_DESIGNWARE_SPI) += designware_spi.o -obj-$(CONFIG_EP93XX_SPI) += ep93xx_spi.o obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o obj-$(CONFIG_FSL_ESPI) += fsl_espi.o diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index df6a91fc9f..e02f2217f4 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -30,6 +30,7 @@ #include <linux/errno.h> #include <wait_bit.h> #include <spi.h> +#include <bouncebuf.h> #include "cadence_qspi.h" #define CQSPI_REG_POLL_US 1 /* 1us */ @@ -633,6 +634,8 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat, { unsigned int remaining = n_rx; unsigned int bytes_to_read = 0; + struct bounce_buffer bb; + u8 *bb_rxbuf; int ret; writel(n_rx, plat->regbase + CQSPI_REG_INDIRECTRDBYTES); @@ -641,6 +644,11 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat, writel(CQSPI_REG_INDIRECTRD_START, plat->regbase + CQSPI_REG_INDIRECTRD); + ret = bounce_buffer_start(&bb, (void *)rxbuf, n_rx, GEN_BB_WRITE); + if (ret) + return ret; + bb_rxbuf = bb.bounce_buffer; + while (remaining > 0) { ret = cadence_qspi_wait_for_data(plat); if (ret < 0) { @@ -654,12 +662,13 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat, bytes_to_read *= CQSPI_FIFO_WIDTH; bytes_to_read = bytes_to_read > remaining ? remaining : bytes_to_read; - /* Handle non-4-byte aligned access to avoid data abort. */ - if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4)) - readsb(plat->ahbbase, rxbuf, bytes_to_read); - else - readsl(plat->ahbbase, rxbuf, bytes_to_read >> 2); - rxbuf += bytes_to_read; + readsl(plat->ahbbase, bb_rxbuf, bytes_to_read >> 2); + if (bytes_to_read % 4) + readsb(plat->ahbbase, + bb_rxbuf + rounddown(bytes_to_read, 4), + bytes_to_read % 4); + + bb_rxbuf += bytes_to_read; remaining -= bytes_to_read; bytes_to_read = cadence_qspi_get_rd_sram_level(plat); } @@ -676,6 +685,7 @@ int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat, /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTRD_DONE, plat->regbase + CQSPI_REG_INDIRECTRD); + bounce_buffer_stop(&bb); return 0; @@ -683,6 +693,7 @@ failrd: /* Cancel the indirect read */ writel(CQSPI_REG_INDIRECTRD_CANCEL, plat->regbase + CQSPI_REG_INDIRECTRD); + bounce_buffer_stop(&bb); return ret; } @@ -724,6 +735,17 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat, unsigned int remaining = n_tx; unsigned int write_bytes; int ret; + struct bounce_buffer bb; + u8 *bb_txbuf; + + /* + * Handle non-4-byte aligned accesses via bounce buffer to + * avoid data abort. + */ + ret = bounce_buffer_start(&bb, (void *)txbuf, n_tx, GEN_BB_READ); + if (ret) + return ret; + bb_txbuf = bb.bounce_buffer; /* Configure the indirect read transfer bytes */ writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES); @@ -734,11 +756,11 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat, while (remaining > 0) { write_bytes = remaining > page_size ? page_size : remaining; - /* Handle non-4-byte aligned access to avoid data abort. */ - if (((uintptr_t)txbuf % 4) || (write_bytes % 4)) - writesb(plat->ahbbase, txbuf, write_bytes); - else - writesl(plat->ahbbase, txbuf, write_bytes >> 2); + writesl(plat->ahbbase, bb_txbuf, write_bytes >> 2); + if (write_bytes % 4) + writesb(plat->ahbbase, + bb_txbuf + rounddown(write_bytes, 4), + write_bytes % 4); ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_SDRAMLEVEL, CQSPI_REG_SDRAMLEVEL_WR_MASK << @@ -748,7 +770,7 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat, goto failwr; } - txbuf += write_bytes; + bb_txbuf += write_bytes; remaining -= write_bytes; } @@ -759,6 +781,7 @@ int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat, printf("Indirect write completion error (%i)\n", ret); goto failwr; } + bounce_buffer_stop(&bb); /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTWR_DONE, @@ -769,6 +792,7 @@ failwr: /* Cancel the indirect write */ writel(CQSPI_REG_INDIRECTWR_CANCEL, plat->regbase + CQSPI_REG_INDIRECTWR); + bounce_buffer_stop(&bb); return ret; } diff --git a/drivers/spi/cf_qspi.c b/drivers/spi/cf_qspi.c deleted file mode 100644 index e57e63eb47..0000000000 --- a/drivers/spi/cf_qspi.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Freescale Coldfire Queued SPI driver - * - * NOTE: - * This driver is written to transfer 8 bit at-a-time and uses the dedicated - * SPI slave select pins as bit-banged GPIO to work with spi_flash subsystem. - * - * Copyright (C) 2011 Ruggedcom, Inc. - * Richard Retanubun (richardretanubun@freescale.com) - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <spi.h> -#include <asm/immap.h> -#include <asm/io.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define to_cf_qspi_slave(s) container_of(s, struct cf_qspi_slave, slave) - -struct cf_qspi_slave { - struct spi_slave slave; /* Specific bus:cs ID for each device */ - qspi_t *regs; /* Pointer to SPI controller registers */ - u16 qmr; /* QMR: Queued Mode Register */ - u16 qwr; /* QWR: Queued Wrap Register */ - u16 qcr; /* QCR: Queued Command Ram */ -}; - -/* Register write wrapper functions */ -static void write_qmr(volatile qspi_t *qspi, u16 val) { qspi->mr = val; } -static void write_qdlyr(volatile qspi_t *qspi, u16 val) { qspi->dlyr = val; } -static void write_qwr(volatile qspi_t *qspi, u16 val) { qspi->wr = val; } -static void write_qir(volatile qspi_t *qspi, u16 val) { qspi->ir = val; } -static void write_qar(volatile qspi_t *qspi, u16 val) { qspi->ar = val; } -static void write_qdr(volatile qspi_t *qspi, u16 val) { qspi->dr = val; } -/* Register read wrapper functions */ -static u16 read_qdlyr(volatile qspi_t *qspi) { return qspi->dlyr; } -static u16 read_qwr(volatile qspi_t *qspi) { return qspi->wr; } -static u16 read_qir(volatile qspi_t *qspi) { return qspi->ir; } -static u16 read_qdr(volatile qspi_t *qspi) { return qspi->dr; } - -/* These call points may be different for each ColdFire CPU */ -extern void cfspi_port_conf(void); -static void cfspi_cs_activate(uint bus, uint cs, uint cs_active_high); -static void cfspi_cs_deactivate(uint bus, uint cs, uint cs_active_high); - -int spi_claim_bus(struct spi_slave *slave) -{ - return 0; -} -void spi_release_bus(struct spi_slave *slave) -{ -} - -__attribute__((weak)) -void spi_init(void) -{ - cfspi_port_conf(); -} - -__attribute__((weak)) -void spi_cs_activate(struct spi_slave *slave) -{ - struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); - - cfspi_cs_activate(slave->bus, slave->cs, !(dev->qwr & QSPI_QWR_CSIV)); -} - -__attribute__((weak)) -void spi_cs_deactivate(struct spi_slave *slave) -{ - struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); - - cfspi_cs_deactivate(slave->bus, slave->cs, !(dev->qwr & QSPI_QWR_CSIV)); -} - -__attribute__((weak)) -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - /* Only 1 bus and 4 chipselect per controller */ - if (bus == 0 && (cs >= 0 && cs < 4)) - return 1; - else - return 0; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); - - free(dev); -} - -/* Translate information given by spi_setup_slave to members of cf_qspi_slave */ -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct cf_qspi_slave *dev = NULL; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - dev = spi_alloc_slave(struct cf_qspi_slave, bus, cs); - if (!dev) - return NULL; - - /* Initialize to known value */ - dev->regs = (qspi_t *)MMAP_QSPI; - dev->qmr = 0; - dev->qwr = 0; - dev->qcr = 0; - - - /* Map max_hz to QMR[BAUD] */ - if (max_hz == 0) /* Go as fast as possible */ - dev->qmr = 2u; - else /* Get the closest baud rate */ - dev->qmr = clamp(((gd->bus_clk >> 2) + max_hz - 1)/max_hz, - 2lu, 255lu); - - /* Map mode to QMR[CPOL] and QMR[CPHA] */ - if (mode & SPI_CPOL) - dev->qmr |= QSPI_QMR_CPOL; - - if (mode & SPI_CPHA) - dev->qmr |= QSPI_QMR_CPHA; - - /* Hardcode bit length to 8 bit per transter */ - dev->qmr |= QSPI_QMR_BITS_8; - - /* Set QMR[MSTR] to enable QSPI as master */ - dev->qmr |= QSPI_QMR_MSTR; - - /* - * Set QCR and QWR to default values for spi flash operation. - * If more custom QCR and QRW are needed, overload mode variable - */ - dev->qcr = (QSPI_QDR_CONT | QSPI_QDR_BITSE); - - if (!(mode & SPI_CS_HIGH)) - dev->qwr |= QSPI_QWR_CSIV; - - return &dev->slave; -} - -/* Transfer 8 bit at a time */ -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) -{ - struct cf_qspi_slave *dev = to_cf_qspi_slave(slave); - volatile qspi_t *qspi = dev->regs; - u8 *txbuf = (u8 *)dout; - u8 *rxbuf = (u8 *)din; - u32 count = DIV_ROUND_UP(bitlen, 8); - u32 n, i = 0; - - /* Sanitize arguments */ - if (slave == NULL) { - printf("%s: NULL slave ptr\n", __func__); - return -1; - } - - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); - - /* There is something to send, lets process it. spi_xfer is also called - * just to toggle chip select, so bitlen of 0 is valid */ - if (count > 0) { - /* - * NOTE: Since chip select is driven as a bit-bang-ed GPIO - * using spi_cs_activate() and spi_cs_deactivate(), - * the chip select settings inside the controller - * (i.e. QCR[CONT] and QWR[CSIV]) are moot. The bits are set to - * keep the controller settings consistent with the actual - * operation of the bus. - */ - - /* Write the slave device's settings for the controller.*/ - write_qmr(qspi, dev->qmr); - write_qwr(qspi, dev->qwr); - - /* Limit transfer to 16 at a time */ - n = min(count, 16u); - do { - /* Setup queue end point */ - write_qwr(qspi, ((read_qwr(qspi) & QSPI_QWR_ENDQP_MASK) - | QSPI_QWR_ENDQP((n-1)))); - - /* Write Command RAM */ - write_qar(qspi, QSPI_QAR_CMD); - for (i = 0; i < n; ++i) - write_qdr(qspi, dev->qcr); - - /* Write TxBuf, if none given, fill with ZEROes */ - write_qar(qspi, QSPI_QAR_TRANS); - if (txbuf) { - for (i = 0; i < n; ++i) - write_qdr(qspi, *txbuf++); - } else { - for (i = 0; i < n; ++i) - write_qdr(qspi, 0); - } - - /* Clear QIR[SPIF] by writing a 1 to it */ - write_qir(qspi, read_qir(qspi) | QSPI_QIR_SPIF); - /* Set QDLYR[SPE] to start sending */ - write_qdlyr(qspi, read_qdlyr(qspi) | QSPI_QDLYR_SPE); - - /* Poll QIR[SPIF] for transfer completion */ - while ((read_qir(qspi) & QSPI_QIR_SPIF) != 1) - udelay(1); - - /* If given read RxBuf, load data to it */ - if (rxbuf) { - write_qar(qspi, QSPI_QAR_RECV); - for (i = 0; i < n; ++i) - *rxbuf++ = read_qdr(qspi); - } - - /* Decrement count */ - count -= n; - } while (count); - } - - if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); - - return 0; -} - -/* Each MCF CPU may have different pin assignments for chip selects. */ -#if defined(CONFIG_M5271) -/* Assert chip select, val = [1|0] , dir = out, mode = GPIO */ -void cfspi_cs_activate(uint bus, uint cs, uint cs_active_high) -{ - debug("%s: bus %d cs %d cs_active_high %d\n", - __func__, bus, cs, cs_active_high); - - switch (cs) { - case 0: /* QSPI_CS[0] = PQSPI[3] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x08); - else - mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xF7); - - mbar_writeByte(MCF_GPIO_PDDR_QSPI, - mbar_readByte(MCF_GPIO_PDDR_QSPI) | 0x08); - - mbar_writeByte(MCF_GPIO_PAR_QSPI, - mbar_readByte(MCF_GPIO_PAR_QSPI) & 0xDF); - break; - case 1: /* QSPI_CS[1] = PQSPI[4] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x10); - else - mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xEF); - - mbar_writeByte(MCF_GPIO_PDDR_QSPI, - mbar_readByte(MCF_GPIO_PDDR_QSPI) | 0x10); - - mbar_writeByte(MCF_GPIO_PAR_QSPI, - mbar_readByte(MCF_GPIO_PAR_QSPI) & 0x3F); - break; - case 2: /* QSPI_CS[2] = PTIMER[7] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x80); - else - mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0x7F); - - mbar_writeByte(MCF_GPIO_PDDR_TIMER, - mbar_readByte(MCF_GPIO_PDDR_TIMER) | 0x80); - - mbar_writeShort(MCF_GPIO_PAR_TIMER, - mbar_readShort(MCF_GPIO_PAR_TIMER) & 0x3FFF); - break; - case 3: /* QSPI_CS[3] = PTIMER[3] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x08); - else - mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0xF7); - - mbar_writeByte(MCF_GPIO_PDDR_TIMER, - mbar_readByte(MCF_GPIO_PDDR_TIMER) | 0x08); - - mbar_writeShort(MCF_GPIO_PAR_TIMER, - mbar_readShort(MCF_GPIO_PAR_TIMER) & 0xFF3F); - break; - } -} - -/* Deassert chip select, val = [1|0], dir = in, mode = GPIO - * direction set as IN to undrive the pin, external pullup/pulldown will bring - * bus to deassert state. - */ -void cfspi_cs_deactivate(uint bus, uint cs, uint cs_active_high) -{ - debug("%s: bus %d cs %d cs_active_high %d\n", - __func__, bus, cs, cs_active_high); - - switch (cs) { - case 0: /* QSPI_CS[0] = PQSPI[3] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xF7); - else - mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x08); - - mbar_writeByte(MCF_GPIO_PDDR_QSPI, - mbar_readByte(MCF_GPIO_PDDR_QSPI) & 0xF7); - - mbar_writeByte(MCF_GPIO_PAR_QSPI, - mbar_readByte(MCF_GPIO_PAR_QSPI) & 0xDF); - break; - case 1: /* QSPI_CS[1] = PQSPI[4] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PCLRR_QSPI, 0xEF); - else - mbar_writeByte(MCF_GPIO_PPDSDR_QSPI, 0x10); - - mbar_writeByte(MCF_GPIO_PDDR_QSPI, - mbar_readByte(MCF_GPIO_PDDR_QSPI) & 0xEF); - - mbar_writeByte(MCF_GPIO_PAR_QSPI, - mbar_readByte(MCF_GPIO_PAR_QSPI) & 0x3F); - break; - case 2: /* QSPI_CS[2] = PTIMER[7] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0x7F); - else - mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x80); - - mbar_writeByte(MCF_GPIO_PDDR_TIMER, - mbar_readByte(MCF_GPIO_PDDR_TIMER) & 0x7F); - - mbar_writeShort(MCF_GPIO_PAR_TIMER, - mbar_readShort(MCF_GPIO_PAR_TIMER) & 0x3FFF); - break; - case 3: /* QSPI_CS[3] = PTIMER[3] */ - if (cs_active_high) - mbar_writeByte(MCF_GPIO_PCLRR_TIMER, 0xF7); - else - mbar_writeByte(MCF_GPIO_PPDSDR_TIMER, 0x08); - - mbar_writeByte(MCF_GPIO_PDDR_TIMER, - mbar_readByte(MCF_GPIO_PDDR_TIMER) & 0xF7); - - mbar_writeShort(MCF_GPIO_PAR_TIMER, - mbar_readShort(MCF_GPIO_PAR_TIMER) & 0xFF3F); - break; - } -} -#endif /* CONFIG_M5271 */ diff --git a/drivers/spi/cf_spi.c b/drivers/spi/cf_spi.c index 6ce11012e8..7be9427781 100644 --- a/drivers/spi/cf_spi.c +++ b/drivers/spi/cf_spi.c @@ -279,10 +279,6 @@ static struct spi_slave *cfspi_setup_slave(struct cf_spi_slave *cfslave, } #endif /* CONFIG_CF_DSPI */ -#ifdef CONFIG_CF_QSPI -/* 52xx, 53xx */ -#endif /* CONFIG_CF_QSPI */ - #ifdef CONFIG_CMD_SPI int spi_cs_is_valid(unsigned int bus, unsigned int cs) { diff --git a/drivers/spi/ep93xx_spi.c b/drivers/spi/ep93xx_spi.c deleted file mode 100644 index cb682ddda4..0000000000 --- a/drivers/spi/ep93xx_spi.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * SPI Driver for EP93xx - * - * Copyright (C) 2013 Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru> - * - * Inspired form linux kernel driver and atmel uboot driver - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <spi.h> -#include <malloc.h> - -#include <asm/io.h> - -#include <asm/arch/ep93xx.h> - -#define SSPBASE SPI_BASE - -#define SSPCR0 0x0000 -#define SSPCR0_MODE_SHIFT 6 -#define SSPCR0_SCR_SHIFT 8 -#define SSPCR0_SPH BIT(7) -#define SSPCR0_SPO BIT(6) -#define SSPCR0_FRF_SPI 0 -#define SSPCR0_DSS_8BIT 7 - -#define SSPCR1 0x0004 -#define SSPCR1_RIE BIT(0) -#define SSPCR1_TIE BIT(1) -#define SSPCR1_RORIE BIT(2) -#define SSPCR1_LBM BIT(3) -#define SSPCR1_SSE BIT(4) -#define SSPCR1_MS BIT(5) -#define SSPCR1_SOD BIT(6) - -#define SSPDR 0x0008 - -#define SSPSR 0x000c -#define SSPSR_TFE BIT(0) -#define SSPSR_TNF BIT(1) -#define SSPSR_RNE BIT(2) -#define SSPSR_RFF BIT(3) -#define SSPSR_BSY BIT(4) -#define SSPCPSR 0x0010 - -#define SSPIIR 0x0014 -#define SSPIIR_RIS BIT(0) -#define SSPIIR_TIS BIT(1) -#define SSPIIR_RORIS BIT(2) -#define SSPICR SSPIIR - -#define SSPCLOCK 14745600 -#define SSP_MAX_RATE (SSPCLOCK / 2) -#define SSP_MIN_RATE (SSPCLOCK / (254 * 256)) - -/* timeout in milliseconds */ -#define SPI_TIMEOUT 5 -/* maximum depth of RX/TX FIFO */ -#define SPI_FIFO_SIZE 8 - -struct ep93xx_spi_slave { - struct spi_slave slave; - - unsigned sspcr0; - unsigned sspcpsr; -}; - -static inline struct ep93xx_spi_slave *to_ep93xx_spi(struct spi_slave *slave) -{ - return container_of(slave, struct ep93xx_spi_slave, slave); -} - -void spi_init() -{ -} - -static inline void ep93xx_spi_write_u8(u16 reg, u8 value) -{ - writel(value, (unsigned int *)(SSPBASE + reg)); -} - -static inline u8 ep93xx_spi_read_u8(u16 reg) -{ - return readl((unsigned int *)(SSPBASE + reg)); -} - -static inline void ep93xx_spi_write_u16(u16 reg, u16 value) -{ - writel(value, (unsigned int *)(SSPBASE + reg)); -} - -static inline u16 ep93xx_spi_read_u16(u16 reg) -{ - return (u16)readl((unsigned int *)(SSPBASE + reg)); -} - -static int ep93xx_spi_init_hw(unsigned int rate, unsigned int mode, - struct ep93xx_spi_slave *slave) -{ - unsigned cpsr, scr; - - if (rate > SSP_MAX_RATE) - rate = SSP_MAX_RATE; - - if (rate < SSP_MIN_RATE) - return -1; - - /* Calculate divisors so that we can get speed according the - * following formula: - * rate = spi_clock_rate / (cpsr * (1 + scr)) - * - * cpsr must be even number and starts from 2, scr can be any number - * between 0 and 255. - */ - for (cpsr = 2; cpsr <= 254; cpsr += 2) { - for (scr = 0; scr <= 255; scr++) { - if ((SSPCLOCK / (cpsr * (scr + 1))) <= rate) { - /* Set CHPA and CPOL, SPI format and 8bit */ - unsigned sspcr0 = (scr << SSPCR0_SCR_SHIFT) | - SSPCR0_FRF_SPI | SSPCR0_DSS_8BIT; - if (mode & SPI_CPHA) - sspcr0 |= SSPCR0_SPH; - if (mode & SPI_CPOL) - sspcr0 |= SSPCR0_SPO; - - slave->sspcr0 = sspcr0; - slave->sspcpsr = cpsr; - return 0; - } - } - } - - return -1; -} - -void spi_set_speed(struct spi_slave *slave, unsigned int hz) -{ - struct ep93xx_spi_slave *as = to_ep93xx_spi(slave); - - unsigned int mode = 0; - if (as->sspcr0 & SSPCR0_SPH) - mode |= SPI_CPHA; - if (as->sspcr0 & SSPCR0_SPO) - mode |= SPI_CPOL; - - ep93xx_spi_init_hw(hz, mode, as); -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct ep93xx_spi_slave *as; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - as = spi_alloc_slave(struct ep93xx_spi_slave, bus, cs); - if (!as) - return NULL; - - if (ep93xx_spi_init_hw(max_hz, mode, as)) { - free(as); - return NULL; - } - - return &as->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct ep93xx_spi_slave *as = to_ep93xx_spi(slave); - - free(as); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct ep93xx_spi_slave *as = to_ep93xx_spi(slave); - - /* Enable the SPI hardware */ - ep93xx_spi_write_u8(SSPCR1, SSPCR1_SSE); - - - ep93xx_spi_write_u8(SSPCPSR, as->sspcpsr); - ep93xx_spi_write_u16(SSPCR0, as->sspcr0); - - debug("Select CS:%d SSPCPSR=%02x SSPCR0=%04x\n", - slave->cs, as->sspcpsr, as->sspcr0); - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Disable the SPI hardware */ - ep93xx_spi_write_u8(SSPCR1, 0); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - unsigned int len_tx; - unsigned int len_rx; - unsigned int len; - u32 status; - const u8 *txp = dout; - u8 *rxp = din; - u8 value; - - debug("spi_xfer: slave %u:%u dout %p din %p bitlen %u\n", - slave->bus, slave->cs, (uint *)dout, (uint *)din, bitlen); - - - if (bitlen == 0) - /* Finish any previously submitted transfers */ - goto out; - - if (bitlen % 8) { - /* Errors always terminate an ongoing transfer */ - flags |= SPI_XFER_END; - goto out; - } - - len = bitlen / 8; - - - if (flags & SPI_XFER_BEGIN) { - /* Empty RX FIFO */ - while ((ep93xx_spi_read_u8(SSPSR) & SSPSR_RNE)) - ep93xx_spi_read_u8(SSPDR); - - spi_cs_activate(slave); - } - - for (len_tx = 0, len_rx = 0; len_rx < len; ) { - status = ep93xx_spi_read_u8(SSPSR); - - if ((len_tx < len) && (status & SSPSR_TNF)) { - if (txp) - value = *txp++; - else - value = 0xff; - - ep93xx_spi_write_u8(SSPDR, value); - len_tx++; - } - - if (status & SSPSR_RNE) { - value = ep93xx_spi_read_u8(SSPDR); - - if (rxp) - *rxp++ = value; - len_rx++; - } - } - -out: - if (flags & SPI_XFER_END) { - /* - * Wait until the transfer is completely done before - * we deactivate CS. - */ - do { - status = ep93xx_spi_read_u8(SSPSR); - } while (status & SSPSR_BSY); - - spi_cs_deactivate(slave); - } - - return 0; -} diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 40839d89e9..261ed128ac 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -112,6 +112,10 @@ config G_DNL_VENDOR_NUM config G_DNL_PRODUCT_NUM hex "Product ID of USB device" +config USBNET_DEVADDR + string "USB Gadget Ethernet device mac address" + default "de:ad:be:ef:00:01" + endif # USB_GADGET_DOWNLOAD endif # USB_GADGET diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c index d72bfdfdd8..cb44374e81 100644 --- a/drivers/usb/gadget/dwc2_udc_otg.c +++ b/drivers/usb/gadget/dwc2_udc_otg.c @@ -63,13 +63,11 @@ static char *state_names[] = { "WAIT_FOR_NULL_COMPLETE", }; -#define DRIVER_DESC "DWC2 HS USB OTG Device Driver, (c) Samsung Electronics" #define DRIVER_VERSION "15 March 2009" struct dwc2_udc *the_controller; static const char driver_name[] = "dwc2-udc"; -static const char driver_desc[] = DRIVER_DESC; static const char ep0name[] = "ep0-control"; /* Max packet size*/ diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 289e5f1583..4137d76c42 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -25,6 +25,7 @@ #include "rndis.h" #include <dm.h> +#include <dm/lists.h> #include <dm/uclass-internal.h> #include <dm/device-internal.h> @@ -115,7 +116,11 @@ struct eth_dev { struct usb_request *tx_req, *rx_req; +#ifndef CONFIG_DM_ETH struct eth_device *net; +#else + struct udevice *net; +#endif struct net_device_stats stats; unsigned int tx_qlen; @@ -142,7 +147,11 @@ struct eth_dev { /*-------------------------------------------------------------------------*/ struct ether_priv { struct eth_dev ethdev; +#ifndef CONFIG_DM_ETH struct eth_device netdev; +#else + struct udevice *netdev; +#endif struct usb_gadget_driver eth_driver; }; @@ -498,6 +507,7 @@ static const struct usb_cdc_mdlm_desc mdlm_desc = { * can't really use its struct. All we do here is say that we're using * the submode of "SAFE" which directly matches the CDC Subset. */ +#ifdef CONFIG_USB_ETH_SUBSET static const u8 mdlm_detail_desc[] = { 6, USB_DT_CS_INTERFACE, @@ -507,6 +517,7 @@ static const u8 mdlm_detail_desc[] = { 0, /* network control capabilities (none) */ 0, /* network data capabilities ("raw" encapsulation) */ }; +#endif #endif @@ -1850,7 +1861,11 @@ static void rndis_control_ack_complete(struct usb_ep *ep, static char rndis_resp_buf[8] __attribute__((aligned(sizeof(__le32)))); +#ifndef CONFIG_DM_ETH static int rndis_control_ack(struct eth_device *net) +#else +static int rndis_control_ack(struct udevice *net) +#endif { struct ether_priv *priv = (struct ether_priv *)net->priv; struct eth_dev *dev = &priv->ethdev; @@ -2000,6 +2015,9 @@ static int eth_bind(struct usb_gadget *gadget) int status = -ENOMEM; int gcnum; u8 tmp[7]; +#ifdef CONFIG_DM_ETH + struct eth_pdata *pdata = dev_get_platdata(l_priv->netdev); +#endif /* these flags are only ever cleared; compiler take note */ #ifndef CONFIG_USB_ETH_CDC @@ -2187,7 +2205,11 @@ autoconf_fail: /* network device setup */ +#ifndef CONFIG_DM_ETH dev->net = &l_priv->netdev; +#else + dev->net = l_priv->netdev; +#endif dev->cdc = cdc; dev->zlp = zlp; @@ -2196,6 +2218,7 @@ autoconf_fail: dev->out_ep = out_ep; dev->status_ep = status_ep; + memset(tmp, 0, sizeof(tmp)); /* * Module params for these addresses should come from ID proms. * The host side address is used with CDC and RNDIS, and commonly @@ -2203,10 +2226,13 @@ autoconf_fail: * host side code for the SAFE thing cares -- its original BLAN * thing didn't, Sharp never assigned those addresses on Zaurii. */ +#ifndef CONFIG_DM_ETH get_ether_addr(dev_addr, dev->net->enetaddr); - - memset(tmp, 0, sizeof(tmp)); memcpy(tmp, dev->net->enetaddr, sizeof(dev->net->enetaddr)); +#else + get_ether_addr(dev_addr, pdata->enetaddr); + memcpy(tmp, pdata->enetaddr, sizeof(pdata->enetaddr)); +#endif get_ether_addr(host_addr, dev->host_mac); @@ -2267,10 +2293,11 @@ autoconf_fail: status_ep ? " STATUS " : "", status_ep ? status_ep->name : "" ); - printf("MAC %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->net->enetaddr[0], dev->net->enetaddr[1], - dev->net->enetaddr[2], dev->net->enetaddr[3], - dev->net->enetaddr[4], dev->net->enetaddr[5]); +#ifndef CONFIG_DM_ETH + printf("MAC %pM\n", dev->net->enetaddr); +#else + printf("MAC %pM\n", pdata->enetaddr); +#endif if (cdc || rndis) printf("HOST MAC %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -2519,13 +2546,12 @@ void _usb_eth_halt(struct ether_priv *priv) } usb_gadget_unregister_driver(&priv->eth_driver); -#ifdef CONFIG_DM_USB - device_remove(dev->usb_udev); -#else +#ifndef CONFIG_DM_USB board_usb_cleanup(0, USB_INIT_DEVICE); #endif } +#ifndef CONFIG_DM_ETH static int usb_eth_init(struct eth_device *netdev, bd_t *bd) { struct ether_priv *priv = (struct ether_priv *)netdev->priv; @@ -2592,3 +2618,114 @@ int usb_eth_initialize(bd_t *bi) eth_register(netdev); return 0; } +#else +static int usb_eth_start(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + + return _usb_eth_init(priv); +} + +static int usb_eth_send(struct udevice *dev, void *packet, int length) +{ + struct ether_priv *priv = dev_get_priv(dev); + + return _usb_eth_send(priv, packet, length); +} + +static int usb_eth_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct ether_priv *priv = dev_get_priv(dev); + struct eth_dev *ethdev = &priv->ethdev; + int ret; + + ret = _usb_eth_recv(priv); + if (ret) { + error("error packet receive\n"); + return ret; + } + + if (packet_received) { + if (ethdev->rx_req) { + *packetp = (uchar *)net_rx_packets[0]; + return ethdev->rx_req->length; + } else { + error("dev->rx_req invalid"); + return -EFAULT; + } + } + + return -EAGAIN; +} + +static int usb_eth_free_pkt(struct udevice *dev, uchar *packet, + int length) +{ + struct ether_priv *priv = dev_get_priv(dev); + struct eth_dev *ethdev = &priv->ethdev; + + packet_received = 0; + + return rx_submit(ethdev, ethdev->rx_req, 0); +} + +static void usb_eth_stop(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + + _usb_eth_halt(priv); +} + +static int usb_eth_probe(struct udevice *dev) +{ + struct ether_priv *priv = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_platdata(dev); + + priv->netdev = dev; + l_priv = priv; + + get_ether_addr(CONFIG_USBNET_DEVADDR, pdata->enetaddr); + eth_setenv_enetaddr("usbnet_devaddr", pdata->enetaddr); + + return 0; +} + +static const struct eth_ops usb_eth_ops = { + .start = usb_eth_start, + .send = usb_eth_send, + .recv = usb_eth_recv, + .free_pkt = usb_eth_free_pkt, + .stop = usb_eth_stop, +}; + +int usb_ether_init(void) +{ + struct udevice *dev; + struct udevice *usb_dev; + int ret; + + ret = uclass_first_device(UCLASS_USB_DEV_GENERIC, &usb_dev); + if (!usb_dev || ret) { + error("No USB device found\n"); + return ret; + } + + ret = device_bind_driver(usb_dev, "usb_ether", "usb_ether", &dev); + if (!dev || ret) { + error("usb - not able to bind usb_ether device\n"); + return ret; + } + + return 0; +} + +U_BOOT_DRIVER(eth_usb) = { + .name = "usb_ether", + .id = UCLASS_ETH, + .probe = usb_eth_probe, + .ops = &usb_eth_ops, + .priv_auto_alloc_size = sizeof(struct ether_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif /* CONFIG_DM_ETH */ diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 844a0c7236..5ad481302b 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -1121,7 +1121,11 @@ int rndis_msg_parser(u8 configNr, u8 *buf) return -ENOTSUPP; } +#ifndef CONFIG_DM_ETH int rndis_register(int (*rndis_control_ack)(struct eth_device *)) +#else +int rndis_register(int (*rndis_control_ack)(struct udevice *)) +#endif { u8 i; @@ -1149,8 +1153,13 @@ void rndis_deregister(int configNr) return; } -int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu, - struct net_device_stats *stats, u16 *cdc_filter) +#ifndef CONFIG_DM_ETH +int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu, + struct net_device_stats *stats, u16 *cdc_filter) +#else +int rndis_set_param_dev(u8 configNr, struct udevice *dev, int mtu, + struct net_device_stats *stats, u16 *cdc_filter) +#endif { debug("%s: configNr = %d\n", __func__, configNr); if (!dev || !stats) diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h index 7a389a580a..084af8541c 100644 --- a/drivers/usb/gadget/rndis.h +++ b/drivers/usb/gadget/rndis.h @@ -222,23 +222,34 @@ typedef struct rndis_params { const u8 *host_mac; u16 *filter; - struct eth_device *dev; struct net_device_stats *stats; int mtu; u32 vendorID; const char *vendorDescr; - int (*ack)(struct eth_device *); +#ifndef CONFIG_DM_ETH + struct eth_device *dev; + int (*ack)(struct eth_device *); +#else + struct udevice *dev; + int (*ack)(struct udevice *); +#endif struct list_head resp_queue; } rndis_params; /* RNDIS Message parser and other useless functions */ int rndis_msg_parser(u8 configNr, u8 *buf); enum rndis_state rndis_get_state(int configNr); -int rndis_register(int (*rndis_control_ack)(struct eth_device *)); void rndis_deregister(int configNr); +#ifndef CONFIG_DM_ETH +int rndis_register(int (*rndis_control_ack)(struct eth_device *)); int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu, - struct net_device_stats *stats, u16 *cdc_filter); + struct net_device_stats *stats, u16 *cdc_filter); +#else +int rndis_register(int (*rndis_control_ack)(struct udevice *)); +int rndis_set_param_dev(u8 configNr, struct udevice *dev, int mtu, + struct net_device_stats *stats, u16 *cdc_filter); +#endif int rndis_set_param_vendor(u8 configNr, u32 vendorID, const char *vendorDescr); int rndis_set_param_medium(u8 configNr, u32 medium, u32 speed); diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index b9c5fbe381..5129a57304 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -37,6 +37,12 @@ config USB_XHCI_ROCKCHIP help Enables support for the on-chip xHCI controller on Rockchip SoCs. +config USB_XHCI_ZYNQMP + bool "Support for Xilinx ZynqMP on-chip xHCI USB controller" + depends on ARCH_ZYNQMP + help + Enables support for the on-chip xHCI controller on Xilinx ZynqMP SoCs. + endif # USB_XHCI_HCD config USB_EHCI_HCD diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c index 48889c1956..7b309b7b96 100644 --- a/drivers/usb/host/ehci-mx6.c +++ b/drivers/usb/host/ehci-mx6.c @@ -15,10 +15,14 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/imx-common/iomux-v3.h> +#include <asm/imx-common/sys_proto.h> #include <dm.h> +#include <power/regulator.h> #include "ehci.h" +DECLARE_GLOBAL_DATA_PTR; + #define USB_OTGREGS_OFFSET 0x000 #define USB_H1REGS_OFFSET 0x200 #define USB_H2REGS_OFFSET 0x400 @@ -48,6 +52,7 @@ #define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS 0x00000040 #define USBNC_OFFSET 0x200 +#define USBNC_PHY_STATUS_OFFSET 0x23C #define USBNC_PHYSTATUS_ID_DIG (1 << 4) /* otg_id status */ #define USBNC_PHYCFG2_ACAENB (1 << 4) /* otg_id detection enable */ #define UCTRL_PWR_POL (1 << 9) /* OTG Polarity of Power Pin */ @@ -384,6 +389,7 @@ int ehci_hcd_stop(int index) struct ehci_mx6_priv_data { struct ehci_ctrl ctrl; struct usb_ehci *ehci; + struct udevice *vbus_supply; enum usb_init_type init_type; int portnr; }; @@ -399,7 +405,15 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev) if (ret) return ret; - board_ehci_power(priv->portnr, (type == USB_INIT_DEVICE) ? 0 : 1); + if (priv->vbus_supply) { + ret = regulator_set_enable(priv->vbus_supply, + (type == USB_INIT_DEVICE) ? + false : true); + if (ret) { + puts("Error enabling VBUS supply\n"); + return ret; + } + } if (type == USB_INIT_DEVICE) return 0; @@ -417,24 +431,108 @@ static const struct ehci_ops mx6_ehci_ops = { .init_after_reset = mx6_init_after_reset }; +static int ehci_usb_phy_mode(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + void *__iomem addr = (void *__iomem)dev_get_addr(dev); + void *__iomem phy_ctrl, *__iomem phy_status; + const void *blob = gd->fdt_blob; + int offset = dev->of_offset, phy_off; + u32 val; + + /* + * About fsl,usbphy, Refer to + * Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt. + */ + if (is_mx6()) { + phy_off = fdtdec_lookup_phandle(blob, + offset, + "fsl,usbphy"); + if (phy_off < 0) + return -EINVAL; + + addr = (void __iomem *)fdtdec_get_addr(blob, phy_off, + "reg"); + if ((fdt_addr_t)addr == FDT_ADDR_T_NONE) + return -EINVAL; + + phy_ctrl = (void __iomem *)(addr + USBPHY_CTRL); + val = readl(phy_ctrl); + + if (val & USBPHY_CTRL_OTG_ID) + plat->init_type = USB_INIT_DEVICE; + else + plat->init_type = USB_INIT_HOST; + } else if (is_mx7()) { + phy_status = (void __iomem *)(addr + + USBNC_PHY_STATUS_OFFSET); + val = readl(phy_status); + + if (val & USBNC_PHYSTATUS_ID_DIG) + plat->init_type = USB_INIT_DEVICE; + else + plat->init_type = USB_INIT_HOST; + } else { + return -EINVAL; + } + + return 0; +} + +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + const char *mode; + + mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "dr_mode", NULL); + if (mode) { + if (strcmp(mode, "peripheral") == 0) + plat->init_type = USB_INIT_DEVICE; + else if (strcmp(mode, "host") == 0) + plat->init_type = USB_INIT_HOST; + else if (strcmp(mode, "otg") == 0) + return ehci_usb_phy_mode(dev); + else + return -EINVAL; + + return 0; + } + + return ehci_usb_phy_mode(dev); +} + static int ehci_usb_probe(struct udevice *dev) { struct usb_platdata *plat = dev_get_platdata(dev); struct usb_ehci *ehci = (struct usb_ehci *)dev_get_addr(dev); struct ehci_mx6_priv_data *priv = dev_get_priv(dev); + enum usb_init_type type = plat->init_type; struct ehci_hccr *hccr; struct ehci_hcor *hcor; int ret; priv->ehci = ehci; priv->portnr = dev->seq; - priv->init_type = plat->init_type; + priv->init_type = type; + + ret = device_get_supply_regulator(dev, "vbus-supply", + &priv->vbus_supply); + if (ret) + debug("%s: No vbus supply\n", dev->name); ret = ehci_mx6_common_init(ehci, priv->portnr); if (ret) return ret; - board_ehci_power(priv->portnr, (priv->init_type == USB_INIT_DEVICE) ? 0 : 1); + if (priv->vbus_supply) { + ret = regulator_set_enable(priv->vbus_supply, + (type == USB_INIT_DEVICE) ? + false : true); + if (ret) { + puts("Error enabling VBUS supply\n"); + return ret; + } + } if (priv->init_type == USB_INIT_HOST) { setbits_le32(&ehci->usbmode, CM_HOST); @@ -460,6 +558,7 @@ U_BOOT_DRIVER(usb_mx6) = { .name = "ehci_mx6", .id = UCLASS_USB, .of_match = mx6_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, .probe = ehci_usb_probe, .remove = ehci_deregister, .ops = &ehci_usb_ops, diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index c0b1b8dc17..a4cbc44564 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -1861,14 +1861,16 @@ static void *video_logo(void) __maybe_unused int y_off = 0; __maybe_unused ulong addr; __maybe_unused char *s; - __maybe_unused int len, space; + __maybe_unused int len, ret, space; splash_get_pos(&video_logo_xpos, &video_logo_ypos); #ifdef CONFIG_SPLASH_SCREEN s = getenv("splashimage"); if (s != NULL) { - splash_screen_prepare(); + ret = splash_screen_prepare(); + if (ret < 0) + return video_fb_address; addr = simple_strtoul(s, NULL, 16); if (video_display_bitmap(addr, diff --git a/drivers/video/rockchip/rk_hdmi.c b/drivers/video/rockchip/rk_hdmi.c index 032b1de103..1a4fa3677e 100644 --- a/drivers/video/rockchip/rk_hdmi.c +++ b/drivers/video/rockchip/rk_hdmi.c @@ -85,13 +85,13 @@ struct hdmi_phy_config { static const struct hdmi_phy_config rockchip_phy_config[] = { { - .mpixelclock = 74250, + .mpixelclock = 74250000, .sym_ctr = 0x8009, .term = 0x0004, .vlev_ctr = 0x0272, }, { - .mpixelclock = 148500, + .mpixelclock = 148500000, .sym_ctr = 0x802b, .term = 0x0004, .vlev_ctr = 0x028d, }, { - .mpixelclock = 297000, + .mpixelclock = 297000000, .sym_ctr = 0x8039, .term = 0x0005, .vlev_ctr = 0x028d, }, { .mpixelclock = ~0ul, @@ -101,22 +101,22 @@ static const struct hdmi_phy_config rockchip_phy_config[] = { static const struct hdmi_mpll_config rockchip_mpll_cfg[] = { { - .mpixelclock = 40000, + .mpixelclock = 40000000, .cpce = 0x00b3, .gmp = 0x0000, .curr = 0x0018, }, { - .mpixelclock = 65000, + .mpixelclock = 65000000, .cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028, }, { - .mpixelclock = 66000, + .mpixelclock = 66000000, .cpce = 0x013e, .gmp = 0x0003, .curr = 0x0038, }, { - .mpixelclock = 83500, + .mpixelclock = 835000000, .cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028, }, { - .mpixelclock = 146250, + .mpixelclock = 146250000, .cpce = 0x0051, .gmp = 0x0002, .curr = 0x0038, }, { - .mpixelclock = 148500, + .mpixelclock = 148500000, .cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000, }, { .mpixelclock = ~0ul, @@ -870,7 +870,7 @@ static int rk_hdmi_probe(struct udevice *dev) clk_free(&clk); } if (ret) { - debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret); + debug("%s: Failed to set hdmi clock: ret=%d\n", __func__, ret); return ret; } diff --git a/drivers/video/tegra124/display.c b/drivers/video/tegra124/display.c index d8999c3c68..28db96c952 100644 --- a/drivers/video/tegra124/display.c +++ b/drivers/video/tegra124/display.c @@ -343,7 +343,7 @@ static int display_init(struct udevice *dev, void *lcdbase, /* * Before we probe the display device (eDP), tell it that this device - * is are the source of the display data. + * is the source of the display data. */ ret = uclass_find_first_device(UCLASS_DISPLAY, &dp_dev); if (ret) { |