Merge tag 'zynq-cleanup-for-3.16' of git://git.xilinx.com/linux-xlnx into next/soc
authorOlof Johansson <olof@lixom.net>
Mon, 26 May 2014 21:52:23 +0000 (14:52 -0700)
committerOlof Johansson <olof@lixom.net>
Mon, 26 May 2014 21:52:23 +0000 (14:52 -0700)
Merge "Xilinx Zynq changes for v3.16" from Michal Simek:

arm: Xilinx Zynq cleanup patches for v3.16

- Add support for BIG Endian
- Add SOC_BUS support
- Sort Kconfig options
- Fix early console

* tag 'zynq-cleanup-for-3.16' of git://git.xilinx.com/linux-xlnx:
  ARM: zynq: Enable big-endian
  ARM: zynq: Fix uart0 early console virtual address
  clocksource: cadence_ttc: Use readl/writel_relaxed instead of __raw
  ARM: zynq: Sort Kconfig options
  ARM: zynq: Add support for SOC_BUS

Signed-off-by: Olof Johansson <olof@lixom.net>
arch/arm/boot/dts/zynq-7000.dtsi
arch/arm/include/debug/zynq.S
arch/arm/mach-zynq/Kconfig
arch/arm/mach-zynq/common.c
arch/arm/mach-zynq/common.h
arch/arm/mach-zynq/headsmp.S
arch/arm/mach-zynq/slcr.c
drivers/clocksource/cadence_ttc_timer.c

index c1176abc34d92d0491eeeadf74a926ff7fc360ed..80d8e4f3f62681db052cd949e5e8044c09804e89 100644 (file)
                        };
                };
 
