summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/Makefile1
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c2
-rw-r--r--arch/arm/cpu/armv7/stv0991/Makefile9
-rw-r--r--arch/arm/cpu/armv7/stv0991/clock.c41
-rw-r--r--arch/arm/cpu/armv7/stv0991/lowlevel.S12
-rw-r--r--arch/arm/cpu/armv7/stv0991/pinmux.c62
-rw-r--r--arch/arm/cpu/armv7/stv0991/reset.c26
-rw-r--r--arch/arm/cpu/armv7/stv0991/timer.c114
-rw-r--r--arch/arm/cpu/armv7/vf610/generic.c21
9 files changed, 277 insertions, 11 deletions
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index e419716..409e6f5 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_OMAP54XX) += omap5/
obj-$(CONFIG_RMOBILE) += rmobile/
obj-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx/
obj-$(CONFIG_SOCFPGA) += socfpga/
+obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_TEGRA20) += tegra20/
obj-$(CONFIG_U8500) += u8500/
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index ab7ac3d..93a02ad 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -443,7 +443,7 @@ int enable_fec_anatop_clock(enum enet_freq freq)
struct anatop_regs __iomem *anatop =
(struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
- if (freq < ENET_25MHz || freq > ENET_125MHz)
+ if (freq < ENET_25MHZ || freq > ENET_125MHZ)
return -EINVAL;
reg = readl(&anatop->pll_enet);
diff --git a/arch/arm/cpu/armv7/stv0991/Makefile b/arch/arm/cpu/armv7/stv0991/Makefile
new file mode 100644
index 0000000..95641d3
--- /dev/null
+++ b/arch/arm/cpu/armv7/stv0991/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2014
+# Vikas Manocha, ST Microelectronics, vikas.manocha@stcom
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y := timer.o clock.o pinmux.o reset.o
+obj-y += lowlevel.o
diff --git a/arch/arm/cpu/armv7/stv0991/clock.c b/arch/arm/cpu/armv7/stv0991/clock.c
new file mode 100644
index 0000000..70b8a8d
--- /dev/null
+++ b/arch/arm/cpu/armv7/stv0991/clock.c
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2014
+ * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/stv0991_cgu.h>
+#include<asm/arch/stv0991_periph.h>
+
+static struct stv0991_cgu_regs *const stv0991_cgu_regs = \
+ (struct stv0991_cgu_regs *) (CGU_BASE_ADDR);
+
+void enable_pll1(void)
+{
+ /* pll1 already configured for 1000Mhz, just need to enable it */
+ writel(readl(&stv0991_cgu_regs->pll1_ctrl) & ~(0x01),
+ &stv0991_cgu_regs->pll1_ctrl);
+}
+
+void clock_setup(int peripheral)
+{
+ switch (peripheral) {
+ case UART_CLOCK_CFG:
+ writel(UART_CLK_CFG, &stv0991_cgu_regs->uart_freq);
+ break;
+ case ETH_CLOCK_CFG:
+ enable_pll1();
+ writel(ETH_CLK_CFG, &stv0991_cgu_regs->eth_freq);
+
+ /* Clock selection for ethernet tx_clk & rx_clk*/
+ writel((readl(&stv0991_cgu_regs->eth_ctrl) & ETH_CLK_MASK)
+ | ETH_CLK_CTRL, &stv0991_cgu_regs->eth_ctrl);
+
+ break;
+ default:
+ break;
+ }
+}
diff --git a/arch/arm/cpu/armv7/stv0991/lowlevel.S b/arch/arm/cpu/armv7/stv0991/lowlevel.S
new file mode 100644
index 0000000..6dafba3
--- /dev/null
+++ b/arch/arm/cpu/armv7/stv0991/lowlevel.S
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2014 stmicroelectronics
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+ mov pc, lr
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/cpu/armv7/stv0991/pinmux.c b/arch/arm/cpu/armv7/stv0991/pinmux.c
new file mode 100644
index 0000000..1d086a2
--- /dev/null
+++ b/arch/arm/cpu/armv7/stv0991/pinmux.c
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2014
+ * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <asm/arch/stv0991_creg.h>
+#include <asm/arch/stv0991_periph.h>
+#include <asm/arch/hardware.h>
+
+static struct stv0991_creg *const stv0991_creg = \
+ (struct stv0991_creg *)CREG_BASE_ADDR;
+
+int stv0991_pinmux_config(int peripheral)
+{
+ switch (peripheral) {
+ case UART_GPIOC_30_31:
+ /* SSDA/SSCL pad muxing to UART Rx/Dx */
+ writel((readl(&stv0991_creg->mux12) & GPIOC_31_MUX_MASK) |
+ CFG_GPIOC_31_UART_RX,
+ &stv0991_creg->mux12);
+ writel((readl(&stv0991_creg->mux12) & GPIOC_30_MUX_MASK) |
+ CFG_GPIOC_30_UART_TX,
+ &stv0991_creg->mux12);
+ /* SSDA/SSCL pad config to push pull*/
+ writel((readl(&stv0991_creg->cfg_pad6) & GPIOC_31_MODE_MASK) |
+ CFG_GPIOC_31_MODE_PP,
+ &stv0991_creg->cfg_pad6);
+ writel((readl(&stv0991_creg->cfg_pad6) & GPIOC_30_MODE_MASK) |
+ CFG_GPIOC_30_MODE_HIGH,
+ &stv0991_creg->cfg_pad6);
+ break;
+ case UART_GPIOB_16_17:
+ /* ethernet rx_6/7 to UART Rx/Dx */
+ writel((readl(&stv0991_creg->mux7) & GPIOB_17_MUX_MASK) |
+ CFG_GPIOB_17_UART_RX,
+ &stv0991_creg->mux7);
+ writel((readl(&stv0991_creg->mux7) & GPIOB_16_MUX_MASK) |
+ CFG_GPIOB_16_UART_TX,
+ &stv0991_creg->mux7);
+ break;
+ case ETH_GPIOB_10_31_C_0_4:
+ writel(readl(&stv0991_creg->mux6) & 0x000000FF,
+ &stv0991_creg->mux6);
+ writel(0x00000000, &stv0991_creg->mux7);
+ writel(0x00000000, &stv0991_creg->mux8);
+ writel(readl(&stv0991_creg->mux9) & 0xFFF00000,
+ &stv0991_creg->mux9);
+ /* Ethernet Voltage configuration to 1.8V*/
+ writel((readl(&stv0991_creg->vdd_pad1) & VDD_ETH_PS_MASK) |
+ ETH_VDD_CFG, &stv0991_creg->vdd_pad1);
+ writel((readl(&stv0991_creg->vdd_pad1) & VDD_ETH_PS_MASK) |
+ ETH_M_VDD_CFG, &stv0991_creg->vdd_pad1);
+
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
diff --git a/arch/arm/cpu/armv7/stv0991/reset.c b/arch/arm/cpu/armv7/stv0991/reset.c
new file mode 100644
index 0000000..3384b32
--- /dev/null
+++ b/arch/arm/cpu/armv7/stv0991/reset.c
@@ -0,0 +1,26 @@
+/*
+ * (C) Copyright 2014
+ * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/stv0991_wdru.h>
+void reset_cpu(ulong ignored)
+{
+ puts("System is going to reboot ...\n");
+ /*
+ * This 1 second delay will allow the above message
+ * to be printed before reset
+ */
+ udelay((1000 * 1000));
+
+ /* Setting bit 1 of the WDRU unit will reset the SoC */
+ writel(WDRU_RST_SYS, &stv0991_wd_ru_ptr->wdru_ctrl1);
+
+ /* system will restart */
+ while (1)
+ ;
+}
diff --git a/arch/arm/cpu/armv7/stv0991/timer.c b/arch/arm/cpu/armv7/stv0991/timer.c
new file mode 100644
index 0000000..8654b8b
--- /dev/null
+++ b/arch/arm/cpu/armv7/stv0991/timer.c
@@ -0,0 +1,114 @@
+/*
+ * (C) Copyright 2014
+ * Vikas Manocha, ST Micoelectronics, vikas.manocha@st.com.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch-stv0991/hardware.h>
+#include <asm/arch-stv0991/stv0991_cgu.h>
+#include <asm/arch-stv0991/stv0991_gpt.h>
+
+static struct stv0991_cgu_regs *const stv0991_cgu_regs = \
+ (struct stv0991_cgu_regs *) (CGU_BASE_ADDR);
+
+#define READ_TIMER() (readl(&gpt1_regs_ptr->cnt) & GPT_FREE_RUNNING)
+#define GPT_RESOLUTION (CONFIG_STV0991_HZ_CLOCK / CONFIG_STV0991_HZ)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define timestamp gd->arch.tbl
+#define lastdec gd->arch.lastinc
+
+int timer_init(void)
+{
+ /* Timer1 clock configuration */
+ writel(TIMER1_CLK_CFG, &stv0991_cgu_regs->tim_freq);
+ writel(readl(&stv0991_cgu_regs->cgu_enable_2) |
+ TIMER1_CLK_EN, &stv0991_cgu_regs->cgu_enable_2);
+
+ /* Stop the timer */
+ writel(readl(&gpt1_regs_ptr->cr1) & ~GPT_CR1_CEN, &gpt1_regs_ptr->cr1);
+ writel(GPT_PRESCALER_128, &gpt1_regs_ptr->psc);
+ /* Configure timer for auto-reload */
+ writel(readl(&gpt1_regs_ptr->cr1) | GPT_MODE_AUTO_RELOAD,
+ &gpt1_regs_ptr->cr1);
+
+ /* load value for free running */
+ writel(GPT_FREE_RUNNING, &gpt1_regs_ptr->arr);
+
+ /* start timer */
+ writel(readl(&gpt1_regs_ptr->cr1) | GPT_CR1_CEN,
+ &gpt1_regs_ptr->cr1);
+
+ /* Reset the timer */
+ lastdec = READ_TIMER();
+ timestamp = 0;
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+ulong get_timer(ulong base)
+{
+ return (get_timer_masked() / GPT_RESOLUTION) - base;
+}
+
+void __udelay(unsigned long usec)
+{
+ ulong tmo;
+ ulong start = get_timer_masked();
+ ulong tenudelcnt = CONFIG_STV0991_HZ_CLOCK / (1000 * 100);
+ ulong rndoff;
+
+ rndoff = (usec % 10) ? 1 : 0;
+
+ /* tenudelcnt timer tick gives 10 microsecconds delay */
+ tmo = ((usec / 10) + rndoff) * tenudelcnt;
+
+ while ((ulong) (get_timer_masked() - start) < tmo)
+ ;
+}
+
+ulong get_timer_masked(void)
+{
+ ulong now = READ_TIMER();
+
+ if (now >= lastdec) {
+ /* normal mode */
+ timestamp += now - lastdec;
+ } else {
+ /* we have an overflow ... */
+ timestamp += now + GPT_FREE_RUNNING - lastdec;
+ }
+ lastdec = now;
+
+ return timestamp;
+}
+
+void udelay_masked(unsigned long usec)
+{
+ return udelay(usec);
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+ return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+ return CONFIG_STV0991_HZ;
+}
diff --git a/arch/arm/cpu/armv7/vf610/generic.c b/arch/arm/cpu/armv7/vf610/generic.c
index a26d63e..92aaad9 100644
--- a/arch/arm/cpu/armv7/vf610/generic.c
+++ b/arch/arm/cpu/armv7/vf610/generic.c
@@ -265,20 +265,21 @@ static char *get_reset_cause(void)
cause = readl(&src_regs->srsr);
writel(cause, &src_regs->srsr);
- cause &= 0xff;
- switch (cause) {
- case 0x08:
- return "WDOG";
- case 0x20:
+ if (cause & SRC_SRSR_POR_RST)
+ return "POWER ON RESET";
+ else if (cause & SRC_SRSR_WDOG_A5)
+ return "WDOG A5";
+ else if (cause & SRC_SRSR_WDOG_M4)
+ return "WDOG M4";
+ else if (cause & SRC_SRSR_JTAG_RST)
return "JTAG HIGH-Z";
- case 0x80:
+ else if (cause & SRC_SRSR_SW_RST)
+ return "SW RESET";
+ else if (cause & SRC_SRSR_RESETB)
return "EXTERNAL RESET";
- case 0xfd:
- return "POR";
- default:
+ else
return "unknown reset";
- }
}
int print_cpuinfo(void)