diff options
author | Olivia Yin-R63875 <r63875@freescale.com> | 2015-03-20 06:47:30 (GMT) |
---|---|---|
committer | Olivia Yin-R63875 <r63875@freescale.com> | 2015-03-20 06:47:30 (GMT) |
commit | 5e2ec78568981f8f93c1eb762e0ebad324c5a90f (patch) | |
tree | b5928669d1b8c88c835509cbf513dbd44db0cda0 /arch | |
parent | dcdf3c4866f92abf960dd4b9a5be1aaed4887405 (diff) | |
parent | b2d58e506b33b18574807e63007e87ebca0f9c07 (diff) | |
download | linux-fsl-qoriq-5e2ec78568981f8f93c1eb762e0ebad324c5a90f.tar.xz |
Merge remote-tracking branch 'ls1-linux/LS1-SDK'
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/boot/dts/ls1021a-qds.dts | 26 | ||||
-rw-r--r-- | arch/arm/boot/dts/ls1021a.dtsi | 12 | ||||
-rw-r--r-- | arch/arm/configs/ls1021a_defconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-ls1021a.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-imx/platsmp.c | 50 | ||||
-rw-r--r-- | arch/arm/mach-imx/pm-ls1.c | 96 | ||||
-rw-r--r-- | arch/arm/mach-imx/src.c | 21 |
7 files changed, 175 insertions, 43 deletions
diff --git a/arch/arm/boot/dts/ls1021a-qds.dts b/arch/arm/boot/dts/ls1021a-qds.dts index 983e1bd..93cda05 100644 --- a/arch/arm/boot/dts/ls1021a-qds.dts +++ b/arch/arm/boot/dts/ls1021a-qds.dts @@ -129,6 +129,32 @@ status = "okay"; }; +&dcu0 { + display = <&display>; + status = "okay"; + + display: display@0 { + bits-per-pixel = <24>; + + display-timings { + native-mode = <&timing0>; + timing0: nl4827hc19 { + clock-frequency = <25174000>; + hactive = <640>; + vactive = <480>; + hback-porch = <48>; + hfront-porch = <16>; + vback-porch = <33>; + vfront-porch = <10>; + hsync-len = <96>; + vsync-len = <2>; + hsync-active = <1>; + vsync-active = <1>; + }; + }; + }; +}; + &enet0 { tbi-handle = <&tbi0>; phy-handle = <&sgmii_phy1c>; diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi index 67909b1..491480f 100644 --- a/arch/arm/boot/dts/ls1021a.dtsi +++ b/arch/arm/boot/dts/ls1021a.dtsi @@ -128,9 +128,17 @@ sdhci,auto-cmd12; big-endian; bus-width = <4>; + sleep = <&rcpm 0x00000080 0x0>; status = "disabled"; }; + sata: sata@3200000 { + compatible = "fsl,ls1021a-ahci"; + reg = <0x0 0x3200000 0x0 0x10000>; + interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&platform_clk 1>; + }; + scfg: scfg@1570000 { compatible = "fsl,ls1021a-scfg", "syscon"; reg = <0x0 0x1570000 0x0 0x10000>; @@ -391,6 +399,7 @@ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; clocks = <&sysclk>; clock-names = "ipg"; + sleep = <&rcpm 0x0 0x40000000>; status = "disabled"; }; @@ -447,6 +456,7 @@ #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + sleep = <&rcpm 0x00000040 0x0>; }; gpio2: gpio@2310000 { @@ -484,6 +494,7 @@ reg = <0x0 0x29d0000 0x0 0x10000>; interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>; big-endian; + sleep = <&rcpm 0x0 0x20000000>; status = "disabled"; }; @@ -606,6 +617,7 @@ fsl,dma-endian-le; fsl,magic-packet; fsl,wake-on-filer; + sleep = <&rcpm 0x80000000 0x0>; fsl,num_rx_queues = <0x1>; fsl,num_tx_queues = <0x1>; local-mac-address = [ 00 00 00 00 00 00 ]; diff --git a/arch/arm/configs/ls1021a_defconfig b/arch/arm/configs/ls1021a_defconfig index a6103b8..12f5f84 100644 --- a/arch/arm/configs/ls1021a_defconfig +++ b/arch/arm/configs/ls1021a_defconfig @@ -98,6 +98,8 @@ CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_SCSI_MULTI_LUN=y CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y CONFIG_SATA_SIL24=y CONFIG_NETDEVICES=y CONFIG_GIANFAR=y diff --git a/arch/arm/mach-imx/mach-ls1021a.c b/arch/arm/mach-imx/mach-ls1021a.c index 3895ffc..3692dd0 100644 --- a/arch/arm/mach-imx/mach-ls1021a.c +++ b/arch/arm/mach-imx/mach-ls1021a.c @@ -7,6 +7,9 @@ * (at your option) any later version. */ +#include <linux/clk-provider.h> +#include <linux/clockchips.h> +#include <linux/clocksource.h> #include <linux/of_platform.h> #include <asm/mach/arch.h> @@ -18,6 +21,13 @@ static void __init ls1021a_init_machine(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); } +static void __init ls1021a_init_time(void) +{ + of_clk_init(NULL); + clocksource_of_init(); + tick_setup_hrtimer_broadcast(); +} + static const char *ls1021a_dt_compat[] __initdata = { "fsl,ls1021a", NULL, @@ -25,6 +35,7 @@ static const char *ls1021a_dt_compat[] __initdata = { DT_MACHINE_START(LS1021A, "Freescale LS1021A") .smp = smp_ops(ls1021a_smp_ops), + .init_time = ls1021a_init_time, .init_machine = ls1021a_init_machine, .dt_compat = ls1021a_dt_compat, .restart = mxc_restart, diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 22f9814..72f8e5f 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -19,6 +19,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/delay.h> +#include <asm/smp_plat.h> #include "common.h" #include "hardware.h" @@ -36,6 +37,8 @@ #define DCSR_RCPM2_DEBUG1 0x400 #define DCSR_RCPM2_DEBUG2 0x414 +#define CCSR_TWAITSR0 0x04C + #define STRIDE_4B 4 u32 g_diag_reg; @@ -43,6 +46,7 @@ static void __iomem *scu_base; static void __iomem *dcfg_base; static void __iomem *scfg_base; static void __iomem *dcsr_rcpm2_base; +static void __iomem *rcpm_base; static u32 secondary_pre_boot_entry; static struct map_desc scu_io_desc __initdata = { @@ -134,7 +138,7 @@ static int ls1021a_secondary_iomap(void) np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg"); if (!np) { pr_err("%s: failed to find dcfg node.\n", __func__); - ret = -EINVAL; + ret = -ENODEV; goto dcfg_err; } @@ -149,7 +153,7 @@ static int ls1021a_secondary_iomap(void) np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg"); if (!np) { pr_err("%s: failed to find scfg node.\n", __func__); - ret = -EINVAL; + ret = -ENODEV; goto scfg_err; } @@ -164,7 +168,7 @@ static int ls1021a_secondary_iomap(void) np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcsr-rcpm"); if (!np) { pr_err("%s: failed to find dcsr node.\n", __func__); - ret = -EINVAL; + ret = -ENODEV; goto dcsr_err; } @@ -176,8 +180,25 @@ static int ls1021a_secondary_iomap(void) goto dcsr_err; } + np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-rcpm-2.1"); + if (!np) { + pr_err("%s(): failed to find the RCPM node.\n", __func__); + ret = -ENODEV; + goto rcpm_err; + } + + rcpm_base = of_iomap(np, 0); + of_node_put(np); + if (!rcpm_base) { + pr_err("%s: failed to map rcpm.\n", __func__); + ret = -ENOMEM; + goto rcpm_err; + } + return 0; +rcpm_err: + iounmap(dcsr_rcpm2_base); dcsr_err: iounmap(scfg_base); scfg_err: @@ -186,13 +207,18 @@ dcfg_err: return ret; } +u32 ls1_get_cpu_arg(int cpu) +{ + BUG_ON(!rcpm_base); + + cpu = cpu_logical_map(cpu); + return ioread32be(rcpm_base + CCSR_TWAITSR0) & (1 << cpu); +} + void ls1021a_set_secondary_entry(void) { unsigned long paddr; - secondary_pre_boot_entry = readl_relaxed(dcfg_base + - DCFG_CCSR_SCRATCHRW1); - if (dcfg_base) { paddr = virt_to_phys(secondary_startup); writel_relaxed(cpu_to_be32(paddr), @@ -220,14 +246,6 @@ static int ls1021a_reset_secondary(unsigned int cpu) SCFG_CORE0_SFT_RST + STRIDE_4B * cpu); mdelay(15); - /* LS1021a errata. after reset, core state machine registers - * need to force release manually. - */ - iowrite32be(0x00000080, dcsr_rcpm2_base + DCSR_RCPM2_DEBUG1); - iowrite32be(0x00000080, dcsr_rcpm2_base + DCSR_RCPM2_DEBUG2); - iowrite32be(0, dcsr_rcpm2_base + DCSR_RCPM2_DEBUG1); - iowrite32be(0, dcsr_rcpm2_base + DCSR_RCPM2_DEBUG2); - /* Release secondary core */ iowrite32be(1 << cpu, dcfg_base + DCFG_CCSR_BRR); @@ -259,6 +277,10 @@ static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus) { ls1021a_secondary_iomap(); + + secondary_pre_boot_entry = readl_relaxed(dcfg_base + + DCFG_CCSR_SCRATCHRW1); + ls1021a_set_secondary_entry(); } diff --git a/arch/arm/mach-imx/pm-ls1.c b/arch/arm/mach-imx/pm-ls1.c index 827a486..b8bfdb5 100644 --- a/arch/arm/mach-imx/pm-ls1.c +++ b/arch/arm/mach-imx/pm-ls1.c @@ -35,6 +35,15 @@ #define CCSR_SCFG_DPSLPCR 0 #define CCSR_SCFG_DPSLPCR_VAL 0x1 #define CCSR_SCFG_PMCINTECR 0x160 +#define CCSR_SCFG_PMCINTECR_LPUART 0x40000000 +#define CCSR_SCFG_PMCINTECR_FTM 0x20000000 +#define CCSR_SCFG_PMCINTECR_GPIO 0x10000000 +#define CCSR_SCFG_PMCINTECR_IRQ0 0x08000000 +#define CCSR_SCFG_PMCINTECR_IRQ1 0x04000000 +#define CCSR_SCFG_PMCINTECR_ETSECRXG0 0x00800000 +#define CCSR_SCFG_PMCINTECR_ETSECRXG1 0x00400000 +#define CCSR_SCFG_PMCINTECR_ETSECERRG0 0x00080000 +#define CCSR_SCFG_PMCINTECR_ETSECERRG1 0x00040000 #define CCSR_SCFG_PMCINTLECR 0x164 #define CCSR_SCFG_PMCINTSR 0x168 #define CCSR_SCFG_SPARECR2 0x504 @@ -50,7 +59,12 @@ #define CCSR_RCPM_CLPCL10SETR 0x1c4 #define CCSR_RCPM_CLPCL10SETR_C0 0x1 #define CCSR_RCPM_IPPDEXPCR0 0x140 +#define CCSR_RCPM_IPPDEXPCR0_ETSEC 0x80000000 +#define CCSR_RCPM_IPPDEXPCR0_GPIO 0x00000040 #define CCSR_RCPM_IPPDEXPCR1 0x144 +#define CCSR_RCPM_IPPDEXPCR1_LPUART 0x40000000 +#define CCSR_RCPM_IPPDEXPCR1_FLEXTIMER 0x20000000 +#define CCSR_RCPM_IPPDEXPCR1_OCRAM1 0x10000000 #define QIXIS_CTL_SYS 0x5 #define QIXIS_CTL_SYS_EVTSW_MASK 0x0c @@ -64,6 +78,10 @@ /* use the last page of SRAM */ #define SRAM_CODE_BASE_PHY (OCRAM_BASE + OCRAM_SIZE - PAGE_SIZE) +#define SLEEP_ARRAY_SIZE 3 + +static u32 ippdexpcr0, ippdexpcr1; + struct ls1_pm_baseaddr { void __iomem *epu; void __iomem *dcsr_rcpm1; @@ -132,17 +150,37 @@ static void ls1_pm_uniomap(void) iounmap(ls1_pm_base.sram); } - -static void ls1_setup_wakeup_source(void) +static void ls1_setup_pmc_int(void) { + u32 pmcintecr; + + pmcintecr = 0; + if (ippdexpcr0 & CCSR_RCPM_IPPDEXPCR0_ETSEC) + pmcintecr |= CCSR_SCFG_PMCINTECR_ETSECRXG0 | + CCSR_SCFG_PMCINTECR_ETSECRXG1 | + CCSR_SCFG_PMCINTECR_ETSECERRG0 | + CCSR_SCFG_PMCINTECR_ETSECERRG1; + + if (ippdexpcr0 & CCSR_RCPM_IPPDEXPCR0_GPIO) + pmcintecr |= CCSR_SCFG_PMCINTECR_GPIO; + + if (ippdexpcr1 & CCSR_RCPM_IPPDEXPCR1_LPUART) + pmcintecr |= CCSR_SCFG_PMCINTECR_LPUART; + + if (ippdexpcr1 & CCSR_RCPM_IPPDEXPCR1_FLEXTIMER) + pmcintecr |= CCSR_SCFG_PMCINTECR_FTM; + + /* always set external IRQ pins as wakeup source */ + pmcintecr |= CCSR_SCFG_PMCINTECR_IRQ0 | CCSR_SCFG_PMCINTECR_IRQ1; + /* enable wakeup interrupt during deep sleep */ - iowrite32be(0xfcfc0000, ls1_pm_base.scfg + CCSR_SCFG_PMCINTECR); + iowrite32be(pmcintecr, ls1_pm_base.scfg + CCSR_SCFG_PMCINTECR); iowrite32be(0, ls1_pm_base.scfg + CCSR_SCFG_PMCINTLECR); /* clear PMC interrupt status */ iowrite32be(0xffffffff, ls1_pm_base.scfg + CCSR_SCFG_PMCINTSR); } -static void ls1_clear_wakeup_source(void) +static void ls1_clear_pmc_int(void) { /* disable wakeup interrupt during deep sleep */ iowrite32be(0, ls1_pm_base.scfg + CCSR_SCFG_PMCINTECR); @@ -153,8 +191,13 @@ static void ls1_clear_wakeup_source(void) /* set IP powerdown exception, make them work during sleep/deep sleep */ static void ls1_set_powerdown(void) { - iowrite32be(0x8000c000, ls1_pm_base.rcpm + CCSR_RCPM_IPPDEXPCR0); - iowrite32be(0xf0000000, ls1_pm_base.rcpm + CCSR_RCPM_IPPDEXPCR1); + iowrite32be(ippdexpcr0, ls1_pm_base.rcpm + CCSR_RCPM_IPPDEXPCR0); + /* + * In the case of SD boot, system can't wake from deep sleep + * if OCRAM1 is powered down. Therefore, keep it on. + */ + ippdexpcr1 |= CCSR_RCPM_IPPDEXPCR1_OCRAM1; + iowrite32be(ippdexpcr1, ls1_pm_base.rcpm + CCSR_RCPM_IPPDEXPCR1); } static void ls1_save_ddr(void *base) @@ -276,11 +319,11 @@ static void ls1_enter_deepsleep(void) /* copy the last stage code to sram */ ls1_copy_sram_code(); - ls1_setup_wakeup_source(); + ls1_setup_pmc_int(); cpu_suspend(SRAM_CODE_BASE_PHY, ls1_start_deepsleep); - ls1_clear_wakeup_source(); + ls1_clear_pmc_int(); /* disable Warm Device Reset */ ls1_clrsetbits_be32(ls1_pm_base.scfg + CCSR_SCFG_DPSLPCR, @@ -291,6 +334,39 @@ static void ls1_enter_deepsleep(void) iowrite8(tmp & ~QIXIS_PWR_CTL2_PCTL, ls1_pm_base.fpga + QIXIS_PWR_CTL2); } +static void ls1_set_power_except(struct device *dev, int on) +{ + int ret; + u32 value[SLEEP_ARRAY_SIZE]; + + /* + * Get the values in the "sleep" property. There are three values. + * The first points to the RCPM node, the second is the value of + * the ippdexpcr0 register, and the third is the value of + * the ippdexpcr1 register. + */ + ret = of_property_read_u32_array(dev->of_node, "sleep", + value, SLEEP_ARRAY_SIZE); + if (ret) { + dev_err(dev, "%s: Can not find the \"sleep\" property.\n", + __func__); + return; + } + + ippdexpcr0 |= value[1]; + ippdexpcr1 |= value[2]; + + pr_debug("%s: set %s as a wakeup source", __func__, + dev->of_node->full_name); +} + +static void ls1_set_wakeup_device(struct device *dev, void *enable) +{ + /* set each device which can act as wakeup source */ + if (device_may_wakeup(dev)) + ls1_set_power_except(dev, *((int *)enable)); +} + static int ls1_suspend_enter(suspend_state_t state) { int ret = 0; @@ -333,6 +409,10 @@ static int ls1_suspend_begin(suspend_state_t state) { ls1_pm_state = state; + ippdexpcr0 = 0; + ippdexpcr1 = 0; + dpm_for_each_dev(NULL, ls1_set_wakeup_device); + if (ls1_pm_state == PM_SUSPEND_MEM) ls1_pm_iomap(); diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index e73cbbe..10a6b1a 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -30,8 +30,6 @@ #define BP_SRC_SCR_CORE1_RST 14 #define BP_SRC_SCR_CORE1_ENABLE 22 -#define CCSR_TWAITSR0 0x04C - static void __iomem *src_base; static DEFINE_SPINLOCK(scr_lock); @@ -116,25 +114,6 @@ void imx_set_cpu_arg(int cpu, u32 arg) writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); } -u32 ls1_get_cpu_arg(int cpu) -{ - struct device_node *np; - void __iomem *ls1_rcpm_base; - - np = of_find_compatible_node(NULL, NULL, "fsl,qoriq-rcpm-2.1"); - if (!np) { - pr_err("%s(): Can not find the RCPM node.\n", __func__); - return -ENODEV; - } - - ls1_rcpm_base = of_iomap(np, 0); - of_node_put(np); - WARN_ON(!ls1_rcpm_base); - - cpu = cpu_logical_map(cpu); - return ioread32be(ls1_rcpm_base + CCSR_TWAITSR0) & (1 << cpu); -} - void imx_src_prepare_restart(void) { u32 val; |