+               devcfg: devcfg@f8007000 {
+                       compatible = "xlnx,zynq-devcfg-1.0";
+                       reg = <0xf8007000 0x100>;
+               } ;
+
                global_timer: timer@f8f00200 {
                        compatible = "arm,cortex-a9-global-timer";
                        reg = <0xf8f00200 0x20>;
index 0b762fafa7586a092399f8864f1cfdeaf3ff05ce..bd13dedbdeffe25cfc455ec3a1f9caa42f314ce4 100644 (file)
 #define UART_SR_TXEMPTY                0x00000008      /* TX FIFO empty */
 
 #define UART0_PHYS             0xE0000000
+#define UART0_VIRT             0xF0000000
 #define UART1_PHYS             0xE0001000
-#define UART_SIZE              SZ_4K
-#define UART_VIRT              0xF0001000
+#define UART1_VIRT             0xF0001000
 
 #if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
 # define LL_UART_PADDR         UART1_PHYS
+# define LL_UART_VADDR         UART1_VIRT
 #else
 # define LL_UART_PADDR         UART0_PHYS
+# define LL_UART_VADDR         UART0_VIRT
 #endif
 
-#define LL_UART_VADDR          UART_VIRT
-
                .macro  addruart, rp, rv, tmp
                ldr     \rp, =LL_UART_PADDR     @ physical
                ldr     \rv, =LL_UART_VADDR     @ virtual
 
                .macro  waituart,rd,rx
 1001:          ldr     \rd, [\rx, #UART_SR_OFFSET]
+ARM_BE8(       rev     \rd, \rd )
                tst     \rd, #UART_SR_TXEMPTY
                beq     1001b
                .endm
 
                .macro  busyuart,rd,rx
 1002:          ldr     \rd, [\rx, #UART_SR_OFFSET]     @ get status register
+ARM_BE8(       rev     \rd, \rd )
                tst     \rd, #UART_SR_TXFULL            @
                bne     1002b                   @ wait if FIFO is full
                .endm
index 58c2b844e0a3c99cac20e1219d48d1685391fe69..573e0db1d0f0a928a9c2290c532490199e137204 100644 (file)
@@ -1,14 +1,16 @@
 config ARCH_ZYNQ
        bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
-       select ARM_AMBA
-       select ARM_GIC
        select ARCH_HAS_CPUFREQ
        select ARCH_HAS_OPP
+       select ARCH_SUPPORTS_BIG_ENDIAN
+       select ARM_AMBA
+       select ARM_GIC
+       select ARM_GLOBAL_TIMER if !CPU_FREQ
+       select CADENCE_TTC_TIMER
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select ICST
-       select CADENCE_TTC_TIMER
-       select ARM_GLOBAL_TIMER if !CPU_FREQ
        select MFD_SYSCON
+       select SOC_BUS
        help
          Support for Xilinx Zynq ARM Cortex A9 Platform
index 6fcc584c1a110fb1986ee9ddbb0ae99bfbf907a4..edbd9d83f407007bf208f3700dabfd8d7dc381d7 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/memblock.h>
 #include <linux/irqchip.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/smp_scu.h>
+#include <asm/system_info.h>
 #include <asm/hardware/cache-l2x0.h>
 
 #include "common.h"
 
+#define ZYNQ_DEVCFG_MCTRL              0x80
+#define ZYNQ_DEVCFG_PS_VERSION_SHIFT   28
+#define ZYNQ_DEVCFG_PS_VERSION_MASK    0xF
+
 void __iomem *zynq_scu_base;
 
 /**
@@ -59,6 +66,38 @@ static struct platform_device zynq_cpuidle_device = {
        .name = "cpuidle-zynq",
 };
 
+/**
+ * zynq_get_revision - Get Zynq silicon revision
+ *
+ * Return: Silicon version or -1 otherwise
+ */
+static int __init zynq_get_revision(void)
+{
+       struct device_node *np;
+       void __iomem *zynq_devcfg_base;
+       u32 revision;
+
+       np = of_find_compatible_node(NULL, NULL, "xlnx,zynq-devcfg-1.0");
+       if (!np) {
+               pr_err("%s: no devcfg node found\n", __func__);
+               return -1;
+       }
+
+       zynq_devcfg_base = of_iomap(np, 0);
+       if (!zynq_devcfg_base) {
+               pr_err("%s: Unable to map I/O memory\n", __func__);
+               return -1;
+       }
+
+       revision = readl(zynq_devcfg_base + ZYNQ_DEVCFG_MCTRL);
+       revision >>= ZYNQ_DEVCFG_PS_VERSION_SHIFT;
+       revision &= ZYNQ_DEVCFG_PS_VERSION_MASK;
+
+       iounmap(zynq_devcfg_base);
+
+       return revision;
+}
+
 /**
  * zynq_init_machine - System specific initialization, intended to be
  *                    called from board specific initialization.
@@ -66,13 +105,43 @@ static struct platform_device zynq_cpuidle_device = {
 static void __init zynq_init_machine(void)
 {
        struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+       struct device *parent = NULL;
 
        /*
         * 64KB way size, 8-way associativity, parity disabled
         */
        l2x0_of_init(0x02060000, 0xF0F0FFFF);
 
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               goto out;
+
+       system_rev = zynq_get_revision();
+
+       soc_dev_attr->family = kasprintf(GFP_KERNEL, "Xilinx Zynq");
+       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "0x%x", system_rev);
+       soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x",
+                                        zynq_slcr_get_device_id());
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR(soc_dev)) {
+               kfree(soc_dev_attr->family);
+               kfree(soc_dev_attr->revision);
+               kfree(soc_dev_attr->soc_id);
+               kfree(soc_dev_attr);
+               goto out;
+       }
+
+       parent = soc_device_to_device(soc_dev);
+
+out:
+       /*
+        * Finished with the static registrations now; fill in the missing
+        * devices
+        */
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
 
        platform_device_register(&zynq_cpuidle_device);
        platform_device_register_full(&devinfo);
index b097844d3175ad7ac8204cfd3dcfd3362e88c265..f652f0a884a67d34da78bfd27966540b97a12312 100644 (file)
@@ -24,6 +24,7 @@ extern int zynq_early_slcr_init(void);
 extern void zynq_slcr_system_reset(void);
 extern void zynq_slcr_cpu_stop(int cpu);
 extern void zynq_slcr_cpu_start(int cpu);
+extern u32 zynq_slcr_get_device_id(void);
 
 #ifdef CONFIG_SMP
 extern void secondary_startup(void);
index 57a32869f0aa3215e0e49c282ca58d7f8976cad3..dd8c071941e7ff3b9f991989ede3acc5aaac856b 100644 (file)
@@ -8,9 +8,12 @@
  */
 #include <linux/linkage.h>
 #include <linux/init.h>
+#include <asm/assembler.h>
 
 ENTRY(zynq_secondary_trampoline)
