diff options
Diffstat (limited to 'drivers')
66 files changed, 1138 insertions, 893 deletions
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/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 c3462ab724..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,24 @@ 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 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/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/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/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/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/ether.c b/drivers/usb/gadget/ether.c index 289e5f1583..f1b0709821 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; }; @@ -1850,7 +1859,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 +2013,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 +2203,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 +2216,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 +2224,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 +2291,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 +2544,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 +2616,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/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; } |