summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorOlivia Yin-R63875 <r63875@freescale.com>2015-03-20 06:47:30 (GMT)
committerOlivia Yin-R63875 <r63875@freescale.com>2015-03-20 06:47:30 (GMT)
commit5e2ec78568981f8f93c1eb762e0ebad324c5a90f (patch)
treeb5928669d1b8c88c835509cbf513dbd44db0cda0 /arch
parentdcdf3c4866f92abf960dd4b9a5be1aaed4887405 (diff)
parentb2d58e506b33b18574807e63007e87ebca0f9c07 (diff)
downloadlinux-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.dts26
-rw-r--r--arch/arm/boot/dts/ls1021a.dtsi12
-rw-r--r--arch/arm/configs/ls1021a_defconfig2
-rw-r--r--arch/arm/mach-imx/mach-ls1021a.c11
-rw-r--r--arch/arm/mach-imx/platsmp.c50
-rw-r--r--arch/arm/mach-imx/pm-ls1.c96
-rw-r--r--arch/arm/mach-imx/src.c21
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;