18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 1999,2000 Arm Limited 48c2ecf20Sopenharmony_ci * Copyright (C) 2000 Deep Blue Solutions Ltd 58c2ecf20Sopenharmony_ci * Copyright (C) 2002 Shane Nay (shane@minirl.com) 68c2ecf20Sopenharmony_ci * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. 78c2ecf20Sopenharmony_ci * - add MX31 specific definitions 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/mm.h> 118c2ecf20Sopenharmony_ci#include <linux/init.h> 128c2ecf20Sopenharmony_ci#include <linux/err.h> 138c2ecf20Sopenharmony_ci#include <linux/io.h> 148c2ecf20Sopenharmony_ci#include <linux/of_address.h> 158c2ecf20Sopenharmony_ci#include <linux/pinctrl/machine.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <asm/system_misc.h> 188c2ecf20Sopenharmony_ci#include <asm/hardware/cache-l2x0.h> 198c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include "common.h" 228c2ecf20Sopenharmony_ci#include "crmregs-imx3.h" 238c2ecf20Sopenharmony_ci#include "hardware.h" 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_civoid __iomem *mx3_ccm_base; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic void imx3_idle(void) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci unsigned long reg = 0; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci __asm__ __volatile__( 328c2ecf20Sopenharmony_ci /* disable I and D cache */ 338c2ecf20Sopenharmony_ci "mrc p15, 0, %0, c1, c0, 0\n" 348c2ecf20Sopenharmony_ci "bic %0, %0, #0x00001000\n" 358c2ecf20Sopenharmony_ci "bic %0, %0, #0x00000004\n" 368c2ecf20Sopenharmony_ci "mcr p15, 0, %0, c1, c0, 0\n" 378c2ecf20Sopenharmony_ci /* invalidate I cache */ 388c2ecf20Sopenharmony_ci "mov %0, #0\n" 398c2ecf20Sopenharmony_ci "mcr p15, 0, %0, c7, c5, 0\n" 408c2ecf20Sopenharmony_ci /* clear and invalidate D cache */ 418c2ecf20Sopenharmony_ci "mov %0, #0\n" 428c2ecf20Sopenharmony_ci "mcr p15, 0, %0, c7, c14, 0\n" 438c2ecf20Sopenharmony_ci /* WFI */ 448c2ecf20Sopenharmony_ci "mov %0, #0\n" 458c2ecf20Sopenharmony_ci "mcr p15, 0, %0, c7, c0, 4\n" 468c2ecf20Sopenharmony_ci "nop\n" "nop\n" "nop\n" "nop\n" 478c2ecf20Sopenharmony_ci "nop\n" "nop\n" "nop\n" 488c2ecf20Sopenharmony_ci /* enable I and D cache */ 498c2ecf20Sopenharmony_ci "mrc p15, 0, %0, c1, c0, 0\n" 508c2ecf20Sopenharmony_ci "orr %0, %0, #0x00001000\n" 518c2ecf20Sopenharmony_ci "orr %0, %0, #0x00000004\n" 528c2ecf20Sopenharmony_ci "mcr p15, 0, %0, c1, c0, 0\n" 538c2ecf20Sopenharmony_ci : "=r" (reg)); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size, 578c2ecf20Sopenharmony_ci unsigned int mtype, void *caller) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci if (mtype == MT_DEVICE) { 608c2ecf20Sopenharmony_ci /* 618c2ecf20Sopenharmony_ci * Access all peripherals below 0x80000000 as nonshared device 628c2ecf20Sopenharmony_ci * on mx3, but leave l2cc alone. Otherwise cache corruptions 638c2ecf20Sopenharmony_ci * can occur. 648c2ecf20Sopenharmony_ci */ 658c2ecf20Sopenharmony_ci if (phys_addr < 0x80000000 && 668c2ecf20Sopenharmony_ci !addr_in_module(phys_addr, MX3x_L2CC)) 678c2ecf20Sopenharmony_ci mtype = MT_DEVICE_NONSHARED; 688c2ecf20Sopenharmony_ci } 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci return __arm_ioremap_caller(phys_addr, size, mtype, caller); 718c2ecf20Sopenharmony_ci} 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_IMX31 748c2ecf20Sopenharmony_cistatic struct map_desc mx31_io_desc[] __initdata = { 758c2ecf20Sopenharmony_ci imx_map_entry(MX31, X_MEMC, MT_DEVICE), 768c2ecf20Sopenharmony_ci imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED), 778c2ecf20Sopenharmony_ci imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED), 788c2ecf20Sopenharmony_ci imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED), 798c2ecf20Sopenharmony_ci imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED), 808c2ecf20Sopenharmony_ci}; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* 838c2ecf20Sopenharmony_ci * This function initializes the memory map. It is called during the 848c2ecf20Sopenharmony_ci * system startup to create static physical to virtual memory mappings 858c2ecf20Sopenharmony_ci * for the IO modules. 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_civoid __init mx31_map_io(void) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc)); 908c2ecf20Sopenharmony_ci} 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistatic void imx31_idle(void) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR); 958c2ecf20Sopenharmony_ci reg &= ~MXC_CCM_CCMR_LPM_MASK; 968c2ecf20Sopenharmony_ci imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci imx3_idle(); 998c2ecf20Sopenharmony_ci} 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_civoid __init imx31_init_early(void) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci struct device_node *np; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci mxc_set_cpu_type(MXC_CPU_MX31); 1068c2ecf20Sopenharmony_ci arch_ioremap_caller = imx3_ioremap_caller; 1078c2ecf20Sopenharmony_ci arm_pm_idle = imx31_idle; 1088c2ecf20Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); 1098c2ecf20Sopenharmony_ci mx3_ccm_base = of_iomap(np, 0); 1108c2ecf20Sopenharmony_ci BUG_ON(!mx3_ccm_base); 1118c2ecf20Sopenharmony_ci} 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_civoid __init mx31_init_irq(void) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci void __iomem *avic_base; 1168c2ecf20Sopenharmony_ci struct device_node *np; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, "fsl,imx31-avic"); 1198c2ecf20Sopenharmony_ci avic_base = of_iomap(np, 0); 1208c2ecf20Sopenharmony_ci BUG_ON(!avic_base); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci mxc_init_irq(avic_base); 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci#endif /* ifdef CONFIG_SOC_IMX31 */ 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci#ifdef CONFIG_SOC_IMX35 1278c2ecf20Sopenharmony_cistatic struct map_desc mx35_io_desc[] __initdata = { 1288c2ecf20Sopenharmony_ci imx_map_entry(MX35, X_MEMC, MT_DEVICE), 1298c2ecf20Sopenharmony_ci imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED), 1308c2ecf20Sopenharmony_ci imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED), 1318c2ecf20Sopenharmony_ci imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED), 1328c2ecf20Sopenharmony_ci imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED), 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_civoid __init mx35_map_io(void) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc)); 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic void imx35_idle(void) 1418c2ecf20Sopenharmony_ci{ 1428c2ecf20Sopenharmony_ci int reg = imx_readl(mx3_ccm_base + MXC_CCM_CCMR); 1438c2ecf20Sopenharmony_ci reg &= ~MXC_CCM_CCMR_LPM_MASK; 1448c2ecf20Sopenharmony_ci reg |= MXC_CCM_CCMR_LPM_WAIT_MX35; 1458c2ecf20Sopenharmony_ci imx_writel(reg, mx3_ccm_base + MXC_CCM_CCMR); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci imx3_idle(); 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_civoid __init imx35_init_early(void) 1518c2ecf20Sopenharmony_ci{ 1528c2ecf20Sopenharmony_ci struct device_node *np; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci mxc_set_cpu_type(MXC_CPU_MX35); 1558c2ecf20Sopenharmony_ci arm_pm_idle = imx35_idle; 1568c2ecf20Sopenharmony_ci arch_ioremap_caller = imx3_ioremap_caller; 1578c2ecf20Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, "fsl,imx35-ccm"); 1588c2ecf20Sopenharmony_ci mx3_ccm_base = of_iomap(np, 0); 1598c2ecf20Sopenharmony_ci BUG_ON(!mx3_ccm_base); 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_civoid __init mx35_init_irq(void) 1638c2ecf20Sopenharmony_ci{ 1648c2ecf20Sopenharmony_ci void __iomem *avic_base; 1658c2ecf20Sopenharmony_ci struct device_node *np; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci np = of_find_compatible_node(NULL, NULL, "fsl,imx35-avic"); 1688c2ecf20Sopenharmony_ci avic_base = of_iomap(np, 0); 1698c2ecf20Sopenharmony_ci BUG_ON(!avic_base); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci mxc_init_irq(avic_base); 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci#endif /* ifdef CONFIG_SOC_IMX35 */ 174