arm: Xilinx Zynq cleanup patches for v3.16
- Add support for BIG Endian - Add SOC_BUS support - Sort Kconfig options - Fix early console -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iEYEABECAAYFAlOCxdwACgkQykllyylKDCEydwCglWoRgU1kvPH6oqyH5esHv7L3 oY4AnA+t3msa91ovFFbsCm2xW77QbbC6 =Ubf9 -----END PGP SIGNATURE----- Merge tag 'zynq-cleanup-for-3.16' of git://git.xilinx.com/linux-xlnx into next/soc 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>
This commit is contained in:
Коммит
4fd0912044
|
@ -177,6 +177,11 @@
|
|||
};
|
||||
};
|
||||
|
||||
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>;
|
||||
|
|
|
@ -20,18 +20,18 @@
|
|||
#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
|
||||
|
@ -43,12 +43,14 @@
|
|||
|
||||
.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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
@ -37,10 +39,15 @@
|
|||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -26,10 +26,13 @@
|
|||
#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.
|
||||
*/
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче