mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 16:20:55 +07:00
Merge branch 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson
* 'for-torvalds' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson: mach-ux500: voltage domain regulators for DB8500 cpufreq: make DB8500 cpufreq driver compile cpufreq: update DB8500 cpufreq driver mach-ux500: move CPUfreq driver to cpufreq subsystem mfd: add DB5500 PRCMU driver mfd: update DB8500 PRCMU driver mach-ux500: move the DB8500 PRCMU driver to MFD mach-ux500: make PRCMU base address dynamic mach-ux500: rename PRCMU driver per SoC mach-ux500: update ASIC version detection mach-ux500: update SoC and board IRQ handling mach-ux500: update the DB5500 register file mach-ux500: update the DB8500 register file
This commit is contained in:
commit
ad363e0916
@ -12,9 +12,12 @@ menu "Ux500 SoC"
|
||||
|
||||
config UX500_SOC_DB5500
|
||||
bool "DB5500"
|
||||
select MFD_DB5500_PRCMU
|
||||
|
||||
config UX500_SOC_DB8500
|
||||
bool "DB8500"
|
||||
select MFD_DB8500_PRCMU
|
||||
select REGULATOR_DB8500_PRCMU
|
||||
|
||||
endmenu
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
obj-y := clock.o cpu.o devices.o devices-common.o \
|
||||
id.o usb.o
|
||||
obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o
|
||||
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
|
||||
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o
|
||||
obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \
|
||||
board-mop500-regulators.o \
|
||||
board-mop500-uib.o board-mop500-stuib.o \
|
||||
@ -17,4 +17,4 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
|
||||
obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o
|
||||
obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o
|
||||
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
|
||||
|
||||
|
@ -188,6 +188,8 @@ void __init u5500_map_io(void)
|
||||
ux500_map_io();
|
||||
|
||||
iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));
|
||||
|
||||
_PRCMU_BASE = __io_address(U5500_PRCMU_BASE);
|
||||
}
|
||||
|
||||
static int usb_db5500_rx_dma_cfg[] = {
|
||||
|
@ -87,6 +87,8 @@ void __init u8500_map_io(void)
|
||||
iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
|
||||
else if (cpu_is_u8500v2())
|
||||
iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
|
||||
|
||||
_PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
|
||||
}
|
||||
|
||||
static struct resource db8500_pmu_resources[] = {
|
||||
@ -129,9 +131,14 @@ static struct platform_device db8500_pmu_device = {
|
||||
.dev.platform_data = &db8500_pmu_platdata,
|
||||
};
|
||||
|
||||
static struct platform_device db8500_prcmu_device = {
|
||||
.name = "db8500-prcmu",
|
||||
};
|
||||
|
||||
static struct platform_device *platform_devs[] __initdata = {
|
||||
&u8500_dma40_device,
|
||||
&db8500_pmu_device,
|
||||
&db8500_prcmu_device,
|
||||
};
|
||||
|
||||
static resource_size_t __initdata db8500_gpio_base[] = {
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/mfd/db8500-prcmu.h>
|
||||
#include <linux/mfd/db5500-prcmu.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
@ -19,10 +21,11 @@
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/setup.h>
|
||||
#include <mach/devices.h>
|
||||
#include <mach/prcmu.h>
|
||||
|
||||
#include "clock.h"
|
||||
|
||||
void __iomem *_PRCMU_BASE;
|
||||
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
static void __iomem *l2x0_base;
|
||||
#endif
|
||||
@ -47,6 +50,8 @@ void __init ux500_init_irq(void)
|
||||
* Init clocks here so that they are available for system timer
|
||||
* initialization.
|
||||
*/
|
||||
if (cpu_is_u5500())
|
||||
db5500_prcmu_early_init();
|
||||
if (cpu_is_u8500())
|
||||
prcmu_early_init();
|
||||
clk_init();
|
||||
|
@ -1,211 +0,0 @@
|
||||
/*
|
||||
* CPU frequency scaling for u8500
|
||||
* Inspired by linux/arch/arm/mach-davinci/cpufreq.c
|
||||
*
|
||||
* Copyright (C) STMicroelectronics 2009
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
*
|
||||
* Author: Sundar Iyer <sundar.iyer@stericsson.com>
|
||||
* Author: Martin Persson <martin.persson@stericsson.com>
|
||||
* Author: Jonas Aaberg <jonas.aberg@stericsson.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/prcmu.h>
|
||||
#include <mach/prcmu-defs.h>
|
||||
|
||||
#define DRIVER_NAME "cpufreq-u8500"
|
||||
#define CPUFREQ_NAME "u8500"
|
||||
|
||||
static struct device *dev;
|
||||
|
||||
static struct cpufreq_frequency_table freq_table[] = {
|
||||
[0] = {
|
||||
.index = 0,
|
||||
.frequency = 200000,
|
||||
},
|
||||
[1] = {
|
||||
.index = 1,
|
||||
.frequency = 300000,
|
||||
},
|
||||
[2] = {
|
||||
.index = 2,
|
||||
.frequency = 600000,
|
||||
},
|
||||
[3] = {
|
||||
/* Used for CPU_OPP_MAX, if available */
|
||||
.index = 3,
|
||||
.frequency = CPUFREQ_TABLE_END,
|
||||
},
|
||||
[4] = {
|
||||
.index = 4,
|
||||
.frequency = CPUFREQ_TABLE_END,
|
||||
},
|
||||
};
|
||||
|
||||
static enum prcmu_cpu_opp index2opp[] = {
|
||||
CPU_OPP_EXT_CLK,
|
||||
CPU_OPP_50,
|
||||
CPU_OPP_100,
|
||||
CPU_OPP_MAX
|
||||
};
|
||||
|
||||
static int u8500_cpufreq_verify_speed(struct cpufreq_policy *policy)
|
||||
{
|
||||
return cpufreq_frequency_table_verify(policy, freq_table);
|
||||
}
|
||||
|
||||
static int u8500_cpufreq_target(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
{
|
||||
struct cpufreq_freqs freqs;
|
||||
unsigned int index;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Ensure desired rate is within allowed range. Some govenors
|
||||
* (ondemand) will just pass target_freq=0 to get the minimum.
|
||||
*/
|
||||
if (target_freq < policy->cpuinfo.min_freq)
|
||||
target_freq = policy->cpuinfo.min_freq;
|
||||
if (target_freq > policy->cpuinfo.max_freq)
|
||||
target_freq = policy->cpuinfo.max_freq;
|
||||
|
||||
ret = cpufreq_frequency_table_target(policy, freq_table,
|
||||
target_freq, relation, &index);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Could not look up next frequency\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
freqs.old = policy->cur;
|
||||
freqs.new = freq_table[index].frequency;
|
||||
freqs.cpu = policy->cpu;
|
||||
|
||||
if (freqs.old == freqs.new) {
|
||||
dev_dbg(dev, "Current and target frequencies are equal\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "transition: %u --> %u\n", freqs.old, freqs.new);
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
ret = prcmu_set_cpu_opp(index2opp[index]);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to set OPP level\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int u8500_cpufreq_getspeed(unsigned int cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; prcmu_get_cpu_opp() != index2opp[i]; i++)
|
||||
;
|
||||
return freq_table[i].frequency;
|
||||
}
|
||||
|
||||
static int __cpuinit u8500_cpu_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int res;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(index2opp) + 1 != ARRAY_SIZE(freq_table));
|
||||
|
||||
if (cpu_is_u8500v2()) {
|
||||
freq_table[1].frequency = 400000;
|
||||
freq_table[2].frequency = 800000;
|
||||
if (prcmu_has_arm_maxopp())
|
||||
freq_table[3].frequency = 1000000;
|
||||
}
|
||||
|
||||
/* get policy fields based on the table */
|
||||
res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||
if (!res)
|
||||
cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
|
||||
else {
|
||||
dev_err(dev, "u8500-cpufreq : Failed to read policy table\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
policy->min = policy->cpuinfo.min_freq;
|
||||
policy->max = policy->cpuinfo.max_freq;
|
||||
policy->cur = u8500_cpufreq_getspeed(policy->cpu);
|
||||
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
|
||||
|
||||
/*
|
||||
* FIXME : Need to take time measurement across the target()
|
||||
* function with no/some/all drivers in the notification
|
||||
* list.
|
||||
*/
|
||||
policy->cpuinfo.transition_latency = 200 * 1000; /* in ns */
|
||||
|
||||
/* policy sharing between dual CPUs */
|
||||
cpumask_copy(policy->cpus, &cpu_present_map);
|
||||
|
||||
policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct freq_attr *u8500_cpufreq_attr[] = {
|
||||
&cpufreq_freq_attr_scaling_available_freqs,
|
||||
NULL,
|
||||
};
|
||||
static int u8500_cpu_exit(struct cpufreq_policy *policy)
|
||||
{
|
||||
cpufreq_frequency_table_put_attr(policy->cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver u8500_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.flags = CPUFREQ_STICKY,
|
||||
.verify = u8500_cpufreq_verify_speed,
|
||||
.target = u8500_cpufreq_target,
|
||||
.get = u8500_cpufreq_getspeed,
|
||||
.init = u8500_cpu_init,
|
||||
.exit = u8500_cpu_exit,
|
||||
.name = CPUFREQ_NAME,
|
||||
.attr = u8500_cpufreq_attr,
|
||||
};
|
||||
|
||||
static int __init u8500_cpufreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
dev = &pdev->dev;
|
||||
return cpufreq_register_driver(&u8500_driver);
|
||||
}
|
||||
|
||||
static int __exit u8500_cpufreq_remove(struct platform_device *pdev)
|
||||
{
|
||||
return cpufreq_unregister_driver(&u8500_driver);
|
||||
}
|
||||
|
||||
static struct platform_driver u8500_cpufreq_driver = {
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.remove = __exit_p(u8500_cpufreq_remove),
|
||||
};
|
||||
|
||||
static int __init u8500_cpufreq_init(void)
|
||||
{
|
||||
return platform_driver_probe(&u8500_cpufreq_driver,
|
||||
&u8500_cpufreq_probe);
|
||||
}
|
||||
|
||||
device_initcall(u8500_cpufreq_init);
|
@ -17,6 +17,8 @@
|
||||
#define U5500_GIC_DIST_BASE 0xA0411000
|
||||
#define U5500_GIC_CPU_BASE 0xA0410100
|
||||
#define U5500_DMA_BASE 0x90030000
|
||||
#define U5500_STM_BASE 0x90020000
|
||||
#define U5500_STM_REG_BASE (U5500_STM_BASE + 0xF000)
|
||||
#define U5500_MCDE_BASE 0xA0400000
|
||||
#define U5500_MODEM_BASE 0xB0000000
|
||||
#define U5500_L2CC_BASE 0xA0412000
|
||||
@ -29,7 +31,9 @@
|
||||
#define U5500_NAND0_BASE 0x60000000
|
||||
#define U5500_NAND1_BASE 0x70000000
|
||||
#define U5500_TWD_BASE 0xa0410600
|
||||
#define U5500_ICN_BASE 0xA0040000
|
||||
#define U5500_B2R2_BASE 0xa0200000
|
||||
#define U5500_BOOT_ROM_BASE 0x90000000
|
||||
|
||||
#define U5500_FSMC_BASE (U5500_PER1_BASE + 0x0000)
|
||||
#define U5500_SDI0_BASE (U5500_PER1_BASE + 0x1000)
|
||||
@ -60,6 +64,7 @@
|
||||
#define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000)
|
||||
#define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000)
|
||||
#define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000)
|
||||
#define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000)
|
||||
|
||||
#define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000)
|
||||
#define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000)
|
||||
@ -83,7 +88,7 @@
|
||||
#define U5500_HASH0_BASE (U5500_PER6_BASE + 0x1000)
|
||||
#define U5500_HASH1_BASE (U5500_PER6_BASE + 0x2000)
|
||||
#define U5500_PKA_BASE (U5500_PER6_BASE + 0x4000)
|
||||
#define U5500_PKAM_BASE (U5500_PER6_BASE + 0x5000)
|
||||
#define U5500_PKAM_BASE (U5500_PER6_BASE + 0x5100)
|
||||
#define U5500_MTU0_BASE (U5500_PER6_BASE + 0x6000)
|
||||
#define U5500_MTU1_BASE (U5500_PER6_BASE + 0x7000)
|
||||
#define U5500_CR_BASE (U5500_PER6_BASE + 0x8000)
|
||||
@ -114,8 +119,19 @@
|
||||
#define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20)
|
||||
#define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F)
|
||||
|
||||
#define U5500_ESRAM_BASE 0x40000000
|
||||
#define U5500_ACCCON_BASE_SEC (0xBFFF0000)
|
||||
#define U5500_ACCCON_BASE (0xBFFF1000)
|
||||
#define U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020)
|
||||
#define U5500_ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC)
|
||||
|
||||
#define U5500_ESRAM_BASE 0x40000000
|
||||
#define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000
|
||||
#define U5500_DMA_LCPA_BASE (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET)
|
||||
|
||||
#define U5500_MCDE_SIZE 0x1000
|
||||
#define U5500_DSI_LINK_SIZE 0x1000
|
||||
#define U5500_DSI_LINK_COUNT 0x2
|
||||
#define U5500_DSI_LINK1_BASE (U5500_MCDE_BASE + U5500_MCDE_SIZE)
|
||||
#define U5500_DSI_LINK2_BASE (U5500_DSI_LINK1_BASE + U5500_DSI_LINK_SIZE)
|
||||
|
||||
#endif
|
||||
|
@ -15,8 +15,13 @@
|
||||
#define U8500_ESRAM_BANK2 (U8500_ESRAM_BANK1 + U8500_ESRAM_BANK_SIZE)
|
||||
#define U8500_ESRAM_BANK3 (U8500_ESRAM_BANK2 + U8500_ESRAM_BANK_SIZE)
|
||||
#define U8500_ESRAM_BANK4 (U8500_ESRAM_BANK3 + U8500_ESRAM_BANK_SIZE)
|
||||
/* Use bank 4 for DMA LCPA */
|
||||
#define U8500_DMA_LCPA_BASE U8500_ESRAM_BANK4
|
||||
/*
|
||||
* on V1 DMA uses 4KB for logical parameters position is right after the 64KB
|
||||
* reserved for security
|
||||
*/
|
||||
#define U8500_ESRAM_DMA_LCPA_OFFSET 0x10000
|
||||
|
||||
#define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET)
|
||||
#define U8500_DMA_LCPA_BASE_ED (U8500_ESRAM_BANK4 + 0x4000)
|
||||
|
||||
#define U8500_PER3_BASE 0x80000000
|
||||
@ -27,9 +32,12 @@
|
||||
#define U8500_B2R2_BASE 0x80130000
|
||||
#define U8500_HSEM_BASE 0x80140000
|
||||
#define U8500_PER4_BASE 0x80150000
|
||||
#define U8500_TPIU_BASE 0x80190000
|
||||
#define U8500_ICN_BASE 0x81000000
|
||||
|
||||
#define U8500_BOOT_ROM_BASE 0x90000000
|
||||
/* ASIC ID is at 0xbf4 offset within this region */
|
||||
#define U8500_ASIC_ID_BASE 0x9001D000
|
||||
|
||||
#define U8500_PER6_BASE 0xa03c0000
|
||||
#define U8500_PER5_BASE 0xa03e0000
|
||||
@ -70,13 +78,15 @@
|
||||
|
||||
/* per6 base addresses */
|
||||
#define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000)
|
||||
#define U8500_PKA_BASE (U8500_PER6_BASE + 0x1000)
|
||||
#define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000)
|
||||
#define U8500_HASH0_BASE (U8500_PER6_BASE + 0x1000)
|
||||
#define U8500_HASH1_BASE (U8500_PER6_BASE + 0x2000)
|
||||
#define U8500_PKA_BASE (U8500_PER6_BASE + 0x4000)
|
||||
#define U8500_PKAM_BASE (U8500_PER6_BASE + 0x5100)
|
||||
#define U8500_MTU0_BASE (U8500_PER6_BASE + 0x6000) /* v1 */
|
||||
#define U8500_MTU1_BASE (U8500_PER6_BASE + 0x7000) /* v1 */
|
||||
#define U8500_CR_BASE (U8500_PER6_BASE + 0x8000) /* v1 */
|
||||
#define U8500_CRYPTO0_BASE (U8500_PER6_BASE + 0xa000)
|
||||
#define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000)
|
||||
#define U8500_CRYP0_BASE (U8500_PER6_BASE + 0xa000)
|
||||
#define U8500_CRYP1_BASE (U8500_PER6_BASE + 0xb000)
|
||||
#define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000)
|
||||
|
||||
/* per5 base addresses */
|
||||
@ -93,7 +103,8 @@
|
||||
#define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000)
|
||||
#define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000)
|
||||
#define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000)
|
||||
#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
|
||||
#define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000)
|
||||
#define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000)
|
||||
|
||||
/* per3 base addresses */
|
||||
#define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000)
|
||||
@ -124,6 +135,7 @@
|
||||
#define U8500_I2C1_BASE (U8500_PER1_BASE + 0x2000)
|
||||
#define U8500_MSP0_BASE (U8500_PER1_BASE + 0x3000)
|
||||
#define U8500_MSP1_BASE (U8500_PER1_BASE + 0x4000)
|
||||
#define U8500_MSP3_BASE (U8500_PER1_BASE + 0x5000)
|
||||
#define U8500_SDI0_BASE (U8500_PER1_BASE + 0x6000)
|
||||
#define U8500_I2C2_BASE (U8500_PER1_BASE + 0x8000)
|
||||
#define U8500_SPI3_BASE (U8500_PER1_BASE + 0x9000)
|
||||
@ -143,4 +155,15 @@
|
||||
#define U8500_GPIOBANK7_BASE (U8500_GPIO2_BASE + 0x80)
|
||||
#define U8500_GPIOBANK8_BASE U8500_GPIO3_BASE
|
||||
|
||||
#define U8500_MCDE_SIZE 0x1000
|
||||
#define U8500_DSI_LINK_SIZE 0x1000
|
||||
#define U8500_DSI_LINK1_BASE (U8500_MCDE_BASE + U8500_MCDE_SIZE)
|
||||
#define U8500_DSI_LINK2_BASE (U8500_DSI_LINK1_BASE + U8500_DSI_LINK_SIZE)
|
||||
#define U8500_DSI_LINK3_BASE (U8500_DSI_LINK2_BASE + U8500_DSI_LINK_SIZE)
|
||||
#define U8500_DSI_LINK_COUNT 0x3
|
||||
|
||||
/* Modem and APE physical addresses */
|
||||
#define U8500_MODEM_BASE 0xe000000
|
||||
#define U8500_APE_BASE 0x6000000
|
||||
|
||||
#endif
|
||||
|
@ -35,6 +35,7 @@
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <mach/id.h>
|
||||
extern void __iomem *_PRCMU_BASE;
|
||||
|
||||
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
|
||||
|
||||
|
@ -75,6 +75,26 @@ static inline bool __attribute_const__ cpu_is_u8500v2(void)
|
||||
return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0);
|
||||
}
|
||||
|
||||
static inline bool cpu_is_u8500v20(void)
|
||||
{
|
||||
return cpu_is_u8500() && (dbx500_revision() == 0xB0);
|
||||
}
|
||||
|
||||
static inline bool cpu_is_u8500v21(void)
|
||||
{
|
||||
return cpu_is_u8500() && (dbx500_revision() == 0xB1);
|
||||
}
|
||||
|
||||
static inline bool cpu_is_u8500v20_or_later(void)
|
||||
{
|
||||
return cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11();
|
||||
}
|
||||
|
||||
static inline bool ux500_is_svp(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#define ux500_unknown_soc() BUG()
|
||||
|
||||
#endif
|
||||
|
@ -50,6 +50,11 @@
|
||||
|
||||
#define MOP500_IRQ_END MOP500_NR_IRQS
|
||||
|
||||
/*
|
||||
* We may have several boards, but only one will run at a
|
||||
* time, so the one with most IRQs will bump this ahead,
|
||||
* but the IRQ_BOARD_START remains the same for either board.
|
||||
*/
|
||||
#if MOP500_IRQ_END > IRQ_BOARD_END
|
||||
#undef IRQ_BOARD_END
|
||||
#define IRQ_BOARD_END MOP500_IRQ_END
|
||||
|
21
arch/arm/mach-ux500/include/mach/irqs-board-u5500.h
Normal file
21
arch/arm/mach-ux500/include/mach/irqs-board-u5500.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License terms: GNU General Public License (GPL) version 2
|
||||
*/
|
||||
|
||||
#ifndef __MACH_IRQS_BOARD_U5500_H
|
||||
#define __MACH_IRQS_BOARD_U5500_H
|
||||
|
||||
#define AB5500_NR_IRQS 5
|
||||
#define IRQ_AB5500_BASE IRQ_BOARD_START
|
||||
#define IRQ_AB5500_END (IRQ_AB5500_BASE + AB5500_NR_IRQS)
|
||||
|
||||
#define U5500_IRQ_END IRQ_AB5500_END
|
||||
|
||||
#if IRQ_BOARD_END < U5500_IRQ_END
|
||||
#undef IRQ_BOARD_END
|
||||
#define IRQ_BOARD_END U5500_IRQ_END
|
||||
#endif
|
||||
|
||||
#endif
|
@ -83,4 +83,31 @@
|
||||
#define IRQ_DB5500_GPIO6 (IRQ_SHPI_START + 125)
|
||||
#define IRQ_DB5500_GPIO7 (IRQ_SHPI_START + 126)
|
||||
|
||||
#ifdef CONFIG_UX500_SOC_DB5500
|
||||
|
||||
/*
|
||||
* After the GPIO ones we reserve a range of IRQ:s in which virtual
|
||||
* IRQ:s representing modem IRQ:s can be allocated
|
||||
*/
|
||||
#define IRQ_MODEM_EVENTS_BASE IRQ_SOC_START
|
||||
#define IRQ_MODEM_EVENTS_NBR 72
|
||||
#define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR)
|
||||
|
||||
/* List of virtual IRQ:s that are allocated from the range above */
|
||||
#define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43)
|
||||
#define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45)
|
||||
#define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41)
|
||||
|
||||
/*
|
||||
* We may have several SoCs, but only one will run at a
|
||||
* time, so the one with most IRQs will bump this ahead,
|
||||
* but the IRQ_SOC_START remains the same for either SoC.
|
||||
*/
|
||||
#if IRQ_SOC_END < IRQ_MODEM_EVENTS_END
|
||||
#undef IRQ_SOC_END
|
||||
#define IRQ_SOC_END IRQ_MODEM_EVENTS_END
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_UX500_SOC_DB5500 */
|
||||
|
||||
#endif
|
||||
|
@ -93,4 +93,58 @@
|
||||
#define IRQ_DB8500_GPIO7 (IRQ_SHPI_START + 126)
|
||||
#define IRQ_DB8500_GPIO8 (IRQ_SHPI_START + 127)
|
||||
|
||||
#define IRQ_CA_WAKE_REQ_ED (IRQ_SHPI_START + 71)
|
||||
#define IRQ_AC_READ_NOTIFICATION_0_ED (IRQ_SHPI_START + 66)
|
||||
#define IRQ_AC_READ_NOTIFICATION_1_ED (IRQ_SHPI_START + 64)
|
||||
#define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED (IRQ_SHPI_START + 67)
|
||||
#define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED (IRQ_SHPI_START + 65)
|
||||
|
||||
#define IRQ_CA_WAKE_REQ_V1 (IRQ_SHPI_START + 83)
|
||||
#define IRQ_AC_READ_NOTIFICATION_0_V1 (IRQ_SHPI_START + 78)
|
||||
#define IRQ_AC_READ_NOTIFICATION_1_V1 (IRQ_SHPI_START + 76)
|
||||
#define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1 (IRQ_SHPI_START + 79)
|
||||
#define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1 (IRQ_SHPI_START + 77)
|
||||
|
||||
#ifdef CONFIG_UX500_SOC_DB8500
|
||||
|
||||
/* Virtual interrupts corresponding to the PRCMU wakeups. */
|
||||
#define IRQ_PRCMU_BASE IRQ_SOC_START
|
||||
#define NUM_PRCMU_WAKEUPS (IRQ_PRCMU_END - IRQ_PRCMU_BASE)
|
||||
|
||||
#define IRQ_PRCMU_RTC (IRQ_PRCMU_BASE)
|
||||
#define IRQ_PRCMU_RTT0 (IRQ_PRCMU_BASE + 1)
|
||||
#define IRQ_PRCMU_RTT1 (IRQ_PRCMU_BASE + 2)
|
||||
#define IRQ_PRCMU_HSI0 (IRQ_PRCMU_BASE + 3)
|
||||
#define IRQ_PRCMU_HSI1 (IRQ_PRCMU_BASE + 4)
|
||||
#define IRQ_PRCMU_CA_WAKE (IRQ_PRCMU_BASE + 5)
|
||||
#define IRQ_PRCMU_USB (IRQ_PRCMU_BASE + 6)
|
||||
#define IRQ_PRCMU_ABB (IRQ_PRCMU_BASE + 7)
|
||||
#define IRQ_PRCMU_ABB_FIFO (IRQ_PRCMU_BASE + 8)
|
||||
#define IRQ_PRCMU_ARM (IRQ_PRCMU_BASE + 9)
|
||||
#define IRQ_PRCMU_MODEM_SW_RESET_REQ (IRQ_PRCMU_BASE + 10)
|
||||
#define IRQ_PRCMU_GPIO0 (IRQ_PRCMU_BASE + 11)
|
||||
#define IRQ_PRCMU_GPIO1 (IRQ_PRCMU_BASE + 12)
|
||||
#define IRQ_PRCMU_GPIO2 (IRQ_PRCMU_BASE + 13)
|
||||
#define IRQ_PRCMU_GPIO3 (IRQ_PRCMU_BASE + 14)
|
||||
#define IRQ_PRCMU_GPIO4 (IRQ_PRCMU_BASE + 15)
|
||||
#define IRQ_PRCMU_GPIO5 (IRQ_PRCMU_BASE + 16)
|
||||
#define IRQ_PRCMU_GPIO6 (IRQ_PRCMU_BASE + 17)
|
||||
#define IRQ_PRCMU_GPIO7 (IRQ_PRCMU_BASE + 18)
|
||||
#define IRQ_PRCMU_GPIO8 (IRQ_PRCMU_BASE + 19)
|
||||
#define IRQ_PRCMU_CA_SLEEP (IRQ_PRCMU_BASE + 20)
|
||||
#define IRQ_PRCMU_HOTMON_LOW (IRQ_PRCMU_BASE + 21)
|
||||
#define IRQ_PRCMU_HOTMON_HIGH (IRQ_PRCMU_BASE + 22)
|
||||
#define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23)
|
||||
|
||||
/*
|
||||
* We may have several SoCs, but only one will run at a
|
||||
* time, so the one with most IRQs will bump this ahead,
|
||||
* but the IRQ_SOC_START remains the same for either SoC.
|
||||
*/
|
||||
#if IRQ_SOC_END < IRQ_PRCMU_END
|
||||
#undef IRQ_SOC_END
|
||||
#define IRQ_SOC_END IRQ_PRCMU_END
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_UX500_SOC_DB8500 */
|
||||
#endif
|
||||
|
@ -10,49 +10,47 @@
|
||||
#ifndef ASM_ARCH_IRQS_H
|
||||
#define ASM_ARCH_IRQS_H
|
||||
|
||||
#include <mach/irqs-db5500.h>
|
||||
#include <mach/irqs-db8500.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#define IRQ_LOCALTIMER 29
|
||||
#define IRQ_LOCALWDOG 30
|
||||
#define IRQ_LOCALTIMER 29
|
||||
#define IRQ_LOCALWDOG 30
|
||||
|
||||
/* Shared Peripheral Interrupt (SHPI) */
|
||||
#define IRQ_SHPI_START 32
|
||||
|
||||
/* Interrupt numbers generic for shared peripheral */
|
||||
/*
|
||||
* MTU0 preserved for now until plat-nomadik is taught not to use it. Don't
|
||||
* add any other IRQs here, use the irqs-dbx500.h files.
|
||||
*/
|
||||
#define IRQ_MTU0 (IRQ_SHPI_START + 4)
|
||||
|
||||
/* There are 128 shared peripheral interrupts assigned to
|
||||
* INTID[160:32]. The first 32 interrupts are reserved.
|
||||
*/
|
||||
#define DBX500_NR_INTERNAL_IRQS 161
|
||||
#define DBX500_NR_INTERNAL_IRQS 160
|
||||
|
||||
/* After chip-specific IRQ numbers we have the GPIO ones */
|
||||
#define NOMADIK_NR_GPIO 288
|
||||
#define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS)
|
||||
#define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - DBX500_NR_INTERNAL_IRQS)
|
||||
#define IRQ_BOARD_START NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
|
||||
#define IRQ_GPIO_END NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
|
||||
|
||||
#define IRQ_SOC_START IRQ_GPIO_END
|
||||
/* This will be overridden by SoC-specific irq headers */
|
||||
#define IRQ_SOC_END IRQ_SOC_START
|
||||
|
||||
#include <mach/irqs-db5500.h>
|
||||
#include <mach/irqs-db8500.h>
|
||||
|
||||
#define IRQ_BOARD_START IRQ_SOC_END
|
||||
/* This will be overridden by board-specific irq headers */
|
||||
#define IRQ_BOARD_END IRQ_BOARD_START
|
||||
#define IRQ_BOARD_END IRQ_BOARD_START
|
||||
|
||||
#ifdef CONFIG_MACH_U8500
|
||||
#include <mach/irqs-board-mop500.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* After the board specific IRQ:s we reserve a range of IRQ:s in which virtual
|
||||
* IRQ:s representing modem IRQ:s can be allocated
|
||||
*/
|
||||
#define IRQ_MODEM_EVENTS_BASE (IRQ_BOARD_END + 1)
|
||||
#define IRQ_MODEM_EVENTS_NBR 72
|
||||
#define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR)
|
||||
#ifdef CONFIG_MACH_U5500
|
||||
#include <mach/irqs-board-u5500.h>
|
||||
#endif
|
||||
|
||||
/* List of virtual IRQ:s that are allocated from the range above */
|
||||
#define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43)
|
||||
#define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45)
|
||||
#define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41)
|
||||
|
||||
#define NR_IRQS IRQ_MODEM_EVENTS_END
|
||||
#define NR_IRQS IRQ_BOARD_END
|
||||
|
||||
#endif /* ASM_ARCH_IRQS_H */
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) STMicroelectronics 2009
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Author: Sundar Iyer <sundar.iyer@stericsson.com>
|
||||
* Author: Martin Persson <martin.persson@stericsson.com>
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
*
|
||||
* PRCM Unit definitions
|
||||
*/
|
||||
|
||||
#ifndef __MACH_PRCMU_DEFS_H
|
||||
#define __MACH_PRCMU_DEFS_H
|
||||
|
||||
enum prcmu_cpu_opp {
|
||||
CPU_OPP_INIT = 0x00,
|
||||
CPU_OPP_NO_CHANGE = 0x01,
|
||||
CPU_OPP_100 = 0x02,
|
||||
CPU_OPP_50 = 0x03,
|
||||
CPU_OPP_MAX = 0x04,
|
||||
CPU_OPP_EXT_CLK = 0x07
|
||||
};
|
||||
enum prcmu_ape_opp {
|
||||
APE_OPP_NO_CHANGE = 0x00,
|
||||
APE_OPP_100 = 0x02,
|
||||
APE_OPP_50 = 0x03,
|
||||
};
|
||||
|
||||
#endif /* __MACH_PRCMU_DEFS_H */
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) STMicroelectronics 2009
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
|
||||
* Author: Sundar Iyer <sundar.iyer@stericsson.com>
|
||||
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
*
|
||||
* PRCM Unit f/w API
|
||||
*/
|
||||
#ifndef __MACH_PRCMU_H
|
||||
#define __MACH_PRCMU_H
|
||||
#include <mach/prcmu-defs.h>
|
||||
|
||||
void __init prcmu_early_init(void);
|
||||
int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
|
||||
int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
|
||||
int prcmu_set_ape_opp(enum prcmu_ape_opp opp);
|
||||
int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp);
|
||||
int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp,
|
||||
enum prcmu_cpu_opp cpu_opp);
|
||||
int prcmu_get_ape_opp(void);
|
||||
int prcmu_get_cpu_opp(void);
|
||||
bool prcmu_has_arm_maxopp(void);
|
||||
|
||||
#endif /* __MACH_PRCMU_H */
|
@ -1,394 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) STMicroelectronics 2009
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
* Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
|
||||
* Author: Sundar Iyer <sundar.iyer@stericsson.com>
|
||||
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
|
||||
*
|
||||
* U8500 PRCM Unit interface driver
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/prcmu-regs.h>
|
||||
#include <mach/prcmu-defs.h>
|
||||
|
||||
/* Global var to runtime determine TCDM base for v2 or v1 */
|
||||
static __iomem void *tcdm_base;
|
||||
|
||||
#define _MBOX_HEADER (tcdm_base + 0xFE8)
|
||||
#define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0)
|
||||
|
||||
#define REQ_MB1 (tcdm_base + 0xFD0)
|
||||
#define REQ_MB5 (tcdm_base + 0xE44)
|
||||
|
||||
#define REQ_MB1_ARMOPP (REQ_MB1 + 0x0)
|
||||
#define REQ_MB1_APEOPP (REQ_MB1 + 0x1)
|
||||
#define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2)
|
||||
|
||||
#define ACK_MB1 (tcdm_base + 0xE04)
|
||||
#define ACK_MB5 (tcdm_base + 0xDF4)
|
||||
|
||||
#define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0)
|
||||
#define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1)
|
||||
|
||||
#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
|
||||
#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
|
||||
#define REQ_MB5_I2C_REG (REQ_MB5 + 2)
|
||||
#define REQ_MB5_I2C_VAL (REQ_MB5 + 3)
|
||||
|
||||
#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
|
||||
#define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
|
||||
|
||||
#define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4)
|
||||
#define PRCM_AVS_ISMODEENABLE 7
|
||||
#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE)
|
||||
|
||||
#define I2C_WRITE(slave) \
|
||||
(((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0))
|
||||
#define I2C_READ(slave) \
|
||||
(((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0))
|
||||
#define I2C_STOP_EN BIT(3)
|
||||
|
||||
enum mb1_h {
|
||||
MB1H_ARM_OPP = 1,
|
||||
MB1H_APE_OPP,
|
||||
MB1H_ARM_APE_OPP,
|
||||
};
|
||||
|
||||
static struct {
|
||||
struct mutex lock;
|
||||
struct completion work;
|
||||
struct {
|
||||
u8 arm_opp;
|
||||
u8 ape_opp;
|
||||
u8 arm_status;
|
||||
u8 ape_status;
|
||||
} ack;
|
||||
} mb1_transfer;
|
||||
|
||||
enum ack_mb5_status {
|
||||
I2C_WR_OK = 0x01,
|
||||
I2C_RD_OK = 0x02,
|
||||
};
|
||||
|
||||
#define MBOX_BIT BIT
|
||||
#define NUM_MBOX 8
|
||||
|
||||
static struct {
|
||||
struct mutex lock;
|
||||
struct completion work;
|
||||
bool failed;
|
||||
struct {
|
||||
u8 status;
|
||||
u8 value;
|
||||
} ack;
|
||||
} mb5_transfer;
|
||||
|
||||
/**
|
||||
* prcmu_abb_read() - Read register value(s) from the ABB.
|
||||
* @slave: The I2C slave address.
|
||||
* @reg: The (start) register address.
|
||||
* @value: The read out value(s).
|
||||
* @size: The number of registers to read.
|
||||
*
|
||||
* Reads register value(s) from the ABB.
|
||||
* @size has to be 1 for the current firmware version.
|
||||
*/
|
||||
int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (size != 1)
|
||||
return -EINVAL;
|
||||
|
||||
r = mutex_lock_interruptible(&mb5_transfer.lock);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
|
||||
cpu_relax();
|
||||
|
||||
writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
|
||||
writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
|
||||
writeb(reg, REQ_MB5_I2C_REG);
|
||||
|
||||
writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
|
||||
if (!wait_for_completion_timeout(&mb5_transfer.work,
|
||||
msecs_to_jiffies(500))) {
|
||||
pr_err("prcmu: prcmu_abb_read timed out.\n");
|
||||
r = -EIO;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
|
||||
if (!r)
|
||||
*value = mb5_transfer.ack.value;
|
||||
|
||||
unlock_and_return:
|
||||
mutex_unlock(&mb5_transfer.lock);
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(prcmu_abb_read);
|
||||
|
||||
/**
|
||||
* prcmu_abb_write() - Write register value(s) to the ABB.
|
||||
* @slave: The I2C slave address.
|
||||
* @reg: The (start) register address.
|
||||
* @value: The value(s) to write.
|
||||
* @size: The number of registers to write.
|
||||
*
|
||||
* Reads register value(s) from the ABB.
|
||||
* @size has to be 1 for the current firmware version.
|
||||
*/
|
||||
int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (size != 1)
|
||||
return -EINVAL;
|
||||
|
||||
r = mutex_lock_interruptible(&mb5_transfer.lock);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
||||
while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
|
||||
cpu_relax();
|
||||
|
||||
writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP);
|
||||
writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
|
||||
writeb(reg, REQ_MB5_I2C_REG);
|
||||
writeb(*value, REQ_MB5_I2C_VAL);
|
||||
|
||||
writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
|
||||
if (!wait_for_completion_timeout(&mb5_transfer.work,
|
||||
msecs_to_jiffies(500))) {
|
||||
pr_err("prcmu: prcmu_abb_write timed out.\n");
|
||||
r = -EIO;
|
||||
goto unlock_and_return;
|
||||
}
|
||||
r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
|
||||
|
||||
unlock_and_return:
|
||||
mutex_unlock(&mb5_transfer.lock);
|
||||
return r;
|
||||
}
|
||||
EXPORT_SYMBOL(prcmu_abb_write);
|
||||
|
||||
static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp,
|
||||
enum prcmu_cpu_opp cpu_opp)
|
||||
{
|
||||
bool do_ape;
|
||||
bool do_arm;
|
||||
int err = 0;
|
||||
|
||||
do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP));
|
||||
do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP));
|
||||
|
||||
mutex_lock(&mb1_transfer.lock);
|
||||
|
||||
while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
|
||||
cpu_relax();
|
||||
|
||||
writeb(0, MBOX_HEADER_REQ_MB0);
|
||||
writeb(cpu_opp, REQ_MB1_ARMOPP);
|
||||
writeb(ape_opp, REQ_MB1_APEOPP);
|
||||
writeb(0, REQ_MB1_BOOSTOPP);
|
||||
writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);
|
||||
wait_for_completion(&mb1_transfer.work);
|
||||
if ((do_ape) && (mb1_transfer.ack.ape_status != 0))
|
||||
err = -EIO;
|
||||
if ((do_arm) && (mb1_transfer.ack.arm_status != 0))
|
||||
err = -EIO;
|
||||
|
||||
mutex_unlock(&mb1_transfer.lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* prcmu_set_ape_opp() - Set the OPP of the APE.
|
||||
* @opp: The OPP to set.
|
||||
*
|
||||
* This function sets the OPP of the APE.
|
||||
*/
|
||||
int prcmu_set_ape_opp(enum prcmu_ape_opp opp)
|
||||
{
|
||||
return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE);
|
||||
}
|
||||
EXPORT_SYMBOL(prcmu_set_ape_opp);
|
||||
|
||||
/**
|
||||
* prcmu_set_cpu_opp() - Set the OPP of the CPU.
|
||||
* @opp: The OPP to set.
|
||||
*
|
||||
* This function sets the OPP of the CPU.
|
||||
*/
|
||||
int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp)
|
||||
{
|
||||
return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp);
|
||||
}
|
||||
EXPORT_SYMBOL(prcmu_set_cpu_opp);
|
||||
|
||||
/**
|
||||
* prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU.
|
||||
* @ape_opp: The APE OPP to set.
|
||||
* @cpu_opp: The CPU OPP to set.
|
||||
*
|
||||
* This function sets the OPPs of the APE and the CPU.
|
||||
*/
|
||||
int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp,
|
||||
enum prcmu_cpu_opp cpu_opp)
|
||||
{
|
||||
return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp);
|
||||
}
|
||||
EXPORT_SYMBOL(prcmu_set_ape_cpu_opps);
|
||||
|
||||
/**
|
||||
* prcmu_get_ape_opp() - Get the OPP of the APE.
|
||||
*
|
||||
* This function gets the OPP of the APE.
|
||||
*/
|
||||
enum prcmu_ape_opp prcmu_get_ape_opp(void)
|
||||
{
|
||||
return readb(ACK_MB1_CURR_APEOPP);
|
||||
}
|
||||
EXPORT_SYMBOL(prcmu_get_ape_opp);
|
||||
|
||||
/**
|
||||
* prcmu_get_cpu_opp() - Get the OPP of the CPU.
|
||||
*
|
||||
* This function gets the OPP of the CPU. The OPP is specified in %%.
|
||||
* PRCMU_OPP_EXT is a special OPP value, not specified in %%.
|
||||
*/
|
||||
int prcmu_get_cpu_opp(void)
|
||||
{
|
||||
return readb(ACK_MB1_CURR_ARMOPP);
|
||||
}
|
||||
EXPORT_SYMBOL(prcmu_get_cpu_opp);
|
||||
|
||||
bool prcmu_has_arm_maxopp(void)
|
||||
{
|
||||
return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK)
|
||||
== PRCM_AVS_ISMODEENABLE_MASK;
|
||||
}
|
||||
|
||||
static void read_mailbox_0(void)
|
||||
{
|
||||
writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void read_mailbox_1(void)
|
||||
{
|
||||
mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP);
|
||||
mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP);
|
||||
complete(&mb1_transfer.work);
|
||||
writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void read_mailbox_2(void)
|
||||
{
|
||||
writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void read_mailbox_3(void)
|
||||
{
|
||||
writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void read_mailbox_4(void)
|
||||
{
|
||||
writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void read_mailbox_5(void)
|
||||
{
|
||||
mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS);
|
||||
mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL);
|
||||
complete(&mb5_transfer.work);
|
||||
writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void read_mailbox_6(void)
|
||||
{
|
||||
writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void read_mailbox_7(void)
|
||||
{
|
||||
writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
|
||||
}
|
||||
|
||||
static void (* const read_mailbox[NUM_MBOX])(void) = {
|
||||
read_mailbox_0,
|
||||
read_mailbox_1,
|
||||
read_mailbox_2,
|
||||
read_mailbox_3,
|
||||
read_mailbox_4,
|
||||
read_mailbox_5,
|
||||
read_mailbox_6,
|
||||
read_mailbox_7
|
||||
};
|
||||
|
||||
static irqreturn_t prcmu_irq_handler(int irq, void *data)
|
||||
{
|
||||
u32 bits;
|
||||
u8 n;
|
||||
|
||||
bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1));
|
||||
if (unlikely(!bits))
|
||||
return IRQ_NONE;
|
||||
|
||||
for (n = 0; bits; n++) {
|
||||
if (bits & MBOX_BIT(n)) {
|
||||
bits -= MBOX_BIT(n);
|
||||
read_mailbox[n]();
|
||||
}
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void __init prcmu_early_init(void)
|
||||
{
|
||||
if (cpu_is_u8500v11() || cpu_is_u8500ed()) {
|
||||
tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1);
|
||||
} else if (cpu_is_u8500v2()) {
|
||||
tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
|
||||
} else {
|
||||
pr_err("prcmu: Unsupported chip version\n");
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static int __init prcmu_init(void)
|
||||
{
|
||||
if (cpu_is_u8500ed()) {
|
||||
pr_err("prcmu: Unsupported chip version\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_init(&mb1_transfer.lock);
|
||||
init_completion(&mb1_transfer.work);
|
||||
mutex_init(&mb5_transfer.lock);
|
||||
init_completion(&mb5_transfer.work);
|
||||
|
||||
/* Clean up the mailbox interrupts after pre-kernel code. */
|
||||
writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
|
||||
|
||||
return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0,
|
||||
"prcmu", NULL);
|
||||
}
|
||||
|
||||
arch_initcall(prcmu_init);
|
@ -39,3 +39,5 @@ obj-$(CONFIG_X86_CPUFREQ_NFORCE2) += cpufreq-nforce2.o
|
||||
|
||||
##################################################################################d
|
||||
|
||||
# ARM SoC drivers
|
||||
obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
|
||||
|
169
drivers/cpufreq/db8500-cpufreq.c
Normal file
169
drivers/cpufreq/db8500-cpufreq.c
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) STMicroelectronics 2009
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
* Author: Sundar Iyer <sundar.iyer@stericsson.com>
|
||||
* Author: Martin Persson <martin.persson@stericsson.com>
|
||||
* Author: Jonas Aaberg <jonas.aberg@stericsson.com>
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mfd/db8500-prcmu.h>
|
||||
#include <mach/id.h>
|
||||
|
||||
static struct cpufreq_frequency_table freq_table[] = {
|
||||
[0] = {
|
||||
.index = 0,
|
||||
.frequency = 300000,
|
||||
},
|
||||
[1] = {
|
||||
.index = 1,
|
||||
.frequency = 600000,
|
||||
},
|
||||
[2] = {
|
||||
/* Used for MAX_OPP, if available */
|
||||
.index = 2,
|
||||
.frequency = CPUFREQ_TABLE_END,
|
||||
},
|
||||
[3] = {
|
||||
.index = 3,
|
||||
.frequency = CPUFREQ_TABLE_END,
|
||||
},
|
||||
};
|
||||
|
||||
static enum arm_opp idx2opp[] = {
|
||||
ARM_50_OPP,
|
||||
ARM_100_OPP,
|
||||
ARM_MAX_OPP
|
||||
};
|
||||
|
||||
static struct freq_attr *db8500_cpufreq_attr[] = {
|
||||
&cpufreq_freq_attr_scaling_available_freqs,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int db8500_cpufreq_verify_speed(struct cpufreq_policy *policy)
|
||||
{
|
||||
return cpufreq_frequency_table_verify(policy, freq_table);
|
||||
}
|
||||
|
||||
static int db8500_cpufreq_target(struct cpufreq_policy *policy,
|
||||
unsigned int target_freq,
|
||||
unsigned int relation)
|
||||
{
|
||||
struct cpufreq_freqs freqs;
|
||||
unsigned int idx;
|
||||
|
||||
/* scale the target frequency to one of the extremes supported */
|
||||
if (target_freq < policy->cpuinfo.min_freq)
|
||||
target_freq = policy->cpuinfo.min_freq;
|
||||
if (target_freq > policy->cpuinfo.max_freq)
|
||||
target_freq = policy->cpuinfo.max_freq;
|
||||
|
||||
/* Lookup the next frequency */
|
||||
if (cpufreq_frequency_table_target
|
||||
(policy, freq_table, target_freq, relation, &idx)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
freqs.old = policy->cur;
|
||||
freqs.new = freq_table[idx].frequency;
|
||||
freqs.cpu = policy->cpu;
|
||||
|
||||
if (freqs.old == freqs.new)
|
||||
return 0;
|
||||
|
||||
/* pre-change notification */
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
|
||||
|
||||
/* request the PRCM unit for opp change */
|
||||
if (prcmu_set_arm_opp(idx2opp[idx])) {
|
||||
pr_err("db8500-cpufreq: Failed to set OPP level\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* post change notification */
|
||||
cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int db8500_cpufreq_getspeed(unsigned int cpu)
|
||||
{
|
||||
int i;
|
||||
/* request the prcm to get the current ARM opp */
|
||||
for (i = 0; prcmu_get_arm_opp() != idx2opp[i]; i++)
|
||||
;
|
||||
return freq_table[i].frequency;
|
||||
}
|
||||
|
||||
static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
|
||||
{
|
||||
int res;
|
||||
int i;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table));
|
||||
|
||||
if (cpu_is_u8500v2() && !prcmu_is_u8400()) {
|
||||
freq_table[0].frequency = 400000;
|
||||
freq_table[1].frequency = 800000;
|
||||
if (prcmu_has_arm_maxopp())
|
||||
freq_table[2].frequency = 1000000;
|
||||
}
|
||||
|
||||
/* get policy fields based on the table */
|
||||
res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
|
||||
if (!res)
|
||||
cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
|
||||
else {
|
||||
pr_err("db8500-cpufreq : Failed to read policy table\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
policy->min = policy->cpuinfo.min_freq;
|
||||
policy->max = policy->cpuinfo.max_freq;
|
||||
policy->cur = db8500_cpufreq_getspeed(policy->cpu);
|
||||
|
||||
for (i = 0; freq_table[i].frequency != policy->cur; i++)
|
||||
;
|
||||
|
||||
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
|
||||
|
||||
/*
|
||||
* FIXME : Need to take time measurement across the target()
|
||||
* function with no/some/all drivers in the notification
|
||||
* list.
|
||||
*/
|
||||
policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */
|
||||
|
||||
/* policy sharing between dual CPUs */
|
||||
cpumask_copy(policy->cpus, &cpu_present_map);
|
||||
|
||||
policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cpufreq_driver db8500_cpufreq_driver = {
|
||||
.flags = CPUFREQ_STICKY,
|
||||
.verify = db8500_cpufreq_verify_speed,
|
||||
.target = db8500_cpufreq_target,
|
||||
.get = db8500_cpufreq_getspeed,
|
||||
.init = db8500_cpufreq_init,
|
||||
.name = "DB8500",
|
||||
.attr = db8500_cpufreq_attr,
|
||||
};
|
||||
|
||||
static int __init db8500_cpufreq_register(void)
|
||||
{
|
||||
if (!cpu_is_u8500v20_or_later())
|
||||
return -ENODEV;
|
||||
|
||||
pr_info("cpufreq for DB8500 started\n");
|
||||
return cpufreq_register_driver(&db8500_cpufreq_driver);
|
||||
}
|
||||
device_initcall(db8500_cpufreq_register);
|
@ -538,7 +538,7 @@ config AB8500_CORE
|
||||
|
||||
config AB8500_I2C_CORE
|
||||
bool "AB8500 register access via PRCMU I2C"
|
||||
depends on AB8500_CORE && UX500_SOC_DB8500
|
||||
depends on AB8500_CORE && MFD_DB8500_PRCMU
|
||||
default y
|
||||
help
|
||||
This enables register access to the AB8500 chip via PRCMU I2C.
|
||||
@ -575,6 +575,26 @@ config AB3550_CORE
|
||||
LEDs, vibrator, system power and temperature, power management
|
||||
and ALSA sound.
|
||||
|
||||
config MFD_DB8500_PRCMU
|
||||
bool "ST-Ericsson DB8500 Power Reset Control Management Unit"
|
||||
depends on UX500_SOC_DB8500
|
||||
select MFD_CORE
|
||||
help
|
||||
Select this option to enable support for the DB8500 Power Reset
|
||||
and Control Management Unit. This is basically an autonomous
|
||||
system controller running an XP70 microprocessor, which is accessed
|
||||
through a register map.
|
||||
|
||||
config MFD_DB5500_PRCMU
|
||||
bool "ST-Ericsson DB5500 Power Reset Control Management Unit"
|
||||
depends on UX500_SOC_DB5500
|
||||
select MFD_CORE
|
||||
help
|
||||
Select this option to enable support for the DB5500 Power Reset
|
||||
and Control Management Unit. This is basically an autonomous
|
||||
system controller running an XP70 microprocessor, which is accessed
|
||||
through a register map.
|
||||
|
||||
config MFD_CS5535
|
||||
tristate "Support for CS5535 and CS5536 southbridge core functions"
|
||||
select MFD_CORE
|
||||
|
@ -74,9 +74,12 @@ obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
|
||||
obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
|
||||
obj-$(CONFIG_AB3550_CORE) += ab3550-core.o
|
||||
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
|
||||
obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o
|
||||
obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
|
||||
obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
|
||||
obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
|
||||
# ab8500-i2c need to come after db8500-prcmu (which provides the channel)
|
||||
obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o
|
||||
obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o
|
||||
obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
|
||||
obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
|
||||
obj-$(CONFIG_LPC_SCH) += lpc_sch.o
|
||||
|
@ -11,8 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/ab8500.h>
|
||||
|
||||
#include <mach/prcmu.h>
|
||||
#include <linux/mfd/db8500-prcmu.h>
|
||||
|
||||
static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
|
||||
{
|
||||
|
@ -15,11 +15,20 @@
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#define _PRCMU_BASE IO_ADDRESS(U8500_PRCMU_BASE)
|
||||
|
||||
#define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118)
|
||||
#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f
|
||||
#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf
|
||||
|
||||
#define PRCM_PLLARM_LOCKP (_PRCMU_BASE + 0x0a8)
|
||||
#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2
|
||||
|
||||
#define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114)
|
||||
#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1
|
||||
|
||||
#define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98)
|
||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1
|
||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100
|
||||
|
||||
#define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0)
|
||||
#define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4)
|
||||
#define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0)
|
||||
@ -28,7 +37,8 @@
|
||||
|
||||
/* ARM WFI Standby signal register */
|
||||
#define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130)
|
||||
#define PRCMU_IOCR (_PRCMU_BASE + 0x310)
|
||||
#define PRCM_IOCR (_PRCMU_BASE + 0x310)
|
||||
#define PRCM_IOCR_IOFORCE 0x1
|
||||
|
||||
/* CPU mailbox registers */
|
||||
#define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc)
|
||||
@ -37,6 +47,8 @@
|
||||
|
||||
/* Dual A9 core interrupt management unit registers */
|
||||
#define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328)
|
||||
#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ 0x1
|
||||
|
||||
#define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c)
|
||||
#define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c)
|
||||
#define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120)
|
||||
@ -74,14 +86,17 @@
|
||||
/* PRCMU clock/PLL/reset registers */
|
||||
#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500)
|
||||
#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504)
|
||||
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
|
||||
#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044)
|
||||
#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064)
|
||||
#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058)
|
||||
#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c)
|
||||
#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530)
|
||||
#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C)
|
||||
#define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508)
|
||||
#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4)
|
||||
#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8)
|
||||
#define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC)
|
||||
|
||||
/* ePOD and memory power signal control registers */
|
||||
#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410)
|
||||
@ -92,5 +107,9 @@
|
||||
|
||||
/* Miscellaneous unit registers */
|
||||
#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324)
|
||||
#define PRCM_GPIOCR (_PRCMU_BASE + 0x138)
|
||||
#define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800
|
||||
#define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1
|
||||
|
||||
#endif /* __MACH_PRCMU_REGS_H */
|
||||
|
||||
#endif /* __MACH_PRCMU__REGS_H */
|
448
drivers/mfd/db5500-prcmu.c
Normal file
448
drivers/mfd/db5500-prcmu.c
Normal file
@ -0,0 +1,448 @@
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
* Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
|
||||
*
|
||||
* U5500 PRCM Unit interface driver
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/db5500-prcmu.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/irqs.h>
|
||||
#include <mach/db5500-regs.h>
|
||||
#include "db5500-prcmu-regs.h"
|
||||
|
||||
#define _PRCM_MB_HEADER (tcdm_base + 0xFE8)
|
||||
#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0)
|
||||
#define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1)
|
||||
#define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2)
|
||||
#define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3)
|
||||
#define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4)
|
||||
#define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5)
|
||||
#define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6)
|
||||
#define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7)
|
||||
#define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8)
|
||||
#define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9)
|
||||
#define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa)
|
||||
#define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb)
|
||||
#define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc)
|
||||
#define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd)
|
||||
#define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe)
|
||||
#define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf)
|
||||
|
||||
/* Req Mailboxes */
|
||||
#define PRCM_REQ_MB0 (tcdm_base + 0xFD8)
|
||||
#define PRCM_REQ_MB1 (tcdm_base + 0xFCC)
|
||||
#define PRCM_REQ_MB2 (tcdm_base + 0xFC4)
|
||||
#define PRCM_REQ_MB3 (tcdm_base + 0xFC0)
|
||||
#define PRCM_REQ_MB4 (tcdm_base + 0xF98)
|
||||
#define PRCM_REQ_MB5 (tcdm_base + 0xF90)
|
||||
#define PRCM_REQ_MB6 (tcdm_base + 0xF8C)
|
||||
#define PRCM_REQ_MB7 (tcdm_base + 0xF84)
|
||||
|
||||
/* Ack Mailboxes */
|
||||
#define PRCM_ACK_MB0 (tcdm_base + 0xF38)
|
||||
#define PRCM_ACK_MB1 (tcdm_base + 0xF30)
|
||||
#define PRCM_ACK_MB2 (tcdm_base + 0xF24)
|
||||
#define PRCM_ACK_MB3 (tcdm_base + 0xF20)
|
||||
#define PRCM_ACK_MB4 (tcdm_base + 0xF1C)
|
||||
#define PRCM_ACK_MB5 (tcdm_base + 0xF14)
|
||||
#define PRCM_ACK_MB6 (tcdm_base + 0xF0C)
|
||||
#define PRCM_ACK_MB7 (tcdm_base + 0xF08)
|
||||
|
||||
enum mb_return_code {
|
||||
RC_SUCCESS,
|
||||
RC_FAIL,
|
||||
};
|
||||
|
||||
/* Mailbox 0 headers. */
|
||||
enum mb0_header {
|
||||
/* request */
|
||||
RMB0H_PWR_STATE_TRANS = 1,
|
||||
RMB0H_WAKE_UP_CFG,
|
||||
RMB0H_RD_WAKE_UP_ACK,
|
||||
/* acknowledge */
|
||||
AMB0H_WAKE_UP = 1,
|
||||
};
|
||||
|
||||
/* Mailbox 5 headers. */
|
||||
enum mb5_header {
|
||||
MB5H_I2C_WRITE = 1,
|
||||
MB5H_I2C_READ,
|
||||
};
|
||||
|
||||
/* Request mailbox 5 fields. */
|
||||
#define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0)
|
||||
#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1)
|
||||
#define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2)
|
||||
#define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4)
|
||||
|
||||
/* Acknowledge mailbox 5 fields. */
|
||||
#define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0)
|
||||
#define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4)
|
||||
|
||||
#define NUM_MB 8
|
||||
#define MBOX_BIT BIT
|
||||
#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1)
|
||||
|
||||
/*
|
||||
* Used by MCDE to setup all necessary PRCMU registers
|
||||
*/
|
||||
#define PRCMU_RESET_DSIPLL 0x00004000
|
||||
#define PRCMU_UNCLAMP_DSIPLL 0x00400800
|
||||
|
||||
/* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/
|
||||
#define PRCMU_DSI_CLOCK_SETTING 0x00000128
|
||||
/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */
|
||||
#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135
|
||||
#define PRCMU_PLLDSI_FREQ_SETTING 0x0004013C
|
||||
#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002
|
||||
#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000101
|
||||
#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101
|
||||
|
||||
#define PRCMU_ENABLE_PLLDSI 0x00000001
|
||||
#define PRCMU_DISABLE_PLLDSI 0x00000000
|
||||
|
||||
#define PRCMU_DSI_RESET_SW 0x00000003
|
||||
|
||||
#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3
|
||||
|
||||
/*
|
||||
* mb0_transfer - state needed for mailbox 0 communication.
|
||||
* @lock: The transaction lock.
|
||||
*/
|
||||
static struct {
|
||||
spinlock_t lock;
|
||||
} mb0_transfer;
|
||||
|
||||
/*
|
||||
* mb5_transfer - state needed for mailbox 5 communication.
|
||||
* @lock: The transaction lock.
|
||||
* @work: The transaction completion structure.
|
||||
* @ack: Reply ("acknowledge") data.
|
||||
*/
|
||||
static struct {
|
||||
struct mutex lock;
|
||||
struct completion work;
|
||||
struct {
|
||||
u8 header;
|
||||
u8 status;
|
||||
u8 value[4];
|
||||
} ack;
|
||||
} mb5_transfer;
|
||||
|
||||
/* PRCMU TCDM base IO address. */
|
||||
static __iomem void *tcdm_base;
|
||||
|
||||
/**
|
||||
* db5500_prcmu_abb_read() - Read register value(s) from the ABB.
|
||||
* @slave: The I2C slave address.
|
||||
* @reg: The (start) register address.
|
||||
* @value: The read out value(s).
|
||||
* @size: The number of registers to read.
|
||||
*
|
||||
* Reads register value(s) from the ABB.
|
||||
* @size has to be <= 4.
|
||||
*/
|
||||
int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((size < 1) || (4 < size))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mb5_transfer.lock);
|
||||
|
||||
while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
|
||||
cpu_relax();
|
||||
writeb(slave, PRCM_REQ_MB5_I2C_SLAVE);
|
||||
writeb(reg, PRCM_REQ_MB5_I2C_REG);
|
||||
writeb(size, PRCM_REQ_MB5_I2C_SIZE);
|
||||
writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER);
|
||||
|
||||
writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
|
||||
wait_for_completion(&mb5_transfer.work);
|
||||
|
||||
r = 0;
|
||||
if ((mb5_transfer.ack.header == MB5H_I2C_READ) &&
|
||||
(mb5_transfer.ack.status == RC_SUCCESS))
|
||||
memcpy(value, mb5_transfer.ack.value, (size_t)size);
|
||||
else
|
||||
r = -EIO;
|
||||
|
||||
mutex_unlock(&mb5_transfer.lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* db5500_prcmu_abb_write() - Write register value(s) to the ABB.
|
||||
* @slave: The I2C slave address.
|
||||
* @reg: The (start) register address.
|
||||
* @value: The value(s) to write.
|
||||
* @size: The number of registers to write.
|
||||
*
|
||||
* Writes register value(s) to the ABB.
|
||||
* @size has to be <= 4.
|
||||
*/
|
||||
int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((size < 1) || (4 < size))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mb5_transfer.lock);
|
||||
|
||||
while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
|
||||
cpu_relax();
|
||||
writeb(slave, PRCM_REQ_MB5_I2C_SLAVE);
|
||||
writeb(reg, PRCM_REQ_MB5_I2C_REG);
|
||||
writeb(size, PRCM_REQ_MB5_I2C_SIZE);
|
||||
memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size);
|
||||
writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER);
|
||||
|
||||
writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
|
||||
wait_for_completion(&mb5_transfer.work);
|
||||
|
||||
if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) &&
|
||||
(mb5_transfer.ack.status == RC_SUCCESS))
|
||||
r = 0;
|
||||
else
|
||||
r = -EIO;
|
||||
|
||||
mutex_unlock(&mb5_transfer.lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int db5500_prcmu_enable_dsipll(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Enable DSIPLL_RESETN resets */
|
||||
writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR);
|
||||
/* Unclamp DSIPLL in/out */
|
||||
writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR);
|
||||
/* Set DSI PLL FREQ */
|
||||
writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ);
|
||||
writel(PRCMU_DSI_PLLOUT_SEL_SETTING,
|
||||
PRCM_DSI_PLLOUT_SEL);
|
||||
/* Enable Escape clocks */
|
||||
writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
|
||||
|
||||
/* Start DSI PLL */
|
||||
writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
|
||||
/* Reset DSI PLL */
|
||||
writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET);
|
||||
for (i = 0; i < 10; i++) {
|
||||
if ((readl(PRCM_PLLDSI_LOCKP) &
|
||||
PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED)
|
||||
break;
|
||||
udelay(100);
|
||||
}
|
||||
/* Release DSIPLL_RESETN */
|
||||
writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int db5500_prcmu_disable_dsipll(void)
|
||||
{
|
||||
/* Disable dsi pll */
|
||||
writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
|
||||
/* Disable escapeclock */
|
||||
writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int db5500_prcmu_set_display_clocks(void)
|
||||
{
|
||||
/* HDMI and TVCLK Should be handled somewhere else */
|
||||
/* PLLDIV=8, PLLSW=2, CLKEN=1 */
|
||||
writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT);
|
||||
/* PLLDIV=14, PLLSW=2, CLKEN=1 */
|
||||
writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ack_dbb_wakeup(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mb0_transfer.lock, flags);
|
||||
|
||||
while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))
|
||||
cpu_relax();
|
||||
|
||||
writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER);
|
||||
writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET);
|
||||
|
||||
spin_unlock_irqrestore(&mb0_transfer.lock, flags);
|
||||
}
|
||||
|
||||
static inline void print_unknown_header_warning(u8 n, u8 header)
|
||||
{
|
||||
pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n",
|
||||
header, n);
|
||||
}
|
||||
|
||||
static bool read_mailbox_0(void)
|
||||
{
|
||||
bool r;
|
||||
u8 header;
|
||||
|
||||
header = readb(PRCM_ACK_MB0_HEADER);
|
||||
switch (header) {
|
||||
case AMB0H_WAKE_UP:
|
||||
r = true;
|
||||
break;
|
||||
default:
|
||||
print_unknown_header_warning(0, header);
|
||||
r = false;
|
||||
break;
|
||||
}
|
||||
writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool read_mailbox_1(void)
|
||||
{
|
||||
writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_mailbox_2(void)
|
||||
{
|
||||
writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_mailbox_3(void)
|
||||
{
|
||||
writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_mailbox_4(void)
|
||||
{
|
||||
writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_mailbox_5(void)
|
||||
{
|
||||
u8 header;
|
||||
|
||||
header = readb(PRCM_ACK_MB5_HEADER);
|
||||
switch (header) {
|
||||
case MB5H_I2C_READ:
|
||||
memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4);
|
||||
case MB5H_I2C_WRITE:
|
||||
mb5_transfer.ack.header = header;
|
||||
mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE);
|
||||
complete(&mb5_transfer.work);
|
||||
break;
|
||||
default:
|
||||
print_unknown_header_warning(5, header);
|
||||
break;
|
||||
}
|
||||
writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_mailbox_6(void)
|
||||
{
|
||||
writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool read_mailbox_7(void)
|
||||
{
|
||||
writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool (* const read_mailbox[NUM_MB])(void) = {
|
||||
read_mailbox_0,
|
||||
read_mailbox_1,
|
||||
read_mailbox_2,
|
||||
read_mailbox_3,
|
||||
read_mailbox_4,
|
||||
read_mailbox_5,
|
||||
read_mailbox_6,
|
||||
read_mailbox_7
|
||||
};
|
||||
|
||||
static irqreturn_t prcmu_irq_handler(int irq, void *data)
|
||||
{
|
||||
u32 bits;
|
||||
u8 n;
|
||||
irqreturn_t r;
|
||||
|
||||
bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS);
|
||||
if (unlikely(!bits))
|
||||
return IRQ_NONE;
|
||||
|
||||
r = IRQ_HANDLED;
|
||||
for (n = 0; bits; n++) {
|
||||
if (bits & MBOX_BIT(n)) {
|
||||
bits -= MBOX_BIT(n);
|
||||
if (read_mailbox[n]())
|
||||
r = IRQ_WAKE_THREAD;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static irqreturn_t prcmu_irq_thread_fn(int irq, void *data)
|
||||
{
|
||||
ack_dbb_wakeup();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
void __init db5500_prcmu_early_init(void)
|
||||
{
|
||||
tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE);
|
||||
spin_lock_init(&mb0_transfer.lock);
|
||||
mutex_init(&mb5_transfer.lock);
|
||||
init_completion(&mb5_transfer.work);
|
||||
}
|
||||
|
||||
/**
|
||||
* prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
|
||||
*
|
||||
*/
|
||||
int __init db5500_prcmu_init(void)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (ux500_is_svp() || !cpu_is_u5500())
|
||||
return -ENODEV;
|
||||
|
||||
/* Clean up the mailbox interrupts after pre-kernel code. */
|
||||
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLEAR);
|
||||
|
||||
r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler,
|
||||
prcmu_irq_thread_fn, 0, "prcmu", NULL);
|
||||
if (r < 0) {
|
||||
pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(db5500_prcmu_init);
|
166
drivers/mfd/db8500-prcmu-regs.h
Normal file
166
drivers/mfd/db8500-prcmu-regs.h
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (C) STMicroelectronics 2009
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
|
||||
* Author: Sundar Iyer <sundar.iyer@stericsson.com>
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
*
|
||||
* PRCM Unit registers
|
||||
*/
|
||||
#ifndef __DB8500_PRCMU_REGS_H
|
||||
#define __DB8500_PRCMU_REGS_H
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <mach/hardware.h>
|
||||
|
||||
#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))
|
||||
|
||||
#define PRCM_ARM_PLLDIVPS 0x118
|
||||
#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE BITS(0, 5)
|
||||
#define PRCM_ARM_PLLDIVPS_MAX_MASK 0xF
|
||||
|
||||
#define PRCM_PLLARM_LOCKP 0x0A8
|
||||
#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 BIT(1)
|
||||
|
||||
#define PRCM_ARM_CHGCLKREQ 0x114
|
||||
#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0)
|
||||
|
||||
#define PRCM_PLLARM_ENABLE 0x98
|
||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE BIT(0)
|
||||
#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON BIT(8)
|
||||
|
||||
#define PRCM_ARMCLKFIX_MGT 0x0
|
||||
#define PRCM_A9_RESETN_CLR 0x1f4
|
||||
#define PRCM_A9_RESETN_SET 0x1f0
|
||||
#define PRCM_ARM_LS_CLAMP 0x30C
|
||||
#define PRCM_SRAM_A9 0x308
|
||||
|
||||
/* ARM WFI Standby signal register */
|
||||
#define PRCM_ARM_WFI_STANDBY 0x130
|
||||
#define PRCM_IOCR 0x310
|
||||
#define PRCM_IOCR_IOFORCE BIT(0)
|
||||
|
||||
/* CPU mailbox registers */
|
||||
#define PRCM_MBOX_CPU_VAL 0x0FC
|
||||
#define PRCM_MBOX_CPU_SET 0x100
|
||||
|
||||
/* Dual A9 core interrupt management unit registers */
|
||||
#define PRCM_A9_MASK_REQ 0x328
|
||||
#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ BIT(0)
|
||||
|
||||
#define PRCM_A9_MASK_ACK 0x32C
|
||||
#define PRCM_ARMITMSK31TO0 0x11C
|
||||
#define PRCM_ARMITMSK63TO32 0x120
|
||||
#define PRCM_ARMITMSK95TO64 0x124
|
||||
#define PRCM_ARMITMSK127TO96 0x128
|
||||
#define PRCM_POWER_STATE_VAL 0x25C
|
||||
#define PRCM_ARMITVAL31TO0 0x260
|
||||
#define PRCM_ARMITVAL63TO32 0x264
|
||||
#define PRCM_ARMITVAL95TO64 0x268
|
||||
#define PRCM_ARMITVAL127TO96 0x26C
|
||||
|
||||
#define PRCM_HOSTACCESS_REQ 0x334
|
||||
#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ BIT(0)
|
||||
|
||||
#define PRCM_ARM_IT1_CLR 0x48C
|
||||
#define PRCM_ARM_IT1_VAL 0x494
|
||||
|
||||
#define PRCM_ITSTATUS0 0x148
|
||||
#define PRCM_ITSTATUS1 0x150
|
||||
#define PRCM_ITSTATUS2 0x158
|
||||
#define PRCM_ITSTATUS3 0x160
|
||||
#define PRCM_ITSTATUS4 0x168
|
||||
#define PRCM_ITSTATUS5 0x484
|
||||
#define PRCM_ITCLEAR5 0x488
|
||||
#define PRCM_ARMIT_MASKXP70_IT 0x1018
|
||||
|
||||
/* System reset register */
|
||||
#define PRCM_APE_SOFTRST 0x228
|
||||
|
||||
/* Level shifter and clamp control registers */
|
||||
#define PRCM_MMIP_LS_CLAMP_SET 0x420
|
||||
#define PRCM_MMIP_LS_CLAMP_CLR 0x424
|
||||
|
||||
/* PRCMU HW semaphore */
|
||||
#define PRCM_SEM 0x400
|
||||
#define PRCM_SEM_PRCM_SEM BIT(0)
|
||||
|
||||
/* PRCMU clock/PLL/reset registers */
|
||||
#define PRCM_PLLDSI_FREQ 0x500
|
||||
#define PRCM_PLLDSI_ENABLE 0x504
|
||||
#define PRCM_PLLDSI_LOCKP 0x508
|
||||
#define PRCM_DSI_PLLOUT_SEL 0x530
|
||||
#define PRCM_DSITVCLK_DIV 0x52C
|
||||
#define PRCM_APE_RESETN_SET 0x1E4
|
||||
#define PRCM_APE_RESETN_CLR 0x1E8
|
||||
|
||||
#define PRCM_TCR 0x1C8
|
||||
#define PRCM_TCR_TENSEL_MASK BITS(0, 7)
|
||||
#define PRCM_TCR_STOP_TIMERS BIT(16)
|
||||
#define PRCM_TCR_DOZE_MODE BIT(17)
|
||||
|
||||
#define PRCM_CLKOCR 0x1CC
|
||||
#define PRCM_CLKOCR_CLKODIV0_SHIFT 0
|
||||
#define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5)
|
||||
#define PRCM_CLKOCR_CLKOSEL0_SHIFT 6
|
||||
#define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8)
|
||||
#define PRCM_CLKOCR_CLKODIV1_SHIFT 16
|
||||
#define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21)
|
||||
#define PRCM_CLKOCR_CLKOSEL1_SHIFT 22
|
||||
#define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24)
|
||||
#define PRCM_CLKOCR_CLK1TYPE BIT(28)
|
||||
|
||||
#define PRCM_SGACLK_MGT 0x014
|
||||
#define PRCM_UARTCLK_MGT 0x018
|
||||
#define PRCM_MSP02CLK_MGT 0x01C
|
||||
#define PRCM_MSP1CLK_MGT 0x288
|
||||
#define PRCM_I2CCLK_MGT 0x020
|
||||
#define PRCM_SDMMCCLK_MGT 0x024
|
||||
#define PRCM_SLIMCLK_MGT 0x028
|
||||
#define PRCM_PER1CLK_MGT 0x02C
|
||||
#define PRCM_PER2CLK_MGT 0x030
|
||||
#define PRCM_PER3CLK_MGT 0x034
|
||||
#define PRCM_PER5CLK_MGT 0x038
|
||||
#define PRCM_PER6CLK_MGT 0x03C
|
||||
#define PRCM_PER7CLK_MGT 0x040
|
||||
#define PRCM_LCDCLK_MGT 0x044
|
||||
#define PRCM_BMLCLK_MGT 0x04C
|
||||
#define PRCM_HSITXCLK_MGT 0x050
|
||||
#define PRCM_HSIRXCLK_MGT 0x054
|
||||
#define PRCM_HDMICLK_MGT 0x058
|
||||
#define PRCM_APEATCLK_MGT 0x05C
|
||||
#define PRCM_APETRACECLK_MGT 0x060
|
||||
#define PRCM_MCDECLK_MGT 0x064
|
||||
#define PRCM_IPI2CCLK_MGT 0x068
|
||||
#define PRCM_DSIALTCLK_MGT 0x06C
|
||||
#define PRCM_DMACLK_MGT 0x074
|
||||
#define PRCM_B2R2CLK_MGT 0x078
|
||||
#define PRCM_TVCLK_MGT 0x07C
|
||||
#define PRCM_UNIPROCLK_MGT 0x278
|
||||
#define PRCM_SSPCLK_MGT 0x280
|
||||
#define PRCM_RNGCLK_MGT 0x284
|
||||
#define PRCM_UICCCLK_MGT 0x27C
|
||||
|
||||
#define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4)
|
||||
#define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7)
|
||||
#define PRCM_CLK_MGT_CLKEN BIT(8)
|
||||
|
||||
/* ePOD and memory power signal control registers */
|
||||
#define PRCM_EPOD_C_SET 0x410
|
||||
#define PRCM_SRAM_LS_SLEEP 0x304
|
||||
|
||||
/* Debug power control unit registers */
|
||||
#define PRCM_POWER_STATE_SET 0x254
|
||||
|
||||
/* Miscellaneous unit registers */
|
||||
#define PRCM_DSI_SW_RESET 0x324
|
||||
#define PRCM_GPIOCR 0x138
|
||||
|
||||
/* GPIOCR register */
|
||||
#define PRCM_GPIOCR_SPI2_SELECT BIT(23)
|
||||
|
||||
#define PRCM_DDR_SUBSYS_APE_MINBW 0x438
|
||||
|
||||
#endif /* __DB8500_PRCMU_REGS_H */
|
2069
drivers/mfd/db8500-prcmu.c
Normal file
2069
drivers/mfd/db8500-prcmu.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -274,6 +274,13 @@ config REGULATOR_AB8500
|
||||
This driver supports the regulators found on the ST-Ericsson mixed
|
||||
signal AB8500 PMIC
|
||||
|
||||
config REGULATOR_DB8500_PRCMU
|
||||
bool "ST-Ericsson DB8500 Voltage Domain Regulators"
|
||||
depends on MFD_DB8500_PRCMU
|
||||
help
|
||||
This driver supports the voltage domain regulators controlled by the
|
||||
DB8500 PRCMU
|
||||
|
||||
config REGULATOR_TPS6586X
|
||||
tristate "TI TPS6586X Power regulators"
|
||||
depends on MFD_TPS6586X
|
||||
|
@ -41,5 +41,6 @@ obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
|
||||
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o
|
||||
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
|
||||
|
||||
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
|
||||
|
558
drivers/regulator/db8500-prcmu.c
Normal file
558
drivers/regulator/db8500-prcmu.c
Normal file
@ -0,0 +1,558 @@
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
* Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
|
||||
* Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
|
||||
*
|
||||
* Power domain regulators on DB8500
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/db8500-prcmu.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/db8500-prcmu.h>
|
||||
|
||||
/*
|
||||
* power state reference count
|
||||
*/
|
||||
static int power_state_active_cnt; /* will initialize to zero */
|
||||
static DEFINE_SPINLOCK(power_state_active_lock);
|
||||
|
||||
static void power_state_active_enable(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&power_state_active_lock, flags);
|
||||
power_state_active_cnt++;
|
||||
spin_unlock_irqrestore(&power_state_active_lock, flags);
|
||||
}
|
||||
|
||||
static int power_state_active_disable(void)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&power_state_active_lock, flags);
|
||||
if (power_state_active_cnt <= 0) {
|
||||
pr_err("power state: unbalanced enable/disable calls\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
power_state_active_cnt--;
|
||||
out:
|
||||
spin_unlock_irqrestore(&power_state_active_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Exported interface for CPUIdle only. This function is called when interrupts
|
||||
* are turned off. Hence, no locking.
|
||||
*/
|
||||
int power_state_active_is_enabled(void)
|
||||
{
|
||||
return (power_state_active_cnt > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct db8500_regulator_info - db8500 regulator information
|
||||
* @dev: device pointer
|
||||
* @desc: regulator description
|
||||
* @rdev: regulator device pointer
|
||||
* @is_enabled: status of the regulator
|
||||
* @epod_id: id for EPOD (power domain)
|
||||
* @is_ramret: RAM retention switch for EPOD (power domain)
|
||||
* @operating_point: operating point (only for vape, to be removed)
|
||||
*
|
||||
*/
|
||||
struct db8500_regulator_info {
|
||||
struct device *dev;
|
||||
struct regulator_desc desc;
|
||||
struct regulator_dev *rdev;
|
||||
bool is_enabled;
|
||||
u16 epod_id;
|
||||
bool is_ramret;
|
||||
bool exclude_from_power_state;
|
||||
unsigned int operating_point;
|
||||
};
|
||||
|
||||
static int db8500_regulator_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
if (info == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
|
||||
info->desc.name);
|
||||
|
||||
info->is_enabled = true;
|
||||
if (!info->exclude_from_power_state)
|
||||
power_state_active_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int db8500_regulator_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int ret = 0;
|
||||
|
||||
if (info == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
|
||||
info->desc.name);
|
||||
|
||||
info->is_enabled = false;
|
||||
if (!info->exclude_from_power_state)
|
||||
ret = power_state_active_disable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
if (info == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"
|
||||
" %i\n", info->desc.name, info->is_enabled);
|
||||
|
||||
return info->is_enabled;
|
||||
}
|
||||
|
||||
/* db8500 regulator operations */
|
||||
static struct regulator_ops db8500_regulator_ops = {
|
||||
.enable = db8500_regulator_enable,
|
||||
.disable = db8500_regulator_disable,
|
||||
.is_enabled = db8500_regulator_is_enabled,
|
||||
};
|
||||
|
||||
/*
|
||||
* EPOD control
|
||||
*/
|
||||
static bool epod_on[NUM_EPOD_ID];
|
||||
static bool epod_ramret[NUM_EPOD_ID];
|
||||
|
||||
static int enable_epod(u16 epod_id, bool ramret)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ramret) {
|
||||
if (!epod_on[epod_id]) {
|
||||
ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
epod_ramret[epod_id] = true;
|
||||
} else {
|
||||
ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
epod_on[epod_id] = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disable_epod(u16 epod_id, bool ramret)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (ramret) {
|
||||
if (!epod_on[epod_id]) {
|
||||
ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
epod_ramret[epod_id] = false;
|
||||
} else {
|
||||
if (epod_ramret[epod_id]) {
|
||||
ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
epod_on[epod_id] = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Regulator switch
|
||||
*/
|
||||
static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
if (info == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",
|
||||
info->desc.name);
|
||||
|
||||
ret = enable_epod(info->epod_id, info->is_ramret);
|
||||
if (ret < 0) {
|
||||
dev_err(rdev_get_dev(rdev),
|
||||
"regulator-switch-%s-enable: prcmu call failed\n",
|
||||
info->desc.name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
info->is_enabled = true;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
int ret;
|
||||
|
||||
if (info == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",
|
||||
info->desc.name);
|
||||
|
||||
ret = disable_epod(info->epod_id, info->is_ramret);
|
||||
if (ret < 0) {
|
||||
dev_err(rdev_get_dev(rdev),
|
||||
"regulator_switch-%s-disable: prcmu call failed\n",
|
||||
info->desc.name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
info->is_enabled = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
|
||||
|
||||
if (info == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
dev_vdbg(rdev_get_dev(rdev),
|
||||
"regulator-switch-%s-is_enabled (is_enabled): %i\n",
|
||||
info->desc.name, info->is_enabled);
|
||||
|
||||
return info->is_enabled;
|
||||
}
|
||||
|
||||
static struct regulator_ops db8500_regulator_switch_ops = {
|
||||
.enable = db8500_regulator_switch_enable,
|
||||
.disable = db8500_regulator_switch_disable,
|
||||
.is_enabled = db8500_regulator_switch_is_enabled,
|
||||
};
|
||||
|
||||
/*
|
||||
* Regulator information
|
||||
*/
|
||||
static struct db8500_regulator_info
|
||||
db8500_regulator_info[DB8500_NUM_REGULATORS] = {
|
||||
[DB8500_REGULATOR_VAPE] = {
|
||||
.desc = {
|
||||
.name = "db8500-vape",
|
||||
.id = DB8500_REGULATOR_VAPE,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
},
|
||||
[DB8500_REGULATOR_VARM] = {
|
||||
.desc = {
|
||||
.name = "db8500-varm",
|
||||
.id = DB8500_REGULATOR_VARM,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
},
|
||||
[DB8500_REGULATOR_VMODEM] = {
|
||||
.desc = {
|
||||
.name = "db8500-vmodem",
|
||||
.id = DB8500_REGULATOR_VMODEM,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
},
|
||||
[DB8500_REGULATOR_VPLL] = {
|
||||
.desc = {
|
||||
.name = "db8500-vpll",
|
||||
.id = DB8500_REGULATOR_VPLL,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
},
|
||||
[DB8500_REGULATOR_VSMPS1] = {
|
||||
.desc = {
|
||||
.name = "db8500-vsmps1",
|
||||
.id = DB8500_REGULATOR_VSMPS1,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
},
|
||||
[DB8500_REGULATOR_VSMPS2] = {
|
||||
.desc = {
|
||||
.name = "db8500-vsmps2",
|
||||
.id = DB8500_REGULATOR_VSMPS2,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.exclude_from_power_state = true,
|
||||
},
|
||||
[DB8500_REGULATOR_VSMPS3] = {
|
||||
.desc = {
|
||||
.name = "db8500-vsmps3",
|
||||
.id = DB8500_REGULATOR_VSMPS3,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
},
|
||||
[DB8500_REGULATOR_VRF1] = {
|
||||
.desc = {
|
||||
.name = "db8500-vrf1",
|
||||
.id = DB8500_REGULATOR_VRF1,
|
||||
.ops = &db8500_regulator_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
|
||||
.desc = {
|
||||
.name = "db8500-sva-mmdsp",
|
||||
.id = DB8500_REGULATOR_SWITCH_SVAMMDSP,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_SVAMMDSP,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
|
||||
.desc = {
|
||||
.name = "db8500-sva-mmdsp-ret",
|
||||
.id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_SVAMMDSP,
|
||||
.is_ramret = true,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_SVAPIPE] = {
|
||||
.desc = {
|
||||
.name = "db8500-sva-pipe",
|
||||
.id = DB8500_REGULATOR_SWITCH_SVAPIPE,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_SVAPIPE,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
|
||||
.desc = {
|
||||
.name = "db8500-sia-mmdsp",
|
||||
.id = DB8500_REGULATOR_SWITCH_SIAMMDSP,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_SIAMMDSP,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
|
||||
.desc = {
|
||||
.name = "db8500-sia-mmdsp-ret",
|
||||
.id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_SIAMMDSP,
|
||||
.is_ramret = true,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_SIAPIPE] = {
|
||||
.desc = {
|
||||
.name = "db8500-sia-pipe",
|
||||
.id = DB8500_REGULATOR_SWITCH_SIAPIPE,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_SIAPIPE,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_SGA] = {
|
||||
.desc = {
|
||||
.name = "db8500-sga",
|
||||
.id = DB8500_REGULATOR_SWITCH_SGA,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_SGA,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
|
||||
.desc = {
|
||||
.name = "db8500-b2r2-mcde",
|
||||
.id = DB8500_REGULATOR_SWITCH_B2R2_MCDE,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_B2R2_MCDE,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_ESRAM12] = {
|
||||
.desc = {
|
||||
.name = "db8500-esram12",
|
||||
.id = DB8500_REGULATOR_SWITCH_ESRAM12,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_ESRAM12,
|
||||
.is_enabled = true,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
|
||||
.desc = {
|
||||
.name = "db8500-esram12-ret",
|
||||
.id = DB8500_REGULATOR_SWITCH_ESRAM12RET,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_ESRAM12,
|
||||
.is_ramret = true,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_ESRAM34] = {
|
||||
.desc = {
|
||||
.name = "db8500-esram34",
|
||||
.id = DB8500_REGULATOR_SWITCH_ESRAM34,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_ESRAM34,
|
||||
.is_enabled = true,
|
||||
},
|
||||
[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
|
||||
.desc = {
|
||||
.name = "db8500-esram34-ret",
|
||||
.id = DB8500_REGULATOR_SWITCH_ESRAM34RET,
|
||||
.ops = &db8500_regulator_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.epod_id = EPOD_ID_ESRAM34,
|
||||
.is_ramret = true,
|
||||
},
|
||||
};
|
||||
|
||||
static int __devinit db8500_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_init_data *db8500_init_data = mfd_get_data(pdev);
|
||||
int i, err;
|
||||
|
||||
/* register all regulators */
|
||||
for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
|
||||
struct db8500_regulator_info *info;
|
||||
struct regulator_init_data *init_data = &db8500_init_data[i];
|
||||
|
||||
/* assign per-regulator data */
|
||||
info = &db8500_regulator_info[i];
|
||||
info->dev = &pdev->dev;
|
||||
|
||||
/* register with the regulator framework */
|
||||
info->rdev = regulator_register(&info->desc, &pdev->dev,
|
||||
init_data, info);
|
||||
if (IS_ERR(info->rdev)) {
|
||||
err = PTR_ERR(info->rdev);
|
||||
dev_err(&pdev->dev, "failed to register %s: err %i\n",
|
||||
info->desc.name, err);
|
||||
|
||||
/* if failing, unregister all earlier regulators */
|
||||
i--;
|
||||
while (i >= 0) {
|
||||
info = &db8500_regulator_info[i];
|
||||
regulator_unregister(info->rdev);
|
||||
i--;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
dev_dbg(rdev_get_dev(info->rdev),
|
||||
"regulator-%s-probed\n", info->desc.name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit db8500_regulator_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
|
||||
struct db8500_regulator_info *info;
|
||||
info = &db8500_regulator_info[i];
|
||||
|
||||
dev_vdbg(rdev_get_dev(info->rdev),
|
||||
"regulator-%s-remove\n", info->desc.name);
|
||||
|
||||
regulator_unregister(info->rdev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver db8500_regulator_driver = {
|
||||
.driver = {
|
||||
.name = "db8500-prcmu-regulators",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = db8500_regulator_probe,
|
||||
.remove = __exit_p(db8500_regulator_remove),
|
||||
};
|
||||
|
||||
static int __init db8500_regulator_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&db8500_regulator_driver);
|
||||
if (ret < 0)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit db8500_regulator_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&db8500_regulator_driver);
|
||||
}
|
||||
|
||||
arch_initcall(db8500_regulator_init);
|
||||
module_exit(db8500_regulator_exit);
|
||||
|
||||
MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
|
||||
MODULE_DESCRIPTION("DB8500 regulator driver");
|
||||
MODULE_LICENSE("GPL v2");
|
45
include/linux/mfd/db5500-prcmu.h
Normal file
45
include/linux/mfd/db5500-prcmu.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
*
|
||||
* U5500 PRCMU API.
|
||||
*/
|
||||
#ifndef __MACH_PRCMU_U5500_H
|
||||
#define __MACH_PRCMU_U5500_H
|
||||
|
||||
#ifdef CONFIG_UX500_SOC_DB5500
|
||||
|
||||
void db5500_prcmu_early_init(void);
|
||||
|
||||
int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
|
||||
int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
|
||||
|
||||
#else /* !CONFIG_UX500_SOC_DB5500 */
|
||||
|
||||
static inline void db5500_prcmu_early_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_UX500_SOC_DB5500 */
|
||||
|
||||
static inline int db5500_prcmu_config_abb_event_readout(u32 abb_events)
|
||||
{
|
||||
#ifdef CONFIG_MACH_U5500_SIMULATOR
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __MACH_PRCMU_U5500_H */
|
978
include/linux/mfd/db8500-prcmu.h
Normal file
978
include/linux/mfd/db8500-prcmu.h
Normal file
@ -0,0 +1,978 @@
|
||||
/*
|
||||
* Copyright (C) STMicroelectronics 2009
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
* Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
|
||||
*
|
||||
* PRCMU f/w APIs
|
||||
*/
|
||||
#ifndef __MFD_DB8500_PRCMU_H
|
||||
#define __MFD_DB8500_PRCMU_H
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
/* This portion previously known as <mach/prcmu-fw-defs_v1.h> */
|
||||
|
||||
/**
|
||||
* enum state - ON/OFF state definition
|
||||
* @OFF: State is ON
|
||||
* @ON: State is OFF
|
||||
*
|
||||
*/
|
||||
enum state {
|
||||
OFF = 0x0,
|
||||
ON = 0x1,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ret_state - general purpose On/Off/Retention states
|
||||
*
|
||||
*/
|
||||
enum ret_state {
|
||||
OFFST = 0,
|
||||
ONST = 1,
|
||||
RETST = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* enum clk_arm - ARM Cortex A9 clock schemes
|
||||
* @A9_OFF:
|
||||
* @A9_BOOT:
|
||||
* @A9_OPPT1:
|
||||
* @A9_OPPT2:
|
||||
* @A9_EXTCLK:
|
||||
*/
|
||||
enum clk_arm {
|
||||
A9_OFF,
|
||||
A9_BOOT,
|
||||
A9_OPPT1,
|
||||
A9_OPPT2,
|
||||
A9_EXTCLK
|
||||
};
|
||||
|
||||
/**
|
||||
* enum clk_gen - GEN#0/GEN#1 clock schemes
|
||||
* @GEN_OFF:
|
||||
* @GEN_BOOT:
|
||||
* @GEN_OPPT1:
|
||||
*/
|
||||
enum clk_gen {
|
||||
GEN_OFF,
|
||||
GEN_BOOT,
|
||||
GEN_OPPT1,
|
||||
};
|
||||
|
||||
/* some information between arm and xp70 */
|
||||
|
||||
/**
|
||||
* enum romcode_write - Romcode message written by A9 AND read by XP70
|
||||
* @RDY_2_DS: Value set when ApDeepSleep state can be executed by XP70
|
||||
* @RDY_2_XP70_RST: Value set when 0x0F has been successfully polled by the
|
||||
* romcode. The xp70 will go into self-reset
|
||||
*/
|
||||
enum romcode_write {
|
||||
RDY_2_DS = 0x09,
|
||||
RDY_2_XP70_RST = 0x10
|
||||
};
|
||||
|
||||
/**
|
||||
* enum romcode_read - Romcode message written by XP70 and read by A9
|
||||
* @INIT: Init value when romcode field is not used
|
||||
* @FS_2_DS: Value set when power state is going from ApExecute to
|
||||
* ApDeepSleep
|
||||
* @END_DS: Value set when ApDeepSleep power state is reached coming from
|
||||
* ApExecute state
|
||||
* @DS_TO_FS: Value set when power state is going from ApDeepSleep to
|
||||
* ApExecute
|
||||
* @END_FS: Value set when ApExecute power state is reached coming from
|
||||
* ApDeepSleep state
|
||||
* @SWR: Value set when power state is going to ApReset
|
||||
* @END_SWR: Value set when the xp70 finished executing ApReset actions and
|
||||
* waits for romcode acknowledgment to go to self-reset
|
||||
*/
|
||||
enum romcode_read {
|
||||
INIT = 0x00,
|
||||
FS_2_DS = 0x0A,
|
||||
END_DS = 0x0B,
|
||||
DS_TO_FS = 0x0C,
|
||||
END_FS = 0x0D,
|
||||
SWR = 0x0E,
|
||||
END_SWR = 0x0F
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ap_pwrst - current power states defined in PRCMU firmware
|
||||
* @NO_PWRST: Current power state init
|
||||
* @AP_BOOT: Current power state is apBoot
|
||||
* @AP_EXECUTE: Current power state is apExecute
|
||||
* @AP_DEEP_SLEEP: Current power state is apDeepSleep
|
||||
* @AP_SLEEP: Current power state is apSleep
|
||||
* @AP_IDLE: Current power state is apIdle
|
||||
* @AP_RESET: Current power state is apReset
|
||||
*/
|
||||
enum ap_pwrst {
|
||||
NO_PWRST = 0x00,
|
||||
AP_BOOT = 0x01,
|
||||
AP_EXECUTE = 0x02,
|
||||
AP_DEEP_SLEEP = 0x03,
|
||||
AP_SLEEP = 0x04,
|
||||
AP_IDLE = 0x05,
|
||||
AP_RESET = 0x06
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ap_pwrst_trans - Transition states defined in PRCMU firmware
|
||||
* @NO_TRANSITION: No power state transition
|
||||
* @APEXECUTE_TO_APSLEEP: Power state transition from ApExecute to ApSleep
|
||||
* @APIDLE_TO_APSLEEP: Power state transition from ApIdle to ApSleep
|
||||
* @APBOOT_TO_APEXECUTE: Power state transition from ApBoot to ApExecute
|
||||
* @APEXECUTE_TO_APDEEPSLEEP: Power state transition from ApExecute to
|
||||
* ApDeepSleep
|
||||
* @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle
|
||||
*/
|
||||
enum ap_pwrst_trans {
|
||||
NO_TRANSITION = 0x00,
|
||||
APEXECUTE_TO_APSLEEP = 0x01,
|
||||
APIDLE_TO_APSLEEP = 0x02, /* To be removed */
|
||||
PRCMU_AP_SLEEP = 0x01,
|
||||
APBOOT_TO_APEXECUTE = 0x03,
|
||||
APEXECUTE_TO_APDEEPSLEEP = 0x04, /* To be removed */
|
||||
PRCMU_AP_DEEP_SLEEP = 0x04,
|
||||
APEXECUTE_TO_APIDLE = 0x05, /* To be removed */
|
||||
PRCMU_AP_IDLE = 0x05,
|
||||
PRCMU_AP_DEEP_IDLE = 0x07,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ddr_pwrst - DDR power states definition
|
||||
* @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged
|
||||
* @DDR_PWR_STATE_ON:
|
||||
* @DDR_PWR_STATE_OFFLOWLAT:
|
||||
* @DDR_PWR_STATE_OFFHIGHLAT:
|
||||
*/
|
||||
enum ddr_pwrst {
|
||||
DDR_PWR_STATE_UNCHANGED = 0x00,
|
||||
DDR_PWR_STATE_ON = 0x01,
|
||||
DDR_PWR_STATE_OFFLOWLAT = 0x02,
|
||||
DDR_PWR_STATE_OFFHIGHLAT = 0x03
|
||||
};
|
||||
|
||||
/**
|
||||
* enum arm_opp - ARM OPP states definition
|
||||
* @ARM_OPP_INIT:
|
||||
* @ARM_NO_CHANGE: The ARM operating point is unchanged
|
||||
* @ARM_100_OPP: The new ARM operating point is arm100opp
|
||||
* @ARM_50_OPP: The new ARM operating point is arm50opp
|
||||
* @ARM_MAX_OPP: Operating point is "max" (more than 100)
|
||||
* @ARM_MAX_FREQ100OPP: Set max opp if available, else 100
|
||||
* @ARM_EXTCLK: The new ARM operating point is armExtClk
|
||||
*/
|
||||
enum arm_opp {
|
||||
ARM_OPP_INIT = 0x00,
|
||||
ARM_NO_CHANGE = 0x01,
|
||||
ARM_100_OPP = 0x02,
|
||||
ARM_50_OPP = 0x03,
|
||||
ARM_MAX_OPP = 0x04,
|
||||
ARM_MAX_FREQ100OPP = 0x05,
|
||||
ARM_EXTCLK = 0x07
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ape_opp - APE OPP states definition
|
||||
* @APE_OPP_INIT:
|
||||
* @APE_NO_CHANGE: The APE operating point is unchanged
|
||||
* @APE_100_OPP: The new APE operating point is ape100opp
|
||||
* @APE_50_OPP: 50%
|
||||
*/
|
||||
enum ape_opp {
|
||||
APE_OPP_INIT = 0x00,
|
||||
APE_NO_CHANGE = 0x01,
|
||||
APE_100_OPP = 0x02,
|
||||
APE_50_OPP = 0x03
|
||||
};
|
||||
|
||||
/**
|
||||
* enum hw_acc_state - State definition for hardware accelerator
|
||||
* @HW_NO_CHANGE: The hardware accelerator state must remain unchanged
|
||||
* @HW_OFF: The hardware accelerator must be switched off
|
||||
* @HW_OFF_RAMRET: The hardware accelerator must be switched off with its
|
||||
* internal RAM in retention
|
||||
* @HW_ON: The hwa hardware accelerator hwa must be switched on
|
||||
*
|
||||
* NOTE! Deprecated, to be removed when all users switched over to use the
|
||||
* regulator API.
|
||||
*/
|
||||
enum hw_acc_state {
|
||||
HW_NO_CHANGE = 0x00,
|
||||
HW_OFF = 0x01,
|
||||
HW_OFF_RAMRET = 0x02,
|
||||
HW_ON = 0x04
|
||||
};
|
||||
|
||||
/**
|
||||
* enum mbox_2_arm_stat - Status messages definition for mbox_arm
|
||||
* @BOOT_TO_EXECUTEOK: The apBoot to apExecute state transition has been
|
||||
* completed
|
||||
* @DEEPSLEEPOK: The apExecute to apDeepSleep state transition has been
|
||||
* completed
|
||||
* @SLEEPOK: The apExecute to apSleep state transition has been completed
|
||||
* @IDLEOK: The apExecute to apIdle state transition has been completed
|
||||
* @SOFTRESETOK: The A9 watchdog/ SoftReset state has been completed
|
||||
* @SOFTRESETGO : The A9 watchdog/SoftReset state is on going
|
||||
* @BOOT_TO_EXECUTE: The apBoot to apExecute state transition is on going
|
||||
* @EXECUTE_TO_DEEPSLEEP: The apExecute to apDeepSleep state transition is on
|
||||
* going
|
||||
* @DEEPSLEEP_TO_EXECUTE: The apDeepSleep to apExecute state transition is on
|
||||
* going
|
||||
* @DEEPSLEEP_TO_EXECUTEOK: The apDeepSleep to apExecute state transition has
|
||||
* been completed
|
||||
* @EXECUTE_TO_SLEEP: The apExecute to apSleep state transition is on going
|
||||
* @SLEEP_TO_EXECUTE: The apSleep to apExecute state transition is on going
|
||||
* @SLEEP_TO_EXECUTEOK: The apSleep to apExecute state transition has been
|
||||
* completed
|
||||
* @EXECUTE_TO_IDLE: The apExecute to apIdle state transition is on going
|
||||
* @IDLE_TO_EXECUTE: The apIdle to apExecute state transition is on going
|
||||
* @IDLE_TO_EXECUTEOK: The apIdle to apExecute state transition has been
|
||||
* completed
|
||||
* @INIT_STATUS: Status init
|
||||
*/
|
||||
enum ap_pwrsttr_status {
|
||||
BOOT_TO_EXECUTEOK = 0xFF,
|
||||
DEEPSLEEPOK = 0xFE,
|
||||
SLEEPOK = 0xFD,
|
||||
IDLEOK = 0xFC,
|
||||
SOFTRESETOK = 0xFB,
|
||||
SOFTRESETGO = 0xFA,
|
||||
BOOT_TO_EXECUTE = 0xF9,
|
||||
EXECUTE_TO_DEEPSLEEP = 0xF8,
|
||||
DEEPSLEEP_TO_EXECUTE = 0xF7,
|
||||
DEEPSLEEP_TO_EXECUTEOK = 0xF6,
|
||||
EXECUTE_TO_SLEEP = 0xF5,
|
||||
SLEEP_TO_EXECUTE = 0xF4,
|
||||
SLEEP_TO_EXECUTEOK = 0xF3,
|
||||
EXECUTE_TO_IDLE = 0xF2,
|
||||
IDLE_TO_EXECUTE = 0xF1,
|
||||
IDLE_TO_EXECUTEOK = 0xF0,
|
||||
RDYTODS_RETURNTOEXE = 0xEF,
|
||||
NORDYTODS_RETURNTOEXE = 0xEE,
|
||||
EXETOSLEEP_RETURNTOEXE = 0xED,
|
||||
EXETOIDLE_RETURNTOEXE = 0xEC,
|
||||
INIT_STATUS = 0xEB,
|
||||
|
||||
/*error messages */
|
||||
INITERROR = 0x00,
|
||||
PLLARMLOCKP_ER = 0x01,
|
||||
PLLDDRLOCKP_ER = 0x02,
|
||||
PLLSOCLOCKP_ER = 0x03,
|
||||
PLLSOCK1LOCKP_ER = 0x04,
|
||||
ARMWFI_ER = 0x05,
|
||||
SYSCLKOK_ER = 0x06,
|
||||
I2C_NACK_DATA_ER = 0x07,
|
||||
BOOT_ER = 0x08,
|
||||
I2C_STATUS_ALWAYS_1 = 0x0A,
|
||||
I2C_NACK_REG_ADDR_ER = 0x0B,
|
||||
I2C_NACK_DATA0123_ER = 0x1B,
|
||||
I2C_NACK_ADDR_ER = 0x1F,
|
||||
CURAPPWRSTISNOT_BOOT = 0x20,
|
||||
CURAPPWRSTISNOT_EXECUTE = 0x21,
|
||||
CURAPPWRSTISNOT_SLEEPMODE = 0x22,
|
||||
CURAPPWRSTISNOT_CORRECTFORIT10 = 0x23,
|
||||
FIFO4500WUISNOT_WUPEVENT = 0x24,
|
||||
PLL32KLOCKP_ER = 0x29,
|
||||
DDRDEEPSLEEPOK_ER = 0x2A,
|
||||
ROMCODEREADY_ER = 0x50,
|
||||
WUPBEFOREDS = 0x51,
|
||||
DDRCONFIG_ER = 0x52,
|
||||
WUPBEFORESLEEP = 0x53,
|
||||
WUPBEFOREIDLE = 0x54
|
||||
}; /* earlier called as mbox_2_arm_stat */
|
||||
|
||||
/**
|
||||
* enum dvfs_stat - DVFS status messages definition
|
||||
* @DVFS_GO: A state transition DVFS is on going
|
||||
* @DVFS_ARM100OPPOK: The state transition DVFS has been completed for 100OPP
|
||||
* @DVFS_ARM50OPPOK: The state transition DVFS has been completed for 50OPP
|
||||
* @DVFS_ARMEXTCLKOK: The state transition DVFS has been completed for EXTCLK
|
||||
* @DVFS_NOCHGTCLKOK: The state transition DVFS has been completed for
|
||||
* NOCHGCLK
|
||||
* @DVFS_INITSTATUS: Value init
|
||||
*/
|
||||
enum dvfs_stat {
|
||||
DVFS_GO = 0xFF,
|
||||
DVFS_ARM100OPPOK = 0xFE,
|
||||
DVFS_ARM50OPPOK = 0xFD,
|
||||
DVFS_ARMEXTCLKOK = 0xFC,
|
||||
DVFS_NOCHGTCLKOK = 0xFB,
|
||||
DVFS_INITSTATUS = 0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sva_mmdsp_stat - SVA MMDSP status messages
|
||||
* @SVA_MMDSP_GO: SVAMMDSP interrupt has happened
|
||||
* @SVA_MMDSP_INIT: Status init
|
||||
*/
|
||||
enum sva_mmdsp_stat {
|
||||
SVA_MMDSP_GO = 0xFF,
|
||||
SVA_MMDSP_INIT = 0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sia_mmdsp_stat - SIA MMDSP status messages
|
||||
* @SIA_MMDSP_GO: SIAMMDSP interrupt has happened
|
||||
* @SIA_MMDSP_INIT: Status init
|
||||
*/
|
||||
enum sia_mmdsp_stat {
|
||||
SIA_MMDSP_GO = 0xFF,
|
||||
SIA_MMDSP_INIT = 0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* enum mbox_to_arm_err - Error messages definition
|
||||
* @INIT_ERR: Init value
|
||||
* @PLLARMLOCKP_ERR: PLLARM has not been correctly locked in given time
|
||||
* @PLLDDRLOCKP_ERR: PLLDDR has not been correctly locked in the given time
|
||||
* @PLLSOC0LOCKP_ERR: PLLSOC0 has not been correctly locked in the given time
|
||||
* @PLLSOC1LOCKP_ERR: PLLSOC1 has not been correctly locked in the given time
|
||||
* @ARMWFI_ERR: The ARM WFI has not been correctly executed in the given time
|
||||
* @SYSCLKOK_ERR: The SYSCLK is not available in the given time
|
||||
* @BOOT_ERR: Romcode has not validated the XP70 self reset in the given time
|
||||
* @ROMCODESAVECONTEXT: The Romcode didn.t correctly save it secure context
|
||||
* @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transfered
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transfered
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transfered through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transfered
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VARMRETENTIONVALTO_ERR: The ARM retention supply value transfered through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transfered
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transfered through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VSAFEHPVALTO_ERR: The SAFE high power supply value transfered through I2C
|
||||
* has not been correctly executed in the given time
|
||||
* @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transfered through I2C has
|
||||
* not been correctly executed in the given time
|
||||
* @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transfered through I2C has
|
||||
* not been correctly executed in the given time
|
||||
* @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transfered through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transfered through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transfered
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @CURAPPWRSTISNOTBOOT:Generated when Arm want to do power state transition
|
||||
* ApBoot to ApExecute but the power current state is not Apboot
|
||||
* @CURAPPWRSTISNOTEXECUTE: Generated when Arm want to do power state
|
||||
* transition from ApExecute to others power state but the
|
||||
* power current state is not ApExecute
|
||||
* @CURAPPWRSTISNOTSLEEPMODE: Generated when wake up events are transmitted
|
||||
* but the power current state is not ApDeepSleep/ApSleep/ApIdle
|
||||
* @CURAPPWRSTISNOTCORRECTDBG: Generated when wake up events are transmitted
|
||||
* but the power current state is not correct
|
||||
* @ARMREGU1VALTO_ERR:The ArmRegu1 value transferred through I2C has not
|
||||
* been correctly executed in the given time
|
||||
* @ARMREGU2VALTO_ERR: The ArmRegu2 value transferred through I2C has not
|
||||
* been correctly executed in the given time
|
||||
* @VAPEREGUVALTO_ERR: The VApeRegu value transfered through I2C has not
|
||||
* been correctly executed in the given time
|
||||
* @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transfered through I2C has not
|
||||
* been correctly executed in the given time
|
||||
* @VMODREGUVALTO_ERR: The VModemRegu value transfered through I2C has not
|
||||
* been correctly executed in the given time
|
||||
*/
|
||||
enum mbox_to_arm_err {
|
||||
INIT_ERR = 0x00,
|
||||
PLLARMLOCKP_ERR = 0x01,
|
||||
PLLDDRLOCKP_ERR = 0x02,
|
||||
PLLSOC0LOCKP_ERR = 0x03,
|
||||
PLLSOC1LOCKP_ERR = 0x04,
|
||||
ARMWFI_ERR = 0x05,
|
||||
SYSCLKOK_ERR = 0x06,
|
||||
BOOT_ERR = 0x07,
|
||||
ROMCODESAVECONTEXT = 0x08,
|
||||
VARMHIGHSPEEDVALTO_ERR = 0x10,
|
||||
VARMHIGHSPEEDACCESS_ERR = 0x11,
|
||||
VARMLOWSPEEDVALTO_ERR = 0x12,
|
||||
VARMLOWSPEEDACCESS_ERR = 0x13,
|
||||
VARMRETENTIONVALTO_ERR = 0x14,
|
||||
VARMRETENTIONACCESS_ERR = 0x15,
|
||||
VAPEHIGHSPEEDVALTO_ERR = 0x16,
|
||||
VSAFEHPVALTO_ERR = 0x17,
|
||||
VMODSEL1VALTO_ERR = 0x18,
|
||||
VMODSEL2VALTO_ERR = 0x19,
|
||||
VARMOFFACCESS_ERR = 0x1A,
|
||||
VAPEOFFACCESS_ERR = 0x1B,
|
||||
VARMRETACCES_ERR = 0x1C,
|
||||
CURAPPWRSTISNOTBOOT = 0x20,
|
||||
CURAPPWRSTISNOTEXECUTE = 0x21,
|
||||
CURAPPWRSTISNOTSLEEPMODE = 0x22,
|
||||
CURAPPWRSTISNOTCORRECTDBG = 0x23,
|
||||
ARMREGU1VALTO_ERR = 0x24,
|
||||
ARMREGU2VALTO_ERR = 0x25,
|
||||
VAPEREGUVALTO_ERR = 0x26,
|
||||
VSMPS3REGUVALTO_ERR = 0x27,
|
||||
VMODREGUVALTO_ERR = 0x28
|
||||
};
|
||||
|
||||
enum hw_acc {
|
||||
SVAMMDSP = 0,
|
||||
SVAPIPE = 1,
|
||||
SIAMMDSP = 2,
|
||||
SIAPIPE = 3,
|
||||
SGA = 4,
|
||||
B2R2MCDE = 5,
|
||||
ESRAM12 = 6,
|
||||
ESRAM34 = 7,
|
||||
};
|
||||
|
||||
enum cs_pwrmgt {
|
||||
PWRDNCS0 = 0,
|
||||
WKUPCS0 = 1,
|
||||
PWRDNCS1 = 2,
|
||||
WKUPCS1 = 3
|
||||
};
|
||||
|
||||
/* Defs related to autonomous power management */
|
||||
|
||||
/**
|
||||
* enum sia_sva_pwr_policy - Power policy
|
||||
* @NO_CHGT: No change
|
||||
* @DSPOFF_HWPOFF:
|
||||
* @DSPOFFRAMRET_HWPOFF:
|
||||
* @DSPCLKOFF_HWPOFF:
|
||||
* @DSPCLKOFF_HWPCLKOFF:
|
||||
*
|
||||
*/
|
||||
enum sia_sva_pwr_policy {
|
||||
NO_CHGT = 0x0,
|
||||
DSPOFF_HWPOFF = 0x1,
|
||||
DSPOFFRAMRET_HWPOFF = 0x2,
|
||||
DSPCLKOFF_HWPOFF = 0x3,
|
||||
DSPCLKOFF_HWPCLKOFF = 0x4,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum auto_enable - Auto Power enable
|
||||
* @AUTO_OFF:
|
||||
* @AUTO_ON:
|
||||
*
|
||||
*/
|
||||
enum auto_enable {
|
||||
AUTO_OFF = 0x0,
|
||||
AUTO_ON = 0x1,
|
||||
};
|
||||
|
||||
/* End of file previously known as prcmu-fw-defs_v1.h */
|
||||
|
||||
/* PRCMU Wakeup defines */
|
||||
enum prcmu_wakeup_index {
|
||||
PRCMU_WAKEUP_INDEX_RTC,
|
||||
PRCMU_WAKEUP_INDEX_RTT0,
|
||||
PRCMU_WAKEUP_INDEX_RTT1,
|
||||
PRCMU_WAKEUP_INDEX_HSI0,
|
||||
PRCMU_WAKEUP_INDEX_HSI1,
|
||||
PRCMU_WAKEUP_INDEX_USB,
|
||||
PRCMU_WAKEUP_INDEX_ABB,
|
||||
PRCMU_WAKEUP_INDEX_ABB_FIFO,
|
||||
PRCMU_WAKEUP_INDEX_ARM,
|
||||
NUM_PRCMU_WAKEUP_INDICES
|
||||
};
|
||||
#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name))
|
||||
|
||||
/* PRCMU QoS APE OPP class */
|
||||
#define PRCMU_QOS_APE_OPP 1
|
||||
#define PRCMU_QOS_DDR_OPP 2
|
||||
#define PRCMU_QOS_DEFAULT_VALUE -1
|
||||
|
||||
/**
|
||||
* enum hw_acc_dev - enum for hw accelerators
|
||||
* @HW_ACC_SVAMMDSP: for SVAMMDSP
|
||||
* @HW_ACC_SVAPIPE: for SVAPIPE
|
||||
* @HW_ACC_SIAMMDSP: for SIAMMDSP
|
||||
* @HW_ACC_SIAPIPE: for SIAPIPE
|
||||
* @HW_ACC_SGA: for SGA
|
||||
* @HW_ACC_B2R2: for B2R2
|
||||
* @HW_ACC_MCDE: for MCDE
|
||||
* @HW_ACC_ESRAM1: for ESRAM1
|
||||
* @HW_ACC_ESRAM2: for ESRAM2
|
||||
* @HW_ACC_ESRAM3: for ESRAM3
|
||||
* @HW_ACC_ESRAM4: for ESRAM4
|
||||
* @NUM_HW_ACC: number of hardware accelerators
|
||||
*
|
||||
* Different hw accelerators which can be turned ON/
|
||||
* OFF or put into retention (MMDSPs and ESRAMs).
|
||||
* Used with EPOD API.
|
||||
*
|
||||
* NOTE! Deprecated, to be removed when all users switched over to use the
|
||||
* regulator API.
|
||||
*/
|
||||
enum hw_acc_dev {
|
||||
HW_ACC_SVAMMDSP,
|
||||
HW_ACC_SVAPIPE,
|
||||
HW_ACC_SIAMMDSP,
|
||||
HW_ACC_SIAPIPE,
|
||||
HW_ACC_SGA,
|
||||
HW_ACC_B2R2,
|
||||
HW_ACC_MCDE,
|
||||
HW_ACC_ESRAM1,
|
||||
HW_ACC_ESRAM2,
|
||||
HW_ACC_ESRAM3,
|
||||
HW_ACC_ESRAM4,
|
||||
NUM_HW_ACC
|
||||
};
|
||||
|
||||
/*
|
||||
* Ids for all EPODs (power domains)
|
||||
* - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP
|
||||
* - EPOD_ID_SVAPIPE: power domain for SVA pipe
|
||||
* - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP
|
||||
* - EPOD_ID_SIAPIPE: power domain for SIA pipe
|
||||
* - EPOD_ID_SGA: power domain for SGA
|
||||
* - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE
|
||||
* - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2
|
||||
* - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4
|
||||
* - NUM_EPOD_ID: number of power domains
|
||||
*/
|
||||
#define EPOD_ID_SVAMMDSP 0
|
||||
#define EPOD_ID_SVAPIPE 1
|
||||
#define EPOD_ID_SIAMMDSP 2
|
||||
#define EPOD_ID_SIAPIPE 3
|
||||
#define EPOD_ID_SGA 4
|
||||
#define EPOD_ID_B2R2_MCDE 5
|
||||
#define EPOD_ID_ESRAM12 6
|
||||
#define EPOD_ID_ESRAM34 7
|
||||
#define NUM_EPOD_ID 8
|
||||
|
||||
/*
|
||||
* state definition for EPOD (power domain)
|
||||
* - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged
|
||||
* - EPOD_STATE_OFF: The EPOD is switched off
|
||||
* - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in
|
||||
* retention
|
||||
* - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off
|
||||
* - EPOD_STATE_ON: Same as above, but with clock enabled
|
||||
*/
|
||||
#define EPOD_STATE_NO_CHANGE 0x00
|
||||
#define EPOD_STATE_OFF 0x01
|
||||
#define EPOD_STATE_RAMRET 0x02
|
||||
#define EPOD_STATE_ON_CLK_OFF 0x03
|
||||
#define EPOD_STATE_ON 0x04
|
||||
|
||||
/*
|
||||
* CLKOUT sources
|
||||
*/
|
||||
#define PRCMU_CLKSRC_CLK38M 0x00
|
||||
#define PRCMU_CLKSRC_ACLK 0x01
|
||||
#define PRCMU_CLKSRC_SYSCLK 0x02
|
||||
#define PRCMU_CLKSRC_LCDCLK 0x03
|
||||
#define PRCMU_CLKSRC_SDMMCCLK 0x04
|
||||
#define PRCMU_CLKSRC_TVCLK 0x05
|
||||
#define PRCMU_CLKSRC_TIMCLK 0x06
|
||||
#define PRCMU_CLKSRC_CLK009 0x07
|
||||
/* These are only valid for CLKOUT1: */
|
||||
#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40
|
||||
#define PRCMU_CLKSRC_I2CCLK 0x41
|
||||
#define PRCMU_CLKSRC_MSP02CLK 0x42
|
||||
#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43
|
||||
#define PRCMU_CLKSRC_HSIRXCLK 0x44
|
||||
#define PRCMU_CLKSRC_HSITXCLK 0x45
|
||||
#define PRCMU_CLKSRC_ARMCLKFIX 0x46
|
||||
#define PRCMU_CLKSRC_HDMICLK 0x47
|
||||
|
||||
/*
|
||||
* Definitions for autonomous power management configuration.
|
||||
*/
|
||||
|
||||
#define PRCMU_AUTO_PM_OFF 0
|
||||
#define PRCMU_AUTO_PM_ON 1
|
||||
|
||||
#define PRCMU_AUTO_PM_POWER_ON_HSEM BIT(0)
|
||||
#define PRCMU_AUTO_PM_POWER_ON_ABB_FIFO_IT BIT(1)
|
||||
|
||||
enum prcmu_auto_pm_policy {
|
||||
PRCMU_AUTO_PM_POLICY_NO_CHANGE,
|
||||
PRCMU_AUTO_PM_POLICY_DSP_OFF_HWP_OFF,
|
||||
PRCMU_AUTO_PM_POLICY_DSP_OFF_RAMRET_HWP_OFF,
|
||||
PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_OFF,
|
||||
PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_CLK_OFF,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct prcmu_auto_pm_config - Autonomous power management configuration.
|
||||
* @sia_auto_pm_enable: SIA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON})
|
||||
* @sia_power_on: SIA power ON enable. (PRCMU_AUTO_PM_POWER_ON_* bitmask)
|
||||
* @sia_policy: SIA power policy. (enum prcmu_auto_pm_policy)
|
||||
* @sva_auto_pm_enable: SVA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON})
|
||||
* @sva_power_on: SVA power ON enable. (PRCMU_AUTO_PM_POWER_ON_* bitmask)
|
||||
* @sva_policy: SVA power policy. (enum prcmu_auto_pm_policy)
|
||||
*/
|
||||
struct prcmu_auto_pm_config {
|
||||
u8 sia_auto_pm_enable;
|
||||
u8 sia_power_on;
|
||||
u8 sia_policy;
|
||||
u8 sva_auto_pm_enable;
|
||||
u8 sva_power_on;
|
||||
u8 sva_policy;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum ddr_opp - DDR OPP states definition
|
||||
* @DDR_100_OPP: The new DDR operating point is ddr100opp
|
||||
* @DDR_50_OPP: The new DDR operating point is ddr50opp
|
||||
* @DDR_25_OPP: The new DDR operating point is ddr25opp
|
||||
*/
|
||||
enum ddr_opp {
|
||||
DDR_100_OPP = 0x00,
|
||||
DDR_50_OPP = 0x01,
|
||||
DDR_25_OPP = 0x02,
|
||||
};
|
||||
|
||||
/*
|
||||
* Clock identifiers.
|
||||
*/
|
||||
enum prcmu_clock {
|
||||
PRCMU_SGACLK,
|
||||
PRCMU_UARTCLK,
|
||||
PRCMU_MSP02CLK,
|
||||
PRCMU_MSP1CLK,
|
||||
PRCMU_I2CCLK,
|
||||
PRCMU_SDMMCCLK,
|
||||
PRCMU_SLIMCLK,
|
||||
PRCMU_PER1CLK,
|
||||
PRCMU_PER2CLK,
|
||||
PRCMU_PER3CLK,
|
||||
PRCMU_PER5CLK,
|
||||
PRCMU_PER6CLK,
|
||||
PRCMU_PER7CLK,
|
||||
PRCMU_LCDCLK,
|
||||
PRCMU_BMLCLK,
|
||||
PRCMU_HSITXCLK,
|
||||
PRCMU_HSIRXCLK,
|
||||
PRCMU_HDMICLK,
|
||||
PRCMU_APEATCLK,
|
||||
PRCMU_APETRACECLK,
|
||||
PRCMU_MCDECLK,
|
||||
PRCMU_IPI2CCLK,
|
||||
PRCMU_DSIALTCLK,
|
||||
PRCMU_DMACLK,
|
||||
PRCMU_B2R2CLK,
|
||||
PRCMU_TVCLK,
|
||||
PRCMU_SSPCLK,
|
||||
PRCMU_RNGCLK,
|
||||
PRCMU_UICCCLK,
|
||||
PRCMU_NUM_REG_CLOCKS,
|
||||
PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS,
|
||||
PRCMU_TIMCLK,
|
||||
};
|
||||
|
||||
/*
|
||||
* Definitions for controlling ESRAM0 in deep sleep.
|
||||
*/
|
||||
#define ESRAM0_DEEP_SLEEP_STATE_OFF 1
|
||||
#define ESRAM0_DEEP_SLEEP_STATE_RET 2
|
||||
|
||||
#ifdef CONFIG_MFD_DB8500_PRCMU
|
||||
void __init prcmu_early_init(void);
|
||||
int prcmu_set_display_clocks(void);
|
||||
int prcmu_disable_dsipll(void);
|
||||
int prcmu_enable_dsipll(void);
|
||||
#else
|
||||
static inline void __init prcmu_early_init(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MFD_DB8500_PRCMU
|
||||
|
||||
int prcmu_set_rc_a2p(enum romcode_write);
|
||||
enum romcode_read prcmu_get_rc_p2a(void);
|
||||
enum ap_pwrst prcmu_get_xp70_current_state(void);
|
||||
int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll);
|
||||
|
||||
void prcmu_enable_wakeups(u32 wakeups);
|
||||
static inline void prcmu_disable_wakeups(void)
|
||||
{
|
||||
prcmu_enable_wakeups(0);
|
||||
}
|
||||
|
||||
void prcmu_config_abb_event_readout(u32 abb_events);
|
||||
void prcmu_get_abb_event_buffer(void __iomem **buf);
|
||||
int prcmu_set_arm_opp(u8 opp);
|
||||
int prcmu_get_arm_opp(void);
|
||||
bool prcmu_has_arm_maxopp(void);
|
||||
bool prcmu_is_u8400(void);
|
||||
int prcmu_set_ape_opp(u8 opp);
|
||||
int prcmu_get_ape_opp(void);
|
||||
int prcmu_request_ape_opp_100_voltage(bool enable);
|
||||
int prcmu_release_usb_wakeup_state(void);
|
||||
int prcmu_set_ddr_opp(u8 opp);
|
||||
int prcmu_get_ddr_opp(void);
|
||||
unsigned long prcmu_qos_get_cpufreq_opp_delay(void);
|
||||
void prcmu_qos_set_cpufreq_opp_delay(unsigned long);
|
||||
/* NOTE! Use regulator framework instead */
|
||||
int prcmu_set_hwacc(u16 hw_acc_dev, u8 state);
|
||||
int prcmu_set_epod(u16 epod_id, u8 epod_state);
|
||||
void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
|
||||
struct prcmu_auto_pm_config *idle);
|
||||
bool prcmu_is_auto_pm_enabled(void);
|
||||
|
||||
int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
|
||||
int prcmu_request_clock(u8 clock, bool enable);
|
||||
int prcmu_set_clock_divider(u8 clock, u8 divider);
|
||||
int prcmu_config_esram0_deep_sleep(u8 state);
|
||||
int prcmu_config_hotdog(u8 threshold);
|
||||
int prcmu_config_hotmon(u8 low, u8 high);
|
||||
int prcmu_start_temp_sense(u16 cycles32k);
|
||||
int prcmu_stop_temp_sense(void);
|
||||
int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
|
||||
int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
|
||||
|
||||
void prcmu_ac_wake_req(void);
|
||||
void prcmu_ac_sleep_req(void);
|
||||
void prcmu_system_reset(u16 reset_code);
|
||||
void prcmu_modem_reset(void);
|
||||
bool prcmu_is_ac_wake_requested(void);
|
||||
void prcmu_enable_spi2(void);
|
||||
void prcmu_disable_spi2(void);
|
||||
|
||||
#else /* !CONFIG_MFD_DB8500_PRCMU */
|
||||
|
||||
static inline int prcmu_set_rc_a2p(enum romcode_write code)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline enum romcode_read prcmu_get_rc_p2a(void)
|
||||
{
|
||||
return INIT;
|
||||
}
|
||||
|
||||
static inline enum ap_pwrst prcmu_get_xp70_current_state(void)
|
||||
{
|
||||
return AP_EXECUTE;
|
||||
}
|
||||
|
||||
static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
|
||||
bool keep_ap_pll)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void prcmu_enable_wakeups(u32 wakeups) {}
|
||||
|
||||
static inline void prcmu_disable_wakeups(void) {}
|
||||
|
||||
static inline void prcmu_config_abb_event_readout(u32 abb_events) {}
|
||||
|
||||
static inline int prcmu_set_arm_opp(u8 opp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_get_arm_opp(void)
|
||||
{
|
||||
return ARM_100_OPP;
|
||||
}
|
||||
|
||||
static bool prcmu_has_arm_maxopp(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool prcmu_is_u8400(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int prcmu_set_ape_opp(u8 opp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_get_ape_opp(void)
|
||||
{
|
||||
return APE_100_OPP;
|
||||
}
|
||||
|
||||
static inline int prcmu_request_ape_opp_100_voltage(bool enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_release_usb_wakeup_state(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_set_ddr_opp(u8 opp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_get_ddr_opp(void)
|
||||
{
|
||||
return DDR_100_OPP;
|
||||
}
|
||||
|
||||
static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {}
|
||||
|
||||
static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
|
||||
struct prcmu_auto_pm_config *idle)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool prcmu_is_auto_pm_enabled(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_request_clock(u8 clock, bool enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_set_clock_divider(u8 clock, u8 divider)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prcmu_config_esram0_deep_sleep(u8 state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_config_hotdog(u8 threshold)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_config_hotmon(u8 low, u8 high)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_start_temp_sense(u16 cycles32k)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_stop_temp_sense(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
static inline void prcmu_ac_wake_req(void) {}
|
||||
|
||||
static inline void prcmu_ac_sleep_req(void) {}
|
||||
|
||||
static inline void prcmu_system_reset(u16 reset_code) {}
|
||||
|
||||
static inline void prcmu_modem_reset(void) {}
|
||||
|
||||
static inline bool prcmu_is_ac_wake_requested(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_UX500_SOC_DB5500
|
||||
static inline int prcmu_set_display_clocks(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_disable_dsipll(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_enable_dsipll(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int prcmu_enable_spi2(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_disable_spi2(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_MFD_DB8500_PRCMU */
|
||||
|
||||
#ifdef CONFIG_UX500_PRCMU_QOS_POWER
|
||||
int prcmu_qos_requirement(int pm_qos_class);
|
||||
int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value);
|
||||
int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value);
|
||||
void prcmu_qos_remove_requirement(int pm_qos_class, char *name);
|
||||
int prcmu_qos_add_notifier(int prcmu_qos_class,
|
||||
struct notifier_block *notifier);
|
||||
int prcmu_qos_remove_notifier(int prcmu_qos_class,
|
||||
struct notifier_block *notifier);
|
||||
#else
|
||||
static inline int prcmu_qos_requirement(int prcmu_qos_class)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_qos_add_requirement(int prcmu_qos_class,
|
||||
char *name, s32 value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int prcmu_qos_update_requirement(int prcmu_qos_class,
|
||||
char *name, s32 new_value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int prcmu_qos_add_notifier(int prcmu_qos_class,
|
||||
struct notifier_block *notifier)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int prcmu_qos_remove_notifier(int prcmu_qos_class,
|
||||
struct notifier_block *notifier)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __MFD_DB8500_PRCMU_H */
|
45
include/linux/regulator/db8500-prcmu.h
Normal file
45
include/linux/regulator/db8500-prcmu.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2010
|
||||
*
|
||||
* License Terms: GNU General Public License v2
|
||||
*
|
||||
* Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
|
||||
*
|
||||
* Interface to power domain regulators on DB8500
|
||||
*/
|
||||
|
||||
#ifndef __REGULATOR_H__
|
||||
#define __REGULATOR_H__
|
||||
|
||||
/* Number of DB8500 regulators and regulator enumeration */
|
||||
enum db8500_regulator_id {
|
||||
DB8500_REGULATOR_VAPE,
|
||||
DB8500_REGULATOR_VARM,
|
||||
DB8500_REGULATOR_VMODEM,
|
||||
DB8500_REGULATOR_VPLL,
|
||||
DB8500_REGULATOR_VSMPS1,
|
||||
DB8500_REGULATOR_VSMPS2,
|
||||
DB8500_REGULATOR_VSMPS3,
|
||||
DB8500_REGULATOR_VRF1,
|
||||
DB8500_REGULATOR_SWITCH_SVAMMDSP,
|
||||
DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
|
||||
DB8500_REGULATOR_SWITCH_SVAPIPE,
|
||||
DB8500_REGULATOR_SWITCH_SIAMMDSP,
|
||||
DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
|
||||
DB8500_REGULATOR_SWITCH_SIAPIPE,
|
||||
DB8500_REGULATOR_SWITCH_SGA,
|
||||
DB8500_REGULATOR_SWITCH_B2R2_MCDE,
|
||||
DB8500_REGULATOR_SWITCH_ESRAM12,
|
||||
DB8500_REGULATOR_SWITCH_ESRAM12RET,
|
||||
DB8500_REGULATOR_SWITCH_ESRAM34,
|
||||
DB8500_REGULATOR_SWITCH_ESRAM34RET,
|
||||
DB8500_NUM_REGULATORS
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported interface for CPUIdle only. This function is called with all
|
||||
* interrupts turned off.
|
||||
*/
|
||||
int power_state_active_is_enabled(void);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user