summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/Kconfig7
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk_zynqmp.c241
-rw-r--r--drivers/fpga/zynqpl.c12
-rw-r--r--drivers/i2c/i2c-cdns.c1
-rw-r--r--drivers/mmc/Kconfig107
-rw-r--r--drivers/mmc/Makefile27
-rw-r--r--drivers/mmc/arm_pl180_mmci.c4
-rw-r--r--drivers/mmc/bfin_sdh.c4
-rw-r--r--drivers/mmc/davinci_mmc.c4
-rw-r--r--drivers/mmc/dw_mmc.c5
-rw-r--r--drivers/mmc/fsl_esdhc.c3
-rw-r--r--drivers/mmc/ftsdc010_mci.c4
-rw-r--r--drivers/mmc/gen_atmel_mci.c4
-rw-r--r--drivers/mmc/mmc_spi.c3
-rw-r--r--drivers/mmc/mvebu_mmc.c4
-rw-r--r--drivers/mmc/mxcmmc.c4
-rw-r--r--drivers/mmc/mxsmmc.c4
-rw-r--r--drivers/mmc/omap_hsmmc.c6
-rw-r--r--drivers/mmc/pic32_sdhci.c17
-rw-r--r--drivers/mmc/pxa_mmc_gen.c8
-rw-r--r--drivers/mmc/rockchip_sdhci.c19
-rw-r--r--drivers/mmc/s3c_sdi.c6
-rw-r--r--drivers/mmc/s5p_sdhci.c15
-rw-r--r--drivers/mmc/sdhci-cadence.c125
-rw-r--r--drivers/mmc/sdhci.c59
-rw-r--r--drivers/mmc/sh_mmcif.c4
-rw-r--r--drivers/mmc/sh_sdhi.c6
-rw-r--r--drivers/mmc/sunxi_mmc.c6
-rw-r--r--drivers/mmc/tegra_mmc.c4
-rw-r--r--drivers/mtd/nand/omap_gpmc.c8
-rw-r--r--drivers/mtd/spi/sunxi_spi_spl.c2
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/designware.c57
-rw-r--r--drivers/net/designware.h13
-rw-r--r--drivers/net/gmac_rockchip.c154
-rw-r--r--drivers/net/phy/xilinx_phy.c4
-rw-r--r--drivers/net/zynq_gem.c50
-rw-r--r--drivers/power/axp152.c2
-rw-r--r--drivers/power/axp209.c2
-rw-r--r--drivers/power/battery/bat_trats2.c2
-rw-r--r--drivers/power/exynos-tmu.c8
-rw-r--r--drivers/power/fuel_gauge/fg_max17042.c4
-rw-r--r--drivers/power/mfd/fg_max77693.c4
-rw-r--r--drivers/power/mfd/pmic_max77693.c8
-rw-r--r--drivers/power/palmas.c11
-rw-r--r--drivers/power/pmic/pmic_hi6553.c4
-rw-r--r--drivers/power/pmic/pmic_max77686.c18
-rw-r--r--drivers/power/pmic/pmic_max8997.c8
-rw-r--r--drivers/power/power_core.c8
-rw-r--r--drivers/power/power_i2c.c21
-rw-r--r--drivers/power/power_spi.c18
-rw-r--r--drivers/power/tps6586x.c12
-rw-r--r--drivers/rtc/Kconfig6
-rw-r--r--drivers/rtc/pcf2127.c42
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/spi/Makefile2
-rw-r--r--drivers/spi/cf_qspi.c354
-rw-r--r--drivers/spi/cf_spi.c4
-rw-r--r--drivers/spi/ep93xx_spi.c272
-rw-r--r--drivers/usb/gadget/Kconfig4
-rw-r--r--drivers/usb/gadget/ether.c153
-rw-r--r--drivers/usb/gadget/rndis.c13
-rw-r--r--drivers/usb/gadget/rndis.h19
-rw-r--r--drivers/video/rockchip/rk_hdmi.c20
66 files changed, 1138 insertions, 893 deletions
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c05ce2a..335ef9e 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 40a5e8c..f55348e 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 0000000..694274d
--- /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(&regs);
+
+ 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(&regs);
+
+ 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(&regs);
+
+ 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 ef889ea..2ff716c 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 f49f60b..ef85a70 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 c3462ab..9ed8da3 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 2b136ea..4dca09c 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 e64ac3c..ddf8383 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 993a00c..1627dca 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 b495c75..9edb668 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 d6ac46c..700f764 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 9796d39..7defeb4 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(&regs->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 e88c632..652a718 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(&regs->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 cca0b04..7dc4a5d 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 2510117..a9d95fb 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 a2792ac..3c7fb21 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 5a385a3..dcf17c5 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 0896028..fe1fe70 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 0a1ee40..b326846 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 2abf943..c06364c 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 a5462e2..f627553 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, &regs->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, &regs->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 c56e1a3..e33e35e 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 1b8358a..faf7b83 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 ac737e0..1f1d2ed 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 0000000..2253bbc
--- /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 cbf5f56..5b404ff 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 69ded9e..1ff59f0 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 78e2ef6..25224e2 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 b8716c9..fd3fc2a 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 97b1154..0211dc7 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 d1e1bdd..f4f0de3 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 e70064c..a24c115 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 929b9e2..f52629f 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 9a7bfc6..2493a48 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 9e6d726..f242fc6 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 d345c5b..7992d0e 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 0000000..5f833fa
--- /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 f3eaf2e..920bfcb 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 d2e5e7c..6dd87cf 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(&regs->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__, &regs->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, &regs->phymntnc);
- if (mdio_wait(regs))
- return 1;
+ err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
+ true, 20000, true);
+ if (err)
+ return err;
if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK)
*data = readl(&regs->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(&regs->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 cd07275..c4b3fe5 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 731b75e..4b25ef2 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 57221ad..6329e02 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 b9968c2..6a66267 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 154ca6a..e433494 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 4519fed..df15508 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 6b28e28..c63390e 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 4f9a62c..c813b21 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 0af7987..b2346b6 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 93c8d2b..8e65331 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 a36a9a0..32afb3f 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 fe1f316..b72286d 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 0dcf9fe..8a8ea10 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 1e55446..ef8531d 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 8650983..f50c4d1 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 57af1b5..cb79a01 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 bc59c6c..dcf0340 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 b26ada3..b11f3ff 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 c1ce158..896b093 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 e57e63e..0000000
--- 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 6ce1101..7be9427 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 cb682dd..0000000
--- 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 40839d8..261ed12 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 289e5f1..f1b0709 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 844a0c7..5ad4813 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 7a389a5..084af85 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 032b1de..1a4fa36 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;
}