linux/arch/arm/mach-imx/mm-imx3.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   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
   8 */
   9
  10#include <linux/mm.h>
  11#include <linux/init.h>
  12#include <linux/err.h>
  13#include <linux/io.h>
  14#include <linux/of_address.h>
  15#include <linux/pinctrl/machine.h>
  16
  17#include <asm/system_misc.h>
  18#include <asm/hardware/cache-l2x0.h>
  19#include <asm/mach/map.h>
  20
  21#include "common.h"
  22#include "crmregs-imx3.h"
  23#include "hardware.h"
  24
  25void __iomem *mx3_ccm_base;
  26
  27static void imx3_idle(void)
  28{
  29        unsigned long reg = 0;
  30
  31        __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));
  54}
  55
  56static void __iomem *imx3_ioremap_caller(phys_addr_t phys_addr, size_t size,
  57                                         unsigned int mtype, void *caller)
  58{
  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
  70        return __arm_ioremap_caller(phys_addr, size, mtype, caller);
  71}
  72
  73#ifdef CONFIG_SOC_IMX31
  74static 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
  92static 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
 101void __init imx31_init_early(void)
 102{
 103        struct device_node *np;
 104
 105        mxc_set_cpu_type(MXC_CPU_MX31);
 106        arch_ioremap_caller = imx3_ioremap_caller;
 107        arm_pm_idle = imx31_idle;
 108        np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm");
 109        mx3_ccm_base = of_iomap(np, 0);
 110        BUG_ON(!mx3_ccm_base);
 111}
 112#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
 128static 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
 138void __init imx35_init_early(void)
 139{
 140        struct device_node *np;
 141
 142        mxc_set_cpu_type(MXC_CPU_MX35);
 143        arm_pm_idle = imx35_idle;
 144        arch_ioremap_caller = imx3_ioremap_caller;
 145        np = of_find_compatible_node(NULL, NULL, "fsl,imx35-ccm");
 146        mx3_ccm_base = of_iomap(np, 0);
 147        BUG_ON(!mx3_ccm_base);
 148}
 149#endif /* ifdef CONFIG_SOC_IMX35 */
 150