^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 1999,2000 Arm Limited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2000 Deep Blue Solutions Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2002 Shane Nay (shane@minirl.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * - add MX31 specific definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pinctrl/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/system_misc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/hardware/cache-l2x0.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/mach/map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "crmregs-imx3.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "hardware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) void __iomem *mx3_ccm_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static void imx3_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned long reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) __asm__ __volatile__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* disable I and D cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) "mrc p15, 0, %0, c1, c0, 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) "bic %0, %0, #0x00001000\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) "bic %0, %0, #0x00000004\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) "mcr p15, 0, %0, c1, c0, 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* invalidate I cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) "mov %0, #0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) "mcr p15, 0, %0, c7, c5, 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /* clear and invalidate D cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) "mov %0, #0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) "mcr p15, 0, %0, c7, c14, 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* WFI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) "mov %0, #0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) "mcr p15, 0, %0, c7, c0, 4\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) "nop\n" "nop\n" "nop\n" "nop\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) "nop\n" "nop\n" "nop\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* enable I and D cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) "mrc p15, 0, %0, c1, c0, 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) "orr %0, %0, #0x00001000\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) "orr %0, %0, #0x00000004\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) "mcr p15, 0, %0, c1, c0, 0\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) : "=r" (reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned int mtype, void *caller)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (mtype == MT_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Access all peripherals below 0x80000000 as nonshared device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * on mx3, but leave l2cc alone. Otherwise cache corruptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * can occur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if (phys_addr < 0x80000000 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) !addr_in_module(phys_addr, MX3x_L2CC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) mtype = MT_DEVICE_NONSHARED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return __arm_ioremap_caller(phys_addr, size, mtype, caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #ifdef CONFIG_SOC_IMX31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static struct map_desc mx31_io_desc[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) imx_map_entry(MX31, X_MEMC, MT_DEVICE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * This function initializes the memory map. It is called during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * system startup to create static physical to virtual memory mappings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * for the IO modules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) void __init mx31_map_io(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static void imx31_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) reg &= ~MXC_CCM_CCMR_LPM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) imx3_idle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void __init imx31_init_early(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) mxc_set_cpu_type(MXC_CPU_MX31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) arch_ioremap_caller = imx3_ioremap_caller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) arm_pm_idle = imx31_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) mx3_ccm_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) BUG_ON(!mx3_ccm_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) void __init mx31_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) void __iomem *avic_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) np = of_find_compatible_node(NULL, NULL, "fsl,imx31-avic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) avic_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) BUG_ON(!avic_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mxc_init_irq(avic_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #endif /* ifdef CONFIG_SOC_IMX31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #ifdef CONFIG_SOC_IMX35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static struct map_desc mx35_io_desc[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) imx_map_entry(MX35, X_MEMC, MT_DEVICE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) void __init mx35_map_io(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static void imx35_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) reg &= ~MXC_CCM_CCMR_LPM_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) reg |= MXC_CCM_CCMR_LPM_WAIT_MX35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) imx3_idle();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) void __init imx35_init_early(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) mxc_set_cpu_type(MXC_CPU_MX35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) arm_pm_idle = imx35_idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) arch_ioremap_caller = imx3_ioremap_caller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) np = of_find_compatible_node(NULL, NULL, "fsl,imx35-ccm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) mx3_ccm_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) BUG_ON(!mx3_ccm_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) void __init mx35_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) void __iomem *avic_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) np = of_find_compatible_node(NULL, NULL, "fsl,imx35-avic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) avic_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) BUG_ON(!avic_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) mxc_init_irq(avic_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #endif /* ifdef CONFIG_SOC_IMX35 */