blob: 28db97289ee8ffec84d83f0b1d024bcd9edd1c7e [file] [log] [blame]
Thomas Gleixnerc942fdd2019-05-27 08:55:06 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +01002/*
3 * Copyright (C) 1999,2000 Arm Limited
4 * Copyright (C) 2000 Deep Blue Solutions Ltd
5 * Copyright (C) 2002 Shane Nay (shane@minirl.com)
6 * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
7 * - add MX31 specific definitions
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +01008 */
9
10#include <linux/mm.h>
11#include <linux/init.h>
12#include <linux/err.h>
Arnd Bergmannc112d2a2016-06-24 12:49:58 +020013#include <linux/io.h>
Fabio Estevam2cf98d12020-09-16 21:41:18 -030014#include <linux/of_address.h>
Dong Aishenga2aa65a2012-05-02 19:31:20 +080015#include <linux/pinctrl/machine.h>
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +010016
Olof Johansson86dfe442012-03-29 23:22:44 -070017#include <asm/system_misc.h>
Shawn Guoddd5f512011-09-28 17:16:05 +080018#include <asm/hardware/cache-l2x0.h>
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +010019#include <asm/mach/map.h>
20
Shawn Guoe3372472012-09-13 21:01:00 +080021#include "common.h"
Sascha Hauereb920442012-04-03 12:42:27 +020022#include "crmregs-imx3.h"
Shawn Guo50f2de62012-09-14 14:14:45 +080023#include "hardware.h"
Sascha Hauereb920442012-04-03 12:42:27 +020024
25void __iomem *mx3_ccm_base;
26
Shawn Guo41e7daf2011-09-28 17:16:06 +080027static void imx3_idle(void)
28{
29 unsigned long reg = 0;
Shawn Guo8c6d8312011-11-11 13:09:18 +080030
Nicolas Pitre4a3ea242011-08-03 11:34:59 -040031 __asm__ __volatile__(
32 /* disable I and D cache */
33 "mrc p15, 0, %0, c1, c0, 0\n"
34 "bic %0, %0, #0x00001000\n"
35 "bic %0, %0, #0x00000004\n"
36 "mcr p15, 0, %0, c1, c0, 0\n"
37 /* invalidate I cache */
38 "mov %0, #0\n"
39 "mcr p15, 0, %0, c7, c5, 0\n"
40 /* clear and invalidate D cache */
41 "mov %0, #0\n"
42 "mcr p15, 0, %0, c7, c14, 0\n"
43 /* WFI */
44 "mov %0, #0\n"
45 "mcr p15, 0, %0, c7, c0, 4\n"
46 "nop\n" "nop\n" "nop\n" "nop\n"
47 "nop\n" "nop\n" "nop\n"
48 /* enable I and D cache */
49 "mrc p15, 0, %0, c1, c0, 0\n"
50 "orr %0, %0, #0x00001000\n"
51 "orr %0, %0, #0x00000004\n"
52 "mcr p15, 0, %0, c1, c0, 0\n"
53 : "=r" (reg));
Shawn Guo41e7daf2011-09-28 17:16:06 +080054}
55
Laura Abbott9b971732013-05-16 19:40:22 +010056static void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size,
Rob Herringc177aa92012-02-13 13:24:15 -060057 unsigned int mtype, void *caller)
Shawn Guof5488972011-09-28 17:16:07 +080058{
59 if (mtype == MT_DEVICE) {
60 /*
61 * Access all peripherals below 0x80000000 as nonshared device
62 * on mx3, but leave l2cc alone. Otherwise cache corruptions
63 * can occur.
64 */
65 if (phys_addr < 0x80000000 &&
66 !addr_in_module(phys_addr, MX3x_L2CC))
67 mtype = MT_DEVICE_NONSHARED;
68 }
69
Rob Herringc177aa92012-02-13 13:24:15 -060070 return __arm_ioremap_caller(phys_addr, size, mtype, caller);
Shawn Guof5488972011-09-28 17:16:07 +080071}
72
Uwe Kleine-König87514fc2011-11-22 10:07:26 +010073#ifdef CONFIG_SOC_IMX31
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +010074static struct map_desc mx31_io_desc[] __initdata = {
75 imx_map_entry(MX31, X_MEMC, MT_DEVICE),
76 imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
77 imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED),
78 imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED),
79 imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED),
80};
81
82/*
83 * This function initializes the memory map. It is called during the
84 * system startup to create static physical to virtual memory mappings
85 * for the IO modules.
86 */
87void __init mx31_map_io(void)
88{
89 iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
90}
91
Arnd Bergmannc112d2a2016-06-24 12:49:58 +020092static void imx31_idle(void)
93{
94 int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR);
95 reg &= ~MXC_CCM_CCMR_LPM_MASK;
96 imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
97
98 imx3_idle();
99}
100
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +0100101void __init imx31_init_early(void)
102{
Fabio Estevam2cf98d12020-09-16 21:41:18 -0300103 struct device_node *np;
104
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +0100105 mxc_set_cpu_type(MXC_CPU_MX31);
Rob Herringc177aa92012-02-13 13:24:15 -0600106 arch_ioremap_caller = imx3_ioremap_caller;
Arnd Bergmannc112d2a2016-06-24 12:49:58 +0200107 arm_pm_idle = imx31_idle;
Fabio Estevam2cf98d12020-09-16 21:41:18 -0300108 np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
109 mx3_ccm_base = of_iomap(np, 0);
110 BUG_ON(!mx3_ccm_base);
Uwe Kleine-König27ad4bf2011-03-17 09:40:29 +0100111}
Uwe Kleine-König87514fc2011-11-22 10:07:26 +0100112#endif /* ifdef CONFIG_SOC_IMX31 */
113
114#ifdef CONFIG_SOC_IMX35
115static struct map_desc mx35_io_desc[] __initdata = {
116 imx_map_entry(MX35, X_MEMC, MT_DEVICE),
117 imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
118 imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
119 imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
120 imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
121};
122
123void __init mx35_map_io(void)
124{
125 iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
126}
127
Arnd Bergmannc112d2a2016-06-24 12:49:58 +0200128static void imx35_idle(void)
129{
130 int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR);
131 reg &= ~MXC_CCM_CCMR_LPM_MASK;
132 reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
133 imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
134
135 imx3_idle();
136}
137
Uwe Kleine-König87514fc2011-11-22 10:07:26 +0100138void __init imx35_init_early(void)
139{
Fabio Estevam2cf98d12020-09-16 21:41:18 -0300140 struct device_node *np;
141
Uwe Kleine-König87514fc2011-11-22 10:07:26 +0100142 mxc_set_cpu_type(MXC_CPU_MX35);
Arnd Bergmannc112d2a2016-06-24 12:49:58 +0200143 arm_pm_idle = imx35_idle;
Rob Herringc177aa92012-02-13 13:24:15 -0600144 arch_ioremap_caller = imx3_ioremap_caller;
Fabio Estevam2cf98d12020-09-16 21:41:18 -0300145 np = of_find_compatible_node(NULL, NULL, "fsl,imx35-ccm");
146 mx3_ccm_base = of_iomap(np, 0);
147 BUG_ON(!mx3_ccm_base);
Uwe Kleine-König87514fc2011-11-22 10:07:26 +0100148}
Uwe Kleine-König87514fc2011-11-22 10:07:26 +0100149#endif /* ifdef CONFIG_SOC_IMX35 */