-       ldr     r0, [pc]
+ARM_BE8(setend be)                             @ ensure we are in BE8 mode
+       ldr     r0, zynq_secondary_trampoline_jump
+ARM_BE8(rev    r0, r0)
        bx      r0
 .globl zynq_secondary_trampoline_jump
 zynq_secondary_trampoline_jump:
index a37d49a6e6578cddf922f45cb8a87c6b306dae25..c43a2d16e223bcfd74eca29eb6200c3bc93ff94d 100644 (file)
 #define SLCR_PS_RST_CTRL_OFFSET                0x200 /* PS Software Reset Control */
 #define SLCR_A9_CPU_RST_CTRL_OFFSET    0x244 /* CPU Software Reset Control */
 #define SLCR_REBOOT_STATUS_OFFSET      0x258 /* PS Reboot Status */
+#define SLCR_PSS_IDCODE                        0x530 /* PS IDCODE */
 
 #define SLCR_UNLOCK_MAGIC              0xDF0D
 #define SLCR_A9_CPU_CLKSTOP            0x10
 #define SLCR_A9_CPU_RST                        0x1
+#define SLCR_PSS_IDCODE_DEVICE_SHIFT   12
+#define SLCR_PSS_IDCODE_DEVICE_MASK    0x1F
 
 static void __iomem *zynq_slcr_base;
 static struct regmap *zynq_slcr_regmap;
@@ -82,6 +85,22 @@ static inline int zynq_slcr_unlock(void)
        return 0;
 }
 
+/**
+ * zynq_slcr_get_device_id - Read device code id
+ *
+ * Return:     Device code id
+ */
+u32 zynq_slcr_get_device_id(void)
+{
+       u32 val;
+
+       zynq_slcr_read(&val, SLCR_PSS_IDCODE);
+       val >>= SLCR_PSS_IDCODE_DEVICE_SHIFT;
+       val &= SLCR_PSS_IDCODE_DEVICE_MASK;
+
+       return val;
+}
+
 /**
  * zynq_slcr_system_reset - Reset the entire system.
  */
