summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2018-08-17 07:24:34 -0400
committerTom Rini <trini@konsulko.com>2018-08-17 07:24:34 -0400
commit719afeb0b3c60af82f701f122978b935aa6a5217 (patch)
tree2e8c4d6074f4cea83524faa719aef0aafd8683b0
parent86cf1c82850f7c226f23684e19616e526ffaf10f (diff)
parentb0c0a715f90690a7dd4f33cb5b5c21960be26d3c (diff)
downloadu-boot-719afeb0b3c60af82f701f122978b935aa6a5217.tar.gz
u-boot-719afeb0b3c60af82f701f122978b935aa6a5217.tar.xz
u-boot-719afeb0b3c60af82f701f122978b935aa6a5217.zip
Merge branch 'master' of git://git.denx.de/u-boot-socfpga
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/dts/socfpga_arria10.dtsi32
-rw-r--r--arch/arm/dts/socfpga_arria10_socdk.dtsi26
-rw-r--r--arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts17
-rw-r--r--arch/arm/dts/socfpga_arria5_socdk.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_de10_nano.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_de1_soc.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_is1.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_socdk.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_sockit.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_socrates.dts5
-rw-r--r--arch/arm/dts/socfpga_cyclone5_sr1500.dts2
-rw-r--r--arch/arm/dts/socfpga_cyclone5_vining_fpga.dts5
-rw-r--r--arch/arm/mach-socfpga/Kconfig10
-rw-r--r--arch/arm/mach-socfpga/clock_manager.c2
-rw-r--r--arch/arm/mach-socfpga/clock_manager_arria10.c306
-rw-r--r--arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h6
-rw-r--r--arch/arm/mach-socfpga/include/mach/misc.h6
-rw-r--r--arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h4
-rw-r--r--arch/arm/mach-socfpga/include/mach/system_manager_s10.h6
-rw-r--r--arch/arm/mach-socfpga/misc_arria10.c176
-rw-r--r--arch/arm/mach-socfpga/misc_gen5.c29
-rw-r--r--arch/arm/mach-socfpga/reset_manager_arria10.c135
-rw-r--r--arch/arm/mach-socfpga/spl_a10.c9
-rw-r--r--arch/arm/mach-socfpga/spl_gen5.c44
-rw-r--r--configs/socfpga_arria10_defconfig2
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/altera/Makefile7
-rw-r--r--drivers/clk/altera/clk-arria10.c363
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c40
-rw-r--r--drivers/net/Kconfig8
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/dwmac_socfpga.c143
35 files changed, 800 insertions, 627 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 63ec02403a..9f5eaf8591 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -772,7 +772,7 @@ config ARCH_SNAPDRAGON
config ARCH_SOCFPGA
bool "Altera SOCFPGA family"
select ARCH_EARLY_INIT_R
- select ARCH_MISC_INIT
+ select ARCH_MISC_INIT if !TARGET_SOCFPGA_ARRIA10
select ARM64 if TARGET_SOCFPGA_STRATIX10
select CPU_V7A if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10
select DM
diff --git a/arch/arm/dts/socfpga_arria10.dtsi b/arch/arm/dts/socfpga_arria10.dtsi
index 2f935a21e9..ce000512ef 100644
--- a/arch/arm/dts/socfpga_arria10.dtsi
+++ b/arch/arm/dts/socfpga_arria10.dtsi
@@ -55,6 +55,7 @@
device_type = "soc";
interrupt-parent = <&intc>;
ranges;
+ u-boot,dm-pre-reloc;
amba {
compatible = "simple-bus";
@@ -93,29 +94,35 @@
clkmgr@ffd04000 {
compatible = "altr,clk-mgr";
reg = <0xffd04000 0x1000>;
+ u-boot,dm-pre-reloc;
clocks {
#address-cells = <1>;
#size-cells = <0>;
+ u-boot,dm-pre-reloc;
cb_intosc_hs_div2_clk: cb_intosc_hs_div2_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
+ u-boot,dm-pre-reloc;
};
cb_intosc_ls_clk: cb_intosc_ls_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
+ u-boot,dm-pre-reloc;
};
f2s_free_clk: f2s_free_clk {
#clock-cells = <0>;
compatible = "fixed-clock";
+ u-boot,dm-pre-reloc;
};
osc1: osc1 {
#clock-cells = <0>;
compatible = "fixed-clock";
+ u-boot,dm-pre-reloc;
};
main_pll: main_pll@40 {
@@ -126,6 +133,7 @@
clocks = <&osc1>, <&cb_intosc_ls_clk>,
<&f2s_free_clk>;
reg = <0x40>;
+ u-boot,dm-pre-reloc;
main_mpu_base_clk: main_mpu_base_clk {
#clock-cells = <0>;
@@ -214,6 +222,7 @@
clocks = <&osc1>, <&cb_intosc_ls_clk>,
<&f2s_free_clk>, <&main_periph_ref_clk>;
reg = <0xC0>;
+ u-boot,dm-pre-reloc;
peri_mpu_base_clk: peri_mpu_base_clk {
#clock-cells = <0>;
@@ -427,8 +436,8 @@
rx-fifo-depth = <16384>;
clocks = <&l4_mp_clk>;
clock-names = "stmmaceth";
- resets = <&rst EMAC0_RESET>;
- reset-names = "stmmaceth";
+ resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>;
+ reset-names = "stmmaceth", "stmmaceth-ocp";
snps,axi-config = <&socfpga_axi_setup>;
status = "disabled";
};
@@ -447,8 +456,8 @@
rx-fifo-depth = <16384>;
clocks = <&l4_mp_clk>;
clock-names = "stmmaceth";
- resets = <&rst EMAC1_RESET>;
- reset-names = "stmmaceth";
+ resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>;
+ reset-names = "stmmaceth", "stmmaceth-ocp";
snps,axi-config = <&socfpga_axi_setup>;
status = "disabled";
};
@@ -467,6 +476,8 @@
rx-fifo-depth = <16384>;
clocks = <&l4_mp_clk>;
clock-names = "stmmaceth";
+ resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>;
+ reset-names = "stmmaceth", "stmmaceth-ocp";
snps,axi-config = <&socfpga_axi_setup>;
status = "disabled";
};
@@ -547,6 +558,8 @@
reg = <0xffc02200 0x100>;
interrupts = <0 105 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&l4_sp_clk>;
+ resets = <&rst I2C0_RESET>;
+ reset-names = "i2c";
status = "disabled";
};
@@ -557,6 +570,8 @@
reg = <0xffc02300 0x100>;
interrupts = <0 106 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&l4_sp_clk>;
+ resets = <&rst I2C1_RESET>;
+ reset-names = "i2c";
status = "disabled";
};
@@ -567,6 +582,8 @@
reg = <0xffc02400 0x100>;
interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&l4_sp_clk>;
+ resets = <&rst I2C2_RESET>;
+ reset-names = "i2c";
status = "disabled";
};
@@ -577,6 +594,8 @@
reg = <0xffc02500 0x100>;
interrupts = <0 108 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&l4_sp_clk>;
+ resets = <&rst I2C3_RESET>;
+ reset-names = "i2c";
status = "disabled";
};
@@ -587,6 +606,8 @@
reg = <0xffc02600 0x100>;
interrupts = <0 109 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&l4_sp_clk>;
+ resets = <&rst I2C4_RESET>;
+ reset-names = "i2c";
status = "disabled";
};
@@ -735,6 +756,7 @@
compatible = "altr,rst-mgr";
reg = <0xffd05000 0x100>;
altr,modrst-offset = <0x20>;
+ u-boot,dm-pre-reloc;
};
scu: snoop-control-unit@ffffc000 {
@@ -795,6 +817,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&l4_sp_clk>;
+ resets = <&rst UART0_RESET>;
status = "disabled";
};
@@ -805,6 +828,7 @@
reg-shift = <2>;
reg-io-width = <4>;
clocks = <&l4_sp_clk>;
+ resets = <&rst UART1_RESET>;
status = "disabled";
};
diff --git a/arch/arm/dts/socfpga_arria10_socdk.dtsi b/arch/arm/dts/socfpga_arria10_socdk.dtsi
index 3f59f02577..9160c20bd0 100644
--- a/arch/arm/dts/socfpga_arria10_socdk.dtsi
+++ b/arch/arm/dts/socfpga_arria10_socdk.dtsi
@@ -23,6 +23,7 @@
aliases {
ethernet0 = &gmac0;
serial0 = &uart1;
+ i2c0 = &i2c1;
};
chosen {
@@ -166,3 +167,28 @@
&watchdog1 {
status = "okay";
};
+
+/* Clock available early */
+&main_noc_base_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&main_periph_ref_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&peri_noc_base_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&noc_free_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&l4_mp_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&l4_sp_clk {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts
index 9c6070ded9..998d811210 100644
--- a/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts
+++ b/arch/arm/dts/socfpga_arria10_socdk_sdmmc.dts
@@ -38,3 +38,20 @@
<48 IRQ_TYPE_LEVEL_HIGH>;
};
};
+
+/* Clock available early */
+&main_sdmmc_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&peri_sdmmc_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&sdmmc_free_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&sdmmc_clk {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_arria5_socdk.dts b/arch/arm/dts/socfpga_arria5_socdk.dts
index 449ba9cbb9..6f4de2f563 100644
--- a/arch/arm/dts/socfpga_arria5_socdk.dts
+++ b/arch/arm/dts/socfpga_arria5_socdk.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
memory {
@@ -99,3 +100,7 @@
cdns,tslch-ns = <4>;
};
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts b/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts
index aeb327dd5b..139a70f265 100644
--- a/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts
+++ b/arch/arm/dts/socfpga_cyclone5_dbm_soc1.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -56,3 +57,7 @@
disable-over-current;
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts b/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts
index f4a98e4bb0..d504150edd 100644
--- a/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts
+++ b/arch/arm/dts/socfpga_cyclone5_de0_nano_soc.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -75,3 +76,7 @@
&usb1 {
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_de10_nano.dts b/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
index 7da2d8b043..d4dd9e9bca 100644
--- a/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
+++ b/arch/arm/dts/socfpga_cyclone5_de10_nano.dts
@@ -13,6 +13,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -65,3 +66,7 @@
&usb1 {
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_de1_soc.dts b/arch/arm/dts/socfpga_cyclone5_de1_soc.dts
index e6fadb4fc9..f62292284d 100644
--- a/arch/arm/dts/socfpga_cyclone5_de1_soc.dts
+++ b/arch/arm/dts/socfpga_cyclone5_de1_soc.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -63,3 +64,7 @@
&usb1 {
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_is1.dts b/arch/arm/dts/socfpga_cyclone5_is1.dts
index aa1ce2c3e2..4e94d86114 100644
--- a/arch/arm/dts/socfpga_cyclone5_is1.dts
+++ b/arch/arm/dts/socfpga_cyclone5_is1.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
memory {
@@ -102,3 +103,7 @@
&usb1 {
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_socdk.dts b/arch/arm/dts/socfpga_cyclone5_socdk.dts
index 55c70abb02..c28be67bb9 100644
--- a/arch/arm/dts/socfpga_cyclone5_socdk.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socdk.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
memory {
@@ -113,3 +114,7 @@
&usb1 {
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_sockit.dts b/arch/arm/dts/socfpga_cyclone5_sockit.dts
index 08d8356d80..c7a6cf2db8 100644
--- a/arch/arm/dts/socfpga_cyclone5_sockit.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sockit.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -93,3 +94,7 @@
&usb1 {
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_socrates.dts b/arch/arm/dts/socfpga_cyclone5_socrates.dts
index 0d452ae300..8cde9906a0 100644
--- a/arch/arm/dts/socfpga_cyclone5_socrates.dts
+++ b/arch/arm/dts/socfpga_cyclone5_socrates.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -84,3 +85,7 @@
disable-over-current;
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/socfpga_cyclone5_sr1500.dts b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
index 341df7a3e7..86c61fe081 100644
--- a/arch/arm/dts/socfpga_cyclone5_sr1500.dts
+++ b/arch/arm/dts/socfpga_cyclone5_sr1500.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -67,6 +68,7 @@
&uart0 {
status = "okay";
+ u-boot,dm-pre-reloc;
};
&usb1 {
diff --git a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
index 7a032af3a4..85ab56379f 100644
--- a/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
+++ b/arch/arm/dts/socfpga_cyclone5_vining_fpga.dts
@@ -11,6 +11,7 @@
chosen {
bootargs = "console=ttyS0,115200";
+ stdout-path = "serial0:115200n8";
};
aliases {
@@ -108,3 +109,7 @@
&usb1 {
status = "okay";
};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 5c1df2cf1f..06f8527aa4 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -11,6 +11,16 @@ config TARGET_SOCFPGA_ARRIA10
bool
select ALTERA_SDRAM
select SPL_BOARD_INIT if SPL
+ select CLK
+ select SPL_CLK if SPL
+ select DM_I2C
+ select DM_RESET
+ select SPL_DM_RESET if SPL
+ select REGMAP
+ select SPL_REGMAP if SPL
+ select SYSCON
+ select SPL_SYSCON if SPL
+ select ETH_DESIGNWARE_SOCFPGA
config TARGET_SOCFPGA_CYCLONE5
bool
diff --git a/arch/arm/mach-socfpga/clock_manager.c b/arch/arm/mach-socfpga/clock_manager.c
index 59ede59b59..9f3c643df8 100644
--- a/arch/arm/mach-socfpga/clock_manager.c
+++ b/arch/arm/mach-socfpga/clock_manager.c
@@ -42,9 +42,11 @@ int cm_wait_for_fsm(void)
int set_cpu_clk_info(void)
{
+#if defined(CONFIG_TARGET_SOCFPGA_GEN5)
/* Calculate the clock frequencies required for drivers */
cm_get_l4_sp_clk_hz();
cm_get_mmc_controller_clk_hz();
+#endif
gd->bd->bi_arm_freq = cm_get_mpu_clk_hz() / 1000000;
gd->bd->bi_dsp_freq = 0;
diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c
index defa2f6261..1b4052cd37 100644
--- a/arch/arm/mach-socfpga/clock_manager_arria10.c
+++ b/arch/arm/mach-socfpga/clock_manager_arria10.c
@@ -7,6 +7,8 @@
#include <fdtdec.h>
#include <asm/io.h>
#include <dm.h>
+#include <clk.h>
+#include <dm/device-internal.h>
#include <asm/arch/clock_manager.h>
static const struct socfpga_clock_manager *clock_manager_base =
@@ -15,10 +17,6 @@ static const struct socfpga_clock_manager *clock_manager_base =
static u32 eosc1_hz;
static u32 cb_intosc_hz;
static u32 f2s_free_hz;
-static u32 cm_l4_main_clk_hz;
-static u32 cm_l4_sp_clk_hz;
-static u32 cm_l4_mp_clk_hz;
-static u32 cm_l4_sys_free_clk_hz;
struct mainpll_cfg {
u32 vco0_psrc;
@@ -141,9 +139,9 @@ struct strtopu32 {
};
const struct strtopu32 dt_to_val[] = {
- { "/clocks/altera_arria10_hps_eosc1", &eosc1_hz},
- { "/clocks/altera_arria10_hps_cb_intosc_ls", &cb_intosc_hz},
- { "/clocks/altera_arria10_hps_f2h_free", &f2s_free_hz},
+ { "altera_arria10_hps_eosc1", &eosc1_hz },
+ { "altera_arria10_hps_cb_intosc_ls", &cb_intosc_hz },
+ { "altera_arria10_hps_f2h_free", &f2s_free_hz },
};
static int of_to_struct(const void *blob, int node, const struct strtou32 *cfg_tab,
@@ -163,28 +161,39 @@ static int of_to_struct(const void *blob, int node, const struct strtou32 *cfg_t
return 0;
}
-static void of_get_input_clks(const void *blob)
+static int of_get_input_clks(const void *blob)
{
- int node, i;
+ struct udevice *dev;
+ struct clk clk;
+ int i, ret;
for (i = 0; i < ARRAY_SIZE(dt_to_val); i++) {
- node = fdt_path_offset(blob, dt_to_val[i].str);
+ memset(&clk, 0, sizeof(clk));
- if (node < 0)
- continue;
+ ret = uclass_get_device_by_name(UCLASS_CLK, dt_to_val[i].str,
+ &dev);
+ if (ret)
+ return ret;
- fdtdec_get_int_array(blob, node, "clock-frequency",
- dt_to_val[i].p, 1);
+ ret = clk_request(dev, &clk);
+ if (ret)
+ return ret;
+
+ *dt_to_val[i].p = clk_get_rate(&clk);
}
+
+ return 0;
}
static int of_get_clk_cfg(const void *blob, struct mainpll_cfg *main_cfg,
struct perpll_cfg *per_cfg)
{
- int node, child, len;
+ int ret, node, child, len;
const char *node_name;
- of_get_input_clks(blob);
+ ret = of_get_input_clks(blob);
+ if (ret)
+ return ret;
node = fdtdec_next_compatible(blob, 0, COMPAT_ALTERA_SOCFPGA_CLK_INIT);
@@ -894,50 +903,6 @@ void cm_use_intosc(void)
CLKMGR_CLKMGR_CTL_BOOTCLK_INTOSC_SET_MSK);
}
-unsigned int cm_get_noc_clk_hz(void)
-{
- unsigned int clk_src, divisor, nocclk, src_hz;
-
- nocclk = readl(&clock_manager_base->main_pll.nocclk);
- clk_src = (nocclk >> CLKMGR_MAINPLL_NOCCLK_SRC_LSB) &
- CLKMGR_MAINPLL_NOCCLK_SRC_MSK;
-
- divisor = 1 + (nocclk & CLKMGR_MAINPLL_NOCDIV_MSK);
-
- if (clk_src == CLKMGR_PERPLLGRP_SRC_MAIN) {
- src_hz = cm_get_main_vco_clk_hz();
- src_hz /= 1 +
- (readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOC_CLK_OFFSET) &
- CLKMGR_MAINPLL_NOCCLK_CNT_MSK);
- } else if (clk_src == CLKMGR_PERPLLGRP_SRC_PERI) {
- src_hz = cm_get_per_vco_clk_hz();
- src_hz /= 1 +
- ((readl(SOCFPGA_CLKMGR_ADDRESS +
- CLKMGR_MAINPLL_NOC_CLK_OFFSET) >>
- CLKMGR_MAINPLL_NOCCLK_PERICNT_LSB) &
- CLKMGR_MAINPLL_NOCCLK_CNT_MSK);
- } else if (clk_src == CLKMGR_PERPLLGRP_SRC_OSC1) {
- src_hz = eosc1_hz;
- } else if (clk_src == CLKMGR_PERPLLGRP_SRC_INTOSC) {
- src_hz = cb_intosc_hz;
- } else if (clk_src == CLKMGR_PERPLLGRP_SRC_FPGA) {
- src_hz = f2s_free_hz;
- } else {
- src_hz = 0;
- }
-
- return src_hz / divisor;
-}
-
-unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift)
-{
- unsigned int divisor2 = 1 <<
- ((readl(&clock_manager_base->main_pll.nocdiv) >>
- nocdivshift) & CLKMGR_MAINPLL_NOCDIV_MSK);
-
- return cm_get_noc_clk_hz() / divisor2;
-}
-
int cm_basic_init(const void *blob)
{
struct mainpll_cfg main_cfg;
@@ -952,213 +917,74 @@ int cm_basic_init(const void *blob)
if (rval)
return rval;
- rval = cm_full_cfg(&main_cfg, &per_cfg);
-
- cm_l4_main_clk_hz =
- cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB);
-
- cm_l4_mp_clk_hz = cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB);
-
- cm_l4_sp_clk_hz = cm_get_l4_sp_clk_hz();
-
- cm_l4_sys_free_clk_hz = cm_get_noc_clk_hz() / 4;
-
- return rval;
+ return cm_full_cfg(&main_cfg, &per_cfg);
}
-unsigned long cm_get_mpu_clk_hz(void)
+static u32 cm_get_rate_dm(char *name)
{
- u32 reg, clk_hz;
- u32 clk_src, mainmpuclk_reg;
-
- mainmpuclk_reg = readl(&clock_manager_base->main_pll.mpuclk);
-
- clk_src = (mainmpuclk_reg >> CLKMGR_MAINPLL_MPUCLK_SRC_LSB) &
- CLKMGR_MAINPLL_MPUCLK_SRC_MSK;
-
- reg = readl(&clock_manager_base->altera.mpuclk);
- /* Check MPU clock source: main, periph, osc1, intosc or f2s? */
- switch (clk_src) {
- case CLKMGR_MAINPLL_MPUCLK_SRC_MAIN:
- clk_hz = cm_get_main_vco_clk_hz();
- clk_hz /= (reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1;
- break;
- case CLKMGR_MAINPLL_MPUCLK_SRC_PERI:
- clk_hz = cm_get_per_vco_clk_hz();
- clk_hz /= (((reg >> CLKMGR_MAINPLL_MPUCLK_PERICNT_LSB) &
- CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1);
- break;
- case CLKMGR_MAINPLL_MPUCLK_SRC_OSC1:
- clk_hz = eosc1_hz;
- break;
- case CLKMGR_MAINPLL_MPUCLK_SRC_INTOSC:
- clk_hz = cb_intosc_hz;
- break;
- case CLKMGR_MAINPLL_MPUCLK_SRC_FPGA:
- clk_hz = f2s_free_hz;
- break;
- default:
- printf("cm_get_mpu_clk_hz invalid clk_src %d\n", clk_src);
+ struct uclass *uc;
+ struct udevice *dev = NULL;
+ struct clk clk = { 0 };
+ ulong rate;
+ int ret;
+
+ /* Device addresses start at 1 */
+ ret = uclass_get(UCLASS_CLK, &uc);
+ if (ret)
return 0;
- }
-
- clk_hz /= (mainmpuclk_reg & CLKMGR_MAINPLL_MPUCLK_CNT_MSK) + 1;
- return clk_hz;
-}
-
-unsigned int cm_get_per_vco_clk_hz(void)
-{
- u32 src_hz = 0;
- u32 clk_src = 0;
- u32 numer = 0;
- u32 denom = 0;
- u32 vco = 0;
-
- clk_src = readl(&clock_manager_base->per_pll.vco0);
-
- clk_src = (clk_src >> CLKMGR_PERPLL_VCO0_PSRC_LSB) &
- CLKMGR_PERPLL_VCO0_PSRC_MSK;
-
- if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_EOSC) {
- src_hz = eosc1_hz;
- } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_E_INTOSC) {
- src_hz = cb_intosc_hz;
- } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_F2S) {
- src_hz = f2s_free_hz;
- } else if (clk_src == CLKMGR_PERPLL_VCO0_PSRC_MAIN) {
- src_hz = cm_get_main_vco_clk_hz();
- src_hz /= (readl(&clock_manager_base->main_pll.cntr15clk) &
- CLKMGR_MAINPLL_CNTRCLK_MSK) + 1;
- } else {
- printf("cm_get_per_vco_clk_hz invalid clk_src %d\n", clk_src);
+ ret = uclass_get_device_by_name(UCLASS_CLK, name, &dev);
+ if (ret)
return 0;
- }
-
- vco = readl(&clock_manager_base->per_pll.vco1);
-
- numer = vco & CLKMGR_PERPLL_VCO1_NUMER_MSK;
-
- denom = (vco >> CLKMGR_PERPLL_VCO1_DENOM_LSB) &
- CLKMGR_PERPLL_VCO1_DENOM_MSK;
-
- vco = src_hz;
- vco /= 1 + denom;
- vco *= 1 + numer;
-
- return vco;
-}
-unsigned int cm_get_main_vco_clk_hz(void)
-{
- u32 src_hz, numer, denom, vco;
-
- u32 clk_src = readl(&clock_manager_base->main_pll.vco0);
-
- clk_src = (clk_src >> CLKMGR_MAINPLL_VCO0_PSRC_LSB) &
- CLKMGR_MAINPLL_VCO0_PSRC_MSK;
-
- if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_EOSC) {
- src_hz = eosc1_hz;
- } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_E_INTOSC) {
- src_hz = cb_intosc_hz;
- } else if (clk_src == CLKMGR_MAINPLL_VCO0_PSRC_F2S) {
- src_hz = f2s_free_hz;
- } else {
- printf("cm_get_main_vco_clk_hz invalid clk_src %d\n", clk_src);
+ ret = device_probe(dev);
+ if (ret)
return 0;
- }
-
- vco = readl(&clock_manager_base->main_pll.vco1);
-
- numer = vco & CLKMGR_MAINPLL_VCO1_NUMER_MSK;
- denom = (vco >> CLKMGR_MAINPLL_VCO1_DENOM_LSB) &
- CLKMGR_MAINPLL_VCO1_DENOM_MSK;
+ ret = clk_request(dev, &clk);
+ if (ret)
+ return 0;
- vco = src_hz;
- vco /= 1 + denom;
- vco *= 1 + numer;
+ rate = clk_get_rate(&clk);
- return vco;
-}
+ clk_free(&clk);
-unsigned int cm_get_l4_sp_clk_hz(void)
-{
- return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4SPCLK_LSB);
+ return rate;
}
-unsigned int cm_get_mmc_controller_clk_hz(void)
+static u32 cm_get_rate_dm_khz(char *name)
{
- u32 clk_hz = 0;
- u32 clk_input = 0;
-
- clk_input = readl(&clock_manager_base->per_pll.cntr6clk);
- clk_input = (clk_input >> CLKMGR_PERPLL_CNTR6CLK_SRC_LSB) &
- CLKMGR_PERPLLGRP_SRC_MSK;
-
- switch (clk_input) {
- case CLKMGR_PERPLLGRP_SRC_MAIN:
- clk_hz = cm_get_main_vco_clk_hz();
- clk_hz /= 1 + (readl(&clock_manager_base->main_pll.cntr6clk) &
- CLKMGR_MAINPLL_CNTRCLK_MSK);
- break;
-
- case CLKMGR_PERPLLGRP_SRC_PERI:
- clk_hz = cm_get_per_vco_clk_hz();
- clk_hz /= 1 + (readl(&clock_manager_base->per_pll.cntr6clk) &
- CLKMGR_PERPLL_CNTRCLK_MSK);
- break;
-
- case CLKMGR_PERPLLGRP_SRC_OSC1:
- clk_hz = eosc1_hz;
- break;
-
- case CLKMGR_PERPLLGRP_SRC_INTOSC:
- clk_hz = cb_intosc_hz;
- break;
-
- case CLKMGR_PERPLLGRP_SRC_FPGA:
- clk_hz = f2s_free_hz;
- break;
- }
-
- return clk_hz / 4;
+ return cm_get_rate_dm(name) / 1000;
}
-unsigned int cm_get_spi_controller_clk_hz(void)
+unsigned long cm_get_mpu_clk_hz(void)
{
- return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB);
+ return cm_get_rate_dm("main_mpu_base_clk");
}
unsigned int cm_get_qspi_controller_clk_hz(void)
{
- return cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB);
+ return cm_get_rate_dm("qspi_clk");
}
-/* Override weak dw_spi_get_clk implementation in designware_spi.c driver */
-int dw_spi_get_clk(struct udevice *bus, ulong *rate)
+unsigned int cm_get_l4_sp_clk_hz(void)
{
- *rate = cm_get_spi_controller_clk_hz();
-
- return 0;
+ return cm_get_rate_dm("l4_sp_clk");
}
void cm_print_clock_quick_summary(void)
{
- printf("MPU %10ld kHz\n", cm_get_mpu_clk_hz() / 1000);
- printf("MMC %8d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
- printf("QSPI %8d kHz\n", cm_get_qspi_controller_clk_hz() / 1000);
- printf("SPI %8d kHz\n", cm_get_spi_controller_clk_hz() / 1000);
- printf("EOSC1 %8d kHz\n", eosc1_hz / 1000);
- printf("cb_intosc %8d kHz\n", cb_intosc_hz / 1000);
- printf("f2s_free %8d kHz\n", f2s_free_hz / 1000);
- printf("Main VCO %8d kHz\n", cm_get_main_vco_clk_hz() / 1000);
- printf("NOC %8d kHz\n", cm_get_noc_clk_hz() / 1000);
- printf("L4 Main %8d kHz\n",
- cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MAINCLK_LSB) / 1000);
- printf("L4 MP %8d kHz\n",
- cm_get_l4_noc_hz(CLKMGR_MAINPLL_NOCDIV_L4MPCLK_LSB) / 1000);
- printf("L4 SP %8d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
- printf("L4 sys free %8d kHz\n", cm_l4_sys_free_clk_hz / 1000);
+ printf("MPU %10d kHz\n", cm_get_rate_dm_khz("main_mpu_base_clk"));
+ printf("MMC %8d kHz\n", cm_get_rate_dm_khz("sdmmc_clk"));
+ printf("QSPI %8d kHz\n", cm_get_rate_dm_khz("qspi_clk"));
+ printf("SPI %8d kHz\n", cm_get_rate_dm_khz("spi_m_clk"));
+ printf("EOSC1 %8d kHz\n", cm_get_rate_dm_khz("osc1"));
+ printf("cb_intosc %8d kHz\n", cm_get_rate_dm_khz("cb_intosc_ls_clk"));
+ printf("f2s_free %8d kHz\n", cm_get_rate_dm_khz("f2s_free_clk"));
+ printf("Main VCO %8d kHz\n", cm_get_rate_dm_khz("main_pll@40"));
+ printf("NOC %8d kHz\n", cm_get_rate_dm_khz("main_noc_base_clk"));
+ printf("L4 Main %8d kHz\n", cm_get_rate_dm_khz("l4_main_clk"));
+ printf("L4 MP %8d kHz\n", cm_get_rate_dm_khz("l4_mp_clk"));
+ printf("L4 SP %8d kHz\n", cm_get_rate_dm_khz("l4_sp_clk"));
+ printf("L4 sys free %8d kHz\n", cm_get_rate_dm_khz("l4_sys_free_clk"));
}
diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h
index cb2306e5bc..b3c8853aa3 100644
--- a/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h
+++ b/arch/arm/mach-socfpga/include/mach/clock_manager_arria10.h
@@ -90,18 +90,12 @@ struct socfpga_clock_manager {
};
void cm_use_intosc(void);
-unsigned int cm_get_noc_clk_hz(void);
-unsigned int cm_get_l4_noc_hz(unsigned int nocdivshift);
int cm_basic_init(const void *blob);
unsigned int cm_get_l4_sp_clk_hz(void);
-unsigned int cm_get_main_vco_clk_hz(void);
-unsigned int cm_get_per_vco_clk_hz(void);
unsigned long cm_get_mpu_clk_hz(void);
unsigned int cm_get_qspi_controller_clk_hz(void);
-unsigned int cm_get_mmc_controller_clk_hz(void);
-unsigned int cm_get_spi_controller_clk_hz(void);
#endif /* __ASSEMBLER__ */
diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h
index 7fe77ac8d8..e7e08b72d2 100644
--- a/arch/arm/mach-socfpga/include/mach/misc.h
+++ b/arch/arm/mach-socfpga/include/mach/misc.h
@@ -21,10 +21,8 @@ void socfpga_fpga_add(void);
static inline void socfpga_fpga_add(void) {}
#endif
-#if defined(CONFIG_TARGET_SOCFPGA_ARRIA10)
-unsigned int dedicated_uart_com_port(const void *blob);
-unsigned int shared_uart_com_port(const void *blob);
-unsigned int uart_com_port(const void *blob);
+#ifdef CONFIG_TARGET_SOCFPGA_GEN5
+void socfpga_sdram_remap_zero(void);
#endif
void do_bridge_reset(int enable);
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h
index 522f714d76..6623ebee65 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager_arria10.h
@@ -10,12 +10,8 @@
void socfpga_watchdog_disable(void);
void socfpga_reset_deassert_noc_ddr_scheduler(void);
-int socfpga_is_wdt_in_reset(void);
-void socfpga_emac_manage_reset(ulong emacbase, u32 state);
int socfpga_reset_deassert_bridges_handoff(void);
-void socfpga_reset_assert_fpga_connected_peripherals(void);
void socfpga_reset_deassert_osc1wd0(void);
-void socfpga_reset_uart(int assert);
int socfpga_bridges_reset(void);
struct socfpga_reset_manager {
diff --git a/arch/arm/mach-socfpga/include/mach/system_manager_s10.h b/arch/arm/mach-socfpga/include/mach/system_manager_s10.h
index 813dff2153..297f9e1999 100644
--- a/arch/arm/mach-socfpga/include/mach/system_manager_s10.h
+++ b/arch/arm/mach-socfpga/include/mach/system_manager_s10.h
@@ -146,9 +146,9 @@ struct socfpga_system_manager {
#define SYSMGR_FPGAINTF_SDMMC BIT(8)
#define SYSMGR_FPGAINTF_SPIM0 BIT(16)
#define SYSMGR_FPGAINTF_SPIM1 BIT(24)
-#define SYSMGR_FPGAINTF_EMAC0 (0x11 << 0)
-#define SYSMGR_FPGAINTF_EMAC1 (0x11 << 8)
-#define SYSMGR_FPGAINTF_EMAC2 (0x11 << 16)
+#define SYSMGR_FPGAINTF_EMAC0 BIT(0)
+#define SYSMGR_FPGAINTF_EMAC1 BIT(8)
+#define SYSMGR_FPGAINTF_EMAC2 BIT(16)
#define SYSMGR_SDMMC_SMPLSEL_SHIFT 4
#define SYSMGR_SDMMC_DRVSEL_SHIFT 0
diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c
index 80bf2f036f..284e076ad6 100644
--- a/arch/arm/mach-socfpga/misc_arria10.c
+++ b/arch/arm/mach-socfpga/misc_arria10.c
@@ -38,48 +38,6 @@ static const struct socfpga_noc_fw_ocram *noc_fw_ocram_base =
static struct socfpga_system_manager *sysmgr_regs =
(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
-/*
- * DesignWare Ethernet initialization
- */
-#ifdef CONFIG_ETH_DESIGNWARE
-static void arria10_dwmac_reset(const u8 of_reset_id, const u8 phymode)
-{
- u32 reset;
-
- if (of_reset_id == EMAC0_RESET) {
- reset = SOCFPGA_RESET(EMAC0);
- } else if (of_reset_id == EMAC1_RESET) {
- reset = SOCFPGA_RESET(EMAC1);
- } else if (of_reset_id == EMAC2_RESET) {
- reset = SOCFPGA_RESET(EMAC2);
- } else {
- printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id);
- return;
- }
-
- clrsetbits_le32(&sysmgr_regs->emac[of_reset_id - EMAC0_RESET],
- SYSMGR_EMACGRP_CTRL_PHYSEL_MASK,
- phymode);
-
- /* Release the EMAC controller from reset */
- socfpga_per_reset(reset, 0);
-}
-
-static int socfpga_eth_reset(void)
-{
- /* Put all GMACs into RESET state. */
- socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1);
- socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1);
- socfpga_per_reset(SOCFPGA_RESET(EMAC2), 1);
- return socfpga_eth_reset_common(arria10_dwmac_reset);
-};
-#else
-static int socfpga_eth_reset(void)
-{
- return 0;
-};
-#endif
-
#if defined(CONFIG_SPL_BUILD)
/*
+ * This function initializes security policies to be consistent across
@@ -128,133 +86,6 @@ int arch_early_init_r(void)
#endif
/*
- * This function looking the 1st encounter UART peripheral,
- * and then return its offset of the dedicated/shared IO pin
- * mux. offset value (zero and above).
- */
-static int find_peripheral_uart(const void *blob,
- int child, const char *node_name)
-{
- int len;
- fdt_addr_t base_addr = 0;
- fdt_size_t size;
- const u32 *cell;
- u32 value, offset = 0;
-
- base_addr = fdtdec_get_addr_size(blob, child, "reg", &size);
- if (base_addr != FDT_ADDR_T_NONE) {
- cell = fdt_getprop(blob, child, "pinctrl-single,pins",
- &len);
- if (cell != NULL) {
- for (; len > 0; len -= (2 * sizeof(u32))) {
- offset = fdt32_to_cpu(*cell++);
- value = fdt32_to_cpu(*cell++);
- /* Found UART peripheral. */
- if (value == PINMUX_UART)
- return offset;
- }
- }
- }
- return -EINVAL;
-}
-
-/*
- * This function looks up the 1st encounter UART peripheral,
- * and then return its offset of the dedicated/shared IO pin
- * mux. UART peripheral is found if the offset is not in negative
- * value.
- */
-static int is_peripheral_uart_true(const void *blob,
- int node, const char *child_name)
-{
- int child, len;
- const char *node_name;
-
- child = fdt_first_subnode(blob, node);
-
- if (child < 0)
- return -EINVAL;
-
- node_name = fdt_get_name(blob, child, &len);
-
- while (node_name) {
- if (!strcmp(child_name, node_name))
- return find_peripheral_uart(blob, child, node_name);
-
- child = fdt_next_subnode(blob, child);
- if (child < 0)
- break;
-
- node_name = fdt_get_name(blob, child, &len);
- }
-
- return -1;
-}
-
-/*
- * This function looking the 1st encounter UART dedicated IO peripheral,
- * and then return based address of the 1st encounter UART dedicated
- * IO peripheral.
- */
-unsigned int dedicated_uart_com_port(const void *blob)
-{
- int node;
-
- node = fdtdec_next_compatible(blob, 0,
- COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
- if (node < 0)
- return 0;
-
- if (is_peripheral_uart_true(blob, node, "dedicated") >= 0)
- return SOCFPGA_UART1_ADDRESS;
-
- return 0;
-}
-
-/*
- * This function looking the 1st encounter UART shared IO peripheral, and then
- * return based address of the 1st encounter UART shared IO peripheral.
- */
-unsigned int shared_uart_com_port(const void *blob)
-{
- int node, ret;
-
- node = fdtdec_next_compatible(blob, 0,
- COMPAT_ALTERA_SOCFPGA_PINCTRL_SINGLE);
- if (node < 0)
- return 0;
-
- ret = is_peripheral_uart_true(blob, node, "shared");
-
- if (ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 ||
- ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 ||
- ret == PINMUX_UART0_TX_SHARED_IO_OFFSET_Q3_3)
- return SOCFPGA_UART0_ADDRESS;
- else if (ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q1_7 ||
- ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 ||
- ret == PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3)
- return SOCFPGA_UART1_ADDRESS;
-
- return 0;
-}
-
-/*
- * This function looking the 1st encounter UART peripheral, and then return
- * base address of the 1st encounter UART peripheral.
- */
-unsigned int uart_com_port(const void *blob)
-{
- unsigned int ret;
-
- ret = dedicated_uart_com_port(blob);
-
- if (ret)
- return ret;
-
- return shared_uart_com_port(blob);
-}
-
-/*
* Print CPU information
*/
#if defined(CONFIG_DISPLAY_CPUINFO)
@@ -270,13 +101,6 @@ int print_cpuinfo(void)
}
#endif
-#ifdef CONFIG_ARCH_MISC_INIT
-int arch_misc_init(void)
-{
- return socfpga_eth_reset();
-}
-#endif
-
void do_bridge_reset(int enable)
{
if (enable)
diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
index 848551c73f..429c3d6cd5 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -175,6 +175,22 @@ static void socfpga_nic301_slave_ns(void)
writel(0x1, &nic301_regs->sdrdata);
}
+void socfpga_sdram_remap_zero(void)
+{
+ socfpga_nic301_slave_ns();
+
+ /*
+ * Private components security:
+ * U-Boot : configure private timer, global timer and cpu component
+ * access as non secure for kernel stage (as required by Linux)
+ */
+ setbits_le32(&scu_regs->sacr, 0xfff);
+
+ /* Configure the L2 controller to make SDRAM start at 0 */
+ writel(0x1, &nic301_regs->remap); /* remap.mpuzero */
+ writel(0x1, &pl310->pl310_addr_filter_start);
+}
+
static u32 iswgrp_handoff[8];
int arch_early_init_r(void)
@@ -195,18 +211,7 @@ int arch_early_init_r(void)
socfpga_bridges_reset(1);
- socfpga_nic301_slave_ns();
-
- /*
- * Private components security:
- * U-Boot : configure private timer, global timer and cpu component
- * access as non secure for kernel stage (as required by Linux)
- */
- setbits_le32(&scu_regs->sacr, 0xfff);
-
- /* Configure the L2 controller to make SDRAM start at 0 */
- writel(0x1, &nic301_regs->remap); /* remap.mpuzero */
- writel(0x1, &pl310->pl310_addr_filter_start);
+ socfpga_sdram_remap_zero();
/* Add device descriptor to FPGA device table */
socfpga_fpga_add();
diff --git a/arch/arm/mach-socfpga/reset_manager_arria10.c b/arch/arm/mach-socfpga/reset_manager_arria10.c
index b4434f2ded..471a3045af 100644
--- a/arch/arm/mach-socfpga/reset_manager_arria10.c
+++ b/arch/arm/mach-socfpga/reset_manager_arria10.c
@@ -20,71 +20,6 @@ static const struct socfpga_reset_manager *reset_manager_base =
static const struct socfpga_system_manager *sysmgr_regs =
(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
-#define ECC_MASK (ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK | \
- ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK | \
- ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK | \
- ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK | \
- ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK | \
- ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK)
-
-void socfpga_reset_uart(int assert)
-{
- unsigned int com_port;
-
- com_port = uart_com_port(gd->fdt_blob);
-
- if (com_port == SOCFPGA_UART1_ADDRESS)
- socfpga_per_reset(SOCFPGA_RESET(UART1), assert);
- else if (com_port == SOCFPGA_UART0_ADDRESS)
- socfpga_per_reset(SOCFPGA_RESET(UART0), assert);
-}
-
-static const u32 per0fpgamasks[] = {
- ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK |
- ALT_RSTMGR_PER0MODRST_EMAC0_SET_MSK,
- ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK |
- ALT_RSTMGR_PER0MODRST_EMAC1_SET_MSK,
- ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK |
- ALT_RSTMGR_PER0MODRST_EMAC2_SET_MSK,
- 0, /* i2c0 per1mod */
- 0, /* i2c1 per1mod */
- 0, /* i2c0_emac */
- 0, /* i2c1_emac */
- 0, /* i2c2_emac */
- ALT_RSTMGR_PER0MODRST_NANDECC_SET_MSK |
- ALT_RSTMGR_PER0MODRST_NAND_SET_MSK,
- ALT_RSTMGR_PER0MODRST_QSPIECC_SET_MSK |
- ALT_RSTMGR_PER0MODRST_QSPI_SET_MSK,
- ALT_RSTMGR_PER0MODRST_SDMMCECC_SET_MSK |
- ALT_RSTMGR_PER0MODRST_SDMMC_SET_MSK,
- ALT_RSTMGR_PER0MODRST_SPIM0_SET_MSK,
- ALT_RSTMGR_PER0MODRST_SPIM1_SET_MSK,
- ALT_RSTMGR_PER0MODRST_SPIS0_SET_MSK,
- ALT_RSTMGR_PER0MODRST_SPIS1_SET_MSK,
- 0, /* uart0 per1mod */
- 0, /* uart1 per1mod */
-};
-
-static const u32 per1fpgamasks[] = {
- 0, /* emac0 per0mod */
- 0, /* emac1 per0mod */
- 0, /* emac2 per0mod */
- ALT_RSTMGR_PER1MODRST_I2C0_SET_MSK,
- ALT_RSTMGR_PER1MODRST_I2C1_SET_MSK,
- ALT_RSTMGR_PER1MODRST_I2C2_SET_MSK, /* i2c0_emac */
- ALT_RSTMGR_PER1MODRST_I2C3_SET_MSK, /* i2c1_emac */
- ALT_RSTMGR_PER1MODRST_I2C4_SET_MSK, /* i2c2_emac */
- 0, /* nand per0mod */
- 0, /* qspi per0mod */
- 0, /* sdmmc per0mod */
- 0, /* spim0 per0mod */
- 0, /* spim1 per0mod */
- 0, /* spis0 per0mod */
- 0, /* spis1 per0mod */
- ALT_RSTMGR_PER1MODRST_UART0_SET_MSK,
- ALT_RSTMGR_PER1MODRST_UART1_SET_MSK,
-};
-
struct bridge_cfg {
int compat_id;
u32 mask_noc;
@@ -139,56 +74,6 @@ void socfpga_reset_deassert_noc_ddr_scheduler(void)
ALT_RSTMGR_BRGMODRST_DDRSCH_SET_MSK);
}
-/* Check whether Watchdog in reset state? */
-int socfpga_is_wdt_in_reset(void)
-{
- u32 val;
-
- val = readl(&reset_manager_base->per1modrst);
- val &= ALT_RSTMGR_PER1MODRST_WD0_SET_MSK;
-
- /* return 0x1 if watchdog in reset */
- return val;
-}
-
-/* emacbase: base address of emac to enable/disable reset
- * state: 0 - disable reset, !0 - enable reset
- */
-void socfpga_emac_manage_reset(ulong emacbase, u32 state)
-{
- ulong eccmask;
- ulong emacmask;
-
- switch (emacbase) {
- case SOCFPGA_EMAC0_ADDRESS:
- eccmask = ALT_RSTMGR_PER0MODRST_EMACECC0_SET_MSK;
- emacmask = ALT_RSTMGR_PER0MODRST_EMAC0_SET_MSK;
- break;
- case SOCFPGA_EMAC1_ADDRESS:
- eccmask = ALT_RSTMGR_PER0MODRST_EMACECC1_SET_MSK;
- emacmask = ALT_RSTMGR_PER0MODRST_EMAC1_SET_MSK;
- break;
- case SOCFPGA_EMAC2_ADDRESS:
- eccmask = ALT_RSTMGR_PER0MODRST_EMACECC2_SET_MSK;
- emacmask = ALT_RSTMGR_PER0MODRST_EMAC2_SET_MSK;
- break;
- default:
- pr_err("emac base address unexpected! %lx", emacbase);
- hang();
- break;
- }
-
- if (state) {
- /* Enable ECC OCP first */
- setbits_le32(&reset_manager_base->per0modrst, eccmask);
- setbits_le32(&reset_manager_base->per0modrst, emacmask);
- } else {
- /* Disable ECC OCP first */
- clrbits_le32(&reset_manager_base->per0modrst, emacmask);
- clrbits_le32(&reset_manager_base->per0modrst, eccmask);
- }
-}
-
static int get_bridge_init_val(const void *blob, int compat_id)
{
int node;
@@ -225,26 +110,6 @@ int socfpga_reset_deassert_bridges_handoff(void)
false, 1000, false);
}
-void socfpga_reset_assert_fpga_connected_peripherals(void)
-{
- u32 mask0 = 0;
- u32 mask1 = 0;
- u32 fpga_pinux_addr = SOCFPGA_PINMUX_FPGA_INTERFACE_ADDRESS;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(per1fpgamasks); i++) {
- if (readl(fpga_pinux_addr)) {
- mask0 |= per0fpgamasks[i];
- mask1 |= per1fpgamasks[i];
- }
- fpga_pinux_addr += sizeof(u32);
- }
-
- setbits_le32(&reset_manager_base->per0modrst, mask0 & ECC_MASK);
- setbits_le32(&reset_manager_base->per1modrst, mask1);
- setbits_le32(&reset_manager_base->per0modrst, mask0);
-}
-
/* Release L4 OSC1 Watchdog Timer 0 from reset through reset manager */
void socfpga_reset_deassert_osc1wd0(void)
{
diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c
index fe4782c9cb..7d35e9daa8 100644
--- a/arch/arm/mach-socfpga/spl_a10.c
+++ b/arch/arm/mach-socfpga/spl_a10.c
@@ -17,6 +17,7 @@
#include <asm/arch/scan_manager.h>
#include <asm/arch/sdram.h>
#include <asm/arch/scu.h>
+#include <asm/arch/misc.h>
#include <asm/arch/nic301.h>
#include <asm/sections.h>
#include <fdtdec.h>
@@ -74,11 +75,13 @@ void spl_board_init(void)
config_dedicated_pins(gd->fdt_blob);
WATCHDOG_RESET();
- /* Release UART from reset */
- socfpga_reset_uart(0);
-
/* enable console uart printing */
preloader_console_init();
+
+ WATCHDOG_RESET();
+
+ /* Add device descriptor to FPGA device table */
+ socfpga_fpga_add();
}
void board_init_f(ulong dummy)
diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
index d6fe7d35af..be318cc0d9 100644
--- a/arch/arm/mach-socfpga/spl_gen5.c
+++ b/arch/arm/mach-socfpga/spl_gen5.c
@@ -5,7 +5,6 @@
#include <common.h>
#include <asm/io.h>
-#include <asm/pl310.h>
#include <asm/u-boot.h>
#include <asm/utils.h>
#include <image.h>
@@ -17,20 +16,13 @@
#include <asm/arch/misc.h>
#include <asm/arch/scan_manager.h>
#include <asm/arch/sdram.h>
-#include <asm/arch/scu.h>
-#include <asm/arch/nic301.h>
#include <asm/sections.h>
+#include <debug_uart.h>
#include <fdtdec.h>
#include <watchdog.h>
DECLARE_GLOBAL_DATA_PTR;
-static struct pl310_regs *const pl310 =
- (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
-static struct scu_registers *scu_regs =
- (struct scu_registers *)SOCFPGA_MPUSCU_ADDRESS;
-static struct nic301_registers *nic301_regs =
- (struct nic301_registers *)SOCFPGA_L3REGS_ADDRESS;
static const struct socfpga_system_manager *sysmgr_regs =
(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
@@ -71,21 +63,12 @@ u32 spl_boot_mode(const u32 boot_device)
}
#endif
-static void socfpga_nic301_slave_ns(void)
-{
- writel(0x1, &nic301_regs->lwhps2fpgaregs);
- writel(0x1, &nic301_regs->hps2fpgaregs);
- writel(0x1, &nic301_regs->acp);
- writel(0x1, &nic301_regs->rom);
- writel(0x1, &nic301_regs->ocram);
- writel(0x1, &nic301_regs->sdrdata);
-}
-
void board_init_f(ulong dummy)
{
const struct cm_config *cm_default_cfg = cm_get_default_config();
unsigned long sdram_size;
unsigned long reg;
+ int ret;
/*
* First C code to run. Clear fake OCRAM ECC first as SBE
@@ -101,14 +84,7 @@ void board_init_f(ulong dummy)
memset(__bss_start, 0, __bss_end - __bss_start);
- socfpga_nic301_slave_ns();
-
- /* Configure ARM MPU SNSAC register. */
- setbits_le32(&scu_regs->sacr, 0xfff);
-
- /* Remap SDRAM to 0x0 */
- writel(0x1, &nic301_regs->remap); /* remap.mpuzero */
- writel(0x1, &pl310->pl310_addr_filter_start);
+ socfpga_sdram_remap_zero();
debug("Freezing all I/O banks\n");
/* freeze all IO banks */
@@ -152,6 +128,17 @@ void board_init_f(ulong dummy)
/* unfreeze / thaw all IO banks */
sys_mgr_frzctrl_thaw_req();
+#ifdef CONFIG_DEBUG_UART
+ socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
+ debug_uart_init();
+#endif
+
+ ret = spl_early_init();
+ if (ret) {
+ debug("spl_early_init() failed: %d\n", ret);
+ hang();
+ }
+
/* enable console uart printing */
preloader_console_init();
@@ -177,7 +164,4 @@ void board_init_f(ulong dummy)
}
socfpga_bridges_reset(1);
-
- /* Configure simple malloc base pointer into RAM. */
- gd->malloc_base = CONFIG_SYS_TEXT_BASE + (1024 * 1024);
}
diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig
index 983d5ee2e8..1b9ce17822 100644
--- a/configs/socfpga_arria10_defconfig
+++ b/configs/socfpga_arria10_defconfig
@@ -35,5 +35,7 @@ CONFIG_DWAPB_GPIO=y
CONFIG_DM_MMC=y
CONFIG_MTD_DEVICE=y
CONFIG_MTD_PARTITIONS=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
CONFIG_SPI=y
CONFIG_USE_TINY_PRINTF=y
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 146283c723..034bf44078 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -11,6 +11,7 @@ obj-y += tegra/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_MESON) += clk_meson.o
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
+obj-$(CONFIG_ARCH_SOCFPGA) += altera/
obj-$(CONFIG_CLK_AT91) += at91/
obj-$(CONFIG_CLK_MVEBU) += mvebu/
obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
diff --git a/drivers/clk/altera/Makefile b/drivers/clk/altera/Makefile
new file mode 100644
index 0000000000..2542b7f51b
--- /dev/null
+++ b/drivers/clk/altera/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2018 Marek Vasut <marex@denx.de>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += clk-arria10.o
diff --git a/drivers/clk/altera/clk-arria10.c b/drivers/clk/altera/clk-arria10.c
new file mode 100644
index 0000000000..78102c760d
--- /dev/null
+++ b/drivers/clk/altera/clk-arria10.c
@@ -0,0 +1,363 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Marek Vasut <marex@denx.de>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/util.h>
+
+#include <asm/arch/clock_manager.h>
+
+enum socfpga_a10_clk_type {
+ SOCFPGA_A10_CLK_MAIN_PLL,
+ SOCFPGA_A10_CLK_PER_PLL,
+ SOCFPGA_A10_CLK_PERIP_CLK,
+ SOCFPGA_A10_CLK_GATE_CLK,
+ SOCFPGA_A10_CLK_UNKNOWN_CLK,
+};
+
+struct socfpga_a10_clk_platdata {
+ enum socfpga_a10_clk_type type;
+ struct clk_bulk clks;
+ u32 regs;
+ /* Fixed divider */
+ u16 fix_div;
+ /* Control register */
+ u16 ctl_reg;
+ /* Divider register */
+ u16 div_reg;
+ u8 div_len;
+ u8 div_off;
+ /* Clock gating register */
+ u16 gate_reg;
+ u8 gate_bit;
+};
+
+static int socfpga_a10_clk_get_upstream(struct clk *clk, struct clk **upclk)
+{
+ struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
+ u32 reg, maxval;
+
+ if (plat->clks.count == 0)
+ return 0;
+
+ if (plat->clks.count == 1) {
+ *upclk = &plat->clks.clks[0];
+ return 0;
+ }
+
+ if (!plat->ctl_reg) {
+ dev_err(clk->dev, "Invalid control register\n");
+ return -EINVAL;
+ }
+
+ reg = readl(plat->regs + plat->ctl_reg);
+
+ /* Assume PLLs are ON for now */
+ if (plat->type == SOCFPGA_A10_CLK_MAIN_PLL) {
+ reg = (reg >> 8) & 0x3;
+ maxval = 2;
+ } else if (plat->type == SOCFPGA_A10_CLK_PER_PLL) {
+ reg = (reg >> 8) & 0x3;
+ maxval = 3;
+ } else {
+ reg = (reg >> 16) & 0x7;
+ maxval = 4;
+ }
+
+ if (reg > maxval) {
+ dev_err(clk->dev, "Invalid clock source\n");
+ return -EINVAL;
+ }
+
+ *upclk = &plat->clks.clks[reg];
+ return 0;
+}
+
+static int socfpga_a10_clk_endisable(struct clk *clk, bool enable)
+{
+ struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
+ struct clk *upclk = NULL;
+ int ret;
+
+ if (!enable && plat->gate_reg)
+ clrbits_le32(plat->regs + plat->gate_reg, BIT(plat->gate_bit));
+
+ ret = socfpga_a10_clk_get_upstream(clk, &upclk);
+ if (ret)
+ return ret;
+
+ if (upclk) {
+ if (enable)
+ clk_enable(upclk);
+ else
+ clk_disable(upclk);
+ }
+
+ if (enable && plat->gate_reg)
+ setbits_le32(plat->regs + plat->gate_reg, BIT(plat->gate_bit));
+
+ return 0;
+}
+
+static int socfpga_a10_clk_enable(struct clk *clk)
+{
+ return socfpga_a10_clk_endisable(clk, true);
+}
+
+static int socfpga_a10_clk_disable(struct clk *clk)
+{
+ return socfpga_a10_clk_endisable(clk, false);
+}
+
+static ulong socfpga_a10_clk_get_rate(struct clk *clk)
+{
+ struct socfpga_a10_clk_platdata *plat = dev_get_platdata(clk->dev);
+ struct clk *upclk = NULL;
+ ulong rate = 0, reg, numer, denom;
+ int ret;
+
+ ret = socfpga_a10_clk_get_upstream(clk, &upclk);
+ if (ret || !upclk)
+ return 0;
+
+ rate = clk_get_rate(upclk);
+
+ if (plat->type == SOCFPGA_A10_CLK_MAIN_PLL) {
+ reg = readl(plat->regs + plat->ctl_reg + 4); /* VCO1 */
+ numer = reg & CLKMGR_MAINPLL_VCO1_NUMER_MSK;
+ denom = (reg >> CLKMGR_MAINPLL_VCO1_DENOM_LSB) &
+ CLKMGR_MAINPLL_VCO1_DENOM_MSK;
+
+ rate /= denom + 1;
+ rate *= numer + 1;
+ } else if (plat->type == SOCFPGA_A10_CLK_PER_PLL) {
+ reg = readl(plat->regs + plat->ctl_reg + 4); /* VCO1 */
+ numer = reg & CLKMGR_PERPLL_VCO1_NUMER_MSK;
+ denom = (reg >> CLKMGR_PERPLL_VCO1_DENOM_LSB) &
+ CLKMGR_PERPLL_VCO1_DENOM_MSK;
+
+ rate /= denom + 1;
+ rate *= numer + 1;
+ } else {
+ rate /= plat->fix_div;
+
+ if (plat->fix_div == 1 && plat->ctl_reg) {
+ reg = readl(plat->regs + plat->ctl_reg);
+ reg &= 0x7ff;
+ rate /= reg + 1;
+ }
+
+ if (plat->div_reg) {
+ reg = readl(plat->regs + plat->div_reg);
+ reg >>= plat->div_off;
+ reg &= (1 << plat->div_len) - 1;
+ if (plat->type == SOCFPGA_A10_CLK_PERIP_CLK)
+ rate /= reg + 1;
+ if (plat->type == SOCFPGA_A10_CLK_GATE_CLK)
+ rate /= 1 << reg;
+ }
+ }
+
+ return rate;
+}
+
+static struct clk_ops socfpga_a10_clk_ops = {
+ .enable = socfpga_a10_clk_enable,
+ .disable = socfpga_a10_clk_disable,
+ .get_rate = socfpga_a10_clk_get_rate,
+};
+
+/*
+ * This workaround tries to fix the massively broken generated "handoff" DT,
+ * which contains duplicate clock nodes without any connection to the clock
+ * manager DT node. Yet, those "handoff" DT nodes contain configuration of
+ * the fixed input clock of the Arria10 which are missing from the base DT
+ * for Arria10.
+ *
+ * This workaround sets up upstream clock for the fixed input clocks of the
+ * A10 described in the base DT such that they map to the fixed clock from
+ * the "handoff" DT. This does not fully match how the clock look on the
+ * A10, but it is the least intrusive way to fix this mess.
+ */
+static void socfpga_a10_handoff_workaround(struct udevice *dev)
+{
+ struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
+ const void *fdt = gd->fdt_blob;
+ struct clk_bulk *bulk = &plat->clks;
+ int i, ret, offset = dev_of_offset(dev);
+ static const char * const socfpga_a10_fixedclk_map[] = {
+ "osc1", "altera_arria10_hps_eosc1",
+ "cb_intosc_ls_clk", "altera_arria10_hps_cb_intosc_ls",
+ "f2s_free_clk", "altera_arria10_hps_f2h_free",
+ };
+
+ if (fdt_node_check_compatible(fdt, offset, "fixed-clock"))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(socfpga_a10_fixedclk_map); i += 2)
+ if (!strcmp(dev->name, socfpga_a10_fixedclk_map[i]))
+ break;
+
+ if (i == ARRAY_SIZE(socfpga_a10_fixedclk_map))
+ return;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK,
+ socfpga_a10_fixedclk_map[i + 1], &dev);
+ if (ret)
+ return;
+
+ bulk->count = 1;
+ bulk->clks = devm_kcalloc(dev, bulk->count,
+ sizeof(struct clk), GFP_KERNEL);
+ if (!bulk->clks)
+ return;
+
+ ret = clk_request(dev, &bulk->clks[0]);
+ if (ret)
+ free(bulk->clks);
+}
+
+static int socfpga_a10_clk_bind(struct udevice *dev)
+{
+ const void *fdt = gd->fdt_blob;
+ int offset = dev_of_offset(dev);
+ bool pre_reloc_only = !(gd->flags & GD_FLG_RELOC);
+ const char *name;
+ int ret;
+
+ for (offset = fdt_first_subnode(fdt, offset);
+ offset > 0;
+ offset = fdt_next_subnode(fdt, offset)) {
+ name = fdt_get_name(fdt, offset, NULL);
+ if (!name)
+ return -EINVAL;
+
+ if (!strcmp(name, "clocks")) {
+ offset = fdt_first_subnode(fdt, offset);
+ name = fdt_get_name(fdt, offset, NULL);
+ if (!name)
+ return -EINVAL;
+ }
+
+ /* Filter out supported sub-clock */
+ if (fdt_node_check_compatible(fdt, offset,
+ "altr,socfpga-a10-pll-clock") &&
+ fdt_node_check_compatible(fdt, offset,
+ "altr,socfpga-a10-perip-clk") &&
+ fdt_node_check_compatible(fdt, offset,
+ "altr,socfpga-a10-gate-clk") &&
+ fdt_node_check_compatible(fdt, offset, "fixed-clock"))
+ continue;
+
+ if (pre_reloc_only && !dm_fdt_pre_reloc(fdt, offset))
+ continue;
+
+ ret = device_bind_driver_to_node(dev, "clk-a10", name,
+ offset_to_ofnode(offset),
+ NULL);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int socfpga_a10_clk_probe(struct udevice *dev)
+{
+ struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
+ const void *fdt = gd->fdt_blob;
+ int offset = dev_of_offset(dev);
+
+ clk_get_bulk(dev, &plat->clks);
+
+ socfpga_a10_handoff_workaround(dev);
+
+ if (!fdt_node_check_compatible(fdt, offset,
+ "altr,socfpga-a10-pll-clock")) {
+ /* Main PLL has 3 upstream clock */
+ if (plat->clks.count == 3)
+ plat->type = SOCFPGA_A10_CLK_MAIN_PLL;
+ else
+ plat->type = SOCFPGA_A10_CLK_PER_PLL;
+ } else if (!fdt_node_check_compatible(fdt, offset,
+ "altr,socfpga-a10-perip-clk")) {
+ plat->type = SOCFPGA_A10_CLK_PERIP_CLK;
+ } else if (!fdt_node_check_compatible(fdt, offset,
+ "altr,socfpga-a10-gate-clk")) {
+ plat->type = SOCFPGA_A10_CLK_GATE_CLK;
+ } else {
+ plat->type = SOCFPGA_A10_CLK_UNKNOWN_CLK;
+ }
+
+ return 0;
+}
+
+static int socfpga_a10_ofdata_to_platdata(struct udevice *dev)
+{
+ struct socfpga_a10_clk_platdata *plat = dev_get_platdata(dev);
+ struct socfpga_a10_clk_platdata *pplat;
+ struct udevice *pdev;
+ const void *fdt = gd->fdt_blob;
+ unsigned int divreg[3], gatereg[2];
+ int ret, offset = dev_of_offset(dev);
+ u32 regs;
+
+ regs = dev_read_u32_default(dev, "reg", 0x0);
+
+ if (!fdt_node_check_compatible(fdt, offset, "altr,clk-mgr")) {
+ plat->regs = devfdt_get_addr(dev);
+ } else {
+ pdev = dev_get_parent(dev);
+ if (!pdev)
+ return -ENODEV;
+
+ pplat = dev_get_platdata(pdev);
+ if (!pplat)
+ return -EINVAL;
+
+ plat->ctl_reg = regs;
+ plat->regs = pplat->regs;
+ }
+
+ plat->type = SOCFPGA_A10_CLK_UNKNOWN_CLK;
+
+ plat->fix_div = dev_read_u32_default(dev, "fixed-divider", 1);
+
+ ret = dev_read_u32_array(dev, "div-reg", divreg, ARRAY_SIZE(divreg));
+ if (!ret) {
+ plat->div_reg = divreg[0];
+ plat->div_len = divreg[2];
+ plat->div_off = divreg[1];
+ }
+
+ ret = dev_read_u32_array(dev, "clk-gate", gatereg, ARRAY_SIZE(gatereg));
+ if (!ret) {
+ plat->gate_reg = gatereg[0];
+ plat->gate_bit = gatereg[1];
+ }
+
+ return 0;
+}
+
+static const struct udevice_id socfpga_a10_clk_match[] = {
+ { .compatible = "altr,clk-mgr" },
+ {}
+};
+
+U_BOOT_DRIVER(socfpga_a10_clk) = {
+ .name = "clk-a10",
+ .id = UCLASS_CLK,
+ .flags = DM_FLAG_PRE_RELOC,
+ .of_match = socfpga_a10_clk_match,
+ .ops = &socfpga_a10_clk_ops,
+ .bind = socfpga_a10_clk_bind,
+ .probe = socfpga_a10_clk_probe,
+ .ofdata_to_platdata = socfpga_a10_ofdata_to_platdata,
+
+ .platdata_auto_alloc_size = sizeof(struct socfpga_a10_clk_platdata),
+};
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index ed8ba10c93..739c1629a2 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <asm/arch/clock_manager.h>
#include <asm/arch/system_manager.h>
+#include <clk.h>
#include <dm.h>
#include <dwmmc.h>
#include <errno.h>
@@ -70,20 +71,39 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
}
-static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev)
+static int socfpga_dwmmc_get_clk_rate(struct udevice *dev)
{
- /* FIXME: probe from DT eventually too/ */
- const unsigned long clk = cm_get_mmc_controller_clk_hz();
-
struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
- int fifo_depth;
+#if CONFIG_IS_ENABLED(CLK)
+ struct clk clk;
+ int ret;
+
+ ret = clk_get_by_index(dev, 1, &clk);
+ if (ret)
+ return ret;
- if (clk == 0) {
+ host->bus_hz = clk_get_rate(&clk);
+
+ clk_free(&clk);
+#else
+ /* Fixed clock divide by 4 which due to the SDMMC wrapper */
+ host->bus_hz = cm_get_mmc_controller_clk_hz();
+#endif
+ if (host->bus_hz == 0) {
printf("DWMMC: MMC clock is zero!");
return -EINVAL;
}
+ return 0;
+}
+
+static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev)
+{
+ struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
+ int fifo_depth;
+
fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
"fifo-depth", 0);
if (fifo_depth < 0) {
@@ -102,8 +122,6 @@ static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev)
* We only have one dwmmc block on gen5 SoCFPGA.
*/
host->dev_index = 0;
- /* Fixed clock divide by 4 which due to the SDMMC wrapper */
- host->bus_hz = clk;
host->fifoth_val = MSIZE(0x2) |
RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);
priv->drvsel = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
@@ -123,6 +141,11 @@ static int socfpga_dwmmc_probe(struct udevice *dev)
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
+ int ret;
+
+ ret = socfpga_dwmmc_get_clk_rate(dev);
+ if (ret)
+ return ret;
socfpga_dwmci_reset(dev);
@@ -130,7 +153,6 @@ static int socfpga_dwmmc_probe(struct udevice *dev)
dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000);
host->mmc = &plat->mmc;
#else
- int ret;
ret = add_dwmci(host, host->bus_hz, 400000);
if (ret)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f762b0898d..d86da7760e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -150,6 +150,14 @@ config ETH_DESIGNWARE
100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to
provide the PHY (physical media interface).
+config ETH_DESIGNWARE_SOCFPGA
+ bool "Altera SoCFPGA extras for Synopsys Designware Ethernet MAC"
+ depends on DM_ETH && ETH_DESIGNWARE
+ help
+ The Altera SoCFPGA requires additional configuration of the
+ Altera system manager to correctly interface with the PHY.
+ This code handles those SoC specifics.
+
config ETHOC
bool "OpenCores 10/100 Mbps Ethernet MAC"
help
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index c1ed44e21f..48a2878071 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o
obj-$(CONFIG_CS8900) += cs8900.o
obj-$(CONFIG_TULIP) += dc2114x.o
obj-$(CONFIG_ETH_DESIGNWARE) += designware.o
+obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o
obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
obj-$(CONFIG_DNET) += dnet.o
obj-$(CONFIG_E1000) += e1000.o
diff --git a/drivers/net/dwmac_socfpga.c b/drivers/net/dwmac_socfpga.c
new file mode 100644
index 0000000000..08fc9677c4
--- /dev/null
+++ b/drivers/net/dwmac_socfpga.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Marek Vasut <marex@denx.de>
+ *
+ * Altera SoCFPGA EMAC extras
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <clk.h>
+#include <phy.h>
+#include <regmap.h>
+#include <reset.h>
+#include <syscon.h>
+#include "designware.h"
+
+#include <asm/arch/system_manager.h>
+
+enum dwmac_type {
+ DWMAC_SOCFPGA_GEN5 = 0,
+ DWMAC_SOCFPGA_ARRIA10,
+ DWMAC_SOCFPGA_STRATIX10,
+};
+
+struct dwmac_socfpga_platdata {
+ struct dw_eth_pdata dw_eth_pdata;
+ enum dwmac_type type;
+ void *phy_intf;
+};
+
+static int dwmac_socfpga_ofdata_to_platdata(struct udevice *dev)
+{
+ struct dwmac_socfpga_platdata *pdata = dev_get_platdata(dev);
+ struct regmap *regmap;
+ struct ofnode_phandle_args args;
+ void *range;
+ int ret;
+
+ ret = dev_read_phandle_with_args(dev, "altr,sysmgr-syscon", NULL,
+ 2, 0, &args);
+ if (ret) {
+ dev_err(dev, "Failed to get syscon: %d\n", ret);
+ return ret;
+ }
+
+ if (args.args_count != 2) {
+ dev_err(dev, "Invalid number of syscon args\n");
+ return -EINVAL;
+ }
+
+ regmap = syscon_node_to_regmap(args.node);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ dev_err(dev, "Failed to get regmap: %d\n", ret);
+ return ret;
+ }
+
+ range = regmap_get_range(regmap, 0);
+ if (!range) {
+ dev_err(dev, "Failed to get regmap range\n");
+ return -ENOMEM;
+ }
+
+ pdata->phy_intf = range + args.args[0];
+
+ /*
+ * Sadly, the Altera DT bindings don't have SoC-specific compatibles,
+ * so we have to guesstimate which SoC we are running on from the
+ * DWMAC version. Luckily, Altera at least updated the DWMAC with
+ * each SoC.
+ */
+ if (ofnode_device_is_compatible(dev->node, "snps,dwmac-3.70a"))
+ pdata->type = DWMAC_SOCFPGA_GEN5;
+
+ if (ofnode_device_is_compatible(dev->node, "snps,dwmac-3.72a"))
+ pdata->type = DWMAC_SOCFPGA_ARRIA10;
+
+ if (ofnode_device_is_compatible(dev->node, "snps,dwmac-3.74a"))
+ pdata->type = DWMAC_SOCFPGA_STRATIX10;
+
+ return designware_eth_ofdata_to_platdata(dev);
+}
+
+static int dwmac_socfpga_probe(struct udevice *dev)
+{
+ struct dwmac_socfpga_platdata *pdata = dev_get_platdata(dev);
+ struct eth_pdata *edata = &pdata->dw_eth_pdata.eth_pdata;
+ struct reset_ctl_bulk reset_bulk;
+ int ret;
+ u8 modereg;
+
+ if (pdata->type == DWMAC_SOCFPGA_ARRIA10) {
+ switch (edata->phy_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
+ break;
+ default:
+ dev_err(dev, "Unsupported PHY mode\n");
+ return -EINVAL;
+ }
+
+ ret = reset_get_bulk(dev, &reset_bulk);
+ if (ret) {
+ dev_err(dev, "Failed to get reset: %d\n", ret);
+ return ret;
+ }
+
+ reset_assert_bulk(&reset_bulk);
+
+ clrsetbits_le32(pdata->phy_intf,
+ SYSMGR_EMACGRP_CTRL_PHYSEL_MASK,
+ modereg);
+
+ reset_release_bulk(&reset_bulk);
+ }
+
+ return designware_eth_probe(dev);
+}
+
+static const struct udevice_id dwmac_socfpga_ids[] = {
+ { .compatible = "altr,socfpga-stmmac" },
+ { }
+};
+
+U_BOOT_DRIVER(dwmac_socfpga) = {
+ .name = "dwmac_socfpga",
+ .id = UCLASS_ETH,
+ .of_match = dwmac_socfpga_ids,
+ .ofdata_to_platdata = dwmac_socfpga_ofdata_to_platdata,
+ .probe = dwmac_socfpga_probe,
+ .ops = &designware_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
+ .platdata_auto_alloc_size = sizeof(struct dwmac_socfpga_platdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};