/*++
linux/arch/arm/mach-wmt/generic.c
wmt generic architecture level codes
Copyright (c) 2013 WonderMedia Technologies, Inc.
This program is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software Foundation,
either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see .
WonderMedia Technologies, Inc.
10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
--*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "generic.h"
#include
#ifdef CONFIG_WMT_NEWSPI_SUPPORT
#include
#endif
#ifdef CONFIG_WMT_NEWSPI1_SUPPORT
#include
#endif
#include
#include
extern void enable_user_access(void);
/* TODO*/
#define PMHC_HIBERNATE 0x205
extern void __init wmt_gpio_init(void);
extern void wmt_power_up_debounce_value(void);
extern void wmt_restart(char mode, const char *cmd);
extern void (*arm_pm_restart)(char str, const char *cmd);
static void wmt_power_off(void)
{
#ifdef CONFIG_PM
/*set power button debounce value*/
wmt_power_up_debounce_value();
#endif
mdelay(100);
local_irq_disable();
*(volatile unsigned int *)0xfe018008 |= 0x03030303; //scu output pm
#ifndef CONFIG_SMP
PMCEU_VAL |= 0x00800000;//sf boot, enable sf for single core pm
mdelay(1);
#endif
/*
* Set scratchpad to zero, just in case it is used as a restart
* address by the bootloader. Since PB_RESUME button has been
* set to be one of the wakeup sources, clean the resume address
* will cause zacboot to issue a SW_RESET, for design a behavior
* to let PB_RESUME button be a power on button.
*
* Also force to disable watchdog timer, if it has been enabled.
*/
HSP0_VAL = 0;
OSTW_VAL &= ~OSTW_WE;
/*
* Well, I cannot power-off myself,
* so try to enter power-off suspend mode.
*/
//for single core
#ifndef CONFIG_SMP
HSP7_VAL = 0xffffffb8;
while(HSP7_VAL != 0xffffffb8);
asm("sev" : : "r" (0));
#endif
//PMWTC_VAL = 0x2000;//DCDET falling
*(unsigned char *)0xfe13005c = 0x0;
#if 0
PMWT_VAL = 0x40000000;
mdelay(1);
PMWS_VAL = PMWS_VAL;
mdelay(1);
PMWE_VAL = 0x00004080;//DCDET + PWRBTN
mdelay(1);
WK_TRG_EN_VAL = 0x00004080;//DCDET + PWRBTN
if (DCDET_STS_VAL & 0x100)
PMHC_VAL = PMHC_SUSPEND;
//#else
if (DCDET_STS_VAL & 0x100)
PMSR_VAL = PMSR_SWR;
else
#endif
PMHC_VAL = PMHC_HIBERNATE;
//asm("mcr%? p15, 0, %0, c7, c0, 4" : : "r" (0)); /* Force ARM to idle mode*/
do {
asm("wfi" : : "r" (0)); /* Force ARM to idle mode*/
} while(1);
}
static struct resource wmt_uart0_resources[] = {
[0] = {
.start = UART0_BASE_ADDR,
.end = (UART0_BASE_ADDR + 0xFFFF),
.flags = IORESOURCE_MEM,
},
};
static struct resource wmt_uart1_resources[] = {
[0] = {
.start = UART1_BASE_ADDR,
.end = (UART1_BASE_ADDR + 0xFFFF),
.flags = IORESOURCE_MEM,
},
};
#ifdef CONFIG_UART_2_3_ENABLE
static struct resource wmt_uart2_resources[] = {
[0] = {
.start = UART2_BASE_ADDR,
.end = (UART2_BASE_ADDR + 0xFFFF),
.flags = IORESOURCE_MEM,
},
};
static struct resource wmt_uart3_resources[] = {
[0] = {
.start = UART3_BASE_ADDR,
.end = (UART3_BASE_ADDR + 0xFFFF),
.flags = IORESOURCE_MEM,
},
};
#endif
static struct platform_device wmt_uart0_device = {
.name = "uart",
.id = 0,
.num_resources = ARRAY_SIZE(wmt_uart0_resources),
.resource = wmt_uart0_resources,
};
static struct platform_device wmt_uart1_device = {
.name = "uart",
.id = 1,
.num_resources = ARRAY_SIZE(wmt_uart1_resources),
.resource = wmt_uart1_resources,
};
#ifdef CONFIG_UART_2_3_ENABLE
static struct platform_device wmt_uart2_device = {
.name = "uart",
.id = 2,
.num_resources = ARRAY_SIZE(wmt_uart2_resources),
.resource = wmt_uart2_resources,
};
static struct platform_device wmt_uart3_device = {
.name = "uart",
.id = 3,
.num_resources = ARRAY_SIZE(wmt_uart3_resources),
.resource = wmt_uart3_resources,
};
#endif
static struct resource wmt_sf_resources[] = {
[0] = {
.start = SF_MEM_CTRL_CFG_BASE_ADDR,
.end = SF_MEM_CTRL_CFG_BASE_ADDR + 0x3FF,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device wmt_sf_device = {
.name = "sf",
.id = 0,
.num_resources = ARRAY_SIZE(wmt_sf_resources),
.resource = wmt_sf_resources,
};
#ifdef CONFIG_MTD_WMT_NOR
static struct resource wmt_nor_resources[] = {
[0] = {
.start = NOR_CTRL_CFG_BASE_ADDR,
.end = NOR_CTRL_CFG_BASE_ADDR + 0x3FF,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device wmt_nor_device = {
.name = "nor",
.id = 0,
.num_resources = ARRAY_SIZE(wmt_nor_resources),
.resource = wmt_nor_resources,
};
#endif
static struct resource wmt_nand_resources[] = {
[0] = {
.start = NF_CTRL_CFG_BASE_ADDR,
.end = NF_CTRL_CFG_BASE_ADDR + 0x3FF,
.flags = IORESOURCE_MEM,
},
};
static u64 wmt_nand_dma_mask = 0xffffffffUL;
static struct platform_device wmt_nand_device = {
.name = "nand",
.id = 0,
.dev = {
.dma_mask = &wmt_nand_dma_mask,
.coherent_dma_mask = ~0,
},
.num_resources = ARRAY_SIZE(wmt_nand_resources),
.resource = wmt_nand_resources,
};
static struct resource wmt_i2s_resources[] = {
[0] = {
.start = 0xD80ED800,
.end = 0xD80EDBFF,
.flags = IORESOURCE_MEM,
},
};
static struct resource wmt_pcm_resources[] = {
[0] = {
.start = 0xD82D0000,
.end = 0xD82D0000 + 0x4f,
.flags = IORESOURCE_MEM,
},
};
static u64 wmt_i2s_dma_mask = 0xffffffffUL;
static u64 wmt_pcm_dma_mask = 0xffffffffUL;
static struct platform_device wmt_i2s_device = {
.name = "wmt-i2s",
.id = 0,
.dev = {
.dma_mask = &wmt_i2s_dma_mask,
.coherent_dma_mask = ~0,
},
.num_resources = ARRAY_SIZE(wmt_i2s_resources),
.resource = wmt_i2s_resources,
};
static struct platform_device wmt_pcm_controller_device = {
.name = "wmt-pcm-controller",
.id = 0,
.dev = {
.dma_mask = &wmt_pcm_dma_mask,
.coherent_dma_mask = ~0,
},
.num_resources = ARRAY_SIZE(wmt_pcm_resources),
.resource = wmt_pcm_resources,
};
static struct platform_device wmt_pcm_dma_device = {
.name = "wmt-pcm-dma",
.id = 0,
};
static struct platform_device wmt_aud_pcm_device = {
.name = "wmt-audio-pcm",
.id = 0,
};
static struct platform_device wmt_i2s_hwdac_device = {
.name = "wmt-i2s-hwdac",
.id = 0,
};
static struct platform_device wmt_switch_device = {
.name = "wmt-switch",
.id = 0,
};
static struct resource wmt_pwm_resources[] = {
[0] = {
.start = 0xD8220000,
.end = 0xD8220000 + 0x44,
.flags = IORESOURCE_MEM,
},
};
struct platform_device wm8880_device_pwm = {
.name = "wm8880-pwm",
.id = 0,
.num_resources = ARRAY_SIZE(wmt_pwm_resources),
.resource = wmt_pwm_resources,
};
#ifdef CONFIG_WMT_NEWSPI_SUPPORT
static struct spi_board_info wmt_spi_board_info[] = {
};
#endif
#ifdef CONFIG_WMT_NEWSPI1_SUPPORT
static struct spi_board_info wmt_spi1_board_info[] = {
};
#endif
#ifdef CONFIG_WMT_NEWSPI_SUPPORT
static struct wmt_spi_hw wmt_spi_info = {
/* spi on wmt can support dma */
.dma_support = SPI_DMA_ENABLE,
/* can support 4 slaves when WMT spi as master */
.num_chipselect = MAX_SPI_SLAVE,
/* wmt spi support 16bits_per_word? i'm not sure */
.bits_per_word_en = BITS8_PER_WORD_EN,
/* wmt spi can support multi-master also, but it seems we do not need it */
.port_mode = PORT_MODE_PTP,
/* ssn driven low when enable */
.ssn_ctrl = SSN_CTRL_HARDWARE,
/* actual 36bytes, but we use 32bytes */
.fifo_size = SPI_FIFO_SIZE,
/* 4Kbytes, same as the DMA */
.max_transfer_length = SPI_MAX_TRANSFER_LENGTH,
/* it's really needed? i'm not sure */
.min_freq_hz = SPI_MIN_FREQ_HZ,
/* max freq 100Mhz */
.max_freq_hz = SPI_MAX_FREQ_HZ,
};
static struct resource wmt_spi_resources[] = {
[0] = {
.start = SPI0_BASE_ADDR,
.end = SPI0_BASE_ADDR + 0xFFFF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_SPI0,
.end = IRQ_SPI0,
.flags = IORESOURCE_IRQ,
},
};
static u64 wmt_spi_dma_mask = 0xFFFFFFFFUL;
static struct platform_device wmt_spi_device = {
.name = "wmt_spi_0",
.id = 0,
.dev = {
.dma_mask = &wmt_spi_dma_mask,
.coherent_dma_mask = ~0,
.platform_data = &wmt_spi_info,
},
.num_resources = ARRAY_SIZE(wmt_spi_resources),
.resource = wmt_spi_resources,
};
#endif
#ifdef CONFIG_WMT_NEWSPI1_SUPPORT
static struct wmt_spi_hw wmt_spi1_info = {
/* spi on wmt can support dma */
.dma_support = SPI_DMA_ENABLE,
/* can support 4 slaves when wmt spi as master */
.num_chipselect = MAX_SPI_SLAVE,
/* wmt spi support 16bits_per_word? i'm not sure */
.bits_per_word_en = BITS8_PER_WORD_EN,
/* wmt spi can support multi-master also, but it seems we do not need it */
.port_mode = PORT_MODE_PTP,
/* ssn driven low when enable */
.ssn_ctrl = SSN_CTRL_HARDWARE,
/* actual 36bytes, but we use 32bytes */
.fifo_size = SPI_FIFO_SIZE,
/* 4Kbytes, same as the DMA */
.max_transfer_length = SPI_MAX_TRANSFER_LENGTH,
/* it's really needed? i'm not sure */
.min_freq_hz = SPI_MIN_FREQ_HZ,
/* max freq 100Mhz */
.max_freq_hz = SPI_MAX_FREQ_HZ,
};
static struct resource wmt_spi1_resources[] = {
[0] = {
.start = SPI1_BASE_ADDR,
.end = SPI1_BASE_ADDR + 0x0000FFFF,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_SPI1,
.end = IRQ_SPI1,
.flags = IORESOURCE_IRQ,
},
};
static u64 wmt_spi1_dma_mask = 0xFFFFFFFFUL;
static struct platform_device wmt_spi1_device = {
.name = "wmt_spi_1",
.id = 1,
.dev = {
.dma_mask = &wmt_spi1_dma_mask,
.coherent_dma_mask = ~0,
.platform_data = &wmt_spi1_info,
},
.num_resources = ARRAY_SIZE(wmt_spi1_resources),
.resource = wmt_spi1_resources,
};
#endif
#ifdef CONFIG_DRM_MALI
static struct platform_device wmt_mali_drm_device = {
.name = "mali_drm",
.id = -1,
};
#endif
#ifdef CONFIG_I2S_CODEC_WM8994
static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
REGULATOR_SUPPLY("DBVDD", "4-001a"),
REGULATOR_SUPPLY("AVDD2", "4-001a"),
REGULATOR_SUPPLY("CPVDD", "4-001a"),
};
static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
REGULATOR_SUPPLY("SPKVDD1", "4-001a"),
REGULATOR_SUPPLY("SPKVDD2", "4-001a"),
};
static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
.constraints = {
.always_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
.consumer_supplies = wm8994_fixed_voltage0_supplies,
};
static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
.constraints = {
.always_on = 1,
},
.num_consumer_supplies = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
.consumer_supplies = wm8994_fixed_voltage1_supplies,
};
static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
.supply_name = "VCC_1.8V_PDA",
.microvolts = 1800000,
.gpio = -EINVAL,
.init_data = &wm8994_fixed_voltage0_init_data,
};
static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
.supply_name = "V_BAT",
.microvolts = 3700000,
.gpio = -EINVAL,
.init_data = &wm8994_fixed_voltage1_init_data,
};
static struct platform_device wm8994_fixed_voltage0 = {
.name = "reg-fixed-voltage",
.id = 0,
.dev = {
.platform_data = &wm8994_fixed_voltage0_config,
},
};
static struct platform_device wm8994_fixed_voltage1 = {
.name = "reg-fixed-voltage",
.id = 1,
.dev = {
.platform_data = &wm8994_fixed_voltage1_config,
},
};
static struct regulator_consumer_supply wm8994_avdd1_supply =
REGULATOR_SUPPLY("AVDD1", "4-001a");
static struct regulator_consumer_supply wm8994_dcvdd_supply =
REGULATOR_SUPPLY("DCVDD", "4-001a");
static struct regulator_init_data wm8994_ldo1_data = {
.constraints = {
.name = "AVDD1_3.0V",
},
.num_consumer_supplies = 1,
.consumer_supplies = &wm8994_avdd1_supply,
};
static struct regulator_init_data wm8994_ldo2_data = {
.constraints = {
.name = "DCVDD_1.0V",
},
.num_consumer_supplies = 1,
.consumer_supplies = &wm8994_dcvdd_supply,
};
static struct wm8994_pdata wm8994_platform_data = {
/* configure gpio1 function for ADCLRCLK */
.gpio_defaults[0] = 0x0100,
/* configure gpio2 & gpio6 function for gpio */
.gpio_defaults[1] = 0x8101, // read-only
.gpio_defaults[5] = 0x0001, // output
/* configure gpio3/4/5/7 function for AIF2 voice */
.gpio_defaults[2] = 0x8100,
.gpio_defaults[3] = 0x8100,
.gpio_defaults[4] = 0x8100,
.gpio_defaults[6] = 0x0100,
/* configure gpio8/9/10/11 function for AIF3 BT */
.gpio_defaults[7] = 0x8100,
.gpio_defaults[8] = 0x0100,
.gpio_defaults[9] = 0x0100,
.gpio_defaults[10] = 0x0100,
.ldo[0] = { 0, &wm8994_ldo1_data }, /* XM0FRNB_2 */
.ldo[1] = { 0, &wm8994_ldo2_data },
};
static struct i2c_board_info wm8994_i2c_dev[] __initdata = {
{I2C_BOARD_INFO("wm8994", 0x1a), .platform_data = &wm8994_platform_data,},
};
#endif
#ifdef CONFIG_ISDBT_MTV23x
static struct i2c_board_info isdbt_i2c_dev[] __initdata = {
{I2C_BOARD_INFO("isdbti2c", 0x43), .platform_data = NULL,},
};
#endif
#ifdef CONFIG_CACHE_L2X0
extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
static void __iomem *l2x0_base;
static DEFINE_RAW_SPINLOCK(l2x0_lock);
static void wmt_l2x0_disable(void)
{
unsigned long flags;
raw_spin_lock_irqsave(&l2x0_lock, flags);
// __l2x0_flush_all();
wmt_smc(WMT_SMC_CMD_PL310CTRL, 0);
dsb();
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
}
#endif
static struct platform_device *wmt_devices[] __initdata = {
&wmt_uart0_device,
&wmt_uart1_device,
#ifdef CONFIG_UART_2_3_ENABLE
&wmt_uart2_device,
&wmt_uart3_device,
#endif
&wmt_sf_device,
#ifdef CONFIG_MTD_WMT_NOR
&wmt_nor_device,
#endif
&wmt_nand_device,
&wmt_i2s_device,
&wmt_pcm_controller_device,
&wmt_pcm_dma_device,
&wmt_aud_pcm_device,
&wmt_i2s_hwdac_device,
// &wmt_pcm_device,
&wmt_switch_device,
#ifdef CONFIG_WMT_NEWSPI_SUPPORT
&wmt_spi_device,
#endif
#ifdef CONFIG_WMT_NEWSPI1_SUPPORT
&wmt_spi1_device,
#endif
#ifdef CONFIG_DRM_MALI
&wmt_mali_drm_device,
#endif
#ifdef CONFIG_I2S_CODEC_WM8994
&wm8994_fixed_voltage0,
&wm8994_fixed_voltage1,
#endif
&wm8880_device_pwm,
};
#ifdef CONFIG_VT1603_IOCTRL_SPI
static struct wmt_spi_slave vt1603_codec_info = {
.dma_en = SPI_DMA_DISABLE,
.bits_per_word = 8,
};
static struct spi_board_info vt1603_spi_board_info[] __initdata = {
{
.modalias = "vt1609",
.bus_num = 0,
.chip_select = 0,
.max_speed_hz = 12000000,
.irq = -1,
.mode = SPI_CLK_MODE3,
.controller_data = &vt1603_codec_info,
},
};
#endif
static struct i2c_board_info cp2682_i2c_dev[] __initdata = {
{I2C_BOARD_INFO("cp2682", (0x2c)),},
};
static char ns_printk_buf[1024];
void sprintk(unsigned int buf, unsigned int len)
{
local_irq_disable();
printk(ns_printk_buf);
wmt_smc(WMT_SMC_CMD_PRINTK_RET, 0);
}
void notify_log_buf()
{
wmt_smc(WMT_SMC_CMD_LOGBUFOK, (unsigned int)sprintk);
wmt_smc(WMT_SMC_CMD_LOGBUF_ADDR, (unsigned int)virt_to_phys(ns_printk_buf));
}
static void wmt_default_idle(void)
{
if (!need_resched()) {
asm("dsb");
asm("wfi");
}
local_irq_enable();
}
static int __init wmt_init(void)
{
/* Add for enable user access to pmu */
unsigned char buf[40];
int varlen=40;
unsigned int pmu_param;
int ret = 0;
int vt1603_spi = 0; //0-->spi, 1-->i2c
/* Add End */
#ifdef CONFIG_CACHE_L2X0
__u32 power_ctrl = 0;
unsigned int onoff = 0;
unsigned int aux = 0x3E440000;
unsigned int prefetch_ctrl = 0x70000007;
unsigned int en_static_address_filtering = 0;
unsigned int address_filtering_start = 0xD8000000;
unsigned int address_filtering_end = 0xD9000000;
unsigned int cpu_trustzone_enabled = 0;
unsigned long flags;
#endif
wmt_gpio_init();
pm_power_off = wmt_power_off;
pm_idle = wmt_default_idle;
arm_pm_restart = wmt_restart;
#ifdef CONFIG_WMT_NEWSPI_SUPPORT
spi_register_board_info(wmt_spi_board_info, ARRAY_SIZE(wmt_spi_board_info));
#endif
#ifdef CONFIG_WMT_NEWSPI1_SUPPORT
spi_register_board_info(wmt_spi1_board_info, ARRAY_SIZE(wmt_spi1_board_info));
#endif
#ifdef CONFIG_VT1603_IOCTRL_SPI
memset(buf, 0, sizeof(buf));
ret = wmt_getsyspara("wmt.vt1603.bus", buf, &varlen);
if (!ret)
{
sscanf(buf, "%d", &vt1603_spi); // 0-->spi, 1-->i2c
}
if (
(!vt1603_spi) && // 0-->spi, 1-->i2c
((!wmt_getsyspara("wmt.audio.i2s", buf, &varlen) &&
(!strncmp(buf, "vt1603", 6) || !strncmp(buf, "vt1609", 6))) || /* audio */
(!wmt_getsyspara("wmt.battery.param", buf, &varlen) && /* battery */
(!strncmp(buf, "vt1603", 6) || !strncmp(buf, "vt1609", 6))))
)
{
spi_register_board_info(vt1603_spi_board_info,
ARRAY_SIZE(vt1603_spi_board_info));
}
#endif
#ifdef CONFIG_I2S_CODEC_WM8994
i2c_register_board_info(4, wm8994_i2c_dev, ARRAY_SIZE(wm8994_i2c_dev));
#endif
#ifdef CONFIG_ISDBT_MTV23x
i2c_register_board_info(4, isdbt_i2c_dev, ARRAY_SIZE(isdbt_i2c_dev));
#endif
#ifdef CONFIG_CACHE_L2X0
if (wmt_getsyspara("wmt.l2c.param",buf,&varlen) == 0)
sscanf(buf,"%d:%x:%x:%d:%x:%x",&onoff, &aux, &prefetch_ctrl, &en_static_address_filtering, &address_filtering_start, &address_filtering_end);
if (wmt_getsyspara("wmt.secure.param",buf,&varlen) == 0)
sscanf(buf,"%d",&cpu_trustzone_enabled);
if(cpu_trustzone_enabled != 1)
cpu_trustzone_enabled = 0;
if (onoff == 1) {
l2x0_base = ioremap(0xD9000000, SZ_4K);
if(cpu_trustzone_enabled == 0)
{
if (en_static_address_filtering == 1) {
writel_relaxed(address_filtering_end, l2x0_base + 0xC04);
writel_relaxed((address_filtering_start | 0x01), l2x0_base + 0xC00);
}
writel_relaxed(0x110, l2x0_base + L2X0_TAG_LATENCY_CTRL);
writel_relaxed(0x110, l2x0_base + L2X0_DATA_LATENCY_CTRL);
power_ctrl = readl_relaxed(l2x0_base + L2X0_POWER_CTRL) | L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
writel_relaxed(power_ctrl, l2x0_base + L2X0_POWER_CTRL);
writel_relaxed(prefetch_ctrl, l2x0_base + L2X0_PREFETCH_CTRL);
}
else
{
if (en_static_address_filtering == 1) {
wmt_smc(WMT_SMC_CMD_PL310FILTER_END, address_filtering_end);
wmt_smc(WMT_SMC_CMD_PL310FILTER_START, (address_filtering_start | 0x01));
}
wmt_smc(WMT_SMC_CMD_PL310TAG_LATENCY, 0x110);
wmt_smc(WMT_SMC_CMD_PL310DATA_LATENCY, 0x110);
power_ctrl = readl_relaxed(l2x0_base + L2X0_POWER_CTRL) | L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
wmt_smc(WMT_SMC_CMD_PL310POWER, power_ctrl);
wmt_smc(WMT_SMC_CMD_PL310PREFETCH, prefetch_ctrl);
raw_spin_lock_irqsave(&l2x0_lock, flags);
writel_relaxed(0xffff, l2x0_base + L2X0_INV_WAY);
while ( readl_relaxed(l2x0_base + L2X0_INV_WAY) & 0xffff)
cpu_relax();
writel_relaxed(0, l2x0_base + L2X0_CACHE_SYNC);
raw_spin_unlock_irqrestore(&l2x0_lock, flags);
/* enable L2X0 */
wmt_smc(WMT_SMC_CMD_PL310CTRL, 1);
}
/* 512KB (32KB/way) 16-way associativity */
l2x0_init(l2x0_base, aux, 0);
if(cpu_trustzone_enabled != 0)
outer_cache.disable = wmt_l2x0_disable;
}
#endif
#ifdef CONFIG_MTD_WMT_SF
/* Add for enable user access to ARM11 performance monitor */
if(wmt_getsyspara("wmt.pmu.param",buf,&varlen) == 0)
sscanf(buf,"%d",&pmu_param );
if(pmu_param & 0x1){
//enable_user_access();
}
#endif
/* Add End */
if(cpu_trustzone_enabled == 1)
notify_log_buf();//Lch for SecureOS_printk
return platform_add_devices(wmt_devices, ARRAY_SIZE(wmt_devices));
}
arch_initcall(wmt_init);