aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2018-03-15 11:10:32 -0400
committerArnd Bergmann <arnd@arndb.de>2018-03-15 11:10:32 -0400
commit0240f307213e4fb238eeacbf4bc18c7a13ac4774 (patch)
tree93f6ab4617658ff9ab4fb2cb199e838c5b2bc7a4
parent8694360b281c91b419c1eb050b53422adcef218e (diff)
parentdee5dee2a5b285d20f55a4758d3a51349691eeea (diff)
Merge tag 'imx-soc-4.17' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux into next/soc
Pull "i.MX SoC changes for 4.17" from Shawn Guo: - Add i.MX 6SoloLiteLite (i.MX6SLL) SoC support on top of the existing i.MX6SL platform code. - Improve the SoC revision mapping by utilizing the MAJOR field of ANATOP DIGPROG register. - Add CPUIDLE_FLAG_TIMER_STOP flag for cpuidle ARM power off state, so that we can use ARM generic timer for some i.MX6 SoC. - Set low-power interrupt mask for i.MX25 to support STOP mode. - Drop EPIT driver as there is no user of it. - Simplify the error path of imx6_pm_get_base() a bit. * tag 'imx-soc-4.17' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux: ARM: imx: Add basic msl support for imx6sll ARM: imx: pm-imx6: Return the error directly ARM: imx: avic: set low-power interrupt mask for imx25 ARM: imx: Improve the soc revision calculation flow ARM: imx: add timer stop flag to ARM power off state ARM: imx: Remove epit support
-rw-r--r--arch/arm/mach-imx/Kconfig20
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/anatop.c56
-rw-r--r--arch/arm/mach-imx/avic.c37
-rw-r--r--arch/arm/mach-imx/cpu.c3
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sl.c7
-rw-r--r--arch/arm/mach-imx/cpuidle-imx6sx.c1
-rw-r--r--arch/arm/mach-imx/epit.c228
-rw-r--r--arch/arm/mach-imx/mach-imx6sl.c10
-rw-r--r--arch/arm/mach-imx/mxc.h6
-rw-r--r--arch/arm/mach-imx/pm-imx6.c7
11 files changed, 89 insertions, 288 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 782699e67600..f53ec31c9f5a 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -32,18 +32,6 @@ config MXC_DEBUG_BOARD
32 data/address de-multiplexing and decode, signal level shift, 32 data/address de-multiplexing and decode, signal level shift,
33 interrupt control and various board functions. 33 interrupt control and various board functions.
34 34
35config HAVE_EPIT
36 bool
37
38config MXC_USE_EPIT
39 bool "Use EPIT instead of GPT"
40 depends on HAVE_EPIT
41 help
42 Use EPIT as the system timer on systems that have it. Normally you
43 don't have a reason to do so as the EPIT has the same features and
44 uses the same clocks as the GPT. Anyway, on some systems the GPT
45 may be in use for other purposes.
46
47config HAVE_IMX_ANATOP 35config HAVE_IMX_ANATOP
48 bool 36 bool
49 37
@@ -85,7 +73,6 @@ config SOC_IMX31
85config SOC_IMX35 73config SOC_IMX35
86 bool 74 bool
87 select ARCH_MXC_IOMUX_V3 75 select ARCH_MXC_IOMUX_V3
88 select HAVE_EPIT
89 select MXC_AVIC 76 select MXC_AVIC
90 select PINCTRL_IMX35 77 select PINCTRL_IMX35
91 78
@@ -512,6 +499,13 @@ config SOC_IMX6SL
512 help 499 help
513 This enables support for Freescale i.MX6 SoloLite processor. 500 This enables support for Freescale i.MX6 SoloLite processor.
514 501
502config SOC_IMX6SLL
503 bool "i.MX6 SoloLiteLite support"
504 select SOC_IMX6
505
506 help
507 This enables support for Freescale i.MX6 SoloLiteLite processor.
508
515config SOC_IMX6SX 509config SOC_IMX6SX
516 bool "i.MX6 SoloX support" 510 bool "i.MX6 SoloX support"
517 select PINCTRL_IMX6SX 511 select PINCTRL_IMX6SX
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 8ff71058207d..78fa86aedf34 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
20obj-$(CONFIG_MXC_TZIC) += tzic.o 20obj-$(CONFIG_MXC_TZIC) += tzic.o
21obj-$(CONFIG_MXC_AVIC) += avic.o 21obj-$(CONFIG_MXC_AVIC) += avic.o
22 22
23obj-$(CONFIG_MXC_USE_EPIT) += epit.o
24obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o 23obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
25 24
26ifeq ($(CONFIG_CPU_IDLE),y) 25ifeq ($(CONFIG_CPU_IDLE),y)
@@ -78,6 +77,7 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
78endif 77endif
79obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o 78obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o
80obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o 79obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o
80obj-$(CONFIG_SOC_IMX6SLL) += mach-imx6sl.o
81obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o 81obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o
82obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o 82obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o
83obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o 83obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
index 649a84c251ad..61f3d94f1633 100644
--- a/arch/arm/mach-imx/anatop.c
+++ b/arch/arm/mach-imx/anatop.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. 2 * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
3 * Copyright 2017-2018 NXP.
3 * 4 *
4 * The code contained herein is licensed under the GNU General Public 5 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License 6 * License. You may obtain a copy of the GNU General Public License
@@ -116,6 +117,7 @@ void __init imx_init_revision_from_anatop(void)
116 unsigned int revision; 117 unsigned int revision;
117 u32 digprog; 118 u32 digprog;
118 u16 offset = ANADIG_DIGPROG; 119 u16 offset = ANADIG_DIGPROG;
120 u8 major_part, minor_part;
119 121
120 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); 122 np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
121 anatop_base = of_iomap(np, 0); 123 anatop_base = of_iomap(np, 0);
@@ -127,45 +129,25 @@ void __init imx_init_revision_from_anatop(void)
127 digprog = readl_relaxed(anatop_base + offset); 129 digprog = readl_relaxed(anatop_base + offset);
128 iounmap(anatop_base); 130 iounmap(anatop_base);
129 131
130 switch (digprog & 0xff) { 132 /*
131 case 0: 133 * On i.MX7D digprog value match linux version format, so
132 /* 134 * it needn't map again and we can use register value directly.
133 * For i.MX6QP, most of the code for i.MX6Q can be resued, 135 */
134 * so internally, we identify it as i.MX6Q Rev 2.0 136 if (of_device_is_compatible(np, "fsl,imx7d-anatop")) {
135 */ 137 revision = digprog & 0xff;
136 if (digprog >> 8 & 0x01) 138 } else {
137 revision = IMX_CHIP_REVISION_2_0;
138 else
139 revision = IMX_CHIP_REVISION_1_0;
140 break;
141 case 1:
142 revision = IMX_CHIP_REVISION_1_1;
143 break;
144 case 2:
145 revision = IMX_CHIP_REVISION_1_2;
146 break;
147 case 3:
148 revision = IMX_CHIP_REVISION_1_3;
149 break;
150 case 4:
151 revision = IMX_CHIP_REVISION_1_4;
152 break;
153 case 5:
154 /*
155 * i.MX6DQ TO1.5 is defined as Rev 1.3 in Data Sheet, marked
156 * as 'D' in Part Number last character.
157 */
158 revision = IMX_CHIP_REVISION_1_5;
159 break;
160 default:
161 /* 139 /*
162 * Fail back to return raw register value instead of 0xff. 140 * MAJOR: [15:8], the major silicon revison;
163 * It will be easy to know version information in SOC if it 141 * MINOR: [7: 0], the minor silicon revison;
164 * can't be recognized by known version. And some chip's (i.MX7D) 142 *
165 * digprog value match linux version format, so it needn't map 143 * please refer to the i.MX RM for the detailed
166 * again and we can use register value directly. 144 * silicon revison bit define.
145 * format the major part and minor part to match the
146 * linux kernel soc version format.
167 */ 147 */
168 revision = digprog & 0xff; 148 major_part = (digprog >> 8) & 0xf;
149 minor_part = digprog & 0xf;
150 revision = ((major_part + 1) << 4) | minor_part;
169 } 151 }
170 152
171 mxc_set_cpu_type(digprog >> 16 & 0xff); 153 mxc_set_cpu_type(digprog >> 16 & 0xff);
diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c
index 1afccae0420c..c0434a36687a 100644
--- a/arch/arm/mach-imx/avic.c
+++ b/arch/arm/mach-imx/avic.c
@@ -22,6 +22,7 @@
22#include <linux/irqdomain.h> 22#include <linux/irqdomain.h>
23#include <linux/io.h> 23#include <linux/io.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_address.h>
25#include <asm/mach/irq.h> 26#include <asm/mach/irq.h>
26#include <asm/exception.h> 27#include <asm/exception.h>
27 28
@@ -51,7 +52,12 @@
51 52
52#define AVIC_NUM_IRQS 64 53#define AVIC_NUM_IRQS 64
53 54
55/* low power interrupt mask registers */
56#define MX25_CCM_LPIMR0 0x68
57#define MX25_CCM_LPIMR1 0x6C
58
54static void __iomem *avic_base; 59static void __iomem *avic_base;
60static void __iomem *mx25_ccm_base;
55static struct irq_domain *domain; 61static struct irq_domain *domain;
56 62
57#ifdef CONFIG_FIQ 63#ifdef CONFIG_FIQ
@@ -93,6 +99,18 @@ static void avic_irq_suspend(struct irq_data *d)
93 99
94 avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask); 100 avic_saved_mask_reg[idx] = imx_readl(avic_base + ct->regs.mask);
95 imx_writel(gc->wake_active, avic_base + ct->regs.mask); 101 imx_writel(gc->wake_active, avic_base + ct->regs.mask);
102
103 if (mx25_ccm_base) {
104 u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ?
105 MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1;
106 /*
107 * The interrupts which are still enabled will be used as wakeup
108 * sources. Allow those interrupts in low-power mode.
109 * The LPIMR registers use 0 to allow an interrupt, the AVIC
110 * registers use 1.
111 */
112 imx_writel(~gc->wake_active, mx25_ccm_base + offs);
113 }
96} 114}
97 115
98static void avic_irq_resume(struct irq_data *d) 116static void avic_irq_resume(struct irq_data *d)
@@ -102,6 +120,13 @@ static void avic_irq_resume(struct irq_data *d)
102 int idx = d->hwirq >> 5; 120 int idx = d->hwirq >> 5;
103 121
104 imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask); 122 imx_writel(avic_saved_mask_reg[idx], avic_base + ct->regs.mask);
123
124 if (mx25_ccm_base) {
125 u8 offs = d->hwirq < AVIC_NUM_IRQS / 2 ?
126 MX25_CCM_LPIMR0 : MX25_CCM_LPIMR1;
127
128 imx_writel(0xffffffff, mx25_ccm_base + offs);
129 }
105} 130}
106 131
107#else 132#else
@@ -158,6 +183,18 @@ void __init mxc_init_irq(void __iomem *irqbase)
158 183
159 avic_base = irqbase; 184 avic_base = irqbase;
160 185
186 np = of_find_compatible_node(NULL, NULL, "fsl,imx25-ccm");
187 mx25_ccm_base = of_iomap(np, 0);
188
189 if (mx25_ccm_base) {
190 /*
191 * By default, we mask all interrupts. We set the actual mask
192 * before we go into low-power mode.
193 */
194 imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR0);
195 imx_writel(0xffffffff, mx25_ccm_base + MX25_CCM_LPIMR1);
196 }
197
161 /* put the AVIC into the reset value with 198 /* put the AVIC into the reset value with
162 * all interrupts disabled 199 * all interrupts disabled
163 */ 200 */
diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c
index d4e55f2a897e..32969f34486a 100644
--- a/arch/arm/mach-imx/cpu.c
+++ b/arch/arm/mach-imx/cpu.c
@@ -135,6 +135,9 @@ struct device * __init imx_soc_device_init(void)
135 case MXC_CPU_IMX6ULL: 135 case MXC_CPU_IMX6ULL:
136 soc_id = "i.MX6ULL"; 136 soc_id = "i.MX6ULL";
137 break; 137 break;
138 case MXC_CPU_IMX6SLL:
139 soc_id = "i.MX6SLL";
140 break;
138 case MXC_CPU_IMX7D: 141 case MXC_CPU_IMX7D:
139 soc_id = "i.MX7D"; 142 soc_id = "i.MX7D";
140 break; 143 break;
diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c
index 8d866fb674a8..fa8ead145d17 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sl.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sl.c
@@ -12,6 +12,7 @@
12 12
13#include "common.h" 13#include "common.h"
14#include "cpuidle.h" 14#include "cpuidle.h"
15#include "hardware.h"
15 16
16static int imx6sl_enter_wait(struct cpuidle_device *dev, 17static int imx6sl_enter_wait(struct cpuidle_device *dev,
17 struct cpuidle_driver *drv, int index) 18 struct cpuidle_driver *drv, int index)
@@ -21,9 +22,11 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev,
21 * Software workaround for ERR005311, see function 22 * Software workaround for ERR005311, see function
22 * description for details. 23 * description for details.
23 */ 24 */
24 imx6sl_set_wait_clk(true); 25 if (cpu_is_imx6sl())
26 imx6sl_set_wait_clk(true);
25 cpu_do_idle(); 27 cpu_do_idle();
26 imx6sl_set_wait_clk(false); 28 if (cpu_is_imx6sl())
29 imx6sl_set_wait_clk(false);
27 imx6_set_lpm(WAIT_CLOCKED); 30 imx6_set_lpm(WAIT_CLOCKED);
28 31
29 return index; 32 return index;
diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c
index c5a5c3a70ab1..d0f14b761ff7 100644
--- a/arch/arm/mach-imx/cpuidle-imx6sx.c
+++ b/arch/arm/mach-imx/cpuidle-imx6sx.c
@@ -89,6 +89,7 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = {
89 */ 89 */
90 .exit_latency = 300, 90 .exit_latency = 300,
91 .target_residency = 500, 91 .target_residency = 500,
92 .flags = CPUIDLE_FLAG_TIMER_STOP,
92 .enter = imx6sx_enter_wait, 93 .enter = imx6sx_enter_wait,
93 .name = "LOW-POWER-IDLE", 94 .name = "LOW-POWER-IDLE",
94 .desc = "ARM power off", 95 .desc = "ARM power off",
diff --git a/arch/arm/mach-imx/epit.c b/arch/arm/mach-imx/epit.c
deleted file mode 100644
index fb9a73a57d00..000000000000
--- a/arch/arm/mach-imx/epit.c
+++ /dev/null
@@ -1,228 +0,0 @@
1/*
2 * linux/arch/arm/plat-mxc/epit.c
3 *
4 * Copyright (C) 2010 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21#define EPITCR 0x00
22#define EPITSR 0x04
23#define EPITLR 0x08
24#define EPITCMPR 0x0c
25#define EPITCNR 0x10
26
27#define EPITCR_EN (1 << 0)
28#define EPITCR_ENMOD (1 << 1)
29#define EPITCR_OCIEN (1 << 2)
30#define EPITCR_RLD (1 << 3)
31#define EPITCR_PRESC(x) (((x) & 0xfff) << 4)
32#define EPITCR_SWR (1 << 16)
33#define EPITCR_IOVW (1 << 17)
34#define EPITCR_DBGEN (1 << 18)
35#define EPITCR_WAITEN (1 << 19)
36#define EPITCR_RES (1 << 20)
37#define EPITCR_STOPEN (1 << 21)
38#define EPITCR_OM_DISCON (0 << 22)
39#define EPITCR_OM_TOGGLE (1 << 22)
40#define EPITCR_OM_CLEAR (2 << 22)
41#define EPITCR_OM_SET (3 << 22)
42#define EPITCR_CLKSRC_OFF (0 << 24)
43#define EPITCR_CLKSRC_PERIPHERAL (1 << 24)
44#define EPITCR_CLKSRC_REF_HIGH (1 << 24)
45#define EPITCR_CLKSRC_REF_LOW (3 << 24)
46
47#define EPITSR_OCIF (1 << 0)
48
49#include <linux/interrupt.h>
50#include <linux/irq.h>
51#include <linux/clockchips.h>
52#include <linux/clk.h>
53#include <linux/err.h>
54#include <asm/mach/time.h>
55
56#include "common.h"
57#include "hardware.h"
58
59static struct clock_event_device clockevent_epit;
60
61static void __iomem *timer_base;
62
63static inline void epit_irq_disable(void)
64{
65 u32 val;
66
67 val = imx_readl(timer_base + EPITCR);
68 val &= ~EPITCR_OCIEN;
69 imx_writel(val, timer_base + EPITCR);
70}
71
72static inline void epit_irq_enable(void)
73{
74 u32 val;
75
76 val = imx_readl(timer_base + EPITCR);
77 val |= EPITCR_OCIEN;
78 imx_writel(val, timer_base + EPITCR);
79}
80
81static void epit_irq_acknowledge(void)
82{
83 imx_writel(EPITSR_OCIF, timer_base + EPITSR);
84}
85
86static int __init epit_clocksource_init(struct clk *timer_clk)
87{
88 unsigned int c = clk_get_rate(timer_clk);
89
90 return clocksource_mmio_init(timer_base + EPITCNR, "epit", c, 200, 32,
91 clocksource_mmio_readl_down);
92}
93
94/* clock event */
95
96static int epit_set_next_event(unsigned long evt,
97 struct clock_event_device *unused)
98{
99 unsigned long tcmp;
100
101 tcmp = imx_readl(timer_base + EPITCNR);
102
103 imx_writel(tcmp - evt, timer_base + EPITCMPR);
104
105 return 0;
106}
107
108/* Left event sources disabled, no more interrupts appear */
109static int epit_shutdown(struct clock_event_device *evt)
110{
111 unsigned long flags;
112
113 /*
114 * The timer interrupt generation is disabled at least
115 * for enough time to call epit_set_next_event()
116 */
117 local_irq_save(flags);
118
119 /* Disable interrupt in GPT module */
120 epit_irq_disable();
121
122 /* Clear pending interrupt */
123 epit_irq_acknowledge();
124
125 local_irq_restore(flags);
126
127 return 0;
128}
129
130static int epit_set_oneshot(struct clock_event_device *evt)
131{
132 unsigned long flags;
133
134 /*
135 * The timer interrupt generation is disabled at least
136 * for enough time to call epit_set_next_event()
137 */
138 local_irq_save(flags);
139
140 /* Disable interrupt in GPT module */
141 epit_irq_disable();
142
143 /* Clear pending interrupt, only while switching mode */
144 if (!clockevent_state_oneshot(evt))
145 epit_irq_acknowledge();
146
147 /*
148 * Do not put overhead of interrupt enable/disable into
149 * epit_set_next_event(), the core has about 4 minutes
150 * to call epit_set_next_event() or shutdown clock after
151 * mode switching
152 */
153 epit_irq_enable();
154 local_irq_restore(flags);
155
156 return 0;
157}
158
159/*
160 * IRQ handler for the timer
161 */
162static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
163{
164 struct clock_event_device *evt = &clockevent_epit;
165
166 epit_irq_acknowledge();
167
168 evt->event_handler(evt);
169
170 return IRQ_HANDLED;
171}
172
173static struct irqaction epit_timer_irq = {
174 .name = "i.MX EPIT Timer Tick",
175 .flags = IRQF_TIMER | IRQF_IRQPOLL,
176 .handler = epit_timer_interrupt,
177};
178
179static struct clock_event_device clockevent_epit = {
180 .name = "epit",
181 .features = CLOCK_EVT_FEAT_ONESHOT,
182 .set_state_shutdown = epit_shutdown,
183 .tick_resume = epit_shutdown,
184 .set_state_oneshot = epit_set_oneshot,
185 .set_next_event = epit_set_next_event,
186 .rating = 200,
187};
188
189static int __init epit_clockevent_init(struct clk *timer_clk)
190{
191 clockevent_epit.cpumask = cpumask_of(0);
192 clockevents_config_and_register(&clockevent_epit,
193 clk_get_rate(timer_clk),
194 0x800, 0xfffffffe);
195
196 return 0;
197}
198
199void __init epit_timer_init(void __iomem *base, int irq)
200{
201 struct clk *timer_clk;
202
203 timer_clk = clk_get_sys("imx-epit.0", NULL);
204 if (IS_ERR(timer_clk)) {
205 pr_err("i.MX epit: unable to get clk\n");
206 return;
207 }
208
209 clk_prepare_enable(timer_clk);
210
211 timer_base = base;
212
213 /*
214 * Initialise to a known state (all timers off, and timing reset)
215 */
216 imx_writel(0x0, timer_base + EPITCR);
217
218 imx_writel(0xffffffff, timer_base + EPITLR);
219 imx_writel(EPITCR_EN | EPITCR_CLKSRC_REF_HIGH | EPITCR_WAITEN,
220 timer_base + EPITCR);
221
222 /* init and register the timer to the framework */
223 epit_clocksource_init(timer_clk);
224 epit_clockevent_init(timer_clk);
225
226 /* Make irqs happen */
227 setup_irq(irq, &epit_timer_irq);
228}
diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c
index 04084900d810..c7a1ef180dda 100644
--- a/arch/arm/mach-imx/mach-imx6sl.c
+++ b/arch/arm/mach-imx/mach-imx6sl.c
@@ -18,6 +18,7 @@
18 18
19#include "common.h" 19#include "common.h"
20#include "cpuidle.h" 20#include "cpuidle.h"
21#include "hardware.h"
21 22
22static void __init imx6sl_fec_init(void) 23static void __init imx6sl_fec_init(void)
23{ 24{
@@ -54,7 +55,8 @@ static void __init imx6sl_init_machine(void)
54 55
55 of_platform_default_populate(NULL, NULL, parent); 56 of_platform_default_populate(NULL, NULL, parent);
56 57
57 imx6sl_fec_init(); 58 if (cpu_is_imx6sl())
59 imx6sl_fec_init();
58 imx_anatop_init(); 60 imx_anatop_init();
59 imx6sl_pm_init(); 61 imx6sl_pm_init();
60} 62}
@@ -66,11 +68,15 @@ static void __init imx6sl_init_irq(void)
66 imx_init_l2cache(); 68 imx_init_l2cache();
67 imx_src_init(); 69 imx_src_init();
68 irqchip_init(); 70 irqchip_init();
69 imx6_pm_ccm_init("fsl,imx6sl-ccm"); 71 if (cpu_is_imx6sl())
72 imx6_pm_ccm_init("fsl,imx6sl-ccm");
73 else
74 imx6_pm_ccm_init("fsl,imx6sll-ccm");
70} 75}
71 76
72static const char * const imx6sl_dt_compat[] __initconst = { 77static const char * const imx6sl_dt_compat[] __initconst = {
73 "fsl,imx6sl", 78 "fsl,imx6sl",
79 "fsl,imx6sll",
74 NULL, 80 NULL,
75}; 81};
76 82
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h
index e00d6260c3df..026e2ca45f1e 100644
--- a/arch/arm/mach-imx/mxc.h
+++ b/arch/arm/mach-imx/mxc.h
@@ -40,6 +40,7 @@
40#define MXC_CPU_IMX6Q 0x63 40#define MXC_CPU_IMX6Q 0x63
41#define MXC_CPU_IMX6UL 0x64 41#define MXC_CPU_IMX6UL 0x64
42#define MXC_CPU_IMX6ULL 0x65 42#define MXC_CPU_IMX6ULL 0x65
43#define MXC_CPU_IMX6SLL 0x67
43#define MXC_CPU_IMX7D 0x72 44#define MXC_CPU_IMX7D 0x72
44 45
45#define IMX_DDR_TYPE_LPDDR2 1 46#define IMX_DDR_TYPE_LPDDR2 1
@@ -79,6 +80,11 @@ static inline bool cpu_is_imx6ull(void)
79 return __mxc_cpu_type == MXC_CPU_IMX6ULL; 80 return __mxc_cpu_type == MXC_CPU_IMX6ULL;
80} 81}
81 82
83static inline bool cpu_is_imx6sll(void)
84{
85 return __mxc_cpu_type == MXC_CPU_IMX6SLL;
86}
87
82static inline bool cpu_is_imx6q(void) 88static inline bool cpu_is_imx6q(void)
83{ 89{
84 return __mxc_cpu_type == MXC_CPU_IMX6Q; 90 return __mxc_cpu_type == MXC_CPU_IMX6Q;
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index ecdf071653d4..017539dd712b 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -428,10 +428,8 @@ static int __init imx6_pm_get_base(struct imx6_pm_base *base,
428 int ret = 0; 428 int ret = 0;
429 429
430 node = of_find_compatible_node(NULL, NULL, compat); 430 node = of_find_compatible_node(NULL, NULL, compat);
431 if (!node) { 431 if (!node)
432 ret = -ENODEV; 432 return -ENODEV;
433 goto out;
434 }
435 433
436 ret = of_address_to_resource(node, 0, &res); 434 ret = of_address_to_resource(node, 0, &res);
437 if (ret) 435 if (ret)
@@ -444,7 +442,6 @@ static int __init imx6_pm_get_base(struct imx6_pm_base *base,
444 442
445put_node: 443put_node:
446 of_node_put(node); 444 of_node_put(node);
447out:
448 return ret; 445 return ret;
449} 446}
450 447