index 49fbe2847c8474cfd9398ee70e5bba713fe381c4..7a08811df9aa61505a763a3be3a5968339453120 100644 (file)
@@ -118,11 +118,11 @@ static void ttc_set_interval(struct ttc_timer *timer,
        u32 ctrl_reg;
 
        /* Disable the counter, set the counter value  and re-enable counter */
-       ctrl_reg = __raw_readl(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
+       ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
        ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
-       __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
+       writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
 
-       __raw_writel(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET);
+       writel_relaxed(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET);
 
        /*
         * Reset the counter (0x10) so that it starts from 0, one-shot
@@ -130,7 +130,7 @@ static void ttc_set_interval(struct ttc_timer *timer,
         */
        ctrl_reg |= CNT_CNTRL_RESET;
        ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
-       __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
+       writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
 }
 
 /**
@@ -147,7 +147,7 @@ static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id)
        struct ttc_timer *timer = &ttce->ttc;
 
        /* Acknowledge the interrupt and call event handler */
-       __raw_readl(timer->base_addr + TTC_ISR_OFFSET);
+       readl_relaxed(timer->base_addr + TTC_ISR_OFFSET);
 
        ttce->ce.event_handler(&ttce->ce);
 
@@ -163,13 +163,13 @@ static cycle_t __ttc_clocksource_read(struct clocksource *cs)
 {
        struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
 
-       return (cycle_t)__raw_readl(timer->base_addr +
+       return (cycle_t)readl_relaxed(timer->base_addr +
                                TTC_COUNT_VAL_OFFSET);
 }
 
 static u64 notrace ttc_sched_clock_read(void)
 {
-       return __raw_readl(ttc_sched_clock_val_reg);
+       return readl_relaxed(ttc_sched_clock_val_reg);
 }
 
 /**
@@ -211,17 +211,17 @@ static void ttc_set_mode(enum clock_event_mode mode,
        case CLOCK_EVT_MODE_ONESHOT:
        case CLOCK_EVT_MODE_UNUSED:
        case CLOCK_EVT_MODE_SHUTDOWN:
-               ctrl_reg = __raw_readl(timer->base_addr +
+               ctrl_reg = readl_relaxed(timer->base_addr +
                                        TTC_CNT_CNTRL_OFFSET);
                ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
-               __raw_writel(ctrl_reg,
+               writel_relaxed(ctrl_reg,
                                timer->base_addr + TTC_CNT_CNTRL_OFFSET);
                break;
        case CLOCK_EVT_MODE_RESUME:
-               ctrl_reg = __raw_readl(timer->base_addr +
+               ctrl_reg = readl_relaxed(timer->base_addr +
                                        TTC_CNT_CNTRL_OFFSET);
                ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
-               __raw_writel(ctrl_reg,
+               writel_relaxed(ctrl_reg,
                                timer->base_addr + TTC_CNT_CNTRL_OFFSET);
                break;
        }
@@ -266,8 +266,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
                 * of an abort.
                 */
                ttccs->scale_clk_ctrl_reg_old =
-                       __raw_readl(ttccs->ttc.base_addr +
-                                       TTC_CLK_CNTRL_OFFSET);
+                       readl_relaxed(ttccs->ttc.base_addr +
+                       TTC_CLK_CNTRL_OFFSET);
 
                psv = (ttccs->scale_clk_ctrl_reg_old &
                                TTC_CLK_CNTRL_PSV_MASK) >>
@@ -291,8 +291,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
                        return NOTIFY_DONE;
 
                /* scale up: adjust divider now - before frequency change */
-               __raw_writel(ttccs->scale_clk_ctrl_reg_new,
-                               ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
+               writel_relaxed(ttccs->scale_clk_ctrl_reg_new,
+                              ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
                break;
        }
        case POST_RATE_CHANGE:
@@ -301,8 +301,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
                        return NOTIFY_OK;
 
                /* scale down: adjust divider now - after frequency change */
-               __raw_writel(ttccs->scale_clk_ctrl_reg_new,
-                               ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
+               writel_relaxed(ttccs->scale_clk_ctrl_reg_new,
+                              ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
                break;
 
        case ABORT_RATE_CHANGE:
@@ -311,8 +311,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
                        return NOTIFY_OK;
 
                /* restore original register value */
-               __raw_writel(ttccs->scale_clk_ctrl_reg_old,
-                               ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
+               writel_relaxed(ttccs->scale_clk_ctrl_reg_old,
+                              ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
                /* fall through */
        default:
                return NOTIFY_DONE;
@@ -359,10 +359,10 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base)
         * with no interrupt and it rolls over at 0xFFFF. Pre-scale
         * it by 32 also. Let it start running now.
         */
-       __raw_writel(0x0,  ttccs->ttc.base_addr + TTC_IER_OFFSET);
-       __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
+       writel_relaxed(0x0,  ttccs->ttc.base_addr + TTC_IER_OFFSET);
+       writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
                     ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
-       __raw_writel(CNT_CNTRL_RESET,
+       writel_relaxed(CNT_CNTRL_RESET,
                     ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
 
        err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE);
@@ -438,10 +438,10 @@ static void __init ttc_setup_clockevent(struct clk *clk,
         * is prescaled by 32 using the interval interrupt. Leave it
         * disabled for now.
         */
-       __raw_writel(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
-       __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
+       writel_relaxed(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
+       writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
                     ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
-       __raw_writel(0x1,  ttcce->ttc.base_addr + TTC_IER_OFFSET);
+       writel_relaxed(0x1,  ttcce->ttc.base_addr + TTC_IER_OFFSET);
 
        err = request_irq(irq, ttc_clock_event_interrupt,
                          IRQF_TIMER, ttcce->ce.name, ttcce);
@@ -490,7 +490,7 @@ static void __init ttc_timer_init(struct device_node *timer)
                BUG();
        }
 
-       clksel = __raw_readl(timer_baseaddr + TTC_CLK_CNTRL_OFFSET);
+       clksel = readl_relaxed(timer_baseaddr + TTC_CLK_CNTRL_OFFSET);
        clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
        clk_cs = of_clk_get(timer, clksel);
        if (IS_ERR(clk_cs)) {
@@ -498,7 +498,7 @@ static void __init ttc_timer_init(struct device_node *timer)
                BUG();
        }
 
-       clksel = __raw_readl(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET);
+       clksel = readl_relaxed(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET);
        clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK);
        clk_ce = of_clk_get(timer, clksel);
        if (IS_ERR(clk_ce)) {
This page took 0.041401 seconds and 5 git commands to generate.