summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/conf/ARMADAXP2
-rw-r--r--sys/arm/include/intr.h2
-rw-r--r--sys/arm/mv/armadaxp/armadaxp.c101
-rw-r--r--sys/arm/mv/common.c75
-rw-r--r--sys/arm/mv/mvreg.h13
-rw-r--r--sys/arm/mv/mvvar.h8
-rw-r--r--sys/arm/mv/mvwin.h2
-rw-r--r--sys/arm/mv/timer.c14
-rw-r--r--sys/boot/fdt/dts/db78460.dts (renamed from sys/boot/fdt/dts/db88f78160.dts)30
9 files changed, 220 insertions, 27 deletions
diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP
index c4139b4..5a4d5c0 100644
--- a/sys/arm/conf/ARMADAXP
+++ b/sys/arm/conf/ARMADAXP
@@ -99,4 +99,4 @@ device vlan
#FDT
options FDT
options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=db88f78160.dts
+makeoptions FDT_DTS_FILE=db78460.dts
diff --git a/sys/arm/include/intr.h b/sys/arm/include/intr.h
index 3606478..4cd2651 100644
--- a/sys/arm/include/intr.h
+++ b/sys/arm/include/intr.h
@@ -54,6 +54,8 @@
#define NIRQ 128
#elif defined(CPU_ARM11)
#define NIRQ 128
+#elif defined(SOC_MV_ARMADAXP)
+#define NIRQ 148
#else
#define NIRQ 32
#endif
diff --git a/sys/arm/mv/armadaxp/armadaxp.c b/sys/arm/mv/armadaxp/armadaxp.c
index 71dfc71..ffb02c5 100644
--- a/sys/arm/mv/armadaxp/armadaxp.c
+++ b/sys/arm/mv/armadaxp/armadaxp.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/bus.h>
+#include <machine/armreg.h>
#include <arm/mv/mvreg.h>
#include <arm/mv/mvvar.h>
@@ -43,24 +44,120 @@ __FBSDID("$FreeBSD$");
#include <machine/fdt.h>
+#define CPU_FREQ_FIELD(sar) (((0x01 & (sar >> 52)) << 3) | \
+ (0x07 & (sar >> 21)))
+#define FAB_FREQ_FIELD(sar) (((0x01 & (sar >> 51)) << 4) | \
+ (0x0F & (sar >> 24)))
+
+static uint32_t count_l2clk(void);
+
+/* XXX Make gpio driver optional and remove it */
struct resource_spec mv_gpio_res[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ SYS_RES_IRQ, 0, RF_ACTIVE },
{ -1, 0 }
};
+struct vco_freq_ratio {
+ uint8_t vco_cpu; /* VCO to CLK0(CPU) clock ratio */
+ uint8_t vco_l2c; /* VCO to NB(L2 cache) clock ratio */
+ uint8_t vco_hcl; /* VCO to HCLK(DDR controller) clock ratio */
+ uint8_t vco_ddr; /* VCO to DR(DDR memory) clock ratio */
+};
+
+static struct vco_freq_ratio freq_conf_table[] = {
+/*00*/ { 1, 1, 4, 2 },
+/*01*/ { 1, 2, 2, 2 },
+/*02*/ { 2, 2, 6, 3 },
+/*03*/ { 2, 2, 3, 3 },
+/*04*/ { 1, 2, 3, 3 },
+/*05*/ { 1, 2, 4, 2 },
+/*06*/ { 1, 1, 2, 2 },
+/*07*/ { 2, 3, 6, 6 },
+/*08*/ { 2, 3, 5, 5 },
+/*09*/ { 1, 2, 6, 3 },
+/*10*/ { 2, 4, 10, 5 },
+/*11*/ { 1, 3, 6, 6 },
+/*12*/ { 1, 2, 5, 5 },
+/*13*/ { 1, 3, 6, 3 },
+/*14*/ { 1, 2, 5, 5 },
+/*15*/ { 2, 2, 5, 5 },
+/*16*/ { 1, 1, 3, 3 },
+/*17*/ { 2, 5, 10, 10 },
+/*18*/ { 1, 3, 8, 4 },
+/*19*/ { 1, 1, 2, 1 },
+/*20*/ { 2, 3, 6, 3 },
+/*21*/ { 1, 2, 8, 4 },
+/*22*/ { 2, 5, 10, 5 }
+};
+
+static uint16_t cpu_clock_table[] = {
+ 1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000, 600, 667, 800, 1600,
+ 2133, 2200, 2400 };
+
uint32_t
get_tclk(void)
{
+ uint32_t cputype;
+
+ cputype = cpufunc_id();
+ cputype &= CPU_ID_CPU_MASK;
- return (TCLK_200MHZ);
+ if (cputype == CPU_ID_MV88SV584X_V7)
+ return (TCLK_250MHZ);
+ else
+ return (TCLK_200MHZ);
+}
+
+static uint32_t
+count_l2clk(void)
+{
+ uint64_t sar_reg;
+ uint32_t freq_vco, freq_l2clk;
+ uint8_t sar_cpu_freq, sar_fab_freq, array_size;
+
+ /* Get value of the SAR register and process it */
+ sar_reg = get_sar_value();
+ sar_cpu_freq = CPU_FREQ_FIELD(sar_reg);
+ sar_fab_freq = FAB_FREQ_FIELD(sar_reg);
+
+ /* Check if CPU frequency field has correct value */
+ array_size = sizeof(cpu_clock_table) / sizeof(cpu_clock_table[0]);
+ if (sar_cpu_freq >= array_size)
+ panic("Reserved value in cpu frequency configuration field: "
+ "%d", sar_cpu_freq);
+
+ /* Check if fabric frequency field has correct value */
+ array_size = sizeof(freq_conf_table) / sizeof(freq_conf_table[0]);
+ if (sar_fab_freq >= array_size)
+ panic("Reserved value in fabric frequency configuration field: "
+ "%d", sar_fab_freq);
+
+ /* Get CPU clock frequency */
+ freq_vco = cpu_clock_table[sar_cpu_freq] *
+ freq_conf_table[sar_fab_freq].vco_cpu;
+
+ /* Get L2CLK clock frequency */
+ freq_l2clk = freq_vco / freq_conf_table[sar_fab_freq].vco_l2c;
+
+ /* Round L2CLK value to integer MHz */
+ if (((freq_vco % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
+ freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
+ freq_l2clk++;
+
+ return (freq_l2clk * 1000000);
}
uint32_t
get_l2clk(void)
{
+ static uint32_t l2clk_freq = 0;
+
+ /* If get_l2clk is called first time get L2CLK value from register */
+ if (l2clk_freq == 0)
+ l2clk_freq = count_l2clk();
- return (TCLK_667MHZ);
+ return (l2clk_freq);
}
int
diff --git a/sys/arm/mv/common.c b/sys/arm/mv/common.c
index 5a81a87..fcfb65f 100644
--- a/sys/arm/mv/common.c
+++ b/sys/arm/mv/common.c
@@ -249,12 +249,47 @@ write_cpu_ctrl(uint32_t reg, uint32_t val)
bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val);
}
+#if defined(SOC_MV_ARMADAXP)
+uint32_t
+read_cpu_mp_clocks(uint32_t reg)
+{
+
+ return (bus_space_read_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg));
+}
+
+void
+write_cpu_mp_clocks(uint32_t reg, uint32_t val)
+{
+
+ bus_space_write_4(fdtbus_bs_tag, MV_MP_CLOCKS_BASE, reg, val);
+}
+
+uint32_t
+read_cpu_misc(uint32_t reg)
+{
+
+ return (bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE, reg));
+}
+
+void
+write_cpu_misc(uint32_t reg, uint32_t val)
+{
+
+ bus_space_write_4(fdtbus_bs_tag, MV_MISC_BASE, reg, val);
+}
+#endif
+
void
cpu_reset(void)
{
+#if defined(SOC_MV_ARMADAXP)
+ write_cpu_misc(RSTOUTn_MASK, SOFT_RST_OUT_EN);
+ write_cpu_misc(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
+#else
write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
+#endif
while (1);
}
@@ -2062,19 +2097,26 @@ fdt_fixup_busfreq(phandle_t root)
phandle_t sb;
pcell_t freq;
+ freq = cpu_to_fdt32(get_tclk());
+
/*
- * This fixup sets the simple-bus bus-frequency property.
+ * Fix bus speed in cpu node
*/
+ if ((sb = OF_finddevice("cpu")) != 0)
+ if (fdt_is_compatible_strict(sb, "ARM,88VS584"))
+ OF_setprop(sb, "bus-frequency", (void *)&freq,
+ sizeof(freq));
- if ((sb = fdt_find_compatible(root, "simple-bus", 1)) == 0)
- return;
-
- freq = cpu_to_fdt32(get_tclk());
- OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
+ /*
+ * This fixup sets the simple-bus bus-frequency property.
+ */
+ if ((sb = fdt_find_compatible(root, "simple-bus", 1)) != 0)
+ OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
}
struct fdt_fixup_entry fdt_fixup_table[] = {
{ "mrvl,DB-88F6281", &fdt_fixup_busfreq },
+ { "mrvl,DB-78460", &fdt_fixup_busfreq },
{ NULL, NULL }
};
@@ -2098,3 +2140,24 @@ fdt_pic_decode_t fdt_pic_table[] = {
&fdt_pic_decode_ic,
NULL
};
+
+uint64_t
+get_sar_value(void)
+{
+ uint32_t sar_low, sar_high;
+
+#if defined(SOC_MV_ARMADAXP)
+ sar_high = bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE,
+ SAMPLE_AT_RESET_HI);
+ sar_low = bus_space_read_4(fdtbus_bs_tag, MV_MISC_BASE,
+ SAMPLE_AT_RESET_LO);
+#else
+ /*
+ * TODO: Add getting proper values for other SoC configurations
+ */
+ sar_high = 0;
+ sar_low = 0;
+#endif
+
+ return (((uint64_t)sar_high << 32) | sar_low);
+}
diff --git a/sys/arm/mv/mvreg.h b/sys/arm/mv/mvreg.h
index 77d30d1..076885c 100644
--- a/sys/arm/mv/mvreg.h
+++ b/sys/arm/mv/mvreg.h
@@ -123,11 +123,21 @@
/*
* System reset
*/
+#if defined(SOC_MV_ARMADAXP)
+#define RSTOUTn_MASK 0x60
+#define SYSTEM_SOFT_RESET 0x64
+#define WD_RSTOUTn_MASK 0x4
+#define WD_GLOBAL_MASK 0x00000100
+#define WD_CPU0_MASK 0x00000001
+#define SOFT_RST_OUT_EN 0x00000001
+#define SYS_SOFT_RST 0x00000001
+#else
#define RSTOUTn_MASK 0x8
#define WD_RST_OUT_EN 0x00000002
#define SOFT_RST_OUT_EN 0x00000004
#define SYSTEM_SOFT_RESET 0xc
#define SYS_SOFT_RST 0x00000001
+#endif
/*
* Power Control
@@ -334,6 +344,9 @@
#define SAMPLE_AT_RESET_HI 0x18
#elif defined(SOC_MV_FREY)
#define SAMPLE_AT_RESET 0x100
+#elif defined(SOC_MV_ARMADAXP)
+#define SAMPLE_AT_RESET_LO 0x30
+#define SAMPLE_AT_RESET_HI 0x34
#endif
/*
diff --git a/sys/arm/mv/mvvar.h b/sys/arm/mv/mvvar.h
index b27de27..4a2c87d 100644
--- a/sys/arm/mv/mvvar.h
+++ b/sys/arm/mv/mvvar.h
@@ -89,6 +89,7 @@ void soc_id(uint32_t *dev, uint32_t *rev);
void soc_dump_decode_win(void);
uint32_t soc_power_ctrl_get(uint32_t mask);
void soc_power_ctrl_set(uint32_t mask);
+uint64_t get_sar_value(void);
int decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
vm_paddr_t remap);
@@ -108,6 +109,13 @@ uint32_t get_l2clk(void);
uint32_t read_cpu_ctrl(uint32_t);
void write_cpu_ctrl(uint32_t, uint32_t);
+#if defined(SOC_MV_ARMADAXP)
+uint32_t read_cpu_mp_clocks(uint32_t reg);
+void write_cpu_mp_clocks(uint32_t reg, uint32_t val);
+uint32_t read_cpu_misc(uint32_t reg);
+void write_cpu_misc(uint32_t reg, uint32_t val);
+#endif
+
int mv_pcib_bar_win_set(device_t dev, uint32_t base, uint32_t size,
uint32_t remap, int winno, int busno);
int mv_pcib_cpu_win_remap(device_t dev, uint32_t remap, uint32_t size);
diff --git a/sys/arm/mv/mvwin.h b/sys/arm/mv/mvwin.h
index 933253c..acc3c19 100644
--- a/sys/arm/mv/mvwin.h
+++ b/sys/arm/mv/mvwin.h
@@ -128,8 +128,10 @@
#define MV_MPP_BASE (MV_BASE + 0x10000)
#if defined(SOC_MV_ARMADAXP)
+#define MV_MISC_BASE (MV_BASE + 0x18200)
#define MV_MBUS_BRIDGE_BASE (MV_BASE + 0x20000)
#define MV_INTREGS_BASE (MV_MBUS_BRIDGE_BASE + 0x80)
+#define MV_MP_CLOCKS_BASE (MV_MBUS_BRIDGE_BASE + 0x700)
#define MV_CPU_CONTROL_BASE (MV_MBUS_BRIDGE_BASE + 0x1800)
#elif !defined(SOC_MV_FREY)
#define MV_MBUS_BRIDGE_BASE (MV_BASE + 0x20000)
diff --git a/sys/arm/mv/timer.c b/sys/arm/mv/timer.c
index 5cf0486..db6e404 100644
--- a/sys/arm/mv/timer.c
+++ b/sys/arm/mv/timer.c
@@ -311,15 +311,19 @@ mv_watchdog_enable(void)
irq_cause &= IRQ_TIMER_WD_CLR;
write_cpu_ctrl(BRIDGE_IRQ_CAUSE, irq_cause);
-#if !defined(SOC_MV_ARMADAXP)
+#if defined(SOC_MV_ARMADAXP)
+ val = read_cpu_mp_clocks(WD_RSTOUTn_MASK);
+ val |= (WD_GLOBAL_MASK | WD_CPU0_MASK);
+ write_cpu_mp_clocks(WD_RSTOUTn_MASK, val);
+#else
irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK);
irq_mask |= IRQ_TIMER_WD_MASK;
write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask);
-#endif
val = read_cpu_ctrl(RSTOUTn_MASK);
val |= WD_RST_OUT_EN;
write_cpu_ctrl(RSTOUTn_MASK, val);
+#endif
val = mv_get_timer_control();
val |= CPU_TIMER_WD_EN | CPU_TIMER_WD_AUTO;
@@ -338,11 +342,15 @@ mv_watchdog_disable(void)
val &= ~(CPU_TIMER_WD_EN | CPU_TIMER_WD_AUTO);
mv_set_timer_control(val);
+#if defined(SOC_MV_ARMADAXP)
+ val = read_cpu_mp_clocks(WD_RSTOUTn_MASK);
+ val &= ~(WD_GLOBAL_MASK | WD_CPU0_MASK);
+ write_cpu_mp_clocks(WD_RSTOUTn_MASK, val);
+#else
val = read_cpu_ctrl(RSTOUTn_MASK);
val &= ~WD_RST_OUT_EN;
write_cpu_ctrl(RSTOUTn_MASK, val);
-#if !defined(SOC_MV_ARMADAXP)
irq_mask = read_cpu_ctrl(BRIDGE_IRQ_MASK);
irq_mask &= ~(IRQ_TIMER_WD_MASK);
write_cpu_ctrl(BRIDGE_IRQ_MASK, irq_mask);
diff --git a/sys/boot/fdt/dts/db88f78160.dts b/sys/boot/fdt/dts/db78460.dts
index fa5c8c6..2db9a99 100644
--- a/sys/boot/fdt/dts/db88f78160.dts
+++ b/sys/boot/fdt/dts/db78460.dts
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Marvell DB-88F78160 Device Tree Source.
+ * Marvell DB-78460 Device Tree Source.
*
* $FreeBSD$
*/
@@ -32,7 +32,7 @@
/dts-v1/;
/ {
- model = "mrvl,DB-78160";
+ model = "mrvl,DB-78460";
#address-cells = <1>;
#size-cells = <1>;
@@ -60,10 +60,10 @@
memory {
device_type = "memory";
- reg = <0x0 0x40000000>; // 2G at 0x0
+ reg = <0x0 0x80000000>; // 2G at 0x0
};
- soc78160@d0000000 {
+ soc78460@d0000000 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
@@ -115,7 +115,7 @@
reg = <0x12000 0x20>;
reg-shift = <2>;
current-speed = <115200>;
- clock-frequency = <200000000>;
+ clock-frequency = <0>;
interrupts = <41>;
interrupt-parent = <&MPIC>;
};
@@ -125,7 +125,7 @@
reg = <0x12100 0x20>;
reg-shift = <2>;
current-speed = <115200>;
- clock-frequency = <200000000>;
+ clock-frequency = <0>;
interrupts = <42>;
interrupt-parent = <&MPIC>;
};
@@ -135,7 +135,7 @@
reg = <0x12200 0x20>;
reg-shift = <2>;
current-speed = <115200>;
- clock-frequency = <200000000>;
+ clock-frequency = <0>;
interrupts = <43>;
interrupt-parent = <&MPIC>;
};
@@ -145,7 +145,7 @@
reg = <0x12300 0x20>;
reg-shift = <2>;
current-speed = <115200>;
- clock-frequency = <200000000>;
+ clock-frequency = <0>;
interrupts = <44>;
interrupt-parent = <&MPIC>;
};
@@ -281,25 +281,25 @@
};
};
- pci0: pcie@f1040000 {
+ pci0: pcie@d0040000 {
compatible = "mrvl,pcie";
device_type = "pci";
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
- reg = <0xf1040000 0x2000>;
+ reg = <0xd0040000 0x2000>;
bus-range = <0 255>;
ranges = <0x02000000 0x0 0x80000000 0x80000000 0x0 0x20000000
0x01000000 0x0 0x00000000 0xa0000000 0x0 0x08000000>;
clock-frequency = <33333333>;
interrupt-parent = <&MPIC>;
- interrupts = <58>;
+ interrupts = <120>;
interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
interrupt-map = <
- 0x0800 0x0 0x0 0x1 &MPIC 0x20
- 0x0800 0x0 0x0 0x2 &MPIC 0x21
- 0x0800 0x0 0x0 0x3 &MPIC 0x22
- 0x0800 0x0 0x0 0x4 &MPIC 0x23
+ 0x0800 0x0 0x0 0x1 &MPIC 0x3A
+ 0x0800 0x0 0x0 0x2 &MPIC 0x3A
+ 0x0800 0x0 0x0 0x3 &MPIC 0x3A
+ 0x0800 0x0 0x0 0x4 &MPIC 0x3A
>;
};
OpenPOWER on IntegriCloud