Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+4755 -707
+3
arch/arm/mach-ux500/Kconfig
··· 12 12 13 13 config UX500_SOC_DB5500 14 14 bool "DB5500" 15 + select MFD_DB5500_PRCMU 15 16 16 17 config UX500_SOC_DB8500 17 18 bool "DB8500" 19 + select MFD_DB8500_PRCMU 20 + select REGULATOR_DB8500_PRCMU 18 21 19 22 endmenu 20 23
+2 -2
arch/arm/mach-ux500/Makefile
··· 5 5 obj-y := clock.o cpu.o devices.o devices-common.o \ 6 6 id.o usb.o 7 7 obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o dma-db5500.o 8 - obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o 8 + obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o 9 9 obj-$(CONFIG_MACH_U8500) += board-mop500.o board-mop500-sdi.o \ 10 10 board-mop500-regulators.o \ 11 11 board-mop500-uib.o board-mop500-stuib.o \ ··· 17 17 obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o 18 18 obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o 19 19 obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o 20 - obj-$(CONFIG_CPU_FREQ) += cpufreq.o 20 +
+2
arch/arm/mach-ux500/cpu-db5500.c
··· 188 188 ux500_map_io(); 189 189 190 190 iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc)); 191 + 192 + _PRCMU_BASE = __io_address(U5500_PRCMU_BASE); 191 193 } 192 194 193 195 static int usb_db5500_rx_dma_cfg[] = {
+7
arch/arm/mach-ux500/cpu-db8500.c
··· 87 87 iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc)); 88 88 else if (cpu_is_u8500v2()) 89 89 iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc)); 90 + 91 + _PRCMU_BASE = __io_address(U8500_PRCMU_BASE); 90 92 } 91 93 92 94 static struct resource db8500_pmu_resources[] = { ··· 131 129 .dev.platform_data = &db8500_pmu_platdata, 132 130 }; 133 131 132 + static struct platform_device db8500_prcmu_device = { 133 + .name = "db8500-prcmu", 134 + }; 135 + 134 136 static struct platform_device *platform_devs[] __initdata = { 135 137 &u8500_dma40_device, 136 138 &db8500_pmu_device, 139 + &db8500_prcmu_device, 137 140 }; 138 141 139 142 static resource_size_t __initdata db8500_gpio_base[] = {
+6 -1
arch/arm/mach-ux500/cpu.c
··· 8 8 #include <linux/platform_device.h> 9 9 #include <linux/io.h> 10 10 #include <linux/clk.h> 11 + #include <linux/mfd/db8500-prcmu.h> 12 + #include <linux/mfd/db5500-prcmu.h> 11 13 12 14 #include <asm/cacheflush.h> 13 15 #include <asm/hardware/cache-l2x0.h> ··· 21 19 #include <mach/hardware.h> 22 20 #include <mach/setup.h> 23 21 #include <mach/devices.h> 24 - #include <mach/prcmu.h> 25 22 26 23 #include "clock.h" 24 + 25 + void __iomem *_PRCMU_BASE; 27 26 28 27 #ifdef CONFIG_CACHE_L2X0 29 28 static void __iomem *l2x0_base; ··· 50 47 * Init clocks here so that they are available for system timer 51 48 * initialization. 52 49 */ 50 + if (cpu_is_u5500()) 51 + db5500_prcmu_early_init(); 53 52 if (cpu_is_u8500()) 54 53 prcmu_early_init(); 55 54 clk_init();
-211
arch/arm/mach-ux500/cpufreq.c
··· 1 - /* 2 - * CPU frequency scaling for u8500 3 - * Inspired by linux/arch/arm/mach-davinci/cpufreq.c 4 - * 5 - * Copyright (C) STMicroelectronics 2009 6 - * Copyright (C) ST-Ericsson SA 2010 7 - * 8 - * License Terms: GNU General Public License v2 9 - * 10 - * Author: Sundar Iyer <sundar.iyer@stericsson.com> 11 - * Author: Martin Persson <martin.persson@stericsson.com> 12 - * Author: Jonas Aaberg <jonas.aberg@stericsson.com> 13 - * 14 - */ 15 - 16 - #include <linux/platform_device.h> 17 - #include <linux/kernel.h> 18 - #include <linux/cpufreq.h> 19 - #include <linux/delay.h> 20 - 21 - #include <mach/hardware.h> 22 - #include <mach/prcmu.h> 23 - #include <mach/prcmu-defs.h> 24 - 25 - #define DRIVER_NAME "cpufreq-u8500" 26 - #define CPUFREQ_NAME "u8500" 27 - 28 - static struct device *dev; 29 - 30 - static struct cpufreq_frequency_table freq_table[] = { 31 - [0] = { 32 - .index = 0, 33 - .frequency = 200000, 34 - }, 35 - [1] = { 36 - .index = 1, 37 - .frequency = 300000, 38 - }, 39 - [2] = { 40 - .index = 2, 41 - .frequency = 600000, 42 - }, 43 - [3] = { 44 - /* Used for CPU_OPP_MAX, if available */ 45 - .index = 3, 46 - .frequency = CPUFREQ_TABLE_END, 47 - }, 48 - [4] = { 49 - .index = 4, 50 - .frequency = CPUFREQ_TABLE_END, 51 - }, 52 - }; 53 - 54 - static enum prcmu_cpu_opp index2opp[] = { 55 - CPU_OPP_EXT_CLK, 56 - CPU_OPP_50, 57 - CPU_OPP_100, 58 - CPU_OPP_MAX 59 - }; 60 - 61 - static int u8500_cpufreq_verify_speed(struct cpufreq_policy *policy) 62 - { 63 - return cpufreq_frequency_table_verify(policy, freq_table); 64 - } 65 - 66 - static int u8500_cpufreq_target(struct cpufreq_policy *policy, 67 - unsigned int target_freq, 68 - unsigned int relation) 69 - { 70 - struct cpufreq_freqs freqs; 71 - unsigned int index; 72 - int ret = 0; 73 - 74 - /* 75 - * Ensure desired rate is within allowed range. Some govenors 76 - * (ondemand) will just pass target_freq=0 to get the minimum. 77 - */ 78 - if (target_freq < policy->cpuinfo.min_freq) 79 - target_freq = policy->cpuinfo.min_freq; 80 - if (target_freq > policy->cpuinfo.max_freq) 81 - target_freq = policy->cpuinfo.max_freq; 82 - 83 - ret = cpufreq_frequency_table_target(policy, freq_table, 84 - target_freq, relation, &index); 85 - if (ret < 0) { 86 - dev_err(dev, "Could not look up next frequency\n"); 87 - return ret; 88 - } 89 - 90 - freqs.old = policy->cur; 91 - freqs.new = freq_table[index].frequency; 92 - freqs.cpu = policy->cpu; 93 - 94 - if (freqs.old == freqs.new) { 95 - dev_dbg(dev, "Current and target frequencies are equal\n"); 96 - return 0; 97 - } 98 - 99 - dev_dbg(dev, "transition: %u --> %u\n", freqs.old, freqs.new); 100 - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 101 - 102 - ret = prcmu_set_cpu_opp(index2opp[index]); 103 - if (ret < 0) { 104 - dev_err(dev, "Failed to set OPP level\n"); 105 - return ret; 106 - } 107 - 108 - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 109 - 110 - return ret; 111 - } 112 - 113 - static unsigned int u8500_cpufreq_getspeed(unsigned int cpu) 114 - { 115 - int i; 116 - 117 - for (i = 0; prcmu_get_cpu_opp() != index2opp[i]; i++) 118 - ; 119 - return freq_table[i].frequency; 120 - } 121 - 122 - static int __cpuinit u8500_cpu_init(struct cpufreq_policy *policy) 123 - { 124 - int res; 125 - 126 - BUILD_BUG_ON(ARRAY_SIZE(index2opp) + 1 != ARRAY_SIZE(freq_table)); 127 - 128 - if (cpu_is_u8500v2()) { 129 - freq_table[1].frequency = 400000; 130 - freq_table[2].frequency = 800000; 131 - if (prcmu_has_arm_maxopp()) 132 - freq_table[3].frequency = 1000000; 133 - } 134 - 135 - /* get policy fields based on the table */ 136 - res = cpufreq_frequency_table_cpuinfo(policy, freq_table); 137 - if (!res) 138 - cpufreq_frequency_table_get_attr(freq_table, policy->cpu); 139 - else { 140 - dev_err(dev, "u8500-cpufreq : Failed to read policy table\n"); 141 - return res; 142 - } 143 - 144 - policy->min = policy->cpuinfo.min_freq; 145 - policy->max = policy->cpuinfo.max_freq; 146 - policy->cur = u8500_cpufreq_getspeed(policy->cpu); 147 - policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 148 - 149 - /* 150 - * FIXME : Need to take time measurement across the target() 151 - * function with no/some/all drivers in the notification 152 - * list. 153 - */ 154 - policy->cpuinfo.transition_latency = 200 * 1000; /* in ns */ 155 - 156 - /* policy sharing between dual CPUs */ 157 - cpumask_copy(policy->cpus, &cpu_present_map); 158 - 159 - policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; 160 - 161 - return res; 162 - } 163 - 164 - static struct freq_attr *u8500_cpufreq_attr[] = { 165 - &cpufreq_freq_attr_scaling_available_freqs, 166 - NULL, 167 - }; 168 - static int u8500_cpu_exit(struct cpufreq_policy *policy) 169 - { 170 - cpufreq_frequency_table_put_attr(policy->cpu); 171 - return 0; 172 - } 173 - 174 - static struct cpufreq_driver u8500_driver = { 175 - .owner = THIS_MODULE, 176 - .flags = CPUFREQ_STICKY, 177 - .verify = u8500_cpufreq_verify_speed, 178 - .target = u8500_cpufreq_target, 179 - .get = u8500_cpufreq_getspeed, 180 - .init = u8500_cpu_init, 181 - .exit = u8500_cpu_exit, 182 - .name = CPUFREQ_NAME, 183 - .attr = u8500_cpufreq_attr, 184 - }; 185 - 186 - static int __init u8500_cpufreq_probe(struct platform_device *pdev) 187 - { 188 - dev = &pdev->dev; 189 - return cpufreq_register_driver(&u8500_driver); 190 - } 191 - 192 - static int __exit u8500_cpufreq_remove(struct platform_device *pdev) 193 - { 194 - return cpufreq_unregister_driver(&u8500_driver); 195 - } 196 - 197 - static struct platform_driver u8500_cpufreq_driver = { 198 - .driver = { 199 - .name = DRIVER_NAME, 200 - .owner = THIS_MODULE, 201 - }, 202 - .remove = __exit_p(u8500_cpufreq_remove), 203 - }; 204 - 205 - static int __init u8500_cpufreq_init(void) 206 - { 207 - return platform_driver_probe(&u8500_cpufreq_driver, 208 - &u8500_cpufreq_probe); 209 - } 210 - 211 - device_initcall(u8500_cpufreq_init);
+18 -2
arch/arm/mach-ux500/include/mach/db5500-regs.h
··· 17 17 #define U5500_GIC_DIST_BASE 0xA0411000 18 18 #define U5500_GIC_CPU_BASE 0xA0410100 19 19 #define U5500_DMA_BASE 0x90030000 20 + #define U5500_STM_BASE 0x90020000 21 + #define U5500_STM_REG_BASE (U5500_STM_BASE + 0xF000) 20 22 #define U5500_MCDE_BASE 0xA0400000 21 23 #define U5500_MODEM_BASE 0xB0000000 22 24 #define U5500_L2CC_BASE 0xA0412000 ··· 31 29 #define U5500_NAND0_BASE 0x60000000 32 30 #define U5500_NAND1_BASE 0x70000000 33 31 #define U5500_TWD_BASE 0xa0410600 32 + #define U5500_ICN_BASE 0xA0040000 34 33 #define U5500_B2R2_BASE 0xa0200000 34 + #define U5500_BOOT_ROM_BASE 0x90000000 35 35 36 36 #define U5500_FSMC_BASE (U5500_PER1_BASE + 0x0000) 37 37 #define U5500_SDI0_BASE (U5500_PER1_BASE + 0x1000) ··· 64 60 #define U5500_MSP1_BASE (U5500_PER4_BASE + 0x9000) 65 61 #define U5500_GPIO2_BASE (U5500_PER4_BASE + 0xA000) 66 62 #define U5500_CDETECT_BASE (U5500_PER4_BASE + 0xF000) 63 + #define U5500_PRCMU_TCDM_BASE (U5500_PER4_BASE + 0x18000) 67 64 68 65 #define U5500_SPI0_BASE (U5500_PER5_BASE + 0x0000) 69 66 #define U5500_SPI1_BASE (U5500_PER5_BASE + 0x1000) ··· 88 83 #define U5500_HASH0_BASE (U5500_PER6_BASE + 0x1000) 89 84 #define U5500_HASH1_BASE (U5500_PER6_BASE + 0x2000) 90 85 #define U5500_PKA_BASE (U5500_PER6_BASE + 0x4000) 91 - #define U5500_PKAM_BASE (U5500_PER6_BASE + 0x5000) 86 + #define U5500_PKAM_BASE (U5500_PER6_BASE + 0x5100) 92 87 #define U5500_MTU0_BASE (U5500_PER6_BASE + 0x6000) 93 88 #define U5500_MTU1_BASE (U5500_PER6_BASE + 0x7000) 94 89 #define U5500_CR_BASE (U5500_PER6_BASE + 0x8000) ··· 119 114 #define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20) 120 115 #define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F) 121 116 122 - #define U5500_ESRAM_BASE 0x40000000 117 + #define U5500_ACCCON_BASE_SEC (0xBFFF0000) 118 + #define U5500_ACCCON_BASE (0xBFFF1000) 119 + #define U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020) 120 + #define U5500_ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC) 121 + 122 + #define U5500_ESRAM_BASE 0x40000000 123 123 #define U5500_ESRAM_DMA_LCPA_OFFSET 0x10000 124 124 #define U5500_DMA_LCPA_BASE (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET) 125 + 126 + #define U5500_MCDE_SIZE 0x1000 127 + #define U5500_DSI_LINK_SIZE 0x1000 128 + #define U5500_DSI_LINK_COUNT 0x2 129 + #define U5500_DSI_LINK1_BASE (U5500_MCDE_BASE + U5500_MCDE_SIZE) 130 + #define U5500_DSI_LINK2_BASE (U5500_DSI_LINK1_BASE + U5500_DSI_LINK_SIZE) 125 131 126 132 #endif
+30 -7
arch/arm/mach-ux500/include/mach/db8500-regs.h
··· 15 15 #define U8500_ESRAM_BANK2 (U8500_ESRAM_BANK1 + U8500_ESRAM_BANK_SIZE) 16 16 #define U8500_ESRAM_BANK3 (U8500_ESRAM_BANK2 + U8500_ESRAM_BANK_SIZE) 17 17 #define U8500_ESRAM_BANK4 (U8500_ESRAM_BANK3 + U8500_ESRAM_BANK_SIZE) 18 - /* Use bank 4 for DMA LCPA */ 19 - #define U8500_DMA_LCPA_BASE U8500_ESRAM_BANK4 18 + /* 19 + * on V1 DMA uses 4KB for logical parameters position is right after the 64KB 20 + * reserved for security 21 + */ 22 + #define U8500_ESRAM_DMA_LCPA_OFFSET 0x10000 23 + 24 + #define U8500_DMA_LCPA_BASE (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET) 20 25 #define U8500_DMA_LCPA_BASE_ED (U8500_ESRAM_BANK4 + 0x4000) 21 26 22 27 #define U8500_PER3_BASE 0x80000000 ··· 32 27 #define U8500_B2R2_BASE 0x80130000 33 28 #define U8500_HSEM_BASE 0x80140000 34 29 #define U8500_PER4_BASE 0x80150000 30 + #define U8500_TPIU_BASE 0x80190000 35 31 #define U8500_ICN_BASE 0x81000000 36 32 37 33 #define U8500_BOOT_ROM_BASE 0x90000000 34 + /* ASIC ID is at 0xbf4 offset within this region */ 35 + #define U8500_ASIC_ID_BASE 0x9001D000 38 36 39 37 #define U8500_PER6_BASE 0xa03c0000 40 38 #define U8500_PER5_BASE 0xa03e0000 ··· 78 70 79 71 /* per6 base addresses */ 80 72 #define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000) 81 - #define U8500_PKA_BASE (U8500_PER6_BASE + 0x1000) 82 - #define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000) 73 + #define U8500_HASH0_BASE (U8500_PER6_BASE + 0x1000) 74 + #define U8500_HASH1_BASE (U8500_PER6_BASE + 0x2000) 75 + #define U8500_PKA_BASE (U8500_PER6_BASE + 0x4000) 76 + #define U8500_PKAM_BASE (U8500_PER6_BASE + 0x5100) 83 77 #define U8500_MTU0_BASE (U8500_PER6_BASE + 0x6000) /* v1 */ 84 78 #define U8500_MTU1_BASE (U8500_PER6_BASE + 0x7000) /* v1 */ 85 79 #define U8500_CR_BASE (U8500_PER6_BASE + 0x8000) /* v1 */ 86 - #define U8500_CRYPTO0_BASE (U8500_PER6_BASE + 0xa000) 87 - #define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000) 80 + #define U8500_CRYP0_BASE (U8500_PER6_BASE + 0xa000) 81 + #define U8500_CRYP1_BASE (U8500_PER6_BASE + 0xb000) 88 82 #define U8500_CLKRST6_BASE (U8500_PER6_BASE + 0xf000) 89 83 90 84 /* per5 base addresses */ ··· 103 93 #define U8500_DMC_BASE (U8500_PER4_BASE + 0x06000) 104 94 #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x07000) 105 95 #define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000) 106 - #define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) 96 + #define U8500_PRCMU_TCDM_BASE (U8500_PER4_BASE + 0x68000) 97 + #define U8500_PRCMU_TCPM_BASE (U8500_PER4_BASE + 0x60000) 107 98 108 99 /* per3 base addresses */ 109 100 #define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) ··· 135 124 #define U8500_I2C1_BASE (U8500_PER1_BASE + 0x2000) 136 125 #define U8500_MSP0_BASE (U8500_PER1_BASE + 0x3000) 137 126 #define U8500_MSP1_BASE (U8500_PER1_BASE + 0x4000) 127 + #define U8500_MSP3_BASE (U8500_PER1_BASE + 0x5000) 138 128 #define U8500_SDI0_BASE (U8500_PER1_BASE + 0x6000) 139 129 #define U8500_I2C2_BASE (U8500_PER1_BASE + 0x8000) 140 130 #define U8500_SPI3_BASE (U8500_PER1_BASE + 0x9000) ··· 154 142 #define U8500_GPIOBANK6_BASE U8500_GPIO2_BASE 155 143 #define U8500_GPIOBANK7_BASE (U8500_GPIO2_BASE + 0x80) 156 144 #define U8500_GPIOBANK8_BASE U8500_GPIO3_BASE 145 + 146 + #define U8500_MCDE_SIZE 0x1000 147 + #define U8500_DSI_LINK_SIZE 0x1000 148 + #define U8500_DSI_LINK1_BASE (U8500_MCDE_BASE + U8500_MCDE_SIZE) 149 + #define U8500_DSI_LINK2_BASE (U8500_DSI_LINK1_BASE + U8500_DSI_LINK_SIZE) 150 + #define U8500_DSI_LINK3_BASE (U8500_DSI_LINK2_BASE + U8500_DSI_LINK_SIZE) 151 + #define U8500_DSI_LINK_COUNT 0x3 152 + 153 + /* Modem and APE physical addresses */ 154 + #define U8500_MODEM_BASE 0xe000000 155 + #define U8500_APE_BASE 0x6000000 157 156 158 157 #endif
+1
arch/arm/mach-ux500/include/mach/hardware.h
··· 35 35 #ifndef __ASSEMBLY__ 36 36 37 37 #include <mach/id.h> 38 + extern void __iomem *_PRCMU_BASE; 38 39 39 40 #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) 40 41
+20
arch/arm/mach-ux500/include/mach/id.h
··· 75 75 return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0); 76 76 } 77 77 78 + static inline bool cpu_is_u8500v20(void) 79 + { 80 + return cpu_is_u8500() && (dbx500_revision() == 0xB0); 81 + } 82 + 83 + static inline bool cpu_is_u8500v21(void) 84 + { 85 + return cpu_is_u8500() && (dbx500_revision() == 0xB1); 86 + } 87 + 88 + static inline bool cpu_is_u8500v20_or_later(void) 89 + { 90 + return cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11(); 91 + } 92 + 93 + static inline bool ux500_is_svp(void) 94 + { 95 + return false; 96 + } 97 + 78 98 #define ux500_unknown_soc() BUG() 79 99 80 100 #endif
+5
arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
··· 50 50 51 51 #define MOP500_IRQ_END MOP500_NR_IRQS 52 52 53 + /* 54 + * We may have several boards, but only one will run at a 55 + * time, so the one with most IRQs will bump this ahead, 56 + * but the IRQ_BOARD_START remains the same for either board. 57 + */ 53 58 #if MOP500_IRQ_END > IRQ_BOARD_END 54 59 #undef IRQ_BOARD_END 55 60 #define IRQ_BOARD_END MOP500_IRQ_END
+21
arch/arm/mach-ux500/include/mach/irqs-board-u5500.h
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License terms: GNU General Public License (GPL) version 2 5 + */ 6 + 7 + #ifndef __MACH_IRQS_BOARD_U5500_H 8 + #define __MACH_IRQS_BOARD_U5500_H 9 + 10 + #define AB5500_NR_IRQS 5 11 + #define IRQ_AB5500_BASE IRQ_BOARD_START 12 + #define IRQ_AB5500_END (IRQ_AB5500_BASE + AB5500_NR_IRQS) 13 + 14 + #define U5500_IRQ_END IRQ_AB5500_END 15 + 16 + #if IRQ_BOARD_END < U5500_IRQ_END 17 + #undef IRQ_BOARD_END 18 + #define IRQ_BOARD_END U5500_IRQ_END 19 + #endif 20 + 21 + #endif
+27
arch/arm/mach-ux500/include/mach/irqs-db5500.h
··· 83 83 #define IRQ_DB5500_GPIO6 (IRQ_SHPI_START + 125) 84 84 #define IRQ_DB5500_GPIO7 (IRQ_SHPI_START + 126) 85 85 86 + #ifdef CONFIG_UX500_SOC_DB5500 87 + 88 + /* 89 + * After the GPIO ones we reserve a range of IRQ:s in which virtual 90 + * IRQ:s representing modem IRQ:s can be allocated 91 + */ 92 + #define IRQ_MODEM_EVENTS_BASE IRQ_SOC_START 93 + #define IRQ_MODEM_EVENTS_NBR 72 94 + #define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR) 95 + 96 + /* List of virtual IRQ:s that are allocated from the range above */ 97 + #define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43) 98 + #define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45) 99 + #define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41) 100 + 101 + /* 102 + * We may have several SoCs, but only one will run at a 103 + * time, so the one with most IRQs will bump this ahead, 104 + * but the IRQ_SOC_START remains the same for either SoC. 105 + */ 106 + #if IRQ_SOC_END < IRQ_MODEM_EVENTS_END 107 + #undef IRQ_SOC_END 108 + #define IRQ_SOC_END IRQ_MODEM_EVENTS_END 109 + #endif 110 + 111 + #endif /* CONFIG_UX500_SOC_DB5500 */ 112 + 86 113 #endif
+54
arch/arm/mach-ux500/include/mach/irqs-db8500.h
··· 93 93 #define IRQ_DB8500_GPIO7 (IRQ_SHPI_START + 126) 94 94 #define IRQ_DB8500_GPIO8 (IRQ_SHPI_START + 127) 95 95 96 + #define IRQ_CA_WAKE_REQ_ED (IRQ_SHPI_START + 71) 97 + #define IRQ_AC_READ_NOTIFICATION_0_ED (IRQ_SHPI_START + 66) 98 + #define IRQ_AC_READ_NOTIFICATION_1_ED (IRQ_SHPI_START + 64) 99 + #define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED (IRQ_SHPI_START + 67) 100 + #define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED (IRQ_SHPI_START + 65) 101 + 102 + #define IRQ_CA_WAKE_REQ_V1 (IRQ_SHPI_START + 83) 103 + #define IRQ_AC_READ_NOTIFICATION_0_V1 (IRQ_SHPI_START + 78) 104 + #define IRQ_AC_READ_NOTIFICATION_1_V1 (IRQ_SHPI_START + 76) 105 + #define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1 (IRQ_SHPI_START + 79) 106 + #define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1 (IRQ_SHPI_START + 77) 107 + 108 + #ifdef CONFIG_UX500_SOC_DB8500 109 + 110 + /* Virtual interrupts corresponding to the PRCMU wakeups. */ 111 + #define IRQ_PRCMU_BASE IRQ_SOC_START 112 + #define NUM_PRCMU_WAKEUPS (IRQ_PRCMU_END - IRQ_PRCMU_BASE) 113 + 114 + #define IRQ_PRCMU_RTC (IRQ_PRCMU_BASE) 115 + #define IRQ_PRCMU_RTT0 (IRQ_PRCMU_BASE + 1) 116 + #define IRQ_PRCMU_RTT1 (IRQ_PRCMU_BASE + 2) 117 + #define IRQ_PRCMU_HSI0 (IRQ_PRCMU_BASE + 3) 118 + #define IRQ_PRCMU_HSI1 (IRQ_PRCMU_BASE + 4) 119 + #define IRQ_PRCMU_CA_WAKE (IRQ_PRCMU_BASE + 5) 120 + #define IRQ_PRCMU_USB (IRQ_PRCMU_BASE + 6) 121 + #define IRQ_PRCMU_ABB (IRQ_PRCMU_BASE + 7) 122 + #define IRQ_PRCMU_ABB_FIFO (IRQ_PRCMU_BASE + 8) 123 + #define IRQ_PRCMU_ARM (IRQ_PRCMU_BASE + 9) 124 + #define IRQ_PRCMU_MODEM_SW_RESET_REQ (IRQ_PRCMU_BASE + 10) 125 + #define IRQ_PRCMU_GPIO0 (IRQ_PRCMU_BASE + 11) 126 + #define IRQ_PRCMU_GPIO1 (IRQ_PRCMU_BASE + 12) 127 + #define IRQ_PRCMU_GPIO2 (IRQ_PRCMU_BASE + 13) 128 + #define IRQ_PRCMU_GPIO3 (IRQ_PRCMU_BASE + 14) 129 + #define IRQ_PRCMU_GPIO4 (IRQ_PRCMU_BASE + 15) 130 + #define IRQ_PRCMU_GPIO5 (IRQ_PRCMU_BASE + 16) 131 + #define IRQ_PRCMU_GPIO6 (IRQ_PRCMU_BASE + 17) 132 + #define IRQ_PRCMU_GPIO7 (IRQ_PRCMU_BASE + 18) 133 + #define IRQ_PRCMU_GPIO8 (IRQ_PRCMU_BASE + 19) 134 + #define IRQ_PRCMU_CA_SLEEP (IRQ_PRCMU_BASE + 20) 135 + #define IRQ_PRCMU_HOTMON_LOW (IRQ_PRCMU_BASE + 21) 136 + #define IRQ_PRCMU_HOTMON_HIGH (IRQ_PRCMU_BASE + 22) 137 + #define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23) 138 + 139 + /* 140 + * We may have several SoCs, but only one will run at a 141 + * time, so the one with most IRQs will bump this ahead, 142 + * but the IRQ_SOC_START remains the same for either SoC. 143 + */ 144 + #if IRQ_SOC_END < IRQ_PRCMU_END 145 + #undef IRQ_SOC_END 146 + #define IRQ_SOC_END IRQ_PRCMU_END 147 + #endif 148 + 149 + #endif /* CONFIG_UX500_SOC_DB8500 */ 96 150 #endif
+22 -24
arch/arm/mach-ux500/include/mach/irqs.h
··· 10 10 #ifndef ASM_ARCH_IRQS_H 11 11 #define ASM_ARCH_IRQS_H 12 12 13 - #include <mach/irqs-db5500.h> 14 - #include <mach/irqs-db8500.h> 13 + #include <mach/hardware.h> 15 14 16 - #define IRQ_LOCALTIMER 29 17 - #define IRQ_LOCALWDOG 30 15 + #define IRQ_LOCALTIMER 29 16 + #define IRQ_LOCALWDOG 30 18 17 19 18 /* Shared Peripheral Interrupt (SHPI) */ 20 19 #define IRQ_SHPI_START 32 21 20 22 - /* Interrupt numbers generic for shared peripheral */ 21 + /* 22 + * MTU0 preserved for now until plat-nomadik is taught not to use it. Don't 23 + * add any other IRQs here, use the irqs-dbx500.h files. 24 + */ 23 25 #define IRQ_MTU0 (IRQ_SHPI_START + 4) 24 26 25 - /* There are 128 shared peripheral interrupts assigned to 26 - * INTID[160:32]. The first 32 interrupts are reserved. 27 - */ 28 - #define DBX500_NR_INTERNAL_IRQS 161 27 + #define DBX500_NR_INTERNAL_IRQS 160 29 28 30 29 /* After chip-specific IRQ numbers we have the GPIO ones */ 31 30 #define NOMADIK_NR_GPIO 288 32 31 #define NOMADIK_GPIO_TO_IRQ(gpio) ((gpio) + DBX500_NR_INTERNAL_IRQS) 33 32 #define NOMADIK_IRQ_TO_GPIO(irq) ((irq) - DBX500_NR_INTERNAL_IRQS) 34 - #define IRQ_BOARD_START NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO) 33 + #define IRQ_GPIO_END NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO) 35 34 35 + #define IRQ_SOC_START IRQ_GPIO_END 36 + /* This will be overridden by SoC-specific irq headers */ 37 + #define IRQ_SOC_END IRQ_SOC_START 38 + 39 + #include <mach/irqs-db5500.h> 40 + #include <mach/irqs-db8500.h> 41 + 42 + #define IRQ_BOARD_START IRQ_SOC_END 36 43 /* This will be overridden by board-specific irq headers */ 37 - #define IRQ_BOARD_END IRQ_BOARD_START 44 + #define IRQ_BOARD_END IRQ_BOARD_START 38 45 39 46 #ifdef CONFIG_MACH_U8500 40 47 #include <mach/irqs-board-mop500.h> 41 48 #endif 42 49 43 - /* 44 - * After the board specific IRQ:s we reserve a range of IRQ:s in which virtual 45 - * IRQ:s representing modem IRQ:s can be allocated 46 - */ 47 - #define IRQ_MODEM_EVENTS_BASE (IRQ_BOARD_END + 1) 48 - #define IRQ_MODEM_EVENTS_NBR 72 49 - #define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR) 50 + #ifdef CONFIG_MACH_U5500 51 + #include <mach/irqs-board-u5500.h> 52 + #endif 50 53 51 - /* List of virtual IRQ:s that are allocated from the range above */ 52 - #define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43) 53 - #define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45) 54 - #define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41) 55 - 56 - #define NR_IRQS IRQ_MODEM_EVENTS_END 54 + #define NR_IRQS IRQ_BOARD_END 57 55 58 56 #endif /* ASM_ARCH_IRQS_H */
-30
arch/arm/mach-ux500/include/mach/prcmu-defs.h
··· 1 - /* 2 - * Copyright (C) STMicroelectronics 2009 3 - * Copyright (C) ST-Ericsson SA 2010 4 - * 5 - * Author: Sundar Iyer <sundar.iyer@stericsson.com> 6 - * Author: Martin Persson <martin.persson@stericsson.com> 7 - * 8 - * License Terms: GNU General Public License v2 9 - * 10 - * PRCM Unit definitions 11 - */ 12 - 13 - #ifndef __MACH_PRCMU_DEFS_H 14 - #define __MACH_PRCMU_DEFS_H 15 - 16 - enum prcmu_cpu_opp { 17 - CPU_OPP_INIT = 0x00, 18 - CPU_OPP_NO_CHANGE = 0x01, 19 - CPU_OPP_100 = 0x02, 20 - CPU_OPP_50 = 0x03, 21 - CPU_OPP_MAX = 0x04, 22 - CPU_OPP_EXT_CLK = 0x07 23 - }; 24 - enum prcmu_ape_opp { 25 - APE_OPP_NO_CHANGE = 0x00, 26 - APE_OPP_100 = 0x02, 27 - APE_OPP_50 = 0x03, 28 - }; 29 - 30 - #endif /* __MACH_PRCMU_DEFS_H */
+23 -4
arch/arm/mach-ux500/include/mach/prcmu-regs.h drivers/mfd/db5500-prcmu-regs.h
··· 15 15 16 16 #include <mach/hardware.h> 17 17 18 - #define _PRCMU_BASE IO_ADDRESS(U8500_PRCMU_BASE) 19 - 20 18 #define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) 19 + #define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE 0x3f 20 + #define PRCM_ARM_PLLDIVPS_MAX_MASK 0xf 21 + 22 + #define PRCM_PLLARM_LOCKP (_PRCMU_BASE + 0x0a8) 23 + #define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 24 + 21 25 #define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) 26 + #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1 27 + 22 28 #define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) 29 + #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 30 + #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON 0x100 31 + 23 32 #define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) 24 33 #define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) 25 34 #define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) ··· 37 28 38 29 /* ARM WFI Standby signal register */ 39 30 #define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) 40 - #define PRCMU_IOCR (_PRCMU_BASE + 0x310) 31 + #define PRCM_IOCR (_PRCMU_BASE + 0x310) 32 + #define PRCM_IOCR_IOFORCE 0x1 41 33 42 34 /* CPU mailbox registers */ 43 35 #define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) ··· 47 37 48 38 /* Dual A9 core interrupt management unit registers */ 49 39 #define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) 40 + #define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ 0x1 41 + 50 42 #define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) 51 43 #define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) 52 44 #define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) ··· 86 74 /* PRCMU clock/PLL/reset registers */ 87 75 #define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) 88 76 #define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) 77 + #define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) 89 78 #define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) 90 79 #define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) 91 80 #define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) 92 81 #define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) 93 82 #define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) 94 83 #define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) 84 + #define PRCM_PLLDSI_LOCKP (_PRCMU_BASE + 0x508) 95 85 #define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) 96 86 #define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) 87 + #define PRCM_CLKOCR (_PRCMU_BASE + 0x1CC) 97 88 98 89 /* ePOD and memory power signal control registers */ 99 90 #define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) ··· 107 92 108 93 /* Miscellaneous unit registers */ 109 94 #define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) 95 + #define PRCM_GPIOCR (_PRCMU_BASE + 0x138) 96 + #define PRCM_GPIOCR_DBG_STM_MOD_CMD1 0x800 97 + #define PRCM_GPIOCR_DBG_UARTMOD_CMD0 0x1 110 98 111 - #endif /* __MACH_PRCMU_REGS_H */ 99 + 100 + #endif /* __MACH_PRCMU__REGS_H */
-28
arch/arm/mach-ux500/include/mach/prcmu.h
··· 1 - /* 2 - * Copyright (C) STMicroelectronics 2009 3 - * Copyright (C) ST-Ericsson SA 2010 4 - * 5 - * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> 6 - * Author: Sundar Iyer <sundar.iyer@stericsson.com> 7 - * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> 8 - * 9 - * License Terms: GNU General Public License v2 10 - * 11 - * PRCM Unit f/w API 12 - */ 13 - #ifndef __MACH_PRCMU_H 14 - #define __MACH_PRCMU_H 15 - #include <mach/prcmu-defs.h> 16 - 17 - void __init prcmu_early_init(void); 18 - int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); 19 - int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); 20 - int prcmu_set_ape_opp(enum prcmu_ape_opp opp); 21 - int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp); 22 - int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, 23 - enum prcmu_cpu_opp cpu_opp); 24 - int prcmu_get_ape_opp(void); 25 - int prcmu_get_cpu_opp(void); 26 - bool prcmu_has_arm_maxopp(void); 27 - 28 - #endif /* __MACH_PRCMU_H */
-394
arch/arm/mach-ux500/prcmu.c
··· 1 - /* 2 - * Copyright (C) STMicroelectronics 2009 3 - * Copyright (C) ST-Ericsson SA 2010 4 - * 5 - * License Terms: GNU General Public License v2 6 - * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> 7 - * Author: Sundar Iyer <sundar.iyer@stericsson.com> 8 - * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> 9 - * 10 - * U8500 PRCM Unit interface driver 11 - * 12 - */ 13 - #include <linux/kernel.h> 14 - #include <linux/module.h> 15 - #include <linux/errno.h> 16 - #include <linux/err.h> 17 - #include <linux/io.h> 18 - #include <linux/mutex.h> 19 - #include <linux/completion.h> 20 - #include <linux/jiffies.h> 21 - #include <linux/bitops.h> 22 - #include <linux/interrupt.h> 23 - 24 - #include <mach/hardware.h> 25 - #include <mach/prcmu-regs.h> 26 - #include <mach/prcmu-defs.h> 27 - 28 - /* Global var to runtime determine TCDM base for v2 or v1 */ 29 - static __iomem void *tcdm_base; 30 - 31 - #define _MBOX_HEADER (tcdm_base + 0xFE8) 32 - #define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0) 33 - 34 - #define REQ_MB1 (tcdm_base + 0xFD0) 35 - #define REQ_MB5 (tcdm_base + 0xE44) 36 - 37 - #define REQ_MB1_ARMOPP (REQ_MB1 + 0x0) 38 - #define REQ_MB1_APEOPP (REQ_MB1 + 0x1) 39 - #define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2) 40 - 41 - #define ACK_MB1 (tcdm_base + 0xE04) 42 - #define ACK_MB5 (tcdm_base + 0xDF4) 43 - 44 - #define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0) 45 - #define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1) 46 - 47 - #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) 48 - #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) 49 - #define REQ_MB5_I2C_REG (REQ_MB5 + 2) 50 - #define REQ_MB5_I2C_VAL (REQ_MB5 + 3) 51 - 52 - #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) 53 - #define ACK_MB5_I2C_VAL (ACK_MB5 + 3) 54 - 55 - #define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4) 56 - #define PRCM_AVS_ISMODEENABLE 7 57 - #define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) 58 - 59 - #define I2C_WRITE(slave) \ 60 - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) 61 - #define I2C_READ(slave) \ 62 - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0)) 63 - #define I2C_STOP_EN BIT(3) 64 - 65 - enum mb1_h { 66 - MB1H_ARM_OPP = 1, 67 - MB1H_APE_OPP, 68 - MB1H_ARM_APE_OPP, 69 - }; 70 - 71 - static struct { 72 - struct mutex lock; 73 - struct completion work; 74 - struct { 75 - u8 arm_opp; 76 - u8 ape_opp; 77 - u8 arm_status; 78 - u8 ape_status; 79 - } ack; 80 - } mb1_transfer; 81 - 82 - enum ack_mb5_status { 83 - I2C_WR_OK = 0x01, 84 - I2C_RD_OK = 0x02, 85 - }; 86 - 87 - #define MBOX_BIT BIT 88 - #define NUM_MBOX 8 89 - 90 - static struct { 91 - struct mutex lock; 92 - struct completion work; 93 - bool failed; 94 - struct { 95 - u8 status; 96 - u8 value; 97 - } ack; 98 - } mb5_transfer; 99 - 100 - /** 101 - * prcmu_abb_read() - Read register value(s) from the ABB. 102 - * @slave: The I2C slave address. 103 - * @reg: The (start) register address. 104 - * @value: The read out value(s). 105 - * @size: The number of registers to read. 106 - * 107 - * Reads register value(s) from the ABB. 108 - * @size has to be 1 for the current firmware version. 109 - */ 110 - int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) 111 - { 112 - int r; 113 - 114 - if (size != 1) 115 - return -EINVAL; 116 - 117 - r = mutex_lock_interruptible(&mb5_transfer.lock); 118 - if (r) 119 - return r; 120 - 121 - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) 122 - cpu_relax(); 123 - 124 - writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP); 125 - writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); 126 - writeb(reg, REQ_MB5_I2C_REG); 127 - 128 - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); 129 - if (!wait_for_completion_timeout(&mb5_transfer.work, 130 - msecs_to_jiffies(500))) { 131 - pr_err("prcmu: prcmu_abb_read timed out.\n"); 132 - r = -EIO; 133 - goto unlock_and_return; 134 - } 135 - r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); 136 - if (!r) 137 - *value = mb5_transfer.ack.value; 138 - 139 - unlock_and_return: 140 - mutex_unlock(&mb5_transfer.lock); 141 - return r; 142 - } 143 - EXPORT_SYMBOL(prcmu_abb_read); 144 - 145 - /** 146 - * prcmu_abb_write() - Write register value(s) to the ABB. 147 - * @slave: The I2C slave address. 148 - * @reg: The (start) register address. 149 - * @value: The value(s) to write. 150 - * @size: The number of registers to write. 151 - * 152 - * Reads register value(s) from the ABB. 153 - * @size has to be 1 for the current firmware version. 154 - */ 155 - int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) 156 - { 157 - int r; 158 - 159 - if (size != 1) 160 - return -EINVAL; 161 - 162 - r = mutex_lock_interruptible(&mb5_transfer.lock); 163 - if (r) 164 - return r; 165 - 166 - 167 - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) 168 - cpu_relax(); 169 - 170 - writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP); 171 - writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); 172 - writeb(reg, REQ_MB5_I2C_REG); 173 - writeb(*value, REQ_MB5_I2C_VAL); 174 - 175 - writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); 176 - if (!wait_for_completion_timeout(&mb5_transfer.work, 177 - msecs_to_jiffies(500))) { 178 - pr_err("prcmu: prcmu_abb_write timed out.\n"); 179 - r = -EIO; 180 - goto unlock_and_return; 181 - } 182 - r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); 183 - 184 - unlock_and_return: 185 - mutex_unlock(&mb5_transfer.lock); 186 - return r; 187 - } 188 - EXPORT_SYMBOL(prcmu_abb_write); 189 - 190 - static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp, 191 - enum prcmu_cpu_opp cpu_opp) 192 - { 193 - bool do_ape; 194 - bool do_arm; 195 - int err = 0; 196 - 197 - do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP)); 198 - do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP)); 199 - 200 - mutex_lock(&mb1_transfer.lock); 201 - 202 - while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) 203 - cpu_relax(); 204 - 205 - writeb(0, MBOX_HEADER_REQ_MB0); 206 - writeb(cpu_opp, REQ_MB1_ARMOPP); 207 - writeb(ape_opp, REQ_MB1_APEOPP); 208 - writeb(0, REQ_MB1_BOOSTOPP); 209 - writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET); 210 - wait_for_completion(&mb1_transfer.work); 211 - if ((do_ape) && (mb1_transfer.ack.ape_status != 0)) 212 - err = -EIO; 213 - if ((do_arm) && (mb1_transfer.ack.arm_status != 0)) 214 - err = -EIO; 215 - 216 - mutex_unlock(&mb1_transfer.lock); 217 - 218 - return err; 219 - } 220 - 221 - /** 222 - * prcmu_set_ape_opp() - Set the OPP of the APE. 223 - * @opp: The OPP to set. 224 - * 225 - * This function sets the OPP of the APE. 226 - */ 227 - int prcmu_set_ape_opp(enum prcmu_ape_opp opp) 228 - { 229 - return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE); 230 - } 231 - EXPORT_SYMBOL(prcmu_set_ape_opp); 232 - 233 - /** 234 - * prcmu_set_cpu_opp() - Set the OPP of the CPU. 235 - * @opp: The OPP to set. 236 - * 237 - * This function sets the OPP of the CPU. 238 - */ 239 - int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp) 240 - { 241 - return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp); 242 - } 243 - EXPORT_SYMBOL(prcmu_set_cpu_opp); 244 - 245 - /** 246 - * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU. 247 - * @ape_opp: The APE OPP to set. 248 - * @cpu_opp: The CPU OPP to set. 249 - * 250 - * This function sets the OPPs of the APE and the CPU. 251 - */ 252 - int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp, 253 - enum prcmu_cpu_opp cpu_opp) 254 - { 255 - return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp); 256 - } 257 - EXPORT_SYMBOL(prcmu_set_ape_cpu_opps); 258 - 259 - /** 260 - * prcmu_get_ape_opp() - Get the OPP of the APE. 261 - * 262 - * This function gets the OPP of the APE. 263 - */ 264 - enum prcmu_ape_opp prcmu_get_ape_opp(void) 265 - { 266 - return readb(ACK_MB1_CURR_APEOPP); 267 - } 268 - EXPORT_SYMBOL(prcmu_get_ape_opp); 269 - 270 - /** 271 - * prcmu_get_cpu_opp() - Get the OPP of the CPU. 272 - * 273 - * This function gets the OPP of the CPU. The OPP is specified in %%. 274 - * PRCMU_OPP_EXT is a special OPP value, not specified in %%. 275 - */ 276 - int prcmu_get_cpu_opp(void) 277 - { 278 - return readb(ACK_MB1_CURR_ARMOPP); 279 - } 280 - EXPORT_SYMBOL(prcmu_get_cpu_opp); 281 - 282 - bool prcmu_has_arm_maxopp(void) 283 - { 284 - return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK) 285 - == PRCM_AVS_ISMODEENABLE_MASK; 286 - } 287 - 288 - static void read_mailbox_0(void) 289 - { 290 - writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); 291 - } 292 - 293 - static void read_mailbox_1(void) 294 - { 295 - mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP); 296 - mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP); 297 - complete(&mb1_transfer.work); 298 - writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); 299 - } 300 - 301 - static void read_mailbox_2(void) 302 - { 303 - writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); 304 - } 305 - 306 - static void read_mailbox_3(void) 307 - { 308 - writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); 309 - } 310 - 311 - static void read_mailbox_4(void) 312 - { 313 - writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); 314 - } 315 - 316 - static void read_mailbox_5(void) 317 - { 318 - mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS); 319 - mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL); 320 - complete(&mb5_transfer.work); 321 - writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); 322 - } 323 - 324 - static void read_mailbox_6(void) 325 - { 326 - writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); 327 - } 328 - 329 - static void read_mailbox_7(void) 330 - { 331 - writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); 332 - } 333 - 334 - static void (* const read_mailbox[NUM_MBOX])(void) = { 335 - read_mailbox_0, 336 - read_mailbox_1, 337 - read_mailbox_2, 338 - read_mailbox_3, 339 - read_mailbox_4, 340 - read_mailbox_5, 341 - read_mailbox_6, 342 - read_mailbox_7 343 - }; 344 - 345 - static irqreturn_t prcmu_irq_handler(int irq, void *data) 346 - { 347 - u32 bits; 348 - u8 n; 349 - 350 - bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1)); 351 - if (unlikely(!bits)) 352 - return IRQ_NONE; 353 - 354 - for (n = 0; bits; n++) { 355 - if (bits & MBOX_BIT(n)) { 356 - bits -= MBOX_BIT(n); 357 - read_mailbox[n](); 358 - } 359 - } 360 - return IRQ_HANDLED; 361 - } 362 - 363 - void __init prcmu_early_init(void) 364 - { 365 - if (cpu_is_u8500v11() || cpu_is_u8500ed()) { 366 - tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); 367 - } else if (cpu_is_u8500v2()) { 368 - tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); 369 - } else { 370 - pr_err("prcmu: Unsupported chip version\n"); 371 - BUG(); 372 - } 373 - } 374 - 375 - static int __init prcmu_init(void) 376 - { 377 - if (cpu_is_u8500ed()) { 378 - pr_err("prcmu: Unsupported chip version\n"); 379 - return 0; 380 - } 381 - 382 - mutex_init(&mb1_transfer.lock); 383 - init_completion(&mb1_transfer.work); 384 - mutex_init(&mb5_transfer.lock); 385 - init_completion(&mb5_transfer.work); 386 - 387 - /* Clean up the mailbox interrupts after pre-kernel code. */ 388 - writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); 389 - 390 - return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0, 391 - "prcmu", NULL); 392 - } 393 - 394 - arch_initcall(prcmu_init);
+2
drivers/cpufreq/Makefile
··· 39 39 40 40 ##################################################################################d 41 41 42 + # ARM SoC drivers 43 + obj-$(CONFIG_UX500_SOC_DB8500) += db8500-cpufreq.o
+169
drivers/cpufreq/db8500-cpufreq.c
··· 1 + /* 2 + * Copyright (C) STMicroelectronics 2009 3 + * Copyright (C) ST-Ericsson SA 2010 4 + * 5 + * License Terms: GNU General Public License v2 6 + * Author: Sundar Iyer <sundar.iyer@stericsson.com> 7 + * Author: Martin Persson <martin.persson@stericsson.com> 8 + * Author: Jonas Aaberg <jonas.aberg@stericsson.com> 9 + * 10 + */ 11 + #include <linux/kernel.h> 12 + #include <linux/cpufreq.h> 13 + #include <linux/delay.h> 14 + #include <linux/slab.h> 15 + #include <linux/mfd/db8500-prcmu.h> 16 + #include <mach/id.h> 17 + 18 + static struct cpufreq_frequency_table freq_table[] = { 19 + [0] = { 20 + .index = 0, 21 + .frequency = 300000, 22 + }, 23 + [1] = { 24 + .index = 1, 25 + .frequency = 600000, 26 + }, 27 + [2] = { 28 + /* Used for MAX_OPP, if available */ 29 + .index = 2, 30 + .frequency = CPUFREQ_TABLE_END, 31 + }, 32 + [3] = { 33 + .index = 3, 34 + .frequency = CPUFREQ_TABLE_END, 35 + }, 36 + }; 37 + 38 + static enum arm_opp idx2opp[] = { 39 + ARM_50_OPP, 40 + ARM_100_OPP, 41 + ARM_MAX_OPP 42 + }; 43 + 44 + static struct freq_attr *db8500_cpufreq_attr[] = { 45 + &cpufreq_freq_attr_scaling_available_freqs, 46 + NULL, 47 + }; 48 + 49 + static int db8500_cpufreq_verify_speed(struct cpufreq_policy *policy) 50 + { 51 + return cpufreq_frequency_table_verify(policy, freq_table); 52 + } 53 + 54 + static int db8500_cpufreq_target(struct cpufreq_policy *policy, 55 + unsigned int target_freq, 56 + unsigned int relation) 57 + { 58 + struct cpufreq_freqs freqs; 59 + unsigned int idx; 60 + 61 + /* scale the target frequency to one of the extremes supported */ 62 + if (target_freq < policy->cpuinfo.min_freq) 63 + target_freq = policy->cpuinfo.min_freq; 64 + if (target_freq > policy->cpuinfo.max_freq) 65 + target_freq = policy->cpuinfo.max_freq; 66 + 67 + /* Lookup the next frequency */ 68 + if (cpufreq_frequency_table_target 69 + (policy, freq_table, target_freq, relation, &idx)) { 70 + return -EINVAL; 71 + } 72 + 73 + freqs.old = policy->cur; 74 + freqs.new = freq_table[idx].frequency; 75 + freqs.cpu = policy->cpu; 76 + 77 + if (freqs.old == freqs.new) 78 + return 0; 79 + 80 + /* pre-change notification */ 81 + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 82 + 83 + /* request the PRCM unit for opp change */ 84 + if (prcmu_set_arm_opp(idx2opp[idx])) { 85 + pr_err("db8500-cpufreq: Failed to set OPP level\n"); 86 + return -EINVAL; 87 + } 88 + 89 + /* post change notification */ 90 + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 91 + 92 + return 0; 93 + } 94 + 95 + static unsigned int db8500_cpufreq_getspeed(unsigned int cpu) 96 + { 97 + int i; 98 + /* request the prcm to get the current ARM opp */ 99 + for (i = 0; prcmu_get_arm_opp() != idx2opp[i]; i++) 100 + ; 101 + return freq_table[i].frequency; 102 + } 103 + 104 + static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy) 105 + { 106 + int res; 107 + int i; 108 + 109 + BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table)); 110 + 111 + if (cpu_is_u8500v2() && !prcmu_is_u8400()) { 112 + freq_table[0].frequency = 400000; 113 + freq_table[1].frequency = 800000; 114 + if (prcmu_has_arm_maxopp()) 115 + freq_table[2].frequency = 1000000; 116 + } 117 + 118 + /* get policy fields based on the table */ 119 + res = cpufreq_frequency_table_cpuinfo(policy, freq_table); 120 + if (!res) 121 + cpufreq_frequency_table_get_attr(freq_table, policy->cpu); 122 + else { 123 + pr_err("db8500-cpufreq : Failed to read policy table\n"); 124 + return res; 125 + } 126 + 127 + policy->min = policy->cpuinfo.min_freq; 128 + policy->max = policy->cpuinfo.max_freq; 129 + policy->cur = db8500_cpufreq_getspeed(policy->cpu); 130 + 131 + for (i = 0; freq_table[i].frequency != policy->cur; i++) 132 + ; 133 + 134 + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; 135 + 136 + /* 137 + * FIXME : Need to take time measurement across the target() 138 + * function with no/some/all drivers in the notification 139 + * list. 140 + */ 141 + policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */ 142 + 143 + /* policy sharing between dual CPUs */ 144 + cpumask_copy(policy->cpus, &cpu_present_map); 145 + 146 + policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; 147 + 148 + return 0; 149 + } 150 + 151 + static struct cpufreq_driver db8500_cpufreq_driver = { 152 + .flags = CPUFREQ_STICKY, 153 + .verify = db8500_cpufreq_verify_speed, 154 + .target = db8500_cpufreq_target, 155 + .get = db8500_cpufreq_getspeed, 156 + .init = db8500_cpufreq_init, 157 + .name = "DB8500", 158 + .attr = db8500_cpufreq_attr, 159 + }; 160 + 161 + static int __init db8500_cpufreq_register(void) 162 + { 163 + if (!cpu_is_u8500v20_or_later()) 164 + return -ENODEV; 165 + 166 + pr_info("cpufreq for DB8500 started\n"); 167 + return cpufreq_register_driver(&db8500_cpufreq_driver); 168 + } 169 + device_initcall(db8500_cpufreq_register);
+21 -1
drivers/mfd/Kconfig
··· 538 538 539 539 config AB8500_I2C_CORE 540 540 bool "AB8500 register access via PRCMU I2C" 541 - depends on AB8500_CORE && UX500_SOC_DB8500 541 + depends on AB8500_CORE && MFD_DB8500_PRCMU 542 542 default y 543 543 help 544 544 This enables register access to the AB8500 chip via PRCMU I2C. ··· 574 574 of the AB3550 such as battery-backed RTC, charging control, 575 575 LEDs, vibrator, system power and temperature, power management 576 576 and ALSA sound. 577 + 578 + config MFD_DB8500_PRCMU 579 + bool "ST-Ericsson DB8500 Power Reset Control Management Unit" 580 + depends on UX500_SOC_DB8500 581 + select MFD_CORE 582 + help 583 + Select this option to enable support for the DB8500 Power Reset 584 + and Control Management Unit. This is basically an autonomous 585 + system controller running an XP70 microprocessor, which is accessed 586 + through a register map. 587 + 588 + config MFD_DB5500_PRCMU 589 + bool "ST-Ericsson DB5500 Power Reset Control Management Unit" 590 + depends on UX500_SOC_DB5500 591 + select MFD_CORE 592 + help 593 + Select this option to enable support for the DB5500 Power Reset 594 + and Control Management Unit. This is basically an autonomous 595 + system controller running an XP70 microprocessor, which is accessed 596 + through a register map. 577 597 578 598 config MFD_CS5535 579 599 tristate "Support for CS5535 and CS5536 southbridge core functions"
+4 -1
drivers/mfd/Makefile
··· 74 74 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 75 75 obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 76 76 obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o 77 - obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o 78 77 obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 79 78 obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o 79 + obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o 80 + # ab8500-i2c need to come after db8500-prcmu (which provides the channel) 81 + obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o 82 + obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o 80 83 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 81 84 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 82 85 obj-$(CONFIG_LPC_SCH) += lpc_sch.o
+1 -2
drivers/mfd/ab8500-i2c.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/platform_device.h> 13 13 #include <linux/mfd/ab8500.h> 14 - 15 - #include <mach/prcmu.h> 14 + #include <linux/mfd/db8500-prcmu.h> 16 15 17 16 static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) 18 17 {
+448
drivers/mfd/db5500-prcmu.c
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> 6 + * 7 + * U5500 PRCM Unit interface driver 8 + */ 9 + #include <linux/module.h> 10 + #include <linux/kernel.h> 11 + #include <linux/delay.h> 12 + #include <linux/errno.h> 13 + #include <linux/err.h> 14 + #include <linux/spinlock.h> 15 + #include <linux/io.h> 16 + #include <linux/slab.h> 17 + #include <linux/mutex.h> 18 + #include <linux/completion.h> 19 + #include <linux/irq.h> 20 + #include <linux/jiffies.h> 21 + #include <linux/bitops.h> 22 + #include <linux/interrupt.h> 23 + #include <linux/mfd/db5500-prcmu.h> 24 + #include <mach/hardware.h> 25 + #include <mach/irqs.h> 26 + #include <mach/db5500-regs.h> 27 + #include "db5500-prcmu-regs.h" 28 + 29 + #define _PRCM_MB_HEADER (tcdm_base + 0xFE8) 30 + #define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0) 31 + #define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1) 32 + #define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2) 33 + #define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3) 34 + #define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4) 35 + #define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5) 36 + #define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6) 37 + #define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7) 38 + #define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8) 39 + #define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9) 40 + #define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa) 41 + #define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb) 42 + #define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc) 43 + #define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd) 44 + #define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe) 45 + #define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf) 46 + 47 + /* Req Mailboxes */ 48 + #define PRCM_REQ_MB0 (tcdm_base + 0xFD8) 49 + #define PRCM_REQ_MB1 (tcdm_base + 0xFCC) 50 + #define PRCM_REQ_MB2 (tcdm_base + 0xFC4) 51 + #define PRCM_REQ_MB3 (tcdm_base + 0xFC0) 52 + #define PRCM_REQ_MB4 (tcdm_base + 0xF98) 53 + #define PRCM_REQ_MB5 (tcdm_base + 0xF90) 54 + #define PRCM_REQ_MB6 (tcdm_base + 0xF8C) 55 + #define PRCM_REQ_MB7 (tcdm_base + 0xF84) 56 + 57 + /* Ack Mailboxes */ 58 + #define PRCM_ACK_MB0 (tcdm_base + 0xF38) 59 + #define PRCM_ACK_MB1 (tcdm_base + 0xF30) 60 + #define PRCM_ACK_MB2 (tcdm_base + 0xF24) 61 + #define PRCM_ACK_MB3 (tcdm_base + 0xF20) 62 + #define PRCM_ACK_MB4 (tcdm_base + 0xF1C) 63 + #define PRCM_ACK_MB5 (tcdm_base + 0xF14) 64 + #define PRCM_ACK_MB6 (tcdm_base + 0xF0C) 65 + #define PRCM_ACK_MB7 (tcdm_base + 0xF08) 66 + 67 + enum mb_return_code { 68 + RC_SUCCESS, 69 + RC_FAIL, 70 + }; 71 + 72 + /* Mailbox 0 headers. */ 73 + enum mb0_header { 74 + /* request */ 75 + RMB0H_PWR_STATE_TRANS = 1, 76 + RMB0H_WAKE_UP_CFG, 77 + RMB0H_RD_WAKE_UP_ACK, 78 + /* acknowledge */ 79 + AMB0H_WAKE_UP = 1, 80 + }; 81 + 82 + /* Mailbox 5 headers. */ 83 + enum mb5_header { 84 + MB5H_I2C_WRITE = 1, 85 + MB5H_I2C_READ, 86 + }; 87 + 88 + /* Request mailbox 5 fields. */ 89 + #define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0) 90 + #define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1) 91 + #define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2) 92 + #define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4) 93 + 94 + /* Acknowledge mailbox 5 fields. */ 95 + #define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0) 96 + #define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4) 97 + 98 + #define NUM_MB 8 99 + #define MBOX_BIT BIT 100 + #define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) 101 + 102 + /* 103 + * Used by MCDE to setup all necessary PRCMU registers 104 + */ 105 + #define PRCMU_RESET_DSIPLL 0x00004000 106 + #define PRCMU_UNCLAMP_DSIPLL 0x00400800 107 + 108 + /* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/ 109 + #define PRCMU_DSI_CLOCK_SETTING 0x00000128 110 + /* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */ 111 + #define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135 112 + #define PRCMU_PLLDSI_FREQ_SETTING 0x0004013C 113 + #define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002 114 + #define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000101 115 + #define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101 116 + 117 + #define PRCMU_ENABLE_PLLDSI 0x00000001 118 + #define PRCMU_DISABLE_PLLDSI 0x00000000 119 + 120 + #define PRCMU_DSI_RESET_SW 0x00000003 121 + 122 + #define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 123 + 124 + /* 125 + * mb0_transfer - state needed for mailbox 0 communication. 126 + * @lock: The transaction lock. 127 + */ 128 + static struct { 129 + spinlock_t lock; 130 + } mb0_transfer; 131 + 132 + /* 133 + * mb5_transfer - state needed for mailbox 5 communication. 134 + * @lock: The transaction lock. 135 + * @work: The transaction completion structure. 136 + * @ack: Reply ("acknowledge") data. 137 + */ 138 + static struct { 139 + struct mutex lock; 140 + struct completion work; 141 + struct { 142 + u8 header; 143 + u8 status; 144 + u8 value[4]; 145 + } ack; 146 + } mb5_transfer; 147 + 148 + /* PRCMU TCDM base IO address. */ 149 + static __iomem void *tcdm_base; 150 + 151 + /** 152 + * db5500_prcmu_abb_read() - Read register value(s) from the ABB. 153 + * @slave: The I2C slave address. 154 + * @reg: The (start) register address. 155 + * @value: The read out value(s). 156 + * @size: The number of registers to read. 157 + * 158 + * Reads register value(s) from the ABB. 159 + * @size has to be <= 4. 160 + */ 161 + int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) 162 + { 163 + int r; 164 + 165 + if ((size < 1) || (4 < size)) 166 + return -EINVAL; 167 + 168 + mutex_lock(&mb5_transfer.lock); 169 + 170 + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) 171 + cpu_relax(); 172 + writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); 173 + writeb(reg, PRCM_REQ_MB5_I2C_REG); 174 + writeb(size, PRCM_REQ_MB5_I2C_SIZE); 175 + writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER); 176 + 177 + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); 178 + wait_for_completion(&mb5_transfer.work); 179 + 180 + r = 0; 181 + if ((mb5_transfer.ack.header == MB5H_I2C_READ) && 182 + (mb5_transfer.ack.status == RC_SUCCESS)) 183 + memcpy(value, mb5_transfer.ack.value, (size_t)size); 184 + else 185 + r = -EIO; 186 + 187 + mutex_unlock(&mb5_transfer.lock); 188 + 189 + return r; 190 + } 191 + 192 + /** 193 + * db5500_prcmu_abb_write() - Write register value(s) to the ABB. 194 + * @slave: The I2C slave address. 195 + * @reg: The (start) register address. 196 + * @value: The value(s) to write. 197 + * @size: The number of registers to write. 198 + * 199 + * Writes register value(s) to the ABB. 200 + * @size has to be <= 4. 201 + */ 202 + int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) 203 + { 204 + int r; 205 + 206 + if ((size < 1) || (4 < size)) 207 + return -EINVAL; 208 + 209 + mutex_lock(&mb5_transfer.lock); 210 + 211 + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) 212 + cpu_relax(); 213 + writeb(slave, PRCM_REQ_MB5_I2C_SLAVE); 214 + writeb(reg, PRCM_REQ_MB5_I2C_REG); 215 + writeb(size, PRCM_REQ_MB5_I2C_SIZE); 216 + memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size); 217 + writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER); 218 + 219 + writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); 220 + wait_for_completion(&mb5_transfer.work); 221 + 222 + if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) && 223 + (mb5_transfer.ack.status == RC_SUCCESS)) 224 + r = 0; 225 + else 226 + r = -EIO; 227 + 228 + mutex_unlock(&mb5_transfer.lock); 229 + 230 + return r; 231 + } 232 + 233 + int db5500_prcmu_enable_dsipll(void) 234 + { 235 + int i; 236 + 237 + /* Enable DSIPLL_RESETN resets */ 238 + writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR); 239 + /* Unclamp DSIPLL in/out */ 240 + writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR); 241 + /* Set DSI PLL FREQ */ 242 + writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ); 243 + writel(PRCMU_DSI_PLLOUT_SEL_SETTING, 244 + PRCM_DSI_PLLOUT_SEL); 245 + /* Enable Escape clocks */ 246 + writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); 247 + 248 + /* Start DSI PLL */ 249 + writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE); 250 + /* Reset DSI PLL */ 251 + writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET); 252 + for (i = 0; i < 10; i++) { 253 + if ((readl(PRCM_PLLDSI_LOCKP) & 254 + PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED) 255 + break; 256 + udelay(100); 257 + } 258 + /* Release DSIPLL_RESETN */ 259 + writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET); 260 + return 0; 261 + } 262 + 263 + int db5500_prcmu_disable_dsipll(void) 264 + { 265 + /* Disable dsi pll */ 266 + writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE); 267 + /* Disable escapeclock */ 268 + writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV); 269 + return 0; 270 + } 271 + 272 + int db5500_prcmu_set_display_clocks(void) 273 + { 274 + /* HDMI and TVCLK Should be handled somewhere else */ 275 + /* PLLDIV=8, PLLSW=2, CLKEN=1 */ 276 + writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT); 277 + /* PLLDIV=14, PLLSW=2, CLKEN=1 */ 278 + writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT); 279 + return 0; 280 + } 281 + 282 + static void ack_dbb_wakeup(void) 283 + { 284 + unsigned long flags; 285 + 286 + spin_lock_irqsave(&mb0_transfer.lock, flags); 287 + 288 + while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) 289 + cpu_relax(); 290 + 291 + writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER); 292 + writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET); 293 + 294 + spin_unlock_irqrestore(&mb0_transfer.lock, flags); 295 + } 296 + 297 + static inline void print_unknown_header_warning(u8 n, u8 header) 298 + { 299 + pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", 300 + header, n); 301 + } 302 + 303 + static bool read_mailbox_0(void) 304 + { 305 + bool r; 306 + u8 header; 307 + 308 + header = readb(PRCM_ACK_MB0_HEADER); 309 + switch (header) { 310 + case AMB0H_WAKE_UP: 311 + r = true; 312 + break; 313 + default: 314 + print_unknown_header_warning(0, header); 315 + r = false; 316 + break; 317 + } 318 + writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); 319 + return r; 320 + } 321 + 322 + static bool read_mailbox_1(void) 323 + { 324 + writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); 325 + return false; 326 + } 327 + 328 + static bool read_mailbox_2(void) 329 + { 330 + writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); 331 + return false; 332 + } 333 + 334 + static bool read_mailbox_3(void) 335 + { 336 + writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); 337 + return false; 338 + } 339 + 340 + static bool read_mailbox_4(void) 341 + { 342 + writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); 343 + return false; 344 + } 345 + 346 + static bool read_mailbox_5(void) 347 + { 348 + u8 header; 349 + 350 + header = readb(PRCM_ACK_MB5_HEADER); 351 + switch (header) { 352 + case MB5H_I2C_READ: 353 + memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4); 354 + case MB5H_I2C_WRITE: 355 + mb5_transfer.ack.header = header; 356 + mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE); 357 + complete(&mb5_transfer.work); 358 + break; 359 + default: 360 + print_unknown_header_warning(5, header); 361 + break; 362 + } 363 + writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); 364 + return false; 365 + } 366 + 367 + static bool read_mailbox_6(void) 368 + { 369 + writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); 370 + return false; 371 + } 372 + 373 + static bool read_mailbox_7(void) 374 + { 375 + writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); 376 + return false; 377 + } 378 + 379 + static bool (* const read_mailbox[NUM_MB])(void) = { 380 + read_mailbox_0, 381 + read_mailbox_1, 382 + read_mailbox_2, 383 + read_mailbox_3, 384 + read_mailbox_4, 385 + read_mailbox_5, 386 + read_mailbox_6, 387 + read_mailbox_7 388 + }; 389 + 390 + static irqreturn_t prcmu_irq_handler(int irq, void *data) 391 + { 392 + u32 bits; 393 + u8 n; 394 + irqreturn_t r; 395 + 396 + bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); 397 + if (unlikely(!bits)) 398 + return IRQ_NONE; 399 + 400 + r = IRQ_HANDLED; 401 + for (n = 0; bits; n++) { 402 + if (bits & MBOX_BIT(n)) { 403 + bits -= MBOX_BIT(n); 404 + if (read_mailbox[n]()) 405 + r = IRQ_WAKE_THREAD; 406 + } 407 + } 408 + return r; 409 + } 410 + 411 + static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) 412 + { 413 + ack_dbb_wakeup(); 414 + return IRQ_HANDLED; 415 + } 416 + 417 + void __init db5500_prcmu_early_init(void) 418 + { 419 + tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE); 420 + spin_lock_init(&mb0_transfer.lock); 421 + mutex_init(&mb5_transfer.lock); 422 + init_completion(&mb5_transfer.work); 423 + } 424 + 425 + /** 426 + * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic 427 + * 428 + */ 429 + int __init db5500_prcmu_init(void) 430 + { 431 + int r = 0; 432 + 433 + if (ux500_is_svp() || !cpu_is_u5500()) 434 + return -ENODEV; 435 + 436 + /* Clean up the mailbox interrupts after pre-kernel code. */ 437 + writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLEAR); 438 + 439 + r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler, 440 + prcmu_irq_thread_fn, 0, "prcmu", NULL); 441 + if (r < 0) { 442 + pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n"); 443 + return -EBUSY; 444 + } 445 + return 0; 446 + } 447 + 448 + arch_initcall(db5500_prcmu_init);
+166
drivers/mfd/db8500-prcmu-regs.h
··· 1 + /* 2 + * Copyright (C) STMicroelectronics 2009 3 + * Copyright (C) ST-Ericsson SA 2010 4 + * 5 + * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> 6 + * Author: Sundar Iyer <sundar.iyer@stericsson.com> 7 + * 8 + * License Terms: GNU General Public License v2 9 + * 10 + * PRCM Unit registers 11 + */ 12 + #ifndef __DB8500_PRCMU_REGS_H 13 + #define __DB8500_PRCMU_REGS_H 14 + 15 + #include <linux/bitops.h> 16 + #include <mach/hardware.h> 17 + 18 + #define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end)) 19 + 20 + #define PRCM_ARM_PLLDIVPS 0x118 21 + #define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE BITS(0, 5) 22 + #define PRCM_ARM_PLLDIVPS_MAX_MASK 0xF 23 + 24 + #define PRCM_PLLARM_LOCKP 0x0A8 25 + #define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 BIT(1) 26 + 27 + #define PRCM_ARM_CHGCLKREQ 0x114 28 + #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0) 29 + 30 + #define PRCM_PLLARM_ENABLE 0x98 31 + #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE BIT(0) 32 + #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON BIT(8) 33 + 34 + #define PRCM_ARMCLKFIX_MGT 0x0 35 + #define PRCM_A9_RESETN_CLR 0x1f4 36 + #define PRCM_A9_RESETN_SET 0x1f0 37 + #define PRCM_ARM_LS_CLAMP 0x30C 38 + #define PRCM_SRAM_A9 0x308 39 + 40 + /* ARM WFI Standby signal register */ 41 + #define PRCM_ARM_WFI_STANDBY 0x130 42 + #define PRCM_IOCR 0x310 43 + #define PRCM_IOCR_IOFORCE BIT(0) 44 + 45 + /* CPU mailbox registers */ 46 + #define PRCM_MBOX_CPU_VAL 0x0FC 47 + #define PRCM_MBOX_CPU_SET 0x100 48 + 49 + /* Dual A9 core interrupt management unit registers */ 50 + #define PRCM_A9_MASK_REQ 0x328 51 + #define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ BIT(0) 52 + 53 + #define PRCM_A9_MASK_ACK 0x32C 54 + #define PRCM_ARMITMSK31TO0 0x11C 55 + #define PRCM_ARMITMSK63TO32 0x120 56 + #define PRCM_ARMITMSK95TO64 0x124 57 + #define PRCM_ARMITMSK127TO96 0x128 58 + #define PRCM_POWER_STATE_VAL 0x25C 59 + #define PRCM_ARMITVAL31TO0 0x260 60 + #define PRCM_ARMITVAL63TO32 0x264 61 + #define PRCM_ARMITVAL95TO64 0x268 62 + #define PRCM_ARMITVAL127TO96 0x26C 63 + 64 + #define PRCM_HOSTACCESS_REQ 0x334 65 + #define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ BIT(0) 66 + 67 + #define PRCM_ARM_IT1_CLR 0x48C 68 + #define PRCM_ARM_IT1_VAL 0x494 69 + 70 + #define PRCM_ITSTATUS0 0x148 71 + #define PRCM_ITSTATUS1 0x150 72 + #define PRCM_ITSTATUS2 0x158 73 + #define PRCM_ITSTATUS3 0x160 74 + #define PRCM_ITSTATUS4 0x168 75 + #define PRCM_ITSTATUS5 0x484 76 + #define PRCM_ITCLEAR5 0x488 77 + #define PRCM_ARMIT_MASKXP70_IT 0x1018 78 + 79 + /* System reset register */ 80 + #define PRCM_APE_SOFTRST 0x228 81 + 82 + /* Level shifter and clamp control registers */ 83 + #define PRCM_MMIP_LS_CLAMP_SET 0x420 84 + #define PRCM_MMIP_LS_CLAMP_CLR 0x424 85 + 86 + /* PRCMU HW semaphore */ 87 + #define PRCM_SEM 0x400 88 + #define PRCM_SEM_PRCM_SEM BIT(0) 89 + 90 + /* PRCMU clock/PLL/reset registers */ 91 + #define PRCM_PLLDSI_FREQ 0x500 92 + #define PRCM_PLLDSI_ENABLE 0x504 93 + #define PRCM_PLLDSI_LOCKP 0x508 94 + #define PRCM_DSI_PLLOUT_SEL 0x530 95 + #define PRCM_DSITVCLK_DIV 0x52C 96 + #define PRCM_APE_RESETN_SET 0x1E4 97 + #define PRCM_APE_RESETN_CLR 0x1E8 98 + 99 + #define PRCM_TCR 0x1C8 100 + #define PRCM_TCR_TENSEL_MASK BITS(0, 7) 101 + #define PRCM_TCR_STOP_TIMERS BIT(16) 102 + #define PRCM_TCR_DOZE_MODE BIT(17) 103 + 104 + #define PRCM_CLKOCR 0x1CC 105 + #define PRCM_CLKOCR_CLKODIV0_SHIFT 0 106 + #define PRCM_CLKOCR_CLKODIV0_MASK BITS(0, 5) 107 + #define PRCM_CLKOCR_CLKOSEL0_SHIFT 6 108 + #define PRCM_CLKOCR_CLKOSEL0_MASK BITS(6, 8) 109 + #define PRCM_CLKOCR_CLKODIV1_SHIFT 16 110 + #define PRCM_CLKOCR_CLKODIV1_MASK BITS(16, 21) 111 + #define PRCM_CLKOCR_CLKOSEL1_SHIFT 22 112 + #define PRCM_CLKOCR_CLKOSEL1_MASK BITS(22, 24) 113 + #define PRCM_CLKOCR_CLK1TYPE BIT(28) 114 + 115 + #define PRCM_SGACLK_MGT 0x014 116 + #define PRCM_UARTCLK_MGT 0x018 117 + #define PRCM_MSP02CLK_MGT 0x01C 118 + #define PRCM_MSP1CLK_MGT 0x288 119 + #define PRCM_I2CCLK_MGT 0x020 120 + #define PRCM_SDMMCCLK_MGT 0x024 121 + #define PRCM_SLIMCLK_MGT 0x028 122 + #define PRCM_PER1CLK_MGT 0x02C 123 + #define PRCM_PER2CLK_MGT 0x030 124 + #define PRCM_PER3CLK_MGT 0x034 125 + #define PRCM_PER5CLK_MGT 0x038 126 + #define PRCM_PER6CLK_MGT 0x03C 127 + #define PRCM_PER7CLK_MGT 0x040 128 + #define PRCM_LCDCLK_MGT 0x044 129 + #define PRCM_BMLCLK_MGT 0x04C 130 + #define PRCM_HSITXCLK_MGT 0x050 131 + #define PRCM_HSIRXCLK_MGT 0x054 132 + #define PRCM_HDMICLK_MGT 0x058 133 + #define PRCM_APEATCLK_MGT 0x05C 134 + #define PRCM_APETRACECLK_MGT 0x060 135 + #define PRCM_MCDECLK_MGT 0x064 136 + #define PRCM_IPI2CCLK_MGT 0x068 137 + #define PRCM_DSIALTCLK_MGT 0x06C 138 + #define PRCM_DMACLK_MGT 0x074 139 + #define PRCM_B2R2CLK_MGT 0x078 140 + #define PRCM_TVCLK_MGT 0x07C 141 + #define PRCM_UNIPROCLK_MGT 0x278 142 + #define PRCM_SSPCLK_MGT 0x280 143 + #define PRCM_RNGCLK_MGT 0x284 144 + #define PRCM_UICCCLK_MGT 0x27C 145 + 146 + #define PRCM_CLK_MGT_CLKPLLDIV_MASK BITS(0, 4) 147 + #define PRCM_CLK_MGT_CLKPLLSW_MASK BITS(5, 7) 148 + #define PRCM_CLK_MGT_CLKEN BIT(8) 149 + 150 + /* ePOD and memory power signal control registers */ 151 + #define PRCM_EPOD_C_SET 0x410 152 + #define PRCM_SRAM_LS_SLEEP 0x304 153 + 154 + /* Debug power control unit registers */ 155 + #define PRCM_POWER_STATE_SET 0x254 156 + 157 + /* Miscellaneous unit registers */ 158 + #define PRCM_DSI_SW_RESET 0x324 159 + #define PRCM_GPIOCR 0x138 160 + 161 + /* GPIOCR register */ 162 + #define PRCM_GPIOCR_SPI2_SELECT BIT(23) 163 + 164 + #define PRCM_DDR_SUBSYS_APE_MINBW 0x438 165 + 166 + #endif /* __DB8500_PRCMU_REGS_H */
+2069
drivers/mfd/db8500-prcmu.c
··· 1 + /* 2 + * Copyright (C) STMicroelectronics 2009 3 + * Copyright (C) ST-Ericsson SA 2010 4 + * 5 + * License Terms: GNU General Public License v2 6 + * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> 7 + * Author: Sundar Iyer <sundar.iyer@stericsson.com> 8 + * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> 9 + * 10 + * U8500 PRCM Unit interface driver 11 + * 12 + */ 13 + #include <linux/module.h> 14 + #include <linux/kernel.h> 15 + #include <linux/delay.h> 16 + #include <linux/errno.h> 17 + #include <linux/err.h> 18 + #include <linux/spinlock.h> 19 + #include <linux/io.h> 20 + #include <linux/slab.h> 21 + #include <linux/mutex.h> 22 + #include <linux/completion.h> 23 + #include <linux/irq.h> 24 + #include <linux/jiffies.h> 25 + #include <linux/bitops.h> 26 + #include <linux/fs.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/uaccess.h> 29 + #include <linux/mfd/core.h> 30 + #include <linux/mfd/db8500-prcmu.h> 31 + #include <linux/regulator/db8500-prcmu.h> 32 + #include <linux/regulator/machine.h> 33 + #include <mach/hardware.h> 34 + #include <mach/irqs.h> 35 + #include <mach/db8500-regs.h> 36 + #include <mach/id.h> 37 + #include "db8500-prcmu-regs.h" 38 + 39 + /* Offset for the firmware version within the TCPM */ 40 + #define PRCMU_FW_VERSION_OFFSET 0xA4 41 + 42 + /* PRCMU project numbers, defined by PRCMU FW */ 43 + #define PRCMU_PROJECT_ID_8500V1_0 1 44 + #define PRCMU_PROJECT_ID_8500V2_0 2 45 + #define PRCMU_PROJECT_ID_8400V2_0 3 46 + 47 + /* Index of different voltages to be used when accessing AVSData */ 48 + #define PRCM_AVS_BASE 0x2FC 49 + #define PRCM_AVS_VBB_RET (PRCM_AVS_BASE + 0x0) 50 + #define PRCM_AVS_VBB_MAX_OPP (PRCM_AVS_BASE + 0x1) 51 + #define PRCM_AVS_VBB_100_OPP (PRCM_AVS_BASE + 0x2) 52 + #define PRCM_AVS_VBB_50_OPP (PRCM_AVS_BASE + 0x3) 53 + #define PRCM_AVS_VARM_MAX_OPP (PRCM_AVS_BASE + 0x4) 54 + #define PRCM_AVS_VARM_100_OPP (PRCM_AVS_BASE + 0x5) 55 + #define PRCM_AVS_VARM_50_OPP (PRCM_AVS_BASE + 0x6) 56 + #define PRCM_AVS_VARM_RET (PRCM_AVS_BASE + 0x7) 57 + #define PRCM_AVS_VAPE_100_OPP (PRCM_AVS_BASE + 0x8) 58 + #define PRCM_AVS_VAPE_50_OPP (PRCM_AVS_BASE + 0x9) 59 + #define PRCM_AVS_VMOD_100_OPP (PRCM_AVS_BASE + 0xA) 60 + #define PRCM_AVS_VMOD_50_OPP (PRCM_AVS_BASE + 0xB) 61 + #define PRCM_AVS_VSAFE (PRCM_AVS_BASE + 0xC) 62 + 63 + #define PRCM_AVS_VOLTAGE 0 64 + #define PRCM_AVS_VOLTAGE_MASK 0x3f 65 + #define PRCM_AVS_ISSLOWSTARTUP 6 66 + #define PRCM_AVS_ISSLOWSTARTUP_MASK (1 << PRCM_AVS_ISSLOWSTARTUP) 67 + #define PRCM_AVS_ISMODEENABLE 7 68 + #define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE) 69 + 70 + #define PRCM_BOOT_STATUS 0xFFF 71 + #define PRCM_ROMCODE_A2P 0xFFE 72 + #define PRCM_ROMCODE_P2A 0xFFD 73 + #define PRCM_XP70_CUR_PWR_STATE 0xFFC /* 4 BYTES */ 74 + 75 + #define PRCM_SW_RST_REASON 0xFF8 /* 2 bytes */ 76 + 77 + #define _PRCM_MBOX_HEADER 0xFE8 /* 16 bytes */ 78 + #define PRCM_MBOX_HEADER_REQ_MB0 (_PRCM_MBOX_HEADER + 0x0) 79 + #define PRCM_MBOX_HEADER_REQ_MB1 (_PRCM_MBOX_HEADER + 0x1) 80 + #define PRCM_MBOX_HEADER_REQ_MB2 (_PRCM_MBOX_HEADER + 0x2) 81 + #define PRCM_MBOX_HEADER_REQ_MB3 (_PRCM_MBOX_HEADER + 0x3) 82 + #define PRCM_MBOX_HEADER_REQ_MB4 (_PRCM_MBOX_HEADER + 0x4) 83 + #define PRCM_MBOX_HEADER_REQ_MB5 (_PRCM_MBOX_HEADER + 0x5) 84 + #define PRCM_MBOX_HEADER_ACK_MB0 (_PRCM_MBOX_HEADER + 0x8) 85 + 86 + /* Req Mailboxes */ 87 + #define PRCM_REQ_MB0 0xFDC /* 12 bytes */ 88 + #define PRCM_REQ_MB1 0xFD0 /* 12 bytes */ 89 + #define PRCM_REQ_MB2 0xFC0 /* 16 bytes */ 90 + #define PRCM_REQ_MB3 0xE4C /* 372 bytes */ 91 + #define PRCM_REQ_MB4 0xE48 /* 4 bytes */ 92 + #define PRCM_REQ_MB5 0xE44 /* 4 bytes */ 93 + 94 + /* Ack Mailboxes */ 95 + #define PRCM_ACK_MB0 0xE08 /* 52 bytes */ 96 + #define PRCM_ACK_MB1 0xE04 /* 4 bytes */ 97 + #define PRCM_ACK_MB2 0xE00 /* 4 bytes */ 98 + #define PRCM_ACK_MB3 0xDFC /* 4 bytes */ 99 + #define PRCM_ACK_MB4 0xDF8 /* 4 bytes */ 100 + #define PRCM_ACK_MB5 0xDF4 /* 4 bytes */ 101 + 102 + /* Mailbox 0 headers */ 103 + #define MB0H_POWER_STATE_TRANS 0 104 + #define MB0H_CONFIG_WAKEUPS_EXE 1 105 + #define MB0H_READ_WAKEUP_ACK 3 106 + #define MB0H_CONFIG_WAKEUPS_SLEEP 4 107 + 108 + #define MB0H_WAKEUP_EXE 2 109 + #define MB0H_WAKEUP_SLEEP 5 110 + 111 + /* Mailbox 0 REQs */ 112 + #define PRCM_REQ_MB0_AP_POWER_STATE (PRCM_REQ_MB0 + 0x0) 113 + #define PRCM_REQ_MB0_AP_PLL_STATE (PRCM_REQ_MB0 + 0x1) 114 + #define PRCM_REQ_MB0_ULP_CLOCK_STATE (PRCM_REQ_MB0 + 0x2) 115 + #define PRCM_REQ_MB0_DO_NOT_WFI (PRCM_REQ_MB0 + 0x3) 116 + #define PRCM_REQ_MB0_WAKEUP_8500 (PRCM_REQ_MB0 + 0x4) 117 + #define PRCM_REQ_MB0_WAKEUP_4500 (PRCM_REQ_MB0 + 0x8) 118 + 119 + /* Mailbox 0 ACKs */ 120 + #define PRCM_ACK_MB0_AP_PWRSTTR_STATUS (PRCM_ACK_MB0 + 0x0) 121 + #define PRCM_ACK_MB0_READ_POINTER (PRCM_ACK_MB0 + 0x1) 122 + #define PRCM_ACK_MB0_WAKEUP_0_8500 (PRCM_ACK_MB0 + 0x4) 123 + #define PRCM_ACK_MB0_WAKEUP_0_4500 (PRCM_ACK_MB0 + 0x8) 124 + #define PRCM_ACK_MB0_WAKEUP_1_8500 (PRCM_ACK_MB0 + 0x1C) 125 + #define PRCM_ACK_MB0_WAKEUP_1_4500 (PRCM_ACK_MB0 + 0x20) 126 + #define PRCM_ACK_MB0_EVENT_4500_NUMBERS 20 127 + 128 + /* Mailbox 1 headers */ 129 + #define MB1H_ARM_APE_OPP 0x0 130 + #define MB1H_RESET_MODEM 0x2 131 + #define MB1H_REQUEST_APE_OPP_100_VOLT 0x3 132 + #define MB1H_RELEASE_APE_OPP_100_VOLT 0x4 133 + #define MB1H_RELEASE_USB_WAKEUP 0x5 134 + 135 + /* Mailbox 1 Requests */ 136 + #define PRCM_REQ_MB1_ARM_OPP (PRCM_REQ_MB1 + 0x0) 137 + #define PRCM_REQ_MB1_APE_OPP (PRCM_REQ_MB1 + 0x1) 138 + #define PRCM_REQ_MB1_APE_OPP_100_RESTORE (PRCM_REQ_MB1 + 0x4) 139 + #define PRCM_REQ_MB1_ARM_OPP_100_RESTORE (PRCM_REQ_MB1 + 0x8) 140 + 141 + /* Mailbox 1 ACKs */ 142 + #define PRCM_ACK_MB1_CURRENT_ARM_OPP (PRCM_ACK_MB1 + 0x0) 143 + #define PRCM_ACK_MB1_CURRENT_APE_OPP (PRCM_ACK_MB1 + 0x1) 144 + #define PRCM_ACK_MB1_APE_VOLTAGE_STATUS (PRCM_ACK_MB1 + 0x2) 145 + #define PRCM_ACK_MB1_DVFS_STATUS (PRCM_ACK_MB1 + 0x3) 146 + 147 + /* Mailbox 2 headers */ 148 + #define MB2H_DPS 0x0 149 + #define MB2H_AUTO_PWR 0x1 150 + 151 + /* Mailbox 2 REQs */ 152 + #define PRCM_REQ_MB2_SVA_MMDSP (PRCM_REQ_MB2 + 0x0) 153 + #define PRCM_REQ_MB2_SVA_PIPE (PRCM_REQ_MB2 + 0x1) 154 + #define PRCM_REQ_MB2_SIA_MMDSP (PRCM_REQ_MB2 + 0x2) 155 + #define PRCM_REQ_MB2_SIA_PIPE (PRCM_REQ_MB2 + 0x3) 156 + #define PRCM_REQ_MB2_SGA (PRCM_REQ_MB2 + 0x4) 157 + #define PRCM_REQ_MB2_B2R2_MCDE (PRCM_REQ_MB2 + 0x5) 158 + #define PRCM_REQ_MB2_ESRAM12 (PRCM_REQ_MB2 + 0x6) 159 + #define PRCM_REQ_MB2_ESRAM34 (PRCM_REQ_MB2 + 0x7) 160 + #define PRCM_REQ_MB2_AUTO_PM_SLEEP (PRCM_REQ_MB2 + 0x8) 161 + #define PRCM_REQ_MB2_AUTO_PM_IDLE (PRCM_REQ_MB2 + 0xC) 162 + 163 + /* Mailbox 2 ACKs */ 164 + #define PRCM_ACK_MB2_DPS_STATUS (PRCM_ACK_MB2 + 0x0) 165 + #define HWACC_PWR_ST_OK 0xFE 166 + 167 + /* Mailbox 3 headers */ 168 + #define MB3H_ANC 0x0 169 + #define MB3H_SIDETONE 0x1 170 + #define MB3H_SYSCLK 0xE 171 + 172 + /* Mailbox 3 Requests */ 173 + #define PRCM_REQ_MB3_ANC_FIR_COEFF (PRCM_REQ_MB3 + 0x0) 174 + #define PRCM_REQ_MB3_ANC_IIR_COEFF (PRCM_REQ_MB3 + 0x20) 175 + #define PRCM_REQ_MB3_ANC_SHIFTER (PRCM_REQ_MB3 + 0x60) 176 + #define PRCM_REQ_MB3_ANC_WARP (PRCM_REQ_MB3 + 0x64) 177 + #define PRCM_REQ_MB3_SIDETONE_FIR_GAIN (PRCM_REQ_MB3 + 0x68) 178 + #define PRCM_REQ_MB3_SIDETONE_FIR_COEFF (PRCM_REQ_MB3 + 0x6C) 179 + #define PRCM_REQ_MB3_SYSCLK_MGT (PRCM_REQ_MB3 + 0x16C) 180 + 181 + /* Mailbox 4 headers */ 182 + #define MB4H_DDR_INIT 0x0 183 + #define MB4H_MEM_ST 0x1 184 + #define MB4H_HOTDOG 0x12 185 + #define MB4H_HOTMON 0x13 186 + #define MB4H_HOT_PERIOD 0x14 187 + 188 + /* Mailbox 4 Requests */ 189 + #define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE (PRCM_REQ_MB4 + 0x0) 190 + #define PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE (PRCM_REQ_MB4 + 0x1) 191 + #define PRCM_REQ_MB4_ESRAM0_ST (PRCM_REQ_MB4 + 0x3) 192 + #define PRCM_REQ_MB4_HOTDOG_THRESHOLD (PRCM_REQ_MB4 + 0x0) 193 + #define PRCM_REQ_MB4_HOTMON_LOW (PRCM_REQ_MB4 + 0x0) 194 + #define PRCM_REQ_MB4_HOTMON_HIGH (PRCM_REQ_MB4 + 0x1) 195 + #define PRCM_REQ_MB4_HOTMON_CONFIG (PRCM_REQ_MB4 + 0x2) 196 + #define PRCM_REQ_MB4_HOT_PERIOD (PRCM_REQ_MB4 + 0x0) 197 + #define HOTMON_CONFIG_LOW BIT(0) 198 + #define HOTMON_CONFIG_HIGH BIT(1) 199 + 200 + /* Mailbox 5 Requests */ 201 + #define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0) 202 + #define PRCM_REQ_MB5_I2C_HW_BITS (PRCM_REQ_MB5 + 0x1) 203 + #define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 0x2) 204 + #define PRCM_REQ_MB5_I2C_VAL (PRCM_REQ_MB5 + 0x3) 205 + #define PRCMU_I2C_WRITE(slave) \ 206 + (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) 207 + #define PRCMU_I2C_READ(slave) \ 208 + (((slave) << 1) | BIT(0) | (cpu_is_u8500v2() ? BIT(6) : 0)) 209 + #define PRCMU_I2C_STOP_EN BIT(3) 210 + 211 + /* Mailbox 5 ACKs */ 212 + #define PRCM_ACK_MB5_I2C_STATUS (PRCM_ACK_MB5 + 0x1) 213 + #define PRCM_ACK_MB5_I2C_VAL (PRCM_ACK_MB5 + 0x3) 214 + #define I2C_WR_OK 0x1 215 + #define I2C_RD_OK 0x2 216 + 217 + #define NUM_MB 8 218 + #define MBOX_BIT BIT 219 + #define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1) 220 + 221 + /* 222 + * Wakeups/IRQs 223 + */ 224 + 225 + #define WAKEUP_BIT_RTC BIT(0) 226 + #define WAKEUP_BIT_RTT0 BIT(1) 227 + #define WAKEUP_BIT_RTT1 BIT(2) 228 + #define WAKEUP_BIT_HSI0 BIT(3) 229 + #define WAKEUP_BIT_HSI1 BIT(4) 230 + #define WAKEUP_BIT_CA_WAKE BIT(5) 231 + #define WAKEUP_BIT_USB BIT(6) 232 + #define WAKEUP_BIT_ABB BIT(7) 233 + #define WAKEUP_BIT_ABB_FIFO BIT(8) 234 + #define WAKEUP_BIT_SYSCLK_OK BIT(9) 235 + #define WAKEUP_BIT_CA_SLEEP BIT(10) 236 + #define WAKEUP_BIT_AC_WAKE_ACK BIT(11) 237 + #define WAKEUP_BIT_SIDE_TONE_OK BIT(12) 238 + #define WAKEUP_BIT_ANC_OK BIT(13) 239 + #define WAKEUP_BIT_SW_ERROR BIT(14) 240 + #define WAKEUP_BIT_AC_SLEEP_ACK BIT(15) 241 + #define WAKEUP_BIT_ARM BIT(17) 242 + #define WAKEUP_BIT_HOTMON_LOW BIT(18) 243 + #define WAKEUP_BIT_HOTMON_HIGH BIT(19) 244 + #define WAKEUP_BIT_MODEM_SW_RESET_REQ BIT(20) 245 + #define WAKEUP_BIT_GPIO0 BIT(23) 246 + #define WAKEUP_BIT_GPIO1 BIT(24) 247 + #define WAKEUP_BIT_GPIO2 BIT(25) 248 + #define WAKEUP_BIT_GPIO3 BIT(26) 249 + #define WAKEUP_BIT_GPIO4 BIT(27) 250 + #define WAKEUP_BIT_GPIO5 BIT(28) 251 + #define WAKEUP_BIT_GPIO6 BIT(29) 252 + #define WAKEUP_BIT_GPIO7 BIT(30) 253 + #define WAKEUP_BIT_GPIO8 BIT(31) 254 + 255 + /* 256 + * This vector maps irq numbers to the bits in the bit field used in 257 + * communication with the PRCMU firmware. 258 + * 259 + * The reason for having this is to keep the irq numbers contiguous even though 260 + * the bits in the bit field are not. (The bits also have a tendency to move 261 + * around, to further complicate matters.) 262 + */ 263 + #define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name) - IRQ_PRCMU_BASE) 264 + #define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name) 265 + static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = { 266 + IRQ_ENTRY(RTC), 267 + IRQ_ENTRY(RTT0), 268 + IRQ_ENTRY(RTT1), 269 + IRQ_ENTRY(HSI0), 270 + IRQ_ENTRY(HSI1), 271 + IRQ_ENTRY(CA_WAKE), 272 + IRQ_ENTRY(USB), 273 + IRQ_ENTRY(ABB), 274 + IRQ_ENTRY(ABB_FIFO), 275 + IRQ_ENTRY(CA_SLEEP), 276 + IRQ_ENTRY(ARM), 277 + IRQ_ENTRY(HOTMON_LOW), 278 + IRQ_ENTRY(HOTMON_HIGH), 279 + IRQ_ENTRY(MODEM_SW_RESET_REQ), 280 + IRQ_ENTRY(GPIO0), 281 + IRQ_ENTRY(GPIO1), 282 + IRQ_ENTRY(GPIO2), 283 + IRQ_ENTRY(GPIO3), 284 + IRQ_ENTRY(GPIO4), 285 + IRQ_ENTRY(GPIO5), 286 + IRQ_ENTRY(GPIO6), 287 + IRQ_ENTRY(GPIO7), 288 + IRQ_ENTRY(GPIO8) 289 + }; 290 + 291 + #define VALID_WAKEUPS (BIT(NUM_PRCMU_WAKEUP_INDICES) - 1) 292 + #define WAKEUP_ENTRY(_name)[PRCMU_WAKEUP_INDEX_##_name] = (WAKEUP_BIT_##_name) 293 + static u32 prcmu_wakeup_bit[NUM_PRCMU_WAKEUP_INDICES] = { 294 + WAKEUP_ENTRY(RTC), 295 + WAKEUP_ENTRY(RTT0), 296 + WAKEUP_ENTRY(RTT1), 297 + WAKEUP_ENTRY(HSI0), 298 + WAKEUP_ENTRY(HSI1), 299 + WAKEUP_ENTRY(USB), 300 + WAKEUP_ENTRY(ABB), 301 + WAKEUP_ENTRY(ABB_FIFO), 302 + WAKEUP_ENTRY(ARM) 303 + }; 304 + 305 + /* 306 + * mb0_transfer - state needed for mailbox 0 communication. 307 + * @lock: The transaction lock. 308 + * @dbb_events_lock: A lock used to handle concurrent access to (parts of) 309 + * the request data. 310 + * @mask_work: Work structure used for (un)masking wakeup interrupts. 311 + * @req: Request data that need to persist between requests. 312 + */ 313 + static struct { 314 + spinlock_t lock; 315 + spinlock_t dbb_irqs_lock; 316 + struct work_struct mask_work; 317 + struct mutex ac_wake_lock; 318 + struct completion ac_wake_work; 319 + struct { 320 + u32 dbb_irqs; 321 + u32 dbb_wakeups; 322 + u32 abb_events; 323 + } req; 324 + } mb0_transfer; 325 + 326 + /* 327 + * mb1_transfer - state needed for mailbox 1 communication. 328 + * @lock: The transaction lock. 329 + * @work: The transaction completion structure. 330 + * @ack: Reply ("acknowledge") data. 331 + */ 332 + static struct { 333 + struct mutex lock; 334 + struct completion work; 335 + struct { 336 + u8 header; 337 + u8 arm_opp; 338 + u8 ape_opp; 339 + u8 ape_voltage_status; 340 + } ack; 341 + } mb1_transfer; 342 + 343 + /* 344 + * mb2_transfer - state needed for mailbox 2 communication. 345 + * @lock: The transaction lock. 346 + * @work: The transaction completion structure. 347 + * @auto_pm_lock: The autonomous power management configuration lock. 348 + * @auto_pm_enabled: A flag indicating whether autonomous PM is enabled. 349 + * @req: Request data that need to persist between requests. 350 + * @ack: Reply ("acknowledge") data. 351 + */ 352 + static struct { 353 + struct mutex lock; 354 + struct completion work; 355 + spinlock_t auto_pm_lock; 356 + bool auto_pm_enabled; 357 + struct { 358 + u8 status; 359 + } ack; 360 + } mb2_transfer; 361 + 362 + /* 363 + * mb3_transfer - state needed for mailbox 3 communication. 364 + * @lock: The request lock. 365 + * @sysclk_lock: A lock used to handle concurrent sysclk requests. 366 + * @sysclk_work: Work structure used for sysclk requests. 367 + */ 368 + static struct { 369 + spinlock_t lock; 370 + struct mutex sysclk_lock; 371 + struct completion sysclk_work; 372 + } mb3_transfer; 373 + 374 + /* 375 + * mb4_transfer - state needed for mailbox 4 communication. 376 + * @lock: The transaction lock. 377 + * @work: The transaction completion structure. 378 + */ 379 + static struct { 380 + struct mutex lock; 381 + struct completion work; 382 + } mb4_transfer; 383 + 384 + /* 385 + * mb5_transfer - state needed for mailbox 5 communication. 386 + * @lock: The transaction lock. 387 + * @work: The transaction completion structure. 388 + * @ack: Reply ("acknowledge") data. 389 + */ 390 + static struct { 391 + struct mutex lock; 392 + struct completion work; 393 + struct { 394 + u8 status; 395 + u8 value; 396 + } ack; 397 + } mb5_transfer; 398 + 399 + static atomic_t ac_wake_req_state = ATOMIC_INIT(0); 400 + 401 + /* Spinlocks */ 402 + static DEFINE_SPINLOCK(clkout_lock); 403 + static DEFINE_SPINLOCK(gpiocr_lock); 404 + 405 + /* Global var to runtime determine TCDM base for v2 or v1 */ 406 + static __iomem void *tcdm_base; 407 + 408 + struct clk_mgt { 409 + unsigned int offset; 410 + u32 pllsw; 411 + }; 412 + 413 + static DEFINE_SPINLOCK(clk_mgt_lock); 414 + 415 + #define CLK_MGT_ENTRY(_name)[PRCMU_##_name] = { (PRCM_##_name##_MGT), 0 } 416 + struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = { 417 + CLK_MGT_ENTRY(SGACLK), 418 + CLK_MGT_ENTRY(UARTCLK), 419 + CLK_MGT_ENTRY(MSP02CLK), 420 + CLK_MGT_ENTRY(MSP1CLK), 421 + CLK_MGT_ENTRY(I2CCLK), 422 + CLK_MGT_ENTRY(SDMMCCLK), 423 + CLK_MGT_ENTRY(SLIMCLK), 424 + CLK_MGT_ENTRY(PER1CLK), 425 + CLK_MGT_ENTRY(PER2CLK), 426 + CLK_MGT_ENTRY(PER3CLK), 427 + CLK_MGT_ENTRY(PER5CLK), 428 + CLK_MGT_ENTRY(PER6CLK), 429 + CLK_MGT_ENTRY(PER7CLK), 430 + CLK_MGT_ENTRY(LCDCLK), 431 + CLK_MGT_ENTRY(BMLCLK), 432 + CLK_MGT_ENTRY(HSITXCLK), 433 + CLK_MGT_ENTRY(HSIRXCLK), 434 + CLK_MGT_ENTRY(HDMICLK), 435 + CLK_MGT_ENTRY(APEATCLK), 436 + CLK_MGT_ENTRY(APETRACECLK), 437 + CLK_MGT_ENTRY(MCDECLK), 438 + CLK_MGT_ENTRY(IPI2CCLK), 439 + CLK_MGT_ENTRY(DSIALTCLK), 440 + CLK_MGT_ENTRY(DMACLK), 441 + CLK_MGT_ENTRY(B2R2CLK), 442 + CLK_MGT_ENTRY(TVCLK), 443 + CLK_MGT_ENTRY(SSPCLK), 444 + CLK_MGT_ENTRY(RNGCLK), 445 + CLK_MGT_ENTRY(UICCCLK), 446 + }; 447 + 448 + /* 449 + * Used by MCDE to setup all necessary PRCMU registers 450 + */ 451 + #define PRCMU_RESET_DSIPLL 0x00004000 452 + #define PRCMU_UNCLAMP_DSIPLL 0x00400800 453 + 454 + #define PRCMU_CLK_PLL_DIV_SHIFT 0 455 + #define PRCMU_CLK_PLL_SW_SHIFT 5 456 + #define PRCMU_CLK_38 (1 << 9) 457 + #define PRCMU_CLK_38_SRC (1 << 10) 458 + #define PRCMU_CLK_38_DIV (1 << 11) 459 + 460 + /* PLLDIV=12, PLLSW=4 (PLLDDR) */ 461 + #define PRCMU_DSI_CLOCK_SETTING 0x0000008C 462 + 463 + /* PLLDIV=8, PLLSW=4 (PLLDDR) */ 464 + #define PRCMU_DSI_CLOCK_SETTING_U8400 0x00000088 465 + 466 + /* DPI 50000000 Hz */ 467 + #define PRCMU_DPI_CLOCK_SETTING ((1 << PRCMU_CLK_PLL_SW_SHIFT) | \ 468 + (16 << PRCMU_CLK_PLL_DIV_SHIFT)) 469 + #define PRCMU_DSI_LP_CLOCK_SETTING 0x00000E00 470 + 471 + /* D=101, N=1, R=4, SELDIV2=0 */ 472 + #define PRCMU_PLLDSI_FREQ_SETTING 0x00040165 473 + 474 + /* D=70, N=1, R=3, SELDIV2=0 */ 475 + #define PRCMU_PLLDSI_FREQ_SETTING_U8400 0x00030146 476 + 477 + #define PRCMU_ENABLE_PLLDSI 0x00000001 478 + #define PRCMU_DISABLE_PLLDSI 0x00000000 479 + #define PRCMU_RELEASE_RESET_DSS 0x0000400C 480 + #define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000202 481 + /* ESC clk, div0=1, div1=1, div2=3 */ 482 + #define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x07030101 483 + #define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00030101 484 + #define PRCMU_DSI_RESET_SW 0x00000007 485 + 486 + #define PRCMU_PLLDSI_LOCKP_LOCKED 0x3 487 + 488 + static struct { 489 + u8 project_number; 490 + u8 api_version; 491 + u8 func_version; 492 + u8 errata; 493 + } prcmu_version; 494 + 495 + 496 + int prcmu_enable_dsipll(void) 497 + { 498 + int i; 499 + unsigned int plldsifreq; 500 + 501 + /* Clear DSIPLL_RESETN */ 502 + writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_CLR)); 503 + /* Unclamp DSIPLL in/out */ 504 + writel(PRCMU_UNCLAMP_DSIPLL, (_PRCMU_BASE + PRCM_MMIP_LS_CLAMP_CLR)); 505 + 506 + if (prcmu_is_u8400()) 507 + plldsifreq = PRCMU_PLLDSI_FREQ_SETTING_U8400; 508 + else 509 + plldsifreq = PRCMU_PLLDSI_FREQ_SETTING; 510 + /* Set DSI PLL FREQ */ 511 + writel(plldsifreq, (_PRCMU_BASE + PRCM_PLLDSI_FREQ)); 512 + writel(PRCMU_DSI_PLLOUT_SEL_SETTING, 513 + (_PRCMU_BASE + PRCM_DSI_PLLOUT_SEL)); 514 + /* Enable Escape clocks */ 515 + writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, 516 + (_PRCMU_BASE + PRCM_DSITVCLK_DIV)); 517 + 518 + /* Start DSI PLL */ 519 + writel(PRCMU_ENABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE)); 520 + /* Reset DSI PLL */ 521 + writel(PRCMU_DSI_RESET_SW, (_PRCMU_BASE + PRCM_DSI_SW_RESET)); 522 + for (i = 0; i < 10; i++) { 523 + if ((readl(_PRCMU_BASE + PRCM_PLLDSI_LOCKP) & 524 + PRCMU_PLLDSI_LOCKP_LOCKED) 525 + == PRCMU_PLLDSI_LOCKP_LOCKED) 526 + break; 527 + udelay(100); 528 + } 529 + /* Set DSIPLL_RESETN */ 530 + writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_SET)); 531 + return 0; 532 + } 533 + 534 + int prcmu_disable_dsipll(void) 535 + { 536 + /* Disable dsi pll */ 537 + writel(PRCMU_DISABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE)); 538 + /* Disable escapeclock */ 539 + writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, 540 + (_PRCMU_BASE + PRCM_DSITVCLK_DIV)); 541 + return 0; 542 + } 543 + 544 + int prcmu_set_display_clocks(void) 545 + { 546 + unsigned long flags; 547 + unsigned int dsiclk; 548 + 549 + if (prcmu_is_u8400()) 550 + dsiclk = PRCMU_DSI_CLOCK_SETTING_U8400; 551 + else 552 + dsiclk = PRCMU_DSI_CLOCK_SETTING; 553 + 554 + spin_lock_irqsave(&clk_mgt_lock, flags); 555 + 556 + /* Grab the HW semaphore. */ 557 + while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) 558 + cpu_relax(); 559 + 560 + writel(dsiclk, (_PRCMU_BASE + PRCM_HDMICLK_MGT)); 561 + writel(PRCMU_DSI_LP_CLOCK_SETTING, (_PRCMU_BASE + PRCM_TVCLK_MGT)); 562 + writel(PRCMU_DPI_CLOCK_SETTING, (_PRCMU_BASE + PRCM_LCDCLK_MGT)); 563 + 564 + /* Release the HW semaphore. */ 565 + writel(0, (_PRCMU_BASE + PRCM_SEM)); 566 + 567 + spin_unlock_irqrestore(&clk_mgt_lock, flags); 568 + 569 + return 0; 570 + } 571 + 572 + /** 573 + * prcmu_enable_spi2 - Enables pin muxing for SPI2 on OtherAlternateC1. 574 + */ 575 + void prcmu_enable_spi2(void) 576 + { 577 + u32 reg; 578 + unsigned long flags; 579 + 580 + spin_lock_irqsave(&gpiocr_lock, flags); 581 + reg = readl(_PRCMU_BASE + PRCM_GPIOCR); 582 + writel(reg | PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR); 583 + spin_unlock_irqrestore(&gpiocr_lock, flags); 584 + } 585 + 586 + /** 587 + * prcmu_disable_spi2 - Disables pin muxing for SPI2 on OtherAlternateC1. 588 + */ 589 + void prcmu_disable_spi2(void) 590 + { 591 + u32 reg; 592 + unsigned long flags; 593 + 594 + spin_lock_irqsave(&gpiocr_lock, flags); 595 + reg = readl(_PRCMU_BASE + PRCM_GPIOCR); 596 + writel(reg & ~PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR); 597 + spin_unlock_irqrestore(&gpiocr_lock, flags); 598 + } 599 + 600 + bool prcmu_has_arm_maxopp(void) 601 + { 602 + return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) & 603 + PRCM_AVS_ISMODEENABLE_MASK) == PRCM_AVS_ISMODEENABLE_MASK; 604 + } 605 + 606 + bool prcmu_is_u8400(void) 607 + { 608 + return prcmu_version.project_number == PRCMU_PROJECT_ID_8400V2_0; 609 + } 610 + 611 + /** 612 + * prcmu_get_boot_status - PRCMU boot status checking 613 + * Returns: the current PRCMU boot status 614 + */ 615 + int prcmu_get_boot_status(void) 616 + { 617 + return readb(tcdm_base + PRCM_BOOT_STATUS); 618 + } 619 + 620 + /** 621 + * prcmu_set_rc_a2p - This function is used to run few power state sequences 622 + * @val: Value to be set, i.e. transition requested 623 + * Returns: 0 on success, -EINVAL on invalid argument 624 + * 625 + * This function is used to run the following power state sequences - 626 + * any state to ApReset, ApDeepSleep to ApExecute, ApExecute to ApDeepSleep 627 + */ 628 + int prcmu_set_rc_a2p(enum romcode_write val) 629 + { 630 + if (val < RDY_2_DS || val > RDY_2_XP70_RST) 631 + return -EINVAL; 632 + writeb(val, (tcdm_base + PRCM_ROMCODE_A2P)); 633 + return 0; 634 + } 635 + 636 + /** 637 + * prcmu_get_rc_p2a - This function is used to get power state sequences 638 + * Returns: the power transition that has last happened 639 + * 640 + * This function can return the following transitions- 641 + * any state to ApReset, ApDeepSleep to ApExecute, ApExecute to ApDeepSleep 642 + */ 643 + enum romcode_read prcmu_get_rc_p2a(void) 644 + { 645 + return readb(tcdm_base + PRCM_ROMCODE_P2A); 646 + } 647 + 648 + /** 649 + * prcmu_get_current_mode - Return the current XP70 power mode 650 + * Returns: Returns the current AP(ARM) power mode: init, 651 + * apBoot, apExecute, apDeepSleep, apSleep, apIdle, apReset 652 + */ 653 + enum ap_pwrst prcmu_get_xp70_current_state(void) 654 + { 655 + return readb(tcdm_base + PRCM_XP70_CUR_PWR_STATE); 656 + } 657 + 658 + /** 659 + * prcmu_config_clkout - Configure one of the programmable clock outputs. 660 + * @clkout: The CLKOUT number (0 or 1). 661 + * @source: The clock to be used (one of the PRCMU_CLKSRC_*). 662 + * @div: The divider to be applied. 663 + * 664 + * Configures one of the programmable clock outputs (CLKOUTs). 665 + * @div should be in the range [1,63] to request a configuration, or 0 to 666 + * inform that the configuration is no longer requested. 667 + */ 668 + int prcmu_config_clkout(u8 clkout, u8 source, u8 div) 669 + { 670 + static int requests[2]; 671 + int r = 0; 672 + unsigned long flags; 673 + u32 val; 674 + u32 bits; 675 + u32 mask; 676 + u32 div_mask; 677 + 678 + BUG_ON(clkout > 1); 679 + BUG_ON(div > 63); 680 + BUG_ON((clkout == 0) && (source > PRCMU_CLKSRC_CLK009)); 681 + 682 + if (!div && !requests[clkout]) 683 + return -EINVAL; 684 + 685 + switch (clkout) { 686 + case 0: 687 + div_mask = PRCM_CLKOCR_CLKODIV0_MASK; 688 + mask = (PRCM_CLKOCR_CLKODIV0_MASK | PRCM_CLKOCR_CLKOSEL0_MASK); 689 + bits = ((source << PRCM_CLKOCR_CLKOSEL0_SHIFT) | 690 + (div << PRCM_CLKOCR_CLKODIV0_SHIFT)); 691 + break; 692 + case 1: 693 + div_mask = PRCM_CLKOCR_CLKODIV1_MASK; 694 + mask = (PRCM_CLKOCR_CLKODIV1_MASK | PRCM_CLKOCR_CLKOSEL1_MASK | 695 + PRCM_CLKOCR_CLK1TYPE); 696 + bits = ((source << PRCM_CLKOCR_CLKOSEL1_SHIFT) | 697 + (div << PRCM_CLKOCR_CLKODIV1_SHIFT)); 698 + break; 699 + } 700 + bits &= mask; 701 + 702 + spin_lock_irqsave(&clkout_lock, flags); 703 + 704 + val = readl(_PRCMU_BASE + PRCM_CLKOCR); 705 + if (val & div_mask) { 706 + if (div) { 707 + if ((val & mask) != bits) { 708 + r = -EBUSY; 709 + goto unlock_and_return; 710 + } 711 + } else { 712 + if ((val & mask & ~div_mask) != bits) { 713 + r = -EINVAL; 714 + goto unlock_and_return; 715 + } 716 + } 717 + } 718 + writel((bits | (val & ~mask)), (_PRCMU_BASE + PRCM_CLKOCR)); 719 + requests[clkout] += (div ? 1 : -1); 720 + 721 + unlock_and_return: 722 + spin_unlock_irqrestore(&clkout_lock, flags); 723 + 724 + return r; 725 + } 726 + 727 + int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll) 728 + { 729 + unsigned long flags; 730 + 731 + BUG_ON((state < PRCMU_AP_SLEEP) || (PRCMU_AP_DEEP_IDLE < state)); 732 + 733 + spin_lock_irqsave(&mb0_transfer.lock, flags); 734 + 735 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) 736 + cpu_relax(); 737 + 738 + writeb(MB0H_POWER_STATE_TRANS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); 739 + writeb(state, (tcdm_base + PRCM_REQ_MB0_AP_POWER_STATE)); 740 + writeb((keep_ap_pll ? 1 : 0), (tcdm_base + PRCM_REQ_MB0_AP_PLL_STATE)); 741 + writeb((keep_ulp_clk ? 1 : 0), 742 + (tcdm_base + PRCM_REQ_MB0_ULP_CLOCK_STATE)); 743 + writeb(0, (tcdm_base + PRCM_REQ_MB0_DO_NOT_WFI)); 744 + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 745 + 746 + spin_unlock_irqrestore(&mb0_transfer.lock, flags); 747 + 748 + return 0; 749 + } 750 + 751 + /* This function should only be called while mb0_transfer.lock is held. */ 752 + static void config_wakeups(void) 753 + { 754 + const u8 header[2] = { 755 + MB0H_CONFIG_WAKEUPS_EXE, 756 + MB0H_CONFIG_WAKEUPS_SLEEP 757 + }; 758 + static u32 last_dbb_events; 759 + static u32 last_abb_events; 760 + u32 dbb_events; 761 + u32 abb_events; 762 + unsigned int i; 763 + 764 + dbb_events = mb0_transfer.req.dbb_irqs | mb0_transfer.req.dbb_wakeups; 765 + dbb_events |= (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK); 766 + 767 + abb_events = mb0_transfer.req.abb_events; 768 + 769 + if ((dbb_events == last_dbb_events) && (abb_events == last_abb_events)) 770 + return; 771 + 772 + for (i = 0; i < 2; i++) { 773 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) 774 + cpu_relax(); 775 + writel(dbb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_8500)); 776 + writel(abb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_4500)); 777 + writeb(header[i], (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); 778 + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 779 + } 780 + last_dbb_events = dbb_events; 781 + last_abb_events = abb_events; 782 + } 783 + 784 + void prcmu_enable_wakeups(u32 wakeups) 785 + { 786 + unsigned long flags; 787 + u32 bits; 788 + int i; 789 + 790 + BUG_ON(wakeups != (wakeups & VALID_WAKEUPS)); 791 + 792 + for (i = 0, bits = 0; i < NUM_PRCMU_WAKEUP_INDICES; i++) { 793 + if (wakeups & BIT(i)) 794 + bits |= prcmu_wakeup_bit[i]; 795 + } 796 + 797 + spin_lock_irqsave(&mb0_transfer.lock, flags); 798 + 799 + mb0_transfer.req.dbb_wakeups = bits; 800 + config_wakeups(); 801 + 802 + spin_unlock_irqrestore(&mb0_transfer.lock, flags); 803 + } 804 + 805 + void prcmu_config_abb_event_readout(u32 abb_events) 806 + { 807 + unsigned long flags; 808 + 809 + spin_lock_irqsave(&mb0_transfer.lock, flags); 810 + 811 + mb0_transfer.req.abb_events = abb_events; 812 + config_wakeups(); 813 + 814 + spin_unlock_irqrestore(&mb0_transfer.lock, flags); 815 + } 816 + 817 + void prcmu_get_abb_event_buffer(void __iomem **buf) 818 + { 819 + if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) 820 + *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500); 821 + else 822 + *buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_0_4500); 823 + } 824 + 825 + /** 826 + * prcmu_set_arm_opp - set the appropriate ARM OPP 827 + * @opp: The new ARM operating point to which transition is to be made 828 + * Returns: 0 on success, non-zero on failure 829 + * 830 + * This function sets the the operating point of the ARM. 831 + */ 832 + int prcmu_set_arm_opp(u8 opp) 833 + { 834 + int r; 835 + 836 + if (opp < ARM_NO_CHANGE || opp > ARM_EXTCLK) 837 + return -EINVAL; 838 + 839 + r = 0; 840 + 841 + mutex_lock(&mb1_transfer.lock); 842 + 843 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) 844 + cpu_relax(); 845 + 846 + writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); 847 + writeb(opp, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); 848 + writeb(APE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); 849 + 850 + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 851 + wait_for_completion(&mb1_transfer.work); 852 + 853 + if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || 854 + (mb1_transfer.ack.arm_opp != opp)) 855 + r = -EIO; 856 + 857 + mutex_unlock(&mb1_transfer.lock); 858 + 859 + return r; 860 + } 861 + 862 + /** 863 + * prcmu_get_arm_opp - get the current ARM OPP 864 + * 865 + * Returns: the current ARM OPP 866 + */ 867 + int prcmu_get_arm_opp(void) 868 + { 869 + return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP); 870 + } 871 + 872 + /** 873 + * prcmu_get_ddr_opp - get the current DDR OPP 874 + * 875 + * Returns: the current DDR OPP 876 + */ 877 + int prcmu_get_ddr_opp(void) 878 + { 879 + return readb(_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW); 880 + } 881 + 882 + /** 883 + * set_ddr_opp - set the appropriate DDR OPP 884 + * @opp: The new DDR operating point to which transition is to be made 885 + * Returns: 0 on success, non-zero on failure 886 + * 887 + * This function sets the operating point of the DDR. 888 + */ 889 + int prcmu_set_ddr_opp(u8 opp) 890 + { 891 + if (opp < DDR_100_OPP || opp > DDR_25_OPP) 892 + return -EINVAL; 893 + /* Changing the DDR OPP can hang the hardware pre-v21 */ 894 + if (cpu_is_u8500v20_or_later() && !cpu_is_u8500v20()) 895 + writeb(opp, (_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW)); 896 + 897 + return 0; 898 + } 899 + /** 900 + * set_ape_opp - set the appropriate APE OPP 901 + * @opp: The new APE operating point to which transition is to be made 902 + * Returns: 0 on success, non-zero on failure 903 + * 904 + * This function sets the operating point of the APE. 905 + */ 906 + int prcmu_set_ape_opp(u8 opp) 907 + { 908 + int r = 0; 909 + 910 + mutex_lock(&mb1_transfer.lock); 911 + 912 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) 913 + cpu_relax(); 914 + 915 + writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); 916 + writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP)); 917 + writeb(opp, (tcdm_base + PRCM_REQ_MB1_APE_OPP)); 918 + 919 + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 920 + wait_for_completion(&mb1_transfer.work); 921 + 922 + if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) || 923 + (mb1_transfer.ack.ape_opp != opp)) 924 + r = -EIO; 925 + 926 + mutex_unlock(&mb1_transfer.lock); 927 + 928 + return r; 929 + } 930 + 931 + /** 932 + * prcmu_get_ape_opp - get the current APE OPP 933 + * 934 + * Returns: the current APE OPP 935 + */ 936 + int prcmu_get_ape_opp(void) 937 + { 938 + return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_APE_OPP); 939 + } 940 + 941 + /** 942 + * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage 943 + * @enable: true to request the higher voltage, false to drop a request. 944 + * 945 + * Calls to this function to enable and disable requests must be balanced. 946 + */ 947 + int prcmu_request_ape_opp_100_voltage(bool enable) 948 + { 949 + int r = 0; 950 + u8 header; 951 + static unsigned int requests; 952 + 953 + mutex_lock(&mb1_transfer.lock); 954 + 955 + if (enable) { 956 + if (0 != requests++) 957 + goto unlock_and_return; 958 + header = MB1H_REQUEST_APE_OPP_100_VOLT; 959 + } else { 960 + if (requests == 0) { 961 + r = -EIO; 962 + goto unlock_and_return; 963 + } else if (1 != requests--) { 964 + goto unlock_and_return; 965 + } 966 + header = MB1H_RELEASE_APE_OPP_100_VOLT; 967 + } 968 + 969 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) 970 + cpu_relax(); 971 + 972 + writeb(header, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); 973 + 974 + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 975 + wait_for_completion(&mb1_transfer.work); 976 + 977 + if ((mb1_transfer.ack.header != header) || 978 + ((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0)) 979 + r = -EIO; 980 + 981 + unlock_and_return: 982 + mutex_unlock(&mb1_transfer.lock); 983 + 984 + return r; 985 + } 986 + 987 + /** 988 + * prcmu_release_usb_wakeup_state - release the state required by a USB wakeup 989 + * 990 + * This function releases the power state requirements of a USB wakeup. 991 + */ 992 + int prcmu_release_usb_wakeup_state(void) 993 + { 994 + int r = 0; 995 + 996 + mutex_lock(&mb1_transfer.lock); 997 + 998 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) 999 + cpu_relax(); 1000 + 1001 + writeb(MB1H_RELEASE_USB_WAKEUP, 1002 + (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); 1003 + 1004 + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1005 + wait_for_completion(&mb1_transfer.work); 1006 + 1007 + if ((mb1_transfer.ack.header != MB1H_RELEASE_USB_WAKEUP) || 1008 + ((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0)) 1009 + r = -EIO; 1010 + 1011 + mutex_unlock(&mb1_transfer.lock); 1012 + 1013 + return r; 1014 + } 1015 + 1016 + /** 1017 + * prcmu_set_epod - set the state of a EPOD (power domain) 1018 + * @epod_id: The EPOD to set 1019 + * @epod_state: The new EPOD state 1020 + * 1021 + * This function sets the state of a EPOD (power domain). It may not be called 1022 + * from interrupt context. 1023 + */ 1024 + int prcmu_set_epod(u16 epod_id, u8 epod_state) 1025 + { 1026 + int r = 0; 1027 + bool ram_retention = false; 1028 + int i; 1029 + 1030 + /* check argument */ 1031 + BUG_ON(epod_id >= NUM_EPOD_ID); 1032 + 1033 + /* set flag if retention is possible */ 1034 + switch (epod_id) { 1035 + case EPOD_ID_SVAMMDSP: 1036 + case EPOD_ID_SIAMMDSP: 1037 + case EPOD_ID_ESRAM12: 1038 + case EPOD_ID_ESRAM34: 1039 + ram_retention = true; 1040 + break; 1041 + } 1042 + 1043 + /* check argument */ 1044 + BUG_ON(epod_state > EPOD_STATE_ON); 1045 + BUG_ON(epod_state == EPOD_STATE_RAMRET && !ram_retention); 1046 + 1047 + /* get lock */ 1048 + mutex_lock(&mb2_transfer.lock); 1049 + 1050 + /* wait for mailbox */ 1051 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(2)) 1052 + cpu_relax(); 1053 + 1054 + /* fill in mailbox */ 1055 + for (i = 0; i < NUM_EPOD_ID; i++) 1056 + writeb(EPOD_STATE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB2 + i)); 1057 + writeb(epod_state, (tcdm_base + PRCM_REQ_MB2 + epod_id)); 1058 + 1059 + writeb(MB2H_DPS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB2)); 1060 + 1061 + writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1062 + 1063 + /* 1064 + * The current firmware version does not handle errors correctly, 1065 + * and we cannot recover if there is an error. 1066 + * This is expected to change when the firmware is updated. 1067 + */ 1068 + if (!wait_for_completion_timeout(&mb2_transfer.work, 1069 + msecs_to_jiffies(20000))) { 1070 + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", 1071 + __func__); 1072 + r = -EIO; 1073 + goto unlock_and_return; 1074 + } 1075 + 1076 + if (mb2_transfer.ack.status != HWACC_PWR_ST_OK) 1077 + r = -EIO; 1078 + 1079 + unlock_and_return: 1080 + mutex_unlock(&mb2_transfer.lock); 1081 + return r; 1082 + } 1083 + 1084 + /** 1085 + * prcmu_configure_auto_pm - Configure autonomous power management. 1086 + * @sleep: Configuration for ApSleep. 1087 + * @idle: Configuration for ApIdle. 1088 + */ 1089 + void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, 1090 + struct prcmu_auto_pm_config *idle) 1091 + { 1092 + u32 sleep_cfg; 1093 + u32 idle_cfg; 1094 + unsigned long flags; 1095 + 1096 + BUG_ON((sleep == NULL) || (idle == NULL)); 1097 + 1098 + sleep_cfg = (sleep->sva_auto_pm_enable & 0xF); 1099 + sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_auto_pm_enable & 0xF)); 1100 + sleep_cfg = ((sleep_cfg << 8) | (sleep->sva_power_on & 0xFF)); 1101 + sleep_cfg = ((sleep_cfg << 8) | (sleep->sia_power_on & 0xFF)); 1102 + sleep_cfg = ((sleep_cfg << 4) | (sleep->sva_policy & 0xF)); 1103 + sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_policy & 0xF)); 1104 + 1105 + idle_cfg = (idle->sva_auto_pm_enable & 0xF); 1106 + idle_cfg = ((idle_cfg << 4) | (idle->sia_auto_pm_enable & 0xF)); 1107 + idle_cfg = ((idle_cfg << 8) | (idle->sva_power_on & 0xFF)); 1108 + idle_cfg = ((idle_cfg << 8) | (idle->sia_power_on & 0xFF)); 1109 + idle_cfg = ((idle_cfg << 4) | (idle->sva_policy & 0xF)); 1110 + idle_cfg = ((idle_cfg << 4) | (idle->sia_policy & 0xF)); 1111 + 1112 + spin_lock_irqsave(&mb2_transfer.auto_pm_lock, flags); 1113 + 1114 + /* 1115 + * The autonomous power management configuration is done through 1116 + * fields in mailbox 2, but these fields are only used as shared 1117 + * variables - i.e. there is no need to send a message. 1118 + */ 1119 + writel(sleep_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_SLEEP)); 1120 + writel(idle_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_IDLE)); 1121 + 1122 + mb2_transfer.auto_pm_enabled = 1123 + ((sleep->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || 1124 + (sleep->sia_auto_pm_enable == PRCMU_AUTO_PM_ON) || 1125 + (idle->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) || 1126 + (idle->sia_auto_pm_enable == PRCMU_AUTO_PM_ON)); 1127 + 1128 + spin_unlock_irqrestore(&mb2_transfer.auto_pm_lock, flags); 1129 + } 1130 + EXPORT_SYMBOL(prcmu_configure_auto_pm); 1131 + 1132 + bool prcmu_is_auto_pm_enabled(void) 1133 + { 1134 + return mb2_transfer.auto_pm_enabled; 1135 + } 1136 + 1137 + static int request_sysclk(bool enable) 1138 + { 1139 + int r; 1140 + unsigned long flags; 1141 + 1142 + r = 0; 1143 + 1144 + mutex_lock(&mb3_transfer.sysclk_lock); 1145 + 1146 + spin_lock_irqsave(&mb3_transfer.lock, flags); 1147 + 1148 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(3)) 1149 + cpu_relax(); 1150 + 1151 + writeb((enable ? ON : OFF), (tcdm_base + PRCM_REQ_MB3_SYSCLK_MGT)); 1152 + 1153 + writeb(MB3H_SYSCLK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB3)); 1154 + writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1155 + 1156 + spin_unlock_irqrestore(&mb3_transfer.lock, flags); 1157 + 1158 + /* 1159 + * The firmware only sends an ACK if we want to enable the 1160 + * SysClk, and it succeeds. 1161 + */ 1162 + if (enable && !wait_for_completion_timeout(&mb3_transfer.sysclk_work, 1163 + msecs_to_jiffies(20000))) { 1164 + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", 1165 + __func__); 1166 + r = -EIO; 1167 + } 1168 + 1169 + mutex_unlock(&mb3_transfer.sysclk_lock); 1170 + 1171 + return r; 1172 + } 1173 + 1174 + static int request_timclk(bool enable) 1175 + { 1176 + u32 val = (PRCM_TCR_DOZE_MODE | PRCM_TCR_TENSEL_MASK); 1177 + 1178 + if (!enable) 1179 + val |= PRCM_TCR_STOP_TIMERS; 1180 + writel(val, (_PRCMU_BASE + PRCM_TCR)); 1181 + 1182 + return 0; 1183 + } 1184 + 1185 + static int request_reg_clock(u8 clock, bool enable) 1186 + { 1187 + u32 val; 1188 + unsigned long flags; 1189 + 1190 + spin_lock_irqsave(&clk_mgt_lock, flags); 1191 + 1192 + /* Grab the HW semaphore. */ 1193 + while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) 1194 + cpu_relax(); 1195 + 1196 + val = readl(_PRCMU_BASE + clk_mgt[clock].offset); 1197 + if (enable) { 1198 + val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw); 1199 + } else { 1200 + clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK); 1201 + val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK); 1202 + } 1203 + writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); 1204 + 1205 + /* Release the HW semaphore. */ 1206 + writel(0, (_PRCMU_BASE + PRCM_SEM)); 1207 + 1208 + spin_unlock_irqrestore(&clk_mgt_lock, flags); 1209 + 1210 + return 0; 1211 + } 1212 + 1213 + /** 1214 + * prcmu_request_clock() - Request for a clock to be enabled or disabled. 1215 + * @clock: The clock for which the request is made. 1216 + * @enable: Whether the clock should be enabled (true) or disabled (false). 1217 + * 1218 + * This function should only be used by the clock implementation. 1219 + * Do not use it from any other place! 1220 + */ 1221 + int prcmu_request_clock(u8 clock, bool enable) 1222 + { 1223 + if (clock < PRCMU_NUM_REG_CLOCKS) 1224 + return request_reg_clock(clock, enable); 1225 + else if (clock == PRCMU_TIMCLK) 1226 + return request_timclk(enable); 1227 + else if (clock == PRCMU_SYSCLK) 1228 + return request_sysclk(enable); 1229 + else 1230 + return -EINVAL; 1231 + } 1232 + 1233 + int prcmu_config_esram0_deep_sleep(u8 state) 1234 + { 1235 + if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) || 1236 + (state < ESRAM0_DEEP_SLEEP_STATE_OFF)) 1237 + return -EINVAL; 1238 + 1239 + mutex_lock(&mb4_transfer.lock); 1240 + 1241 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) 1242 + cpu_relax(); 1243 + 1244 + writeb(MB4H_MEM_ST, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); 1245 + writeb(((DDR_PWR_STATE_OFFHIGHLAT << 4) | DDR_PWR_STATE_ON), 1246 + (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE)); 1247 + writeb(DDR_PWR_STATE_ON, 1248 + (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE)); 1249 + writeb(state, (tcdm_base + PRCM_REQ_MB4_ESRAM0_ST)); 1250 + 1251 + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1252 + wait_for_completion(&mb4_transfer.work); 1253 + 1254 + mutex_unlock(&mb4_transfer.lock); 1255 + 1256 + return 0; 1257 + } 1258 + 1259 + int prcmu_config_hotdog(u8 threshold) 1260 + { 1261 + mutex_lock(&mb4_transfer.lock); 1262 + 1263 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) 1264 + cpu_relax(); 1265 + 1266 + writeb(threshold, (tcdm_base + PRCM_REQ_MB4_HOTDOG_THRESHOLD)); 1267 + writeb(MB4H_HOTDOG, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); 1268 + 1269 + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1270 + wait_for_completion(&mb4_transfer.work); 1271 + 1272 + mutex_unlock(&mb4_transfer.lock); 1273 + 1274 + return 0; 1275 + } 1276 + 1277 + int prcmu_config_hotmon(u8 low, u8 high) 1278 + { 1279 + mutex_lock(&mb4_transfer.lock); 1280 + 1281 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) 1282 + cpu_relax(); 1283 + 1284 + writeb(low, (tcdm_base + PRCM_REQ_MB4_HOTMON_LOW)); 1285 + writeb(high, (tcdm_base + PRCM_REQ_MB4_HOTMON_HIGH)); 1286 + writeb((HOTMON_CONFIG_LOW | HOTMON_CONFIG_HIGH), 1287 + (tcdm_base + PRCM_REQ_MB4_HOTMON_CONFIG)); 1288 + writeb(MB4H_HOTMON, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); 1289 + 1290 + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1291 + wait_for_completion(&mb4_transfer.work); 1292 + 1293 + mutex_unlock(&mb4_transfer.lock); 1294 + 1295 + return 0; 1296 + } 1297 + 1298 + static int config_hot_period(u16 val) 1299 + { 1300 + mutex_lock(&mb4_transfer.lock); 1301 + 1302 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4)) 1303 + cpu_relax(); 1304 + 1305 + writew(val, (tcdm_base + PRCM_REQ_MB4_HOT_PERIOD)); 1306 + writeb(MB4H_HOT_PERIOD, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4)); 1307 + 1308 + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1309 + wait_for_completion(&mb4_transfer.work); 1310 + 1311 + mutex_unlock(&mb4_transfer.lock); 1312 + 1313 + return 0; 1314 + } 1315 + 1316 + int prcmu_start_temp_sense(u16 cycles32k) 1317 + { 1318 + if (cycles32k == 0xFFFF) 1319 + return -EINVAL; 1320 + 1321 + return config_hot_period(cycles32k); 1322 + } 1323 + 1324 + int prcmu_stop_temp_sense(void) 1325 + { 1326 + return config_hot_period(0xFFFF); 1327 + } 1328 + 1329 + /** 1330 + * prcmu_set_clock_divider() - Configure the clock divider. 1331 + * @clock: The clock for which the request is made. 1332 + * @divider: The clock divider. (< 32) 1333 + * 1334 + * This function should only be used by the clock implementation. 1335 + * Do not use it from any other place! 1336 + */ 1337 + int prcmu_set_clock_divider(u8 clock, u8 divider) 1338 + { 1339 + u32 val; 1340 + unsigned long flags; 1341 + 1342 + if ((clock >= PRCMU_NUM_REG_CLOCKS) || (divider < 1) || (31 < divider)) 1343 + return -EINVAL; 1344 + 1345 + spin_lock_irqsave(&clk_mgt_lock, flags); 1346 + 1347 + /* Grab the HW semaphore. */ 1348 + while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0) 1349 + cpu_relax(); 1350 + 1351 + val = readl(_PRCMU_BASE + clk_mgt[clock].offset); 1352 + val &= ~(PRCM_CLK_MGT_CLKPLLDIV_MASK); 1353 + val |= (u32)divider; 1354 + writel(val, (_PRCMU_BASE + clk_mgt[clock].offset)); 1355 + 1356 + /* Release the HW semaphore. */ 1357 + writel(0, (_PRCMU_BASE + PRCM_SEM)); 1358 + 1359 + spin_unlock_irqrestore(&clk_mgt_lock, flags); 1360 + 1361 + return 0; 1362 + } 1363 + 1364 + /** 1365 + * prcmu_abb_read() - Read register value(s) from the ABB. 1366 + * @slave: The I2C slave address. 1367 + * @reg: The (start) register address. 1368 + * @value: The read out value(s). 1369 + * @size: The number of registers to read. 1370 + * 1371 + * Reads register value(s) from the ABB. 1372 + * @size has to be 1 for the current firmware version. 1373 + */ 1374 + int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) 1375 + { 1376 + int r; 1377 + 1378 + if (size != 1) 1379 + return -EINVAL; 1380 + 1381 + mutex_lock(&mb5_transfer.lock); 1382 + 1383 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) 1384 + cpu_relax(); 1385 + 1386 + writeb(PRCMU_I2C_READ(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); 1387 + writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS)); 1388 + writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); 1389 + writeb(0, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); 1390 + 1391 + writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1392 + 1393 + if (!wait_for_completion_timeout(&mb5_transfer.work, 1394 + msecs_to_jiffies(20000))) { 1395 + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", 1396 + __func__); 1397 + r = -EIO; 1398 + } else { 1399 + r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); 1400 + } 1401 + 1402 + if (!r) 1403 + *value = mb5_transfer.ack.value; 1404 + 1405 + mutex_unlock(&mb5_transfer.lock); 1406 + 1407 + return r; 1408 + } 1409 + 1410 + /** 1411 + * prcmu_abb_write() - Write register value(s) to the ABB. 1412 + * @slave: The I2C slave address. 1413 + * @reg: The (start) register address. 1414 + * @value: The value(s) to write. 1415 + * @size: The number of registers to write. 1416 + * 1417 + * Reads register value(s) from the ABB. 1418 + * @size has to be 1 for the current firmware version. 1419 + */ 1420 + int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) 1421 + { 1422 + int r; 1423 + 1424 + if (size != 1) 1425 + return -EINVAL; 1426 + 1427 + mutex_lock(&mb5_transfer.lock); 1428 + 1429 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) 1430 + cpu_relax(); 1431 + 1432 + writeb(PRCMU_I2C_WRITE(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP)); 1433 + writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS)); 1434 + writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG)); 1435 + writeb(*value, (tcdm_base + PRCM_REQ_MB5_I2C_VAL)); 1436 + 1437 + writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1438 + 1439 + if (!wait_for_completion_timeout(&mb5_transfer.work, 1440 + msecs_to_jiffies(20000))) { 1441 + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", 1442 + __func__); 1443 + r = -EIO; 1444 + } else { 1445 + r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); 1446 + } 1447 + 1448 + mutex_unlock(&mb5_transfer.lock); 1449 + 1450 + return r; 1451 + } 1452 + 1453 + /** 1454 + * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem 1455 + */ 1456 + void prcmu_ac_wake_req(void) 1457 + { 1458 + u32 val; 1459 + 1460 + mutex_lock(&mb0_transfer.ac_wake_lock); 1461 + 1462 + val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ); 1463 + if (val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ) 1464 + goto unlock_and_return; 1465 + 1466 + atomic_set(&ac_wake_req_state, 1); 1467 + 1468 + writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), 1469 + (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); 1470 + 1471 + if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, 1472 + msecs_to_jiffies(20000))) { 1473 + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", 1474 + __func__); 1475 + } 1476 + 1477 + unlock_and_return: 1478 + mutex_unlock(&mb0_transfer.ac_wake_lock); 1479 + } 1480 + 1481 + /** 1482 + * prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem 1483 + */ 1484 + void prcmu_ac_sleep_req() 1485 + { 1486 + u32 val; 1487 + 1488 + mutex_lock(&mb0_transfer.ac_wake_lock); 1489 + 1490 + val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ); 1491 + if (!(val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ)) 1492 + goto unlock_and_return; 1493 + 1494 + writel((val & ~PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ), 1495 + (_PRCMU_BASE + PRCM_HOSTACCESS_REQ)); 1496 + 1497 + if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, 1498 + msecs_to_jiffies(20000))) { 1499 + pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n", 1500 + __func__); 1501 + } 1502 + 1503 + atomic_set(&ac_wake_req_state, 0); 1504 + 1505 + unlock_and_return: 1506 + mutex_unlock(&mb0_transfer.ac_wake_lock); 1507 + } 1508 + 1509 + bool prcmu_is_ac_wake_requested(void) 1510 + { 1511 + return (atomic_read(&ac_wake_req_state) != 0); 1512 + } 1513 + 1514 + /** 1515 + * prcmu_system_reset - System reset 1516 + * 1517 + * Saves the reset reason code and then sets the APE_SOFRST register which 1518 + * fires interrupt to fw 1519 + */ 1520 + void prcmu_system_reset(u16 reset_code) 1521 + { 1522 + writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON)); 1523 + writel(1, (_PRCMU_BASE + PRCM_APE_SOFTRST)); 1524 + } 1525 + 1526 + /** 1527 + * prcmu_reset_modem - ask the PRCMU to reset modem 1528 + */ 1529 + void prcmu_modem_reset(void) 1530 + { 1531 + mutex_lock(&mb1_transfer.lock); 1532 + 1533 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1)) 1534 + cpu_relax(); 1535 + 1536 + writeb(MB1H_RESET_MODEM, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1)); 1537 + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1538 + wait_for_completion(&mb1_transfer.work); 1539 + 1540 + /* 1541 + * No need to check return from PRCMU as modem should go in reset state 1542 + * This state is already managed by upper layer 1543 + */ 1544 + 1545 + mutex_unlock(&mb1_transfer.lock); 1546 + } 1547 + 1548 + static void ack_dbb_wakeup(void) 1549 + { 1550 + unsigned long flags; 1551 + 1552 + spin_lock_irqsave(&mb0_transfer.lock, flags); 1553 + 1554 + while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0)) 1555 + cpu_relax(); 1556 + 1557 + writeb(MB0H_READ_WAKEUP_ACK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0)); 1558 + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET)); 1559 + 1560 + spin_unlock_irqrestore(&mb0_transfer.lock, flags); 1561 + } 1562 + 1563 + static inline void print_unknown_header_warning(u8 n, u8 header) 1564 + { 1565 + pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n", 1566 + header, n); 1567 + } 1568 + 1569 + static bool read_mailbox_0(void) 1570 + { 1571 + bool r; 1572 + u32 ev; 1573 + unsigned int n; 1574 + u8 header; 1575 + 1576 + header = readb(tcdm_base + PRCM_MBOX_HEADER_ACK_MB0); 1577 + switch (header) { 1578 + case MB0H_WAKEUP_EXE: 1579 + case MB0H_WAKEUP_SLEEP: 1580 + if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1) 1581 + ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_1_8500); 1582 + else 1583 + ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_0_8500); 1584 + 1585 + if (ev & (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK)) 1586 + complete(&mb0_transfer.ac_wake_work); 1587 + if (ev & WAKEUP_BIT_SYSCLK_OK) 1588 + complete(&mb3_transfer.sysclk_work); 1589 + 1590 + ev &= mb0_transfer.req.dbb_irqs; 1591 + 1592 + for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) { 1593 + if (ev & prcmu_irq_bit[n]) 1594 + generic_handle_irq(IRQ_PRCMU_BASE + n); 1595 + } 1596 + r = true; 1597 + break; 1598 + default: 1599 + print_unknown_header_warning(0, header); 1600 + r = false; 1601 + break; 1602 + } 1603 + writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1604 + return r; 1605 + } 1606 + 1607 + static bool read_mailbox_1(void) 1608 + { 1609 + mb1_transfer.ack.header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB1); 1610 + mb1_transfer.ack.arm_opp = readb(tcdm_base + 1611 + PRCM_ACK_MB1_CURRENT_ARM_OPP); 1612 + mb1_transfer.ack.ape_opp = readb(tcdm_base + 1613 + PRCM_ACK_MB1_CURRENT_APE_OPP); 1614 + mb1_transfer.ack.ape_voltage_status = readb(tcdm_base + 1615 + PRCM_ACK_MB1_APE_VOLTAGE_STATUS); 1616 + writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1617 + complete(&mb1_transfer.work); 1618 + return false; 1619 + } 1620 + 1621 + static bool read_mailbox_2(void) 1622 + { 1623 + mb2_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB2_DPS_STATUS); 1624 + writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1625 + complete(&mb2_transfer.work); 1626 + return false; 1627 + } 1628 + 1629 + static bool read_mailbox_3(void) 1630 + { 1631 + writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1632 + return false; 1633 + } 1634 + 1635 + static bool read_mailbox_4(void) 1636 + { 1637 + u8 header; 1638 + bool do_complete = true; 1639 + 1640 + header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB4); 1641 + switch (header) { 1642 + case MB4H_MEM_ST: 1643 + case MB4H_HOTDOG: 1644 + case MB4H_HOTMON: 1645 + case MB4H_HOT_PERIOD: 1646 + break; 1647 + default: 1648 + print_unknown_header_warning(4, header); 1649 + do_complete = false; 1650 + break; 1651 + } 1652 + 1653 + writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1654 + 1655 + if (do_complete) 1656 + complete(&mb4_transfer.work); 1657 + 1658 + return false; 1659 + } 1660 + 1661 + static bool read_mailbox_5(void) 1662 + { 1663 + mb5_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB5_I2C_STATUS); 1664 + mb5_transfer.ack.value = readb(tcdm_base + PRCM_ACK_MB5_I2C_VAL); 1665 + writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1666 + complete(&mb5_transfer.work); 1667 + return false; 1668 + } 1669 + 1670 + static bool read_mailbox_6(void) 1671 + { 1672 + writel(MBOX_BIT(6), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1673 + return false; 1674 + } 1675 + 1676 + static bool read_mailbox_7(void) 1677 + { 1678 + writel(MBOX_BIT(7), (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 1679 + return false; 1680 + } 1681 + 1682 + static bool (* const read_mailbox[NUM_MB])(void) = { 1683 + read_mailbox_0, 1684 + read_mailbox_1, 1685 + read_mailbox_2, 1686 + read_mailbox_3, 1687 + read_mailbox_4, 1688 + read_mailbox_5, 1689 + read_mailbox_6, 1690 + read_mailbox_7 1691 + }; 1692 + 1693 + static irqreturn_t prcmu_irq_handler(int irq, void *data) 1694 + { 1695 + u32 bits; 1696 + u8 n; 1697 + irqreturn_t r; 1698 + 1699 + bits = (readl(_PRCMU_BASE + PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS); 1700 + if (unlikely(!bits)) 1701 + return IRQ_NONE; 1702 + 1703 + r = IRQ_HANDLED; 1704 + for (n = 0; bits; n++) { 1705 + if (bits & MBOX_BIT(n)) { 1706 + bits -= MBOX_BIT(n); 1707 + if (read_mailbox[n]()) 1708 + r = IRQ_WAKE_THREAD; 1709 + } 1710 + } 1711 + return r; 1712 + } 1713 + 1714 + static irqreturn_t prcmu_irq_thread_fn(int irq, void *data) 1715 + { 1716 + ack_dbb_wakeup(); 1717 + return IRQ_HANDLED; 1718 + } 1719 + 1720 + static void prcmu_mask_work(struct work_struct *work) 1721 + { 1722 + unsigned long flags; 1723 + 1724 + spin_lock_irqsave(&mb0_transfer.lock, flags); 1725 + 1726 + config_wakeups(); 1727 + 1728 + spin_unlock_irqrestore(&mb0_transfer.lock, flags); 1729 + } 1730 + 1731 + static void prcmu_irq_mask(struct irq_data *d) 1732 + { 1733 + unsigned long flags; 1734 + 1735 + spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); 1736 + 1737 + mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; 1738 + 1739 + spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); 1740 + 1741 + if (d->irq != IRQ_PRCMU_CA_SLEEP) 1742 + schedule_work(&mb0_transfer.mask_work); 1743 + } 1744 + 1745 + static void prcmu_irq_unmask(struct irq_data *d) 1746 + { 1747 + unsigned long flags; 1748 + 1749 + spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); 1750 + 1751 + mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; 1752 + 1753 + spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); 1754 + 1755 + if (d->irq != IRQ_PRCMU_CA_SLEEP) 1756 + schedule_work(&mb0_transfer.mask_work); 1757 + } 1758 + 1759 + static void noop(struct irq_data *d) 1760 + { 1761 + } 1762 + 1763 + static struct irq_chip prcmu_irq_chip = { 1764 + .name = "prcmu", 1765 + .irq_disable = prcmu_irq_mask, 1766 + .irq_ack = noop, 1767 + .irq_mask = prcmu_irq_mask, 1768 + .irq_unmask = prcmu_irq_unmask, 1769 + }; 1770 + 1771 + void __init prcmu_early_init(void) 1772 + { 1773 + unsigned int i; 1774 + 1775 + if (cpu_is_u8500v1()) { 1776 + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1); 1777 + } else if (cpu_is_u8500v2()) { 1778 + void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K); 1779 + 1780 + if (tcpm_base != NULL) { 1781 + int version; 1782 + version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET); 1783 + prcmu_version.project_number = version & 0xFF; 1784 + prcmu_version.api_version = (version >> 8) & 0xFF; 1785 + prcmu_version.func_version = (version >> 16) & 0xFF; 1786 + prcmu_version.errata = (version >> 24) & 0xFF; 1787 + pr_info("PRCMU firmware version %d.%d.%d\n", 1788 + (version >> 8) & 0xFF, (version >> 16) & 0xFF, 1789 + (version >> 24) & 0xFF); 1790 + iounmap(tcpm_base); 1791 + } 1792 + 1793 + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); 1794 + } else { 1795 + pr_err("prcmu: Unsupported chip version\n"); 1796 + BUG(); 1797 + } 1798 + 1799 + spin_lock_init(&mb0_transfer.lock); 1800 + spin_lock_init(&mb0_transfer.dbb_irqs_lock); 1801 + mutex_init(&mb0_transfer.ac_wake_lock); 1802 + init_completion(&mb0_transfer.ac_wake_work); 1803 + mutex_init(&mb1_transfer.lock); 1804 + init_completion(&mb1_transfer.work); 1805 + mutex_init(&mb2_transfer.lock); 1806 + init_completion(&mb2_transfer.work); 1807 + spin_lock_init(&mb2_transfer.auto_pm_lock); 1808 + spin_lock_init(&mb3_transfer.lock); 1809 + mutex_init(&mb3_transfer.sysclk_lock); 1810 + init_completion(&mb3_transfer.sysclk_work); 1811 + mutex_init(&mb4_transfer.lock); 1812 + init_completion(&mb4_transfer.work); 1813 + mutex_init(&mb5_transfer.lock); 1814 + init_completion(&mb5_transfer.work); 1815 + 1816 + INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); 1817 + 1818 + /* Initalize irqs. */ 1819 + for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) { 1820 + unsigned int irq; 1821 + 1822 + irq = IRQ_PRCMU_BASE + i; 1823 + irq_set_chip_and_handler(irq, &prcmu_irq_chip, 1824 + handle_simple_irq); 1825 + set_irq_flags(irq, IRQF_VALID); 1826 + } 1827 + } 1828 + 1829 + /* 1830 + * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC 1831 + */ 1832 + static struct regulator_consumer_supply db8500_vape_consumers[] = { 1833 + REGULATOR_SUPPLY("v-ape", NULL), 1834 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"), 1835 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), 1836 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), 1837 + REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), 1838 + /* "v-mmc" changed to "vcore" in the mainline kernel */ 1839 + REGULATOR_SUPPLY("vcore", "sdi0"), 1840 + REGULATOR_SUPPLY("vcore", "sdi1"), 1841 + REGULATOR_SUPPLY("vcore", "sdi2"), 1842 + REGULATOR_SUPPLY("vcore", "sdi3"), 1843 + REGULATOR_SUPPLY("vcore", "sdi4"), 1844 + REGULATOR_SUPPLY("v-dma", "dma40.0"), 1845 + REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"), 1846 + /* "v-uart" changed to "vcore" in the mainline kernel */ 1847 + REGULATOR_SUPPLY("vcore", "uart0"), 1848 + REGULATOR_SUPPLY("vcore", "uart1"), 1849 + REGULATOR_SUPPLY("vcore", "uart2"), 1850 + REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"), 1851 + }; 1852 + 1853 + static struct regulator_consumer_supply db8500_vsmps2_consumers[] = { 1854 + /* CG2900 and CW1200 power to off-chip peripherals */ 1855 + REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"), 1856 + REGULATOR_SUPPLY("wlan_1v8", "cw1200.0"), 1857 + REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"), 1858 + /* AV8100 regulator */ 1859 + REGULATOR_SUPPLY("hdmi_1v8", "0-0070"), 1860 + }; 1861 + 1862 + static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = { 1863 + REGULATOR_SUPPLY("vsupply", "b2r2.0"), 1864 + REGULATOR_SUPPLY("vsupply", "mcde.0"), 1865 + }; 1866 + 1867 + static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = { 1868 + [DB8500_REGULATOR_VAPE] = { 1869 + .constraints = { 1870 + .name = "db8500-vape", 1871 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1872 + }, 1873 + .consumer_supplies = db8500_vape_consumers, 1874 + .num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers), 1875 + }, 1876 + [DB8500_REGULATOR_VARM] = { 1877 + .constraints = { 1878 + .name = "db8500-varm", 1879 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1880 + }, 1881 + }, 1882 + [DB8500_REGULATOR_VMODEM] = { 1883 + .constraints = { 1884 + .name = "db8500-vmodem", 1885 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1886 + }, 1887 + }, 1888 + [DB8500_REGULATOR_VPLL] = { 1889 + .constraints = { 1890 + .name = "db8500-vpll", 1891 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1892 + }, 1893 + }, 1894 + [DB8500_REGULATOR_VSMPS1] = { 1895 + .constraints = { 1896 + .name = "db8500-vsmps1", 1897 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1898 + }, 1899 + }, 1900 + [DB8500_REGULATOR_VSMPS2] = { 1901 + .constraints = { 1902 + .name = "db8500-vsmps2", 1903 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1904 + }, 1905 + .consumer_supplies = db8500_vsmps2_consumers, 1906 + .num_consumer_supplies = ARRAY_SIZE(db8500_vsmps2_consumers), 1907 + }, 1908 + [DB8500_REGULATOR_VSMPS3] = { 1909 + .constraints = { 1910 + .name = "db8500-vsmps3", 1911 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1912 + }, 1913 + }, 1914 + [DB8500_REGULATOR_VRF1] = { 1915 + .constraints = { 1916 + .name = "db8500-vrf1", 1917 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1918 + }, 1919 + }, 1920 + [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { 1921 + .supply_regulator = "db8500-vape", 1922 + .constraints = { 1923 + .name = "db8500-sva-mmdsp", 1924 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1925 + }, 1926 + }, 1927 + [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { 1928 + .constraints = { 1929 + /* "ret" means "retention" */ 1930 + .name = "db8500-sva-mmdsp-ret", 1931 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1932 + }, 1933 + }, 1934 + [DB8500_REGULATOR_SWITCH_SVAPIPE] = { 1935 + .supply_regulator = "db8500-vape", 1936 + .constraints = { 1937 + .name = "db8500-sva-pipe", 1938 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1939 + }, 1940 + }, 1941 + [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { 1942 + .supply_regulator = "db8500-vape", 1943 + .constraints = { 1944 + .name = "db8500-sia-mmdsp", 1945 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1946 + }, 1947 + }, 1948 + [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { 1949 + .constraints = { 1950 + .name = "db8500-sia-mmdsp-ret", 1951 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1952 + }, 1953 + }, 1954 + [DB8500_REGULATOR_SWITCH_SIAPIPE] = { 1955 + .supply_regulator = "db8500-vape", 1956 + .constraints = { 1957 + .name = "db8500-sia-pipe", 1958 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1959 + }, 1960 + }, 1961 + [DB8500_REGULATOR_SWITCH_SGA] = { 1962 + .supply_regulator = "db8500-vape", 1963 + .constraints = { 1964 + .name = "db8500-sga", 1965 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1966 + }, 1967 + }, 1968 + [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { 1969 + .supply_regulator = "db8500-vape", 1970 + .constraints = { 1971 + .name = "db8500-b2r2-mcde", 1972 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1973 + }, 1974 + .consumer_supplies = db8500_b2r2_mcde_consumers, 1975 + .num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers), 1976 + }, 1977 + [DB8500_REGULATOR_SWITCH_ESRAM12] = { 1978 + .supply_regulator = "db8500-vape", 1979 + .constraints = { 1980 + .name = "db8500-esram12", 1981 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1982 + }, 1983 + }, 1984 + [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { 1985 + .constraints = { 1986 + .name = "db8500-esram12-ret", 1987 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1988 + }, 1989 + }, 1990 + [DB8500_REGULATOR_SWITCH_ESRAM34] = { 1991 + .supply_regulator = "db8500-vape", 1992 + .constraints = { 1993 + .name = "db8500-esram34", 1994 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 1995 + }, 1996 + }, 1997 + [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { 1998 + .constraints = { 1999 + .name = "db8500-esram34-ret", 2000 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 2001 + }, 2002 + }, 2003 + }; 2004 + 2005 + static struct mfd_cell db8500_prcmu_devs[] = { 2006 + { 2007 + .name = "db8500-prcmu-regulators", 2008 + .mfd_data = &db8500_regulators, 2009 + }, 2010 + { 2011 + .name = "cpufreq-u8500", 2012 + }, 2013 + }; 2014 + 2015 + /** 2016 + * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic 2017 + * 2018 + */ 2019 + static int __init db8500_prcmu_probe(struct platform_device *pdev) 2020 + { 2021 + int err = 0; 2022 + 2023 + if (ux500_is_svp()) 2024 + return -ENODEV; 2025 + 2026 + /* Clean up the mailbox interrupts after pre-kernel code. */ 2027 + writel(ALL_MBOX_BITS, (_PRCMU_BASE + PRCM_ARM_IT1_CLR)); 2028 + 2029 + err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 2030 + prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); 2031 + if (err < 0) { 2032 + pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); 2033 + err = -EBUSY; 2034 + goto no_irq_return; 2035 + } 2036 + 2037 + if (cpu_is_u8500v20_or_later()) 2038 + prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); 2039 + 2040 + err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, 2041 + ARRAY_SIZE(db8500_prcmu_devs), NULL, 2042 + 0); 2043 + 2044 + if (err) 2045 + pr_err("prcmu: Failed to add subdevices\n"); 2046 + else 2047 + pr_info("DB8500 PRCMU initialized\n"); 2048 + 2049 + no_irq_return: 2050 + return err; 2051 + } 2052 + 2053 + static struct platform_driver db8500_prcmu_driver = { 2054 + .driver = { 2055 + .name = "db8500-prcmu", 2056 + .owner = THIS_MODULE, 2057 + }, 2058 + }; 2059 + 2060 + static int __init db8500_prcmu_init(void) 2061 + { 2062 + return platform_driver_probe(&db8500_prcmu_driver, db8500_prcmu_probe); 2063 + } 2064 + 2065 + arch_initcall(db8500_prcmu_init); 2066 + 2067 + MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com>"); 2068 + MODULE_DESCRIPTION("DB8500 PRCM Unit driver"); 2069 + MODULE_LICENSE("GPL v2");
+7
drivers/regulator/Kconfig
··· 274 274 This driver supports the regulators found on the ST-Ericsson mixed 275 275 signal AB8500 PMIC 276 276 277 + config REGULATOR_DB8500_PRCMU 278 + bool "ST-Ericsson DB8500 Voltage Domain Regulators" 279 + depends on MFD_DB8500_PRCMU 280 + help 281 + This driver supports the voltage domain regulators controlled by the 282 + DB8500 PRCMU 283 + 277 284 config REGULATOR_TPS6586X 278 285 tristate "TI TPS6586X Power regulators" 279 286 depends on MFD_TPS6586X
+1
drivers/regulator/Makefile
··· 41 41 obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o 42 42 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o 43 43 obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o 44 + obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o 44 45 45 46 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
+558
drivers/regulator/db8500-prcmu.c
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License Terms: GNU General Public License v2 5 + * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson 6 + * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson 7 + * 8 + * Power domain regulators on DB8500 9 + */ 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/init.h> 13 + #include <linux/err.h> 14 + #include <linux/spinlock.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/mfd/core.h> 17 + #include <linux/mfd/db8500-prcmu.h> 18 + #include <linux/regulator/driver.h> 19 + #include <linux/regulator/machine.h> 20 + #include <linux/regulator/db8500-prcmu.h> 21 + 22 + /* 23 + * power state reference count 24 + */ 25 + static int power_state_active_cnt; /* will initialize to zero */ 26 + static DEFINE_SPINLOCK(power_state_active_lock); 27 + 28 + static void power_state_active_enable(void) 29 + { 30 + unsigned long flags; 31 + 32 + spin_lock_irqsave(&power_state_active_lock, flags); 33 + power_state_active_cnt++; 34 + spin_unlock_irqrestore(&power_state_active_lock, flags); 35 + } 36 + 37 + static int power_state_active_disable(void) 38 + { 39 + int ret = 0; 40 + unsigned long flags; 41 + 42 + spin_lock_irqsave(&power_state_active_lock, flags); 43 + if (power_state_active_cnt <= 0) { 44 + pr_err("power state: unbalanced enable/disable calls\n"); 45 + ret = -EINVAL; 46 + goto out; 47 + } 48 + 49 + power_state_active_cnt--; 50 + out: 51 + spin_unlock_irqrestore(&power_state_active_lock, flags); 52 + return ret; 53 + } 54 + 55 + /* 56 + * Exported interface for CPUIdle only. This function is called when interrupts 57 + * are turned off. Hence, no locking. 58 + */ 59 + int power_state_active_is_enabled(void) 60 + { 61 + return (power_state_active_cnt > 0); 62 + } 63 + 64 + /** 65 + * struct db8500_regulator_info - db8500 regulator information 66 + * @dev: device pointer 67 + * @desc: regulator description 68 + * @rdev: regulator device pointer 69 + * @is_enabled: status of the regulator 70 + * @epod_id: id for EPOD (power domain) 71 + * @is_ramret: RAM retention switch for EPOD (power domain) 72 + * @operating_point: operating point (only for vape, to be removed) 73 + * 74 + */ 75 + struct db8500_regulator_info { 76 + struct device *dev; 77 + struct regulator_desc desc; 78 + struct regulator_dev *rdev; 79 + bool is_enabled; 80 + u16 epod_id; 81 + bool is_ramret; 82 + bool exclude_from_power_state; 83 + unsigned int operating_point; 84 + }; 85 + 86 + static int db8500_regulator_enable(struct regulator_dev *rdev) 87 + { 88 + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); 89 + 90 + if (info == NULL) 91 + return -EINVAL; 92 + 93 + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", 94 + info->desc.name); 95 + 96 + info->is_enabled = true; 97 + if (!info->exclude_from_power_state) 98 + power_state_active_enable(); 99 + 100 + return 0; 101 + } 102 + 103 + static int db8500_regulator_disable(struct regulator_dev *rdev) 104 + { 105 + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); 106 + int ret = 0; 107 + 108 + if (info == NULL) 109 + return -EINVAL; 110 + 111 + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", 112 + info->desc.name); 113 + 114 + info->is_enabled = false; 115 + if (!info->exclude_from_power_state) 116 + ret = power_state_active_disable(); 117 + 118 + return ret; 119 + } 120 + 121 + static int db8500_regulator_is_enabled(struct regulator_dev *rdev) 122 + { 123 + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); 124 + 125 + if (info == NULL) 126 + return -EINVAL; 127 + 128 + dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):" 129 + " %i\n", info->desc.name, info->is_enabled); 130 + 131 + return info->is_enabled; 132 + } 133 + 134 + /* db8500 regulator operations */ 135 + static struct regulator_ops db8500_regulator_ops = { 136 + .enable = db8500_regulator_enable, 137 + .disable = db8500_regulator_disable, 138 + .is_enabled = db8500_regulator_is_enabled, 139 + }; 140 + 141 + /* 142 + * EPOD control 143 + */ 144 + static bool epod_on[NUM_EPOD_ID]; 145 + static bool epod_ramret[NUM_EPOD_ID]; 146 + 147 + static int enable_epod(u16 epod_id, bool ramret) 148 + { 149 + int ret; 150 + 151 + if (ramret) { 152 + if (!epod_on[epod_id]) { 153 + ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); 154 + if (ret < 0) 155 + return ret; 156 + } 157 + epod_ramret[epod_id] = true; 158 + } else { 159 + ret = prcmu_set_epod(epod_id, EPOD_STATE_ON); 160 + if (ret < 0) 161 + return ret; 162 + epod_on[epod_id] = true; 163 + } 164 + 165 + return 0; 166 + } 167 + 168 + static int disable_epod(u16 epod_id, bool ramret) 169 + { 170 + int ret; 171 + 172 + if (ramret) { 173 + if (!epod_on[epod_id]) { 174 + ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); 175 + if (ret < 0) 176 + return ret; 177 + } 178 + epod_ramret[epod_id] = false; 179 + } else { 180 + if (epod_ramret[epod_id]) { 181 + ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET); 182 + if (ret < 0) 183 + return ret; 184 + } else { 185 + ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF); 186 + if (ret < 0) 187 + return ret; 188 + } 189 + epod_on[epod_id] = false; 190 + } 191 + 192 + return 0; 193 + } 194 + 195 + /* 196 + * Regulator switch 197 + */ 198 + static int db8500_regulator_switch_enable(struct regulator_dev *rdev) 199 + { 200 + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); 201 + int ret; 202 + 203 + if (info == NULL) 204 + return -EINVAL; 205 + 206 + dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n", 207 + info->desc.name); 208 + 209 + ret = enable_epod(info->epod_id, info->is_ramret); 210 + if (ret < 0) { 211 + dev_err(rdev_get_dev(rdev), 212 + "regulator-switch-%s-enable: prcmu call failed\n", 213 + info->desc.name); 214 + goto out; 215 + } 216 + 217 + info->is_enabled = true; 218 + out: 219 + return ret; 220 + } 221 + 222 + static int db8500_regulator_switch_disable(struct regulator_dev *rdev) 223 + { 224 + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); 225 + int ret; 226 + 227 + if (info == NULL) 228 + return -EINVAL; 229 + 230 + dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n", 231 + info->desc.name); 232 + 233 + ret = disable_epod(info->epod_id, info->is_ramret); 234 + if (ret < 0) { 235 + dev_err(rdev_get_dev(rdev), 236 + "regulator_switch-%s-disable: prcmu call failed\n", 237 + info->desc.name); 238 + goto out; 239 + } 240 + 241 + info->is_enabled = 0; 242 + out: 243 + return ret; 244 + } 245 + 246 + static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) 247 + { 248 + struct db8500_regulator_info *info = rdev_get_drvdata(rdev); 249 + 250 + if (info == NULL) 251 + return -EINVAL; 252 + 253 + dev_vdbg(rdev_get_dev(rdev), 254 + "regulator-switch-%s-is_enabled (is_enabled): %i\n", 255 + info->desc.name, info->is_enabled); 256 + 257 + return info->is_enabled; 258 + } 259 + 260 + static struct regulator_ops db8500_regulator_switch_ops = { 261 + .enable = db8500_regulator_switch_enable, 262 + .disable = db8500_regulator_switch_disable, 263 + .is_enabled = db8500_regulator_switch_is_enabled, 264 + }; 265 + 266 + /* 267 + * Regulator information 268 + */ 269 + static struct db8500_regulator_info 270 + db8500_regulator_info[DB8500_NUM_REGULATORS] = { 271 + [DB8500_REGULATOR_VAPE] = { 272 + .desc = { 273 + .name = "db8500-vape", 274 + .id = DB8500_REGULATOR_VAPE, 275 + .ops = &db8500_regulator_ops, 276 + .type = REGULATOR_VOLTAGE, 277 + .owner = THIS_MODULE, 278 + }, 279 + }, 280 + [DB8500_REGULATOR_VARM] = { 281 + .desc = { 282 + .name = "db8500-varm", 283 + .id = DB8500_REGULATOR_VARM, 284 + .ops = &db8500_regulator_ops, 285 + .type = REGULATOR_VOLTAGE, 286 + .owner = THIS_MODULE, 287 + }, 288 + }, 289 + [DB8500_REGULATOR_VMODEM] = { 290 + .desc = { 291 + .name = "db8500-vmodem", 292 + .id = DB8500_REGULATOR_VMODEM, 293 + .ops = &db8500_regulator_ops, 294 + .type = REGULATOR_VOLTAGE, 295 + .owner = THIS_MODULE, 296 + }, 297 + }, 298 + [DB8500_REGULATOR_VPLL] = { 299 + .desc = { 300 + .name = "db8500-vpll", 301 + .id = DB8500_REGULATOR_VPLL, 302 + .ops = &db8500_regulator_ops, 303 + .type = REGULATOR_VOLTAGE, 304 + .owner = THIS_MODULE, 305 + }, 306 + }, 307 + [DB8500_REGULATOR_VSMPS1] = { 308 + .desc = { 309 + .name = "db8500-vsmps1", 310 + .id = DB8500_REGULATOR_VSMPS1, 311 + .ops = &db8500_regulator_ops, 312 + .type = REGULATOR_VOLTAGE, 313 + .owner = THIS_MODULE, 314 + }, 315 + }, 316 + [DB8500_REGULATOR_VSMPS2] = { 317 + .desc = { 318 + .name = "db8500-vsmps2", 319 + .id = DB8500_REGULATOR_VSMPS2, 320 + .ops = &db8500_regulator_ops, 321 + .type = REGULATOR_VOLTAGE, 322 + .owner = THIS_MODULE, 323 + }, 324 + .exclude_from_power_state = true, 325 + }, 326 + [DB8500_REGULATOR_VSMPS3] = { 327 + .desc = { 328 + .name = "db8500-vsmps3", 329 + .id = DB8500_REGULATOR_VSMPS3, 330 + .ops = &db8500_regulator_ops, 331 + .type = REGULATOR_VOLTAGE, 332 + .owner = THIS_MODULE, 333 + }, 334 + }, 335 + [DB8500_REGULATOR_VRF1] = { 336 + .desc = { 337 + .name = "db8500-vrf1", 338 + .id = DB8500_REGULATOR_VRF1, 339 + .ops = &db8500_regulator_ops, 340 + .type = REGULATOR_VOLTAGE, 341 + .owner = THIS_MODULE, 342 + }, 343 + }, 344 + [DB8500_REGULATOR_SWITCH_SVAMMDSP] = { 345 + .desc = { 346 + .name = "db8500-sva-mmdsp", 347 + .id = DB8500_REGULATOR_SWITCH_SVAMMDSP, 348 + .ops = &db8500_regulator_switch_ops, 349 + .type = REGULATOR_VOLTAGE, 350 + .owner = THIS_MODULE, 351 + }, 352 + .epod_id = EPOD_ID_SVAMMDSP, 353 + }, 354 + [DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = { 355 + .desc = { 356 + .name = "db8500-sva-mmdsp-ret", 357 + .id = DB8500_REGULATOR_SWITCH_SVAMMDSPRET, 358 + .ops = &db8500_regulator_switch_ops, 359 + .type = REGULATOR_VOLTAGE, 360 + .owner = THIS_MODULE, 361 + }, 362 + .epod_id = EPOD_ID_SVAMMDSP, 363 + .is_ramret = true, 364 + }, 365 + [DB8500_REGULATOR_SWITCH_SVAPIPE] = { 366 + .desc = { 367 + .name = "db8500-sva-pipe", 368 + .id = DB8500_REGULATOR_SWITCH_SVAPIPE, 369 + .ops = &db8500_regulator_switch_ops, 370 + .type = REGULATOR_VOLTAGE, 371 + .owner = THIS_MODULE, 372 + }, 373 + .epod_id = EPOD_ID_SVAPIPE, 374 + }, 375 + [DB8500_REGULATOR_SWITCH_SIAMMDSP] = { 376 + .desc = { 377 + .name = "db8500-sia-mmdsp", 378 + .id = DB8500_REGULATOR_SWITCH_SIAMMDSP, 379 + .ops = &db8500_regulator_switch_ops, 380 + .type = REGULATOR_VOLTAGE, 381 + .owner = THIS_MODULE, 382 + }, 383 + .epod_id = EPOD_ID_SIAMMDSP, 384 + }, 385 + [DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = { 386 + .desc = { 387 + .name = "db8500-sia-mmdsp-ret", 388 + .id = DB8500_REGULATOR_SWITCH_SIAMMDSPRET, 389 + .ops = &db8500_regulator_switch_ops, 390 + .type = REGULATOR_VOLTAGE, 391 + .owner = THIS_MODULE, 392 + }, 393 + .epod_id = EPOD_ID_SIAMMDSP, 394 + .is_ramret = true, 395 + }, 396 + [DB8500_REGULATOR_SWITCH_SIAPIPE] = { 397 + .desc = { 398 + .name = "db8500-sia-pipe", 399 + .id = DB8500_REGULATOR_SWITCH_SIAPIPE, 400 + .ops = &db8500_regulator_switch_ops, 401 + .type = REGULATOR_VOLTAGE, 402 + .owner = THIS_MODULE, 403 + }, 404 + .epod_id = EPOD_ID_SIAPIPE, 405 + }, 406 + [DB8500_REGULATOR_SWITCH_SGA] = { 407 + .desc = { 408 + .name = "db8500-sga", 409 + .id = DB8500_REGULATOR_SWITCH_SGA, 410 + .ops = &db8500_regulator_switch_ops, 411 + .type = REGULATOR_VOLTAGE, 412 + .owner = THIS_MODULE, 413 + }, 414 + .epod_id = EPOD_ID_SGA, 415 + }, 416 + [DB8500_REGULATOR_SWITCH_B2R2_MCDE] = { 417 + .desc = { 418 + .name = "db8500-b2r2-mcde", 419 + .id = DB8500_REGULATOR_SWITCH_B2R2_MCDE, 420 + .ops = &db8500_regulator_switch_ops, 421 + .type = REGULATOR_VOLTAGE, 422 + .owner = THIS_MODULE, 423 + }, 424 + .epod_id = EPOD_ID_B2R2_MCDE, 425 + }, 426 + [DB8500_REGULATOR_SWITCH_ESRAM12] = { 427 + .desc = { 428 + .name = "db8500-esram12", 429 + .id = DB8500_REGULATOR_SWITCH_ESRAM12, 430 + .ops = &db8500_regulator_switch_ops, 431 + .type = REGULATOR_VOLTAGE, 432 + .owner = THIS_MODULE, 433 + }, 434 + .epod_id = EPOD_ID_ESRAM12, 435 + .is_enabled = true, 436 + }, 437 + [DB8500_REGULATOR_SWITCH_ESRAM12RET] = { 438 + .desc = { 439 + .name = "db8500-esram12-ret", 440 + .id = DB8500_REGULATOR_SWITCH_ESRAM12RET, 441 + .ops = &db8500_regulator_switch_ops, 442 + .type = REGULATOR_VOLTAGE, 443 + .owner = THIS_MODULE, 444 + }, 445 + .epod_id = EPOD_ID_ESRAM12, 446 + .is_ramret = true, 447 + }, 448 + [DB8500_REGULATOR_SWITCH_ESRAM34] = { 449 + .desc = { 450 + .name = "db8500-esram34", 451 + .id = DB8500_REGULATOR_SWITCH_ESRAM34, 452 + .ops = &db8500_regulator_switch_ops, 453 + .type = REGULATOR_VOLTAGE, 454 + .owner = THIS_MODULE, 455 + }, 456 + .epod_id = EPOD_ID_ESRAM34, 457 + .is_enabled = true, 458 + }, 459 + [DB8500_REGULATOR_SWITCH_ESRAM34RET] = { 460 + .desc = { 461 + .name = "db8500-esram34-ret", 462 + .id = DB8500_REGULATOR_SWITCH_ESRAM34RET, 463 + .ops = &db8500_regulator_switch_ops, 464 + .type = REGULATOR_VOLTAGE, 465 + .owner = THIS_MODULE, 466 + }, 467 + .epod_id = EPOD_ID_ESRAM34, 468 + .is_ramret = true, 469 + }, 470 + }; 471 + 472 + static int __devinit db8500_regulator_probe(struct platform_device *pdev) 473 + { 474 + struct regulator_init_data *db8500_init_data = mfd_get_data(pdev); 475 + int i, err; 476 + 477 + /* register all regulators */ 478 + for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { 479 + struct db8500_regulator_info *info; 480 + struct regulator_init_data *init_data = &db8500_init_data[i]; 481 + 482 + /* assign per-regulator data */ 483 + info = &db8500_regulator_info[i]; 484 + info->dev = &pdev->dev; 485 + 486 + /* register with the regulator framework */ 487 + info->rdev = regulator_register(&info->desc, &pdev->dev, 488 + init_data, info); 489 + if (IS_ERR(info->rdev)) { 490 + err = PTR_ERR(info->rdev); 491 + dev_err(&pdev->dev, "failed to register %s: err %i\n", 492 + info->desc.name, err); 493 + 494 + /* if failing, unregister all earlier regulators */ 495 + i--; 496 + while (i >= 0) { 497 + info = &db8500_regulator_info[i]; 498 + regulator_unregister(info->rdev); 499 + i--; 500 + } 501 + return err; 502 + } 503 + 504 + dev_dbg(rdev_get_dev(info->rdev), 505 + "regulator-%s-probed\n", info->desc.name); 506 + } 507 + 508 + return 0; 509 + } 510 + 511 + static int __exit db8500_regulator_remove(struct platform_device *pdev) 512 + { 513 + int i; 514 + 515 + for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { 516 + struct db8500_regulator_info *info; 517 + info = &db8500_regulator_info[i]; 518 + 519 + dev_vdbg(rdev_get_dev(info->rdev), 520 + "regulator-%s-remove\n", info->desc.name); 521 + 522 + regulator_unregister(info->rdev); 523 + } 524 + 525 + return 0; 526 + } 527 + 528 + static struct platform_driver db8500_regulator_driver = { 529 + .driver = { 530 + .name = "db8500-prcmu-regulators", 531 + .owner = THIS_MODULE, 532 + }, 533 + .probe = db8500_regulator_probe, 534 + .remove = __exit_p(db8500_regulator_remove), 535 + }; 536 + 537 + static int __init db8500_regulator_init(void) 538 + { 539 + int ret; 540 + 541 + ret = platform_driver_register(&db8500_regulator_driver); 542 + if (ret < 0) 543 + return -ENODEV; 544 + 545 + return 0; 546 + } 547 + 548 + static void __exit db8500_regulator_exit(void) 549 + { 550 + platform_driver_unregister(&db8500_regulator_driver); 551 + } 552 + 553 + arch_initcall(db8500_regulator_init); 554 + module_exit(db8500_regulator_exit); 555 + 556 + MODULE_AUTHOR("STMicroelectronics/ST-Ericsson"); 557 + MODULE_DESCRIPTION("DB8500 regulator driver"); 558 + MODULE_LICENSE("GPL v2");
+45
include/linux/mfd/db5500-prcmu.h
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License Terms: GNU General Public License v2 5 + * 6 + * U5500 PRCMU API. 7 + */ 8 + #ifndef __MACH_PRCMU_U5500_H 9 + #define __MACH_PRCMU_U5500_H 10 + 11 + #ifdef CONFIG_UX500_SOC_DB5500 12 + 13 + void db5500_prcmu_early_init(void); 14 + 15 + int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); 16 + int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); 17 + 18 + #else /* !CONFIG_UX500_SOC_DB5500 */ 19 + 20 + static inline void db5500_prcmu_early_init(void) 21 + { 22 + } 23 + 24 + static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) 25 + { 26 + return -ENOSYS; 27 + } 28 + 29 + static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) 30 + { 31 + return -ENOSYS; 32 + } 33 + 34 + #endif /* CONFIG_UX500_SOC_DB5500 */ 35 + 36 + static inline int db5500_prcmu_config_abb_event_readout(u32 abb_events) 37 + { 38 + #ifdef CONFIG_MACH_U5500_SIMULATOR 39 + return 0; 40 + #else 41 + return -1; 42 + #endif 43 + } 44 + 45 + #endif /* __MACH_PRCMU_U5500_H */
+978
include/linux/mfd/db8500-prcmu.h
··· 1 + /* 2 + * Copyright (C) STMicroelectronics 2009 3 + * Copyright (C) ST-Ericsson SA 2010 4 + * 5 + * License Terms: GNU General Public License v2 6 + * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com> 7 + * 8 + * PRCMU f/w APIs 9 + */ 10 + #ifndef __MFD_DB8500_PRCMU_H 11 + #define __MFD_DB8500_PRCMU_H 12 + 13 + #include <linux/interrupt.h> 14 + #include <linux/notifier.h> 15 + 16 + /* This portion previously known as <mach/prcmu-fw-defs_v1.h> */ 17 + 18 + /** 19 + * enum state - ON/OFF state definition 20 + * @OFF: State is ON 21 + * @ON: State is OFF 22 + * 23 + */ 24 + enum state { 25 + OFF = 0x0, 26 + ON = 0x1, 27 + }; 28 + 29 + /** 30 + * enum ret_state - general purpose On/Off/Retention states 31 + * 32 + */ 33 + enum ret_state { 34 + OFFST = 0, 35 + ONST = 1, 36 + RETST = 2 37 + }; 38 + 39 + /** 40 + * enum clk_arm - ARM Cortex A9 clock schemes 41 + * @A9_OFF: 42 + * @A9_BOOT: 43 + * @A9_OPPT1: 44 + * @A9_OPPT2: 45 + * @A9_EXTCLK: 46 + */ 47 + enum clk_arm { 48 + A9_OFF, 49 + A9_BOOT, 50 + A9_OPPT1, 51 + A9_OPPT2, 52 + A9_EXTCLK 53 + }; 54 + 55 + /** 56 + * enum clk_gen - GEN#0/GEN#1 clock schemes 57 + * @GEN_OFF: 58 + * @GEN_BOOT: 59 + * @GEN_OPPT1: 60 + */ 61 + enum clk_gen { 62 + GEN_OFF, 63 + GEN_BOOT, 64 + GEN_OPPT1, 65 + }; 66 + 67 + /* some information between arm and xp70 */ 68 + 69 + /** 70 + * enum romcode_write - Romcode message written by A9 AND read by XP70 71 + * @RDY_2_DS: Value set when ApDeepSleep state can be executed by XP70 72 + * @RDY_2_XP70_RST: Value set when 0x0F has been successfully polled by the 73 + * romcode. The xp70 will go into self-reset 74 + */ 75 + enum romcode_write { 76 + RDY_2_DS = 0x09, 77 + RDY_2_XP70_RST = 0x10 78 + }; 79 + 80 + /** 81 + * enum romcode_read - Romcode message written by XP70 and read by A9 82 + * @INIT: Init value when romcode field is not used 83 + * @FS_2_DS: Value set when power state is going from ApExecute to 84 + * ApDeepSleep 85 + * @END_DS: Value set when ApDeepSleep power state is reached coming from 86 + * ApExecute state 87 + * @DS_TO_FS: Value set when power state is going from ApDeepSleep to 88 + * ApExecute 89 + * @END_FS: Value set when ApExecute power state is reached coming from 90 + * ApDeepSleep state 91 + * @SWR: Value set when power state is going to ApReset 92 + * @END_SWR: Value set when the xp70 finished executing ApReset actions and 93 + * waits for romcode acknowledgment to go to self-reset 94 + */ 95 + enum romcode_read { 96 + INIT = 0x00, 97 + FS_2_DS = 0x0A, 98 + END_DS = 0x0B, 99 + DS_TO_FS = 0x0C, 100 + END_FS = 0x0D, 101 + SWR = 0x0E, 102 + END_SWR = 0x0F 103 + }; 104 + 105 + /** 106 + * enum ap_pwrst - current power states defined in PRCMU firmware 107 + * @NO_PWRST: Current power state init 108 + * @AP_BOOT: Current power state is apBoot 109 + * @AP_EXECUTE: Current power state is apExecute 110 + * @AP_DEEP_SLEEP: Current power state is apDeepSleep 111 + * @AP_SLEEP: Current power state is apSleep 112 + * @AP_IDLE: Current power state is apIdle 113 + * @AP_RESET: Current power state is apReset 114 + */ 115 + enum ap_pwrst { 116 + NO_PWRST = 0x00, 117 + AP_BOOT = 0x01, 118 + AP_EXECUTE = 0x02, 119 + AP_DEEP_SLEEP = 0x03, 120 + AP_SLEEP = 0x04, 121 + AP_IDLE = 0x05, 122 + AP_RESET = 0x06 123 + }; 124 + 125 + /** 126 + * enum ap_pwrst_trans - Transition states defined in PRCMU firmware 127 + * @NO_TRANSITION: No power state transition 128 + * @APEXECUTE_TO_APSLEEP: Power state transition from ApExecute to ApSleep 129 + * @APIDLE_TO_APSLEEP: Power state transition from ApIdle to ApSleep 130 + * @APBOOT_TO_APEXECUTE: Power state transition from ApBoot to ApExecute 131 + * @APEXECUTE_TO_APDEEPSLEEP: Power state transition from ApExecute to 132 + * ApDeepSleep 133 + * @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle 134 + */ 135 + enum ap_pwrst_trans { 136 + NO_TRANSITION = 0x00, 137 + APEXECUTE_TO_APSLEEP = 0x01, 138 + APIDLE_TO_APSLEEP = 0x02, /* To be removed */ 139 + PRCMU_AP_SLEEP = 0x01, 140 + APBOOT_TO_APEXECUTE = 0x03, 141 + APEXECUTE_TO_APDEEPSLEEP = 0x04, /* To be removed */ 142 + PRCMU_AP_DEEP_SLEEP = 0x04, 143 + APEXECUTE_TO_APIDLE = 0x05, /* To be removed */ 144 + PRCMU_AP_IDLE = 0x05, 145 + PRCMU_AP_DEEP_IDLE = 0x07, 146 + }; 147 + 148 + /** 149 + * enum ddr_pwrst - DDR power states definition 150 + * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged 151 + * @DDR_PWR_STATE_ON: 152 + * @DDR_PWR_STATE_OFFLOWLAT: 153 + * @DDR_PWR_STATE_OFFHIGHLAT: 154 + */ 155 + enum ddr_pwrst { 156 + DDR_PWR_STATE_UNCHANGED = 0x00, 157 + DDR_PWR_STATE_ON = 0x01, 158 + DDR_PWR_STATE_OFFLOWLAT = 0x02, 159 + DDR_PWR_STATE_OFFHIGHLAT = 0x03 160 + }; 161 + 162 + /** 163 + * enum arm_opp - ARM OPP states definition 164 + * @ARM_OPP_INIT: 165 + * @ARM_NO_CHANGE: The ARM operating point is unchanged 166 + * @ARM_100_OPP: The new ARM operating point is arm100opp 167 + * @ARM_50_OPP: The new ARM operating point is arm50opp 168 + * @ARM_MAX_OPP: Operating point is "max" (more than 100) 169 + * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100 170 + * @ARM_EXTCLK: The new ARM operating point is armExtClk 171 + */ 172 + enum arm_opp { 173 + ARM_OPP_INIT = 0x00, 174 + ARM_NO_CHANGE = 0x01, 175 + ARM_100_OPP = 0x02, 176 + ARM_50_OPP = 0x03, 177 + ARM_MAX_OPP = 0x04, 178 + ARM_MAX_FREQ100OPP = 0x05, 179 + ARM_EXTCLK = 0x07 180 + }; 181 + 182 + /** 183 + * enum ape_opp - APE OPP states definition 184 + * @APE_OPP_INIT: 185 + * @APE_NO_CHANGE: The APE operating point is unchanged 186 + * @APE_100_OPP: The new APE operating point is ape100opp 187 + * @APE_50_OPP: 50% 188 + */ 189 + enum ape_opp { 190 + APE_OPP_INIT = 0x00, 191 + APE_NO_CHANGE = 0x01, 192 + APE_100_OPP = 0x02, 193 + APE_50_OPP = 0x03 194 + }; 195 + 196 + /** 197 + * enum hw_acc_state - State definition for hardware accelerator 198 + * @HW_NO_CHANGE: The hardware accelerator state must remain unchanged 199 + * @HW_OFF: The hardware accelerator must be switched off 200 + * @HW_OFF_RAMRET: The hardware accelerator must be switched off with its 201 + * internal RAM in retention 202 + * @HW_ON: The hwa hardware accelerator hwa must be switched on 203 + * 204 + * NOTE! Deprecated, to be removed when all users switched over to use the 205 + * regulator API. 206 + */ 207 + enum hw_acc_state { 208 + HW_NO_CHANGE = 0x00, 209 + HW_OFF = 0x01, 210 + HW_OFF_RAMRET = 0x02, 211 + HW_ON = 0x04 212 + }; 213 + 214 + /** 215 + * enum mbox_2_arm_stat - Status messages definition for mbox_arm 216 + * @BOOT_TO_EXECUTEOK: The apBoot to apExecute state transition has been 217 + * completed 218 + * @DEEPSLEEPOK: The apExecute to apDeepSleep state transition has been 219 + * completed 220 + * @SLEEPOK: The apExecute to apSleep state transition has been completed 221 + * @IDLEOK: The apExecute to apIdle state transition has been completed 222 + * @SOFTRESETOK: The A9 watchdog/ SoftReset state has been completed 223 + * @SOFTRESETGO : The A9 watchdog/SoftReset state is on going 224 + * @BOOT_TO_EXECUTE: The apBoot to apExecute state transition is on going 225 + * @EXECUTE_TO_DEEPSLEEP: The apExecute to apDeepSleep state transition is on 226 + * going 227 + * @DEEPSLEEP_TO_EXECUTE: The apDeepSleep to apExecute state transition is on 228 + * going 229 + * @DEEPSLEEP_TO_EXECUTEOK: The apDeepSleep to apExecute state transition has 230 + * been completed 231 + * @EXECUTE_TO_SLEEP: The apExecute to apSleep state transition is on going 232 + * @SLEEP_TO_EXECUTE: The apSleep to apExecute state transition is on going 233 + * @SLEEP_TO_EXECUTEOK: The apSleep to apExecute state transition has been 234 + * completed 235 + * @EXECUTE_TO_IDLE: The apExecute to apIdle state transition is on going 236 + * @IDLE_TO_EXECUTE: The apIdle to apExecute state transition is on going 237 + * @IDLE_TO_EXECUTEOK: The apIdle to apExecute state transition has been 238 + * completed 239 + * @INIT_STATUS: Status init 240 + */ 241 + enum ap_pwrsttr_status { 242 + BOOT_TO_EXECUTEOK = 0xFF, 243 + DEEPSLEEPOK = 0xFE, 244 + SLEEPOK = 0xFD, 245 + IDLEOK = 0xFC, 246 + SOFTRESETOK = 0xFB, 247 + SOFTRESETGO = 0xFA, 248 + BOOT_TO_EXECUTE = 0xF9, 249 + EXECUTE_TO_DEEPSLEEP = 0xF8, 250 + DEEPSLEEP_TO_EXECUTE = 0xF7, 251 + DEEPSLEEP_TO_EXECUTEOK = 0xF6, 252 + EXECUTE_TO_SLEEP = 0xF5, 253 + SLEEP_TO_EXECUTE = 0xF4, 254 + SLEEP_TO_EXECUTEOK = 0xF3, 255 + EXECUTE_TO_IDLE = 0xF2, 256 + IDLE_TO_EXECUTE = 0xF1, 257 + IDLE_TO_EXECUTEOK = 0xF0, 258 + RDYTODS_RETURNTOEXE = 0xEF, 259 + NORDYTODS_RETURNTOEXE = 0xEE, 260 + EXETOSLEEP_RETURNTOEXE = 0xED, 261 + EXETOIDLE_RETURNTOEXE = 0xEC, 262 + INIT_STATUS = 0xEB, 263 + 264 + /*error messages */ 265 + INITERROR = 0x00, 266 + PLLARMLOCKP_ER = 0x01, 267 + PLLDDRLOCKP_ER = 0x02, 268 + PLLSOCLOCKP_ER = 0x03, 269 + PLLSOCK1LOCKP_ER = 0x04, 270 + ARMWFI_ER = 0x05, 271 + SYSCLKOK_ER = 0x06, 272 + I2C_NACK_DATA_ER = 0x07, 273 + BOOT_ER = 0x08, 274 + I2C_STATUS_ALWAYS_1 = 0x0A, 275 + I2C_NACK_REG_ADDR_ER = 0x0B, 276 + I2C_NACK_DATA0123_ER = 0x1B, 277 + I2C_NACK_ADDR_ER = 0x1F, 278 + CURAPPWRSTISNOT_BOOT = 0x20, 279 + CURAPPWRSTISNOT_EXECUTE = 0x21, 280 + CURAPPWRSTISNOT_SLEEPMODE = 0x22, 281 + CURAPPWRSTISNOT_CORRECTFORIT10 = 0x23, 282 + FIFO4500WUISNOT_WUPEVENT = 0x24, 283 + PLL32KLOCKP_ER = 0x29, 284 + DDRDEEPSLEEPOK_ER = 0x2A, 285 + ROMCODEREADY_ER = 0x50, 286 + WUPBEFOREDS = 0x51, 287 + DDRCONFIG_ER = 0x52, 288 + WUPBEFORESLEEP = 0x53, 289 + WUPBEFOREIDLE = 0x54 290 + }; /* earlier called as mbox_2_arm_stat */ 291 + 292 + /** 293 + * enum dvfs_stat - DVFS status messages definition 294 + * @DVFS_GO: A state transition DVFS is on going 295 + * @DVFS_ARM100OPPOK: The state transition DVFS has been completed for 100OPP 296 + * @DVFS_ARM50OPPOK: The state transition DVFS has been completed for 50OPP 297 + * @DVFS_ARMEXTCLKOK: The state transition DVFS has been completed for EXTCLK 298 + * @DVFS_NOCHGTCLKOK: The state transition DVFS has been completed for 299 + * NOCHGCLK 300 + * @DVFS_INITSTATUS: Value init 301 + */ 302 + enum dvfs_stat { 303 + DVFS_GO = 0xFF, 304 + DVFS_ARM100OPPOK = 0xFE, 305 + DVFS_ARM50OPPOK = 0xFD, 306 + DVFS_ARMEXTCLKOK = 0xFC, 307 + DVFS_NOCHGTCLKOK = 0xFB, 308 + DVFS_INITSTATUS = 0x00 309 + }; 310 + 311 + /** 312 + * enum sva_mmdsp_stat - SVA MMDSP status messages 313 + * @SVA_MMDSP_GO: SVAMMDSP interrupt has happened 314 + * @SVA_MMDSP_INIT: Status init 315 + */ 316 + enum sva_mmdsp_stat { 317 + SVA_MMDSP_GO = 0xFF, 318 + SVA_MMDSP_INIT = 0x00 319 + }; 320 + 321 + /** 322 + * enum sia_mmdsp_stat - SIA MMDSP status messages 323 + * @SIA_MMDSP_GO: SIAMMDSP interrupt has happened 324 + * @SIA_MMDSP_INIT: Status init 325 + */ 326 + enum sia_mmdsp_stat { 327 + SIA_MMDSP_GO = 0xFF, 328 + SIA_MMDSP_INIT = 0x00 329 + }; 330 + 331 + /** 332 + * enum mbox_to_arm_err - Error messages definition 333 + * @INIT_ERR: Init value 334 + * @PLLARMLOCKP_ERR: PLLARM has not been correctly locked in given time 335 + * @PLLDDRLOCKP_ERR: PLLDDR has not been correctly locked in the given time 336 + * @PLLSOC0LOCKP_ERR: PLLSOC0 has not been correctly locked in the given time 337 + * @PLLSOC1LOCKP_ERR: PLLSOC1 has not been correctly locked in the given time 338 + * @ARMWFI_ERR: The ARM WFI has not been correctly executed in the given time 339 + * @SYSCLKOK_ERR: The SYSCLK is not available in the given time 340 + * @BOOT_ERR: Romcode has not validated the XP70 self reset in the given time 341 + * @ROMCODESAVECONTEXT: The Romcode didn.t correctly save it secure context 342 + * @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transfered 343 + * through I2C has not been correctly executed in the given time 344 + * @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transfered 345 + * through I2C has not been correctly executed in the given time 346 + * @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transfered through 347 + * I2C has not been correctly executed in the given time 348 + * @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transfered 349 + * through I2C has not been correctly executed in the given time 350 + * @VARMRETENTIONVALTO_ERR: The ARM retention supply value transfered through 351 + * I2C has not been correctly executed in the given time 352 + * @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transfered 353 + * through I2C has not been correctly executed in the given time 354 + * @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transfered through 355 + * I2C has not been correctly executed in the given time 356 + * @VSAFEHPVALTO_ERR: The SAFE high power supply value transfered through I2C 357 + * has not been correctly executed in the given time 358 + * @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transfered through I2C has 359 + * not been correctly executed in the given time 360 + * @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transfered through I2C has 361 + * not been correctly executed in the given time 362 + * @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transfered through 363 + * I2C has not been correctly executed in the given time 364 + * @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transfered through 365 + * I2C has not been correctly executed in the given time 366 + * @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transfered 367 + * through I2C has not been correctly executed in the given time 368 + * @CURAPPWRSTISNOTBOOT:Generated when Arm want to do power state transition 369 + * ApBoot to ApExecute but the power current state is not Apboot 370 + * @CURAPPWRSTISNOTEXECUTE: Generated when Arm want to do power state 371 + * transition from ApExecute to others power state but the 372 + * power current state is not ApExecute 373 + * @CURAPPWRSTISNOTSLEEPMODE: Generated when wake up events are transmitted 374 + * but the power current state is not ApDeepSleep/ApSleep/ApIdle 375 + * @CURAPPWRSTISNOTCORRECTDBG: Generated when wake up events are transmitted 376 + * but the power current state is not correct 377 + * @ARMREGU1VALTO_ERR:The ArmRegu1 value transferred through I2C has not 378 + * been correctly executed in the given time 379 + * @ARMREGU2VALTO_ERR: The ArmRegu2 value transferred through I2C has not 380 + * been correctly executed in the given time 381 + * @VAPEREGUVALTO_ERR: The VApeRegu value transfered through I2C has not 382 + * been correctly executed in the given time 383 + * @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transfered through I2C has not 384 + * been correctly executed in the given time 385 + * @VMODREGUVALTO_ERR: The VModemRegu value transfered through I2C has not 386 + * been correctly executed in the given time 387 + */ 388 + enum mbox_to_arm_err { 389 + INIT_ERR = 0x00, 390 + PLLARMLOCKP_ERR = 0x01, 391 + PLLDDRLOCKP_ERR = 0x02, 392 + PLLSOC0LOCKP_ERR = 0x03, 393 + PLLSOC1LOCKP_ERR = 0x04, 394 + ARMWFI_ERR = 0x05, 395 + SYSCLKOK_ERR = 0x06, 396 + BOOT_ERR = 0x07, 397 + ROMCODESAVECONTEXT = 0x08, 398 + VARMHIGHSPEEDVALTO_ERR = 0x10, 399 + VARMHIGHSPEEDACCESS_ERR = 0x11, 400 + VARMLOWSPEEDVALTO_ERR = 0x12, 401 + VARMLOWSPEEDACCESS_ERR = 0x13, 402 + VARMRETENTIONVALTO_ERR = 0x14, 403 + VARMRETENTIONACCESS_ERR = 0x15, 404 + VAPEHIGHSPEEDVALTO_ERR = 0x16, 405 + VSAFEHPVALTO_ERR = 0x17, 406 + VMODSEL1VALTO_ERR = 0x18, 407 + VMODSEL2VALTO_ERR = 0x19, 408 + VARMOFFACCESS_ERR = 0x1A, 409 + VAPEOFFACCESS_ERR = 0x1B, 410 + VARMRETACCES_ERR = 0x1C, 411 + CURAPPWRSTISNOTBOOT = 0x20, 412 + CURAPPWRSTISNOTEXECUTE = 0x21, 413 + CURAPPWRSTISNOTSLEEPMODE = 0x22, 414 + CURAPPWRSTISNOTCORRECTDBG = 0x23, 415 + ARMREGU1VALTO_ERR = 0x24, 416 + ARMREGU2VALTO_ERR = 0x25, 417 + VAPEREGUVALTO_ERR = 0x26, 418 + VSMPS3REGUVALTO_ERR = 0x27, 419 + VMODREGUVALTO_ERR = 0x28 420 + }; 421 + 422 + enum hw_acc { 423 + SVAMMDSP = 0, 424 + SVAPIPE = 1, 425 + SIAMMDSP = 2, 426 + SIAPIPE = 3, 427 + SGA = 4, 428 + B2R2MCDE = 5, 429 + ESRAM12 = 6, 430 + ESRAM34 = 7, 431 + }; 432 + 433 + enum cs_pwrmgt { 434 + PWRDNCS0 = 0, 435 + WKUPCS0 = 1, 436 + PWRDNCS1 = 2, 437 + WKUPCS1 = 3 438 + }; 439 + 440 + /* Defs related to autonomous power management */ 441 + 442 + /** 443 + * enum sia_sva_pwr_policy - Power policy 444 + * @NO_CHGT: No change 445 + * @DSPOFF_HWPOFF: 446 + * @DSPOFFRAMRET_HWPOFF: 447 + * @DSPCLKOFF_HWPOFF: 448 + * @DSPCLKOFF_HWPCLKOFF: 449 + * 450 + */ 451 + enum sia_sva_pwr_policy { 452 + NO_CHGT = 0x0, 453 + DSPOFF_HWPOFF = 0x1, 454 + DSPOFFRAMRET_HWPOFF = 0x2, 455 + DSPCLKOFF_HWPOFF = 0x3, 456 + DSPCLKOFF_HWPCLKOFF = 0x4, 457 + }; 458 + 459 + /** 460 + * enum auto_enable - Auto Power enable 461 + * @AUTO_OFF: 462 + * @AUTO_ON: 463 + * 464 + */ 465 + enum auto_enable { 466 + AUTO_OFF = 0x0, 467 + AUTO_ON = 0x1, 468 + }; 469 + 470 + /* End of file previously known as prcmu-fw-defs_v1.h */ 471 + 472 + /* PRCMU Wakeup defines */ 473 + enum prcmu_wakeup_index { 474 + PRCMU_WAKEUP_INDEX_RTC, 475 + PRCMU_WAKEUP_INDEX_RTT0, 476 + PRCMU_WAKEUP_INDEX_RTT1, 477 + PRCMU_WAKEUP_INDEX_HSI0, 478 + PRCMU_WAKEUP_INDEX_HSI1, 479 + PRCMU_WAKEUP_INDEX_USB, 480 + PRCMU_WAKEUP_INDEX_ABB, 481 + PRCMU_WAKEUP_INDEX_ABB_FIFO, 482 + PRCMU_WAKEUP_INDEX_ARM, 483 + NUM_PRCMU_WAKEUP_INDICES 484 + }; 485 + #define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name)) 486 + 487 + /* PRCMU QoS APE OPP class */ 488 + #define PRCMU_QOS_APE_OPP 1 489 + #define PRCMU_QOS_DDR_OPP 2 490 + #define PRCMU_QOS_DEFAULT_VALUE -1 491 + 492 + /** 493 + * enum hw_acc_dev - enum for hw accelerators 494 + * @HW_ACC_SVAMMDSP: for SVAMMDSP 495 + * @HW_ACC_SVAPIPE: for SVAPIPE 496 + * @HW_ACC_SIAMMDSP: for SIAMMDSP 497 + * @HW_ACC_SIAPIPE: for SIAPIPE 498 + * @HW_ACC_SGA: for SGA 499 + * @HW_ACC_B2R2: for B2R2 500 + * @HW_ACC_MCDE: for MCDE 501 + * @HW_ACC_ESRAM1: for ESRAM1 502 + * @HW_ACC_ESRAM2: for ESRAM2 503 + * @HW_ACC_ESRAM3: for ESRAM3 504 + * @HW_ACC_ESRAM4: for ESRAM4 505 + * @NUM_HW_ACC: number of hardware accelerators 506 + * 507 + * Different hw accelerators which can be turned ON/ 508 + * OFF or put into retention (MMDSPs and ESRAMs). 509 + * Used with EPOD API. 510 + * 511 + * NOTE! Deprecated, to be removed when all users switched over to use the 512 + * regulator API. 513 + */ 514 + enum hw_acc_dev { 515 + HW_ACC_SVAMMDSP, 516 + HW_ACC_SVAPIPE, 517 + HW_ACC_SIAMMDSP, 518 + HW_ACC_SIAPIPE, 519 + HW_ACC_SGA, 520 + HW_ACC_B2R2, 521 + HW_ACC_MCDE, 522 + HW_ACC_ESRAM1, 523 + HW_ACC_ESRAM2, 524 + HW_ACC_ESRAM3, 525 + HW_ACC_ESRAM4, 526 + NUM_HW_ACC 527 + }; 528 + 529 + /* 530 + * Ids for all EPODs (power domains) 531 + * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP 532 + * - EPOD_ID_SVAPIPE: power domain for SVA pipe 533 + * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP 534 + * - EPOD_ID_SIAPIPE: power domain for SIA pipe 535 + * - EPOD_ID_SGA: power domain for SGA 536 + * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE 537 + * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2 538 + * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4 539 + * - NUM_EPOD_ID: number of power domains 540 + */ 541 + #define EPOD_ID_SVAMMDSP 0 542 + #define EPOD_ID_SVAPIPE 1 543 + #define EPOD_ID_SIAMMDSP 2 544 + #define EPOD_ID_SIAPIPE 3 545 + #define EPOD_ID_SGA 4 546 + #define EPOD_ID_B2R2_MCDE 5 547 + #define EPOD_ID_ESRAM12 6 548 + #define EPOD_ID_ESRAM34 7 549 + #define NUM_EPOD_ID 8 550 + 551 + /* 552 + * state definition for EPOD (power domain) 553 + * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged 554 + * - EPOD_STATE_OFF: The EPOD is switched off 555 + * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in 556 + * retention 557 + * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off 558 + * - EPOD_STATE_ON: Same as above, but with clock enabled 559 + */ 560 + #define EPOD_STATE_NO_CHANGE 0x00 561 + #define EPOD_STATE_OFF 0x01 562 + #define EPOD_STATE_RAMRET 0x02 563 + #define EPOD_STATE_ON_CLK_OFF 0x03 564 + #define EPOD_STATE_ON 0x04 565 + 566 + /* 567 + * CLKOUT sources 568 + */ 569 + #define PRCMU_CLKSRC_CLK38M 0x00 570 + #define PRCMU_CLKSRC_ACLK 0x01 571 + #define PRCMU_CLKSRC_SYSCLK 0x02 572 + #define PRCMU_CLKSRC_LCDCLK 0x03 573 + #define PRCMU_CLKSRC_SDMMCCLK 0x04 574 + #define PRCMU_CLKSRC_TVCLK 0x05 575 + #define PRCMU_CLKSRC_TIMCLK 0x06 576 + #define PRCMU_CLKSRC_CLK009 0x07 577 + /* These are only valid for CLKOUT1: */ 578 + #define PRCMU_CLKSRC_SIAMMDSPCLK 0x40 579 + #define PRCMU_CLKSRC_I2CCLK 0x41 580 + #define PRCMU_CLKSRC_MSP02CLK 0x42 581 + #define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43 582 + #define PRCMU_CLKSRC_HSIRXCLK 0x44 583 + #define PRCMU_CLKSRC_HSITXCLK 0x45 584 + #define PRCMU_CLKSRC_ARMCLKFIX 0x46 585 + #define PRCMU_CLKSRC_HDMICLK 0x47 586 + 587 + /* 588 + * Definitions for autonomous power management configuration. 589 + */ 590 + 591 + #define PRCMU_AUTO_PM_OFF 0 592 + #define PRCMU_AUTO_PM_ON 1 593 + 594 + #define PRCMU_AUTO_PM_POWER_ON_HSEM BIT(0) 595 + #define PRCMU_AUTO_PM_POWER_ON_ABB_FIFO_IT BIT(1) 596 + 597 + enum prcmu_auto_pm_policy { 598 + PRCMU_AUTO_PM_POLICY_NO_CHANGE, 599 + PRCMU_AUTO_PM_POLICY_DSP_OFF_HWP_OFF, 600 + PRCMU_AUTO_PM_POLICY_DSP_OFF_RAMRET_HWP_OFF, 601 + PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_OFF, 602 + PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_CLK_OFF, 603 + }; 604 + 605 + /** 606 + * struct prcmu_auto_pm_config - Autonomous power management configuration. 607 + * @sia_auto_pm_enable: SIA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON}) 608 + * @sia_power_on: SIA power ON enable. (PRCMU_AUTO_PM_POWER_ON_* bitmask) 609 + * @sia_policy: SIA power policy. (enum prcmu_auto_pm_policy) 610 + * @sva_auto_pm_enable: SVA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON}) 611 + * @sva_power_on: SVA power ON enable. (PRCMU_AUTO_PM_POWER_ON_* bitmask) 612 + * @sva_policy: SVA power policy. (enum prcmu_auto_pm_policy) 613 + */ 614 + struct prcmu_auto_pm_config { 615 + u8 sia_auto_pm_enable; 616 + u8 sia_power_on; 617 + u8 sia_policy; 618 + u8 sva_auto_pm_enable; 619 + u8 sva_power_on; 620 + u8 sva_policy; 621 + }; 622 + 623 + /** 624 + * enum ddr_opp - DDR OPP states definition 625 + * @DDR_100_OPP: The new DDR operating point is ddr100opp 626 + * @DDR_50_OPP: The new DDR operating point is ddr50opp 627 + * @DDR_25_OPP: The new DDR operating point is ddr25opp 628 + */ 629 + enum ddr_opp { 630 + DDR_100_OPP = 0x00, 631 + DDR_50_OPP = 0x01, 632 + DDR_25_OPP = 0x02, 633 + }; 634 + 635 + /* 636 + * Clock identifiers. 637 + */ 638 + enum prcmu_clock { 639 + PRCMU_SGACLK, 640 + PRCMU_UARTCLK, 641 + PRCMU_MSP02CLK, 642 + PRCMU_MSP1CLK, 643 + PRCMU_I2CCLK, 644 + PRCMU_SDMMCCLK, 645 + PRCMU_SLIMCLK, 646 + PRCMU_PER1CLK, 647 + PRCMU_PER2CLK, 648 + PRCMU_PER3CLK, 649 + PRCMU_PER5CLK, 650 + PRCMU_PER6CLK, 651 + PRCMU_PER7CLK, 652 + PRCMU_LCDCLK, 653 + PRCMU_BMLCLK, 654 + PRCMU_HSITXCLK, 655 + PRCMU_HSIRXCLK, 656 + PRCMU_HDMICLK, 657 + PRCMU_APEATCLK, 658 + PRCMU_APETRACECLK, 659 + PRCMU_MCDECLK, 660 + PRCMU_IPI2CCLK, 661 + PRCMU_DSIALTCLK, 662 + PRCMU_DMACLK, 663 + PRCMU_B2R2CLK, 664 + PRCMU_TVCLK, 665 + PRCMU_SSPCLK, 666 + PRCMU_RNGCLK, 667 + PRCMU_UICCCLK, 668 + PRCMU_NUM_REG_CLOCKS, 669 + PRCMU_SYSCLK = PRCMU_NUM_REG_CLOCKS, 670 + PRCMU_TIMCLK, 671 + }; 672 + 673 + /* 674 + * Definitions for controlling ESRAM0 in deep sleep. 675 + */ 676 + #define ESRAM0_DEEP_SLEEP_STATE_OFF 1 677 + #define ESRAM0_DEEP_SLEEP_STATE_RET 2 678 + 679 + #ifdef CONFIG_MFD_DB8500_PRCMU 680 + void __init prcmu_early_init(void); 681 + int prcmu_set_display_clocks(void); 682 + int prcmu_disable_dsipll(void); 683 + int prcmu_enable_dsipll(void); 684 + #else 685 + static inline void __init prcmu_early_init(void) {} 686 + #endif 687 + 688 + #ifdef CONFIG_MFD_DB8500_PRCMU 689 + 690 + int prcmu_set_rc_a2p(enum romcode_write); 691 + enum romcode_read prcmu_get_rc_p2a(void); 692 + enum ap_pwrst prcmu_get_xp70_current_state(void); 693 + int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll); 694 + 695 + void prcmu_enable_wakeups(u32 wakeups); 696 + static inline void prcmu_disable_wakeups(void) 697 + { 698 + prcmu_enable_wakeups(0); 699 + } 700 + 701 + void prcmu_config_abb_event_readout(u32 abb_events); 702 + void prcmu_get_abb_event_buffer(void __iomem **buf); 703 + int prcmu_set_arm_opp(u8 opp); 704 + int prcmu_get_arm_opp(void); 705 + bool prcmu_has_arm_maxopp(void); 706 + bool prcmu_is_u8400(void); 707 + int prcmu_set_ape_opp(u8 opp); 708 + int prcmu_get_ape_opp(void); 709 + int prcmu_request_ape_opp_100_voltage(bool enable); 710 + int prcmu_release_usb_wakeup_state(void); 711 + int prcmu_set_ddr_opp(u8 opp); 712 + int prcmu_get_ddr_opp(void); 713 + unsigned long prcmu_qos_get_cpufreq_opp_delay(void); 714 + void prcmu_qos_set_cpufreq_opp_delay(unsigned long); 715 + /* NOTE! Use regulator framework instead */ 716 + int prcmu_set_hwacc(u16 hw_acc_dev, u8 state); 717 + int prcmu_set_epod(u16 epod_id, u8 epod_state); 718 + void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, 719 + struct prcmu_auto_pm_config *idle); 720 + bool prcmu_is_auto_pm_enabled(void); 721 + 722 + int prcmu_config_clkout(u8 clkout, u8 source, u8 div); 723 + int prcmu_request_clock(u8 clock, bool enable); 724 + int prcmu_set_clock_divider(u8 clock, u8 divider); 725 + int prcmu_config_esram0_deep_sleep(u8 state); 726 + int prcmu_config_hotdog(u8 threshold); 727 + int prcmu_config_hotmon(u8 low, u8 high); 728 + int prcmu_start_temp_sense(u16 cycles32k); 729 + int prcmu_stop_temp_sense(void); 730 + int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); 731 + int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); 732 + 733 + void prcmu_ac_wake_req(void); 734 + void prcmu_ac_sleep_req(void); 735 + void prcmu_system_reset(u16 reset_code); 736 + void prcmu_modem_reset(void); 737 + bool prcmu_is_ac_wake_requested(void); 738 + void prcmu_enable_spi2(void); 739 + void prcmu_disable_spi2(void); 740 + 741 + #else /* !CONFIG_MFD_DB8500_PRCMU */ 742 + 743 + static inline int prcmu_set_rc_a2p(enum romcode_write code) 744 + { 745 + return 0; 746 + } 747 + 748 + static inline enum romcode_read prcmu_get_rc_p2a(void) 749 + { 750 + return INIT; 751 + } 752 + 753 + static inline enum ap_pwrst prcmu_get_xp70_current_state(void) 754 + { 755 + return AP_EXECUTE; 756 + } 757 + 758 + static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk, 759 + bool keep_ap_pll) 760 + { 761 + return 0; 762 + } 763 + 764 + static inline void prcmu_enable_wakeups(u32 wakeups) {} 765 + 766 + static inline void prcmu_disable_wakeups(void) {} 767 + 768 + static inline void prcmu_config_abb_event_readout(u32 abb_events) {} 769 + 770 + static inline int prcmu_set_arm_opp(u8 opp) 771 + { 772 + return 0; 773 + } 774 + 775 + static inline int prcmu_get_arm_opp(void) 776 + { 777 + return ARM_100_OPP; 778 + } 779 + 780 + static bool prcmu_has_arm_maxopp(void) 781 + { 782 + return false; 783 + } 784 + 785 + static bool prcmu_is_u8400(void) 786 + { 787 + return false; 788 + } 789 + 790 + static inline int prcmu_set_ape_opp(u8 opp) 791 + { 792 + return 0; 793 + } 794 + 795 + static inline int prcmu_get_ape_opp(void) 796 + { 797 + return APE_100_OPP; 798 + } 799 + 800 + static inline int prcmu_request_ape_opp_100_voltage(bool enable) 801 + { 802 + return 0; 803 + } 804 + 805 + static inline int prcmu_release_usb_wakeup_state(void) 806 + { 807 + return 0; 808 + } 809 + 810 + static inline int prcmu_set_ddr_opp(u8 opp) 811 + { 812 + return 0; 813 + } 814 + 815 + static inline int prcmu_get_ddr_opp(void) 816 + { 817 + return DDR_100_OPP; 818 + } 819 + 820 + static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) 821 + { 822 + return 0; 823 + } 824 + 825 + static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {} 826 + 827 + static inline int prcmu_set_hwacc(u16 hw_acc_dev, u8 state) 828 + { 829 + return 0; 830 + } 831 + 832 + static inline void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep, 833 + struct prcmu_auto_pm_config *idle) 834 + { 835 + } 836 + 837 + static inline bool prcmu_is_auto_pm_enabled(void) 838 + { 839 + return false; 840 + } 841 + 842 + static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div) 843 + { 844 + return 0; 845 + } 846 + 847 + static inline int prcmu_request_clock(u8 clock, bool enable) 848 + { 849 + return 0; 850 + } 851 + 852 + static inline int prcmu_set_clock_divider(u8 clock, u8 divider) 853 + { 854 + return 0; 855 + } 856 + 857 + int prcmu_config_esram0_deep_sleep(u8 state) 858 + { 859 + return 0; 860 + } 861 + 862 + static inline int prcmu_config_hotdog(u8 threshold) 863 + { 864 + return 0; 865 + } 866 + 867 + static inline int prcmu_config_hotmon(u8 low, u8 high) 868 + { 869 + return 0; 870 + } 871 + 872 + static inline int prcmu_start_temp_sense(u16 cycles32k) 873 + { 874 + return 0; 875 + } 876 + 877 + static inline int prcmu_stop_temp_sense(void) 878 + { 879 + return 0; 880 + } 881 + 882 + static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) 883 + { 884 + return -ENOSYS; 885 + } 886 + 887 + static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) 888 + { 889 + return -ENOSYS; 890 + } 891 + 892 + static inline void prcmu_ac_wake_req(void) {} 893 + 894 + static inline void prcmu_ac_sleep_req(void) {} 895 + 896 + static inline void prcmu_system_reset(u16 reset_code) {} 897 + 898 + static inline void prcmu_modem_reset(void) {} 899 + 900 + static inline bool prcmu_is_ac_wake_requested(void) 901 + { 902 + return false; 903 + } 904 + 905 + #ifndef CONFIG_UX500_SOC_DB5500 906 + static inline int prcmu_set_display_clocks(void) 907 + { 908 + return 0; 909 + } 910 + 911 + static inline int prcmu_disable_dsipll(void) 912 + { 913 + return 0; 914 + } 915 + 916 + static inline int prcmu_enable_dsipll(void) 917 + { 918 + return 0; 919 + } 920 + #endif 921 + 922 + static inline int prcmu_enable_spi2(void) 923 + { 924 + return 0; 925 + } 926 + 927 + static inline int prcmu_disable_spi2(void) 928 + { 929 + return 0; 930 + } 931 + 932 + #endif /* !CONFIG_MFD_DB8500_PRCMU */ 933 + 934 + #ifdef CONFIG_UX500_PRCMU_QOS_POWER 935 + int prcmu_qos_requirement(int pm_qos_class); 936 + int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value); 937 + int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value); 938 + void prcmu_qos_remove_requirement(int pm_qos_class, char *name); 939 + int prcmu_qos_add_notifier(int prcmu_qos_class, 940 + struct notifier_block *notifier); 941 + int prcmu_qos_remove_notifier(int prcmu_qos_class, 942 + struct notifier_block *notifier); 943 + #else 944 + static inline int prcmu_qos_requirement(int prcmu_qos_class) 945 + { 946 + return 0; 947 + } 948 + 949 + static inline int prcmu_qos_add_requirement(int prcmu_qos_class, 950 + char *name, s32 value) 951 + { 952 + return 0; 953 + } 954 + 955 + static inline int prcmu_qos_update_requirement(int prcmu_qos_class, 956 + char *name, s32 new_value) 957 + { 958 + return 0; 959 + } 960 + 961 + static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name) 962 + { 963 + } 964 + 965 + static inline int prcmu_qos_add_notifier(int prcmu_qos_class, 966 + struct notifier_block *notifier) 967 + { 968 + return 0; 969 + } 970 + static inline int prcmu_qos_remove_notifier(int prcmu_qos_class, 971 + struct notifier_block *notifier) 972 + { 973 + return 0; 974 + } 975 + 976 + #endif 977 + 978 + #endif /* __MFD_DB8500_PRCMU_H */
+45
include/linux/regulator/db8500-prcmu.h
··· 1 + /* 2 + * Copyright (C) ST-Ericsson SA 2010 3 + * 4 + * License Terms: GNU General Public License v2 5 + * 6 + * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson 7 + * 8 + * Interface to power domain regulators on DB8500 9 + */ 10 + 11 + #ifndef __REGULATOR_H__ 12 + #define __REGULATOR_H__ 13 + 14 + /* Number of DB8500 regulators and regulator enumeration */ 15 + enum db8500_regulator_id { 16 + DB8500_REGULATOR_VAPE, 17 + DB8500_REGULATOR_VARM, 18 + DB8500_REGULATOR_VMODEM, 19 + DB8500_REGULATOR_VPLL, 20 + DB8500_REGULATOR_VSMPS1, 21 + DB8500_REGULATOR_VSMPS2, 22 + DB8500_REGULATOR_VSMPS3, 23 + DB8500_REGULATOR_VRF1, 24 + DB8500_REGULATOR_SWITCH_SVAMMDSP, 25 + DB8500_REGULATOR_SWITCH_SVAMMDSPRET, 26 + DB8500_REGULATOR_SWITCH_SVAPIPE, 27 + DB8500_REGULATOR_SWITCH_SIAMMDSP, 28 + DB8500_REGULATOR_SWITCH_SIAMMDSPRET, 29 + DB8500_REGULATOR_SWITCH_SIAPIPE, 30 + DB8500_REGULATOR_SWITCH_SGA, 31 + DB8500_REGULATOR_SWITCH_B2R2_MCDE, 32 + DB8500_REGULATOR_SWITCH_ESRAM12, 33 + DB8500_REGULATOR_SWITCH_ESRAM12RET, 34 + DB8500_REGULATOR_SWITCH_ESRAM34, 35 + DB8500_REGULATOR_SWITCH_ESRAM34RET, 36 + DB8500_NUM_REGULATORS 37 + }; 38 + 39 + /* 40 + * Exported interface for CPUIdle only. This function is called with all 41 + * interrupts turned off. 42 + */ 43 + int power_state_active_is_enabled(void); 44 + 45 + #endif