diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 16:35:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-19 16:35:07 -0400 |
| commit | e4e47eb15b7884963efe7f98231009c5770a2c3d (patch) | |
| tree | ebd3536a3aa728089168f072c88858578535046d | |
| parent | 711f77f53c5ff6aa61dbe8e5f518e50d6306e89d (diff) | |
| parent | 7b52161d14fa8a22a2387f4aa2fb7b854587830d (diff) | |
Merge branch 'msm-core' of git://codeaurora.org/quic/kernel/dwalker/linux-msm
* 'msm-core' of git://codeaurora.org/quic/kernel/dwalker/linux-msm: (72 commits)
msm: 7x30 Kconfig and makefile changes
msm: clock support for the MSM7x30 CPU.
msm: physical offset for MSM7X30
msm: io: add io support for 7x30
msm: Add extern for 7x30 clock list.
msm: dma: add 7x30 security domain abstraction
msm: update basic board layout for MSM7x30
msm: add devices-msm7x30.c
msm: add msm_iomap-7x30.h for MSM7x30 support
msm: irqs: add irqs-7x30.h for MSM7x30 support
msm: 8x50 Kconfig changes
msm: physical offset for QSD8x50
msm: io: add io support for 8x50
msm: add extern for 8x50 clock list.
msm: add devices-qsd8x50.c
msm: update basic board layout for QSD8x50
msm: add msm_iomap-8x50.h for QSD8x50 support
msm: irqs: add irqs-8x50.h for QSD8x50 support
msm: timer: allow MSM_DGT_BASE to be overriden
msm: add Qualcomm 7x30 interrupt controller driver.
...
56 files changed, 6539 insertions, 453 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index a77ae73a5f6e..8e019486b006 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -819,6 +819,7 @@ ARM/QUALCOMM MSM MACHINE SUPPORT | |||
| 819 | M: David Brown <davidb@codeaurora.org> | 819 | M: David Brown <davidb@codeaurora.org> |
| 820 | M: Daniel Walker <dwalker@codeaurora.org> | 820 | M: Daniel Walker <dwalker@codeaurora.org> |
| 821 | M: Bryan Huntsman <bryanh@codeaurora.org> | 821 | M: Bryan Huntsman <bryanh@codeaurora.org> |
| 822 | L: linux-arm-msm@vger.kernel.org | ||
| 822 | F: arch/arm/mach-msm/ | 823 | F: arch/arm/mach-msm/ |
| 823 | F: drivers/video/msm/ | 824 | F: drivers/video/msm/ |
| 824 | F: drivers/mmc/host/msm_sdcc.c | 825 | F: drivers/mmc/host/msm_sdcc.c |
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index b9fd5c528e5b..47264a76eeb3 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig | |||
| @@ -1,7 +1,80 @@ | |||
| 1 | if ARCH_MSM | 1 | if ARCH_MSM |
| 2 | 2 | ||
| 3 | comment "MSM Board Type" | 3 | choice |
| 4 | prompt "Qualcomm MSM SoC Type" | ||
| 5 | default ARCH_MSM7X00A | ||
| 6 | |||
| 7 | config ARCH_MSM7X00A | ||
| 8 | bool "MSM7x00A / MSM7x01A" | ||
| 9 | select ARCH_MSM_ARM11 | ||
| 10 | select MSM_SMD | ||
| 11 | select MSM_SMD_PKG3 | ||
| 12 | select CPU_V6 | ||
| 13 | |||
| 14 | config ARCH_MSM7X30 | ||
| 15 | bool "MSM7x30" | ||
| 16 | select ARCH_MSM_SCORPION | ||
| 17 | select MSM_SMD | ||
| 18 | select MSM_VIC | ||
| 19 | select CPU_V7 | ||
| 20 | select MSM_REMOTE_SPINLOCK_DEKKERS | ||
| 21 | |||
| 22 | config ARCH_QSD8X50 | ||
| 23 | bool "QSD8X50" | ||
| 24 | select ARCH_MSM_SCORPION | ||
| 25 | select MSM_SMD | ||
| 26 | select MSM_VIC | ||
| 27 | select CPU_V7 | ||
| 28 | select MSM_REMOTE_SPINLOCK_LDREX | ||
| 29 | endchoice | ||
| 30 | |||
| 31 | config MSM_SOC_REV_A | ||
| 32 | bool | ||
| 33 | |||
| 34 | config ARCH_MSM_ARM11 | ||
| 35 | bool | ||
| 36 | config ARCH_MSM_SCORPION | ||
| 37 | bool | ||
| 38 | |||
| 39 | config MSM_VIC | ||
| 40 | bool | ||
| 41 | |||
| 42 | menu "Qualcomm MSM Board Type" | ||
| 43 | |||
| 44 | config MACH_HALIBUT | ||
| 4 | depends on ARCH_MSM | 45 | depends on ARCH_MSM |
| 46 | depends on ARCH_MSM7X00A | ||
| 47 | bool "Halibut Board (QCT SURF7201A)" | ||
| 48 | help | ||
| 49 | Support for the Qualcomm SURF7201A eval board. | ||
| 50 | |||
| 51 | config MACH_TROUT | ||
| 52 | depends on ARCH_MSM | ||
| 53 | depends on ARCH_MSM7X00A | ||
| 54 | bool "HTC Dream (aka trout)" | ||
| 55 | help | ||
| 56 | Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. | ||
| 57 | |||
| 58 | config MACH_MSM7X30_SURF | ||
| 59 | depends on ARCH_MSM7X30 | ||
| 60 | bool "MSM7x30 SURF" | ||
| 61 | help | ||
| 62 | Support for the Qualcomm MSM7x30 SURF eval board. | ||
| 63 | |||
| 64 | config MACH_QSD8X50_SURF | ||
| 65 | depends on ARCH_QSD8X50 | ||
| 66 | bool "QSD8x50 SURF" | ||
| 67 | help | ||
| 68 | Support for the Qualcomm QSD8x50 SURF eval board. | ||
| 69 | |||
| 70 | config MACH_QSD8X50A_ST1_5 | ||
| 71 | depends on ARCH_QSD8X50 | ||
| 72 | select MSM_SOC_REV_A | ||
| 73 | bool "QSD8x50A ST1.5" | ||
| 74 | help | ||
| 75 | Support for the Qualcomm ST1.5. | ||
| 76 | |||
| 77 | endmenu | ||
| 5 | 78 | ||
| 6 | config MSM_DEBUG_UART | 79 | config MSM_DEBUG_UART |
| 7 | int | 80 | int |
| @@ -27,19 +100,10 @@ choice | |||
| 27 | bool "UART3" | 100 | bool "UART3" |
| 28 | endchoice | 101 | endchoice |
| 29 | 102 | ||
| 30 | config MACH_HALIBUT | 103 | config MSM_SMD_PKG3 |
| 31 | depends on ARCH_MSM | 104 | bool |
| 32 | select CPU_V6 | ||
| 33 | default y | ||
| 34 | bool "Halibut Board (QCT SURF7201A)" | ||
| 35 | help | ||
| 36 | Support for the Qualcomm SURF7201A eval board. | ||
| 37 | 105 | ||
| 38 | config MACH_TROUT | 106 | config MSM_SMD |
| 39 | select CPU_V6 | 107 | bool |
| 40 | default y | ||
| 41 | bool "HTC Dream (aka trout)" | ||
| 42 | help | ||
| 43 | Support for the HTC Dream, T-Mobile G1, Android ADP1 devices. | ||
| 44 | 108 | ||
| 45 | endif | 109 | endif |
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 91e6f5c95dc1..66677f0acaed 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile | |||
| @@ -1,9 +1,22 @@ | |||
| 1 | obj-y += io.o idle.o irq.o timer.o dma.o | ||
| 2 | obj-y += devices.o | ||
| 3 | obj-y += proc_comm.o | 1 | obj-y += proc_comm.o |
| 2 | obj-y += io.o idle.o timer.o dma.o | ||
| 4 | obj-y += vreg.o | 3 | obj-y += vreg.o |
| 5 | obj-y += clock.o clock-7x01a.o | 4 | obj-y += acpuclock-arm11.o |
| 5 | obj-y += clock.o clock-pcom.o | ||
| 6 | obj-y += gpio.o | ||
| 6 | 7 | ||
| 7 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o | 8 | ifdef CONFIG_MSM_VIC |
| 9 | obj-y += irq-vic.o | ||
| 10 | else | ||
| 11 | obj-y += irq.o | ||
| 12 | endif | ||
| 13 | |||
| 14 | obj-$(CONFIG_ARCH_QSD8X50) += sirc.o | ||
| 15 | obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o | ||
| 16 | obj-$(CONFIG_MSM_SMD) += last_radio_log.o | ||
| 17 | |||
| 18 | obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o | ||
| 19 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o | ||
| 20 | obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o | ||
| 21 | obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o | ||
| 8 | 22 | ||
| 9 | obj-$(CONFIG_MACH_TROUT) += board-dream.o | ||
diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c new file mode 100644 index 000000000000..af5e85b91d02 --- /dev/null +++ b/arch/arm/mach-msm/acpuclock-arm11.c | |||
| @@ -0,0 +1,526 @@ | |||
| 1 | /* arch/arm/mach-msm/acpuclock.c | ||
| 2 | * | ||
| 3 | * MSM architecture clock driver | ||
| 4 | * | ||
| 5 | * Copyright (C) 2007 Google, Inc. | ||
| 6 | * Copyright (c) 2007 QUALCOMM Incorporated | ||
| 7 | * Author: San Mehat <san@android.com> | ||
| 8 | * | ||
| 9 | * This software is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2, as published by the Free Software Foundation, and | ||
| 11 | * may be copied, distributed, and modified under those terms. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/version.h> | ||
| 21 | #include <linux/kernel.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/list.h> | ||
| 24 | #include <linux/errno.h> | ||
| 25 | #include <linux/string.h> | ||
| 26 | #include <linux/delay.h> | ||
| 27 | #include <linux/clk.h> | ||
| 28 | #include <linux/cpufreq.h> | ||
| 29 | #include <linux/mutex.h> | ||
| 30 | #include <linux/io.h> | ||
| 31 | #include <mach/board.h> | ||
| 32 | #include <mach/msm_iomap.h> | ||
| 33 | |||
| 34 | #include "proc_comm.h" | ||
| 35 | #include "acpuclock.h" | ||
| 36 | |||
| 37 | |||
| 38 | #define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100) | ||
| 39 | #define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) | ||
| 40 | #define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) | ||
| 41 | |||
| 42 | /* | ||
| 43 | * ARM11 clock configuration for specific ACPU speeds | ||
| 44 | */ | ||
| 45 | |||
| 46 | #define ACPU_PLL_TCXO -1 | ||
| 47 | #define ACPU_PLL_0 0 | ||
| 48 | #define ACPU_PLL_1 1 | ||
| 49 | #define ACPU_PLL_2 2 | ||
| 50 | #define ACPU_PLL_3 3 | ||
| 51 | |||
| 52 | #define PERF_SWITCH_DEBUG 0 | ||
| 53 | #define PERF_SWITCH_STEP_DEBUG 0 | ||
| 54 | |||
| 55 | struct clock_state | ||
| 56 | { | ||
| 57 | struct clkctl_acpu_speed *current_speed; | ||
| 58 | struct mutex lock; | ||
| 59 | uint32_t acpu_switch_time_us; | ||
| 60 | uint32_t max_speed_delta_khz; | ||
| 61 | uint32_t vdd_switch_time_us; | ||
| 62 | unsigned long power_collapse_khz; | ||
| 63 | unsigned long wait_for_irq_khz; | ||
| 64 | }; | ||
| 65 | |||
| 66 | static struct clk *ebi1_clk; | ||
| 67 | static struct clock_state drv_state = { 0 }; | ||
| 68 | |||
| 69 | static void __init acpuclk_init(void); | ||
| 70 | |||
| 71 | /* MSM7201A Levels 3-6 all correspond to 1.2V, level 7 corresponds to 1.325V. */ | ||
| 72 | enum { | ||
| 73 | VDD_0 = 0, | ||
| 74 | VDD_1 = 1, | ||
| 75 | VDD_2 = 2, | ||
| 76 | VDD_3 = 3, | ||
| 77 | VDD_4 = 3, | ||
| 78 | VDD_5 = 3, | ||
| 79 | VDD_6 = 3, | ||
| 80 | VDD_7 = 7, | ||
| 81 | VDD_END | ||
| 82 | }; | ||
| 83 | |||
| 84 | struct clkctl_acpu_speed { | ||
| 85 | unsigned int a11clk_khz; | ||
| 86 | int pll; | ||
| 87 | unsigned int a11clk_src_sel; | ||
| 88 | unsigned int a11clk_src_div; | ||
| 89 | unsigned int ahbclk_khz; | ||
| 90 | unsigned int ahbclk_div; | ||
| 91 | int vdd; | ||
| 92 | unsigned int axiclk_khz; | ||
| 93 | unsigned long lpj; /* loops_per_jiffy */ | ||
| 94 | /* Index in acpu_freq_tbl[] for steppings. */ | ||
| 95 | short down; | ||
| 96 | short up; | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* | ||
| 100 | * ACPU speed table. Complete table is shown but certain speeds are commented | ||
| 101 | * out to optimized speed switching. Initalize loops_per_jiffy to 0. | ||
| 102 | * | ||
| 103 | * Table stepping up/down is optimized for 256mhz jumps while staying on the | ||
| 104 | * same PLL. | ||
| 105 | */ | ||
| 106 | #if (0) | ||
| 107 | static struct clkctl_acpu_speed acpu_freq_tbl[] = { | ||
| 108 | { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 8 }, | ||
| 109 | { 61440, ACPU_PLL_0, 4, 3, 61440, 0, VDD_0, 30720, 0, 0, 8 }, | ||
| 110 | { 81920, ACPU_PLL_0, 4, 2, 40960, 1, VDD_0, 61440, 0, 0, 8 }, | ||
| 111 | { 96000, ACPU_PLL_1, 1, 7, 48000, 1, VDD_0, 61440, 0, 0, 9 }, | ||
| 112 | { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 8 }, | ||
| 113 | { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 12 }, | ||
| 114 | { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 11 }, | ||
| 115 | { 192000, ACPU_PLL_1, 1, 3, 64000, 2, VDD_3, 61440, 0, 0, 12 }, | ||
| 116 | { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 12 }, | ||
| 117 | { 256000, ACPU_PLL_1, 1, 2, 128000, 2, VDD_5, 128000, 0, 0, 12 }, | ||
| 118 | { 264000, ACPU_PLL_2, 2, 3, 88000, 2, VDD_5, 128000, 0, 6, 13 }, | ||
| 119 | { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 6, 13 }, | ||
| 120 | { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 5, -1 }, | ||
| 121 | { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 11, -1 }, | ||
| 122 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 123 | }; | ||
| 124 | #else /* Table of freq we currently use. */ | ||
| 125 | static struct clkctl_acpu_speed acpu_freq_tbl[] = { | ||
| 126 | { 19200, ACPU_PLL_TCXO, 0, 0, 19200, 0, VDD_0, 30720, 0, 0, 4 }, | ||
| 127 | { 122880, ACPU_PLL_0, 4, 1, 61440, 1, VDD_3, 61440, 0, 0, 4 }, | ||
| 128 | { 128000, ACPU_PLL_1, 1, 5, 64000, 1, VDD_3, 61440, 0, 0, 6 }, | ||
| 129 | { 176000, ACPU_PLL_2, 2, 5, 88000, 1, VDD_3, 61440, 0, 0, 5 }, | ||
| 130 | { 245760, ACPU_PLL_0, 4, 0, 81920, 2, VDD_4, 61440, 0, 0, 5 }, | ||
| 131 | { 352000, ACPU_PLL_2, 2, 2, 88000, 3, VDD_5, 128000, 0, 3, 7 }, | ||
| 132 | { 384000, ACPU_PLL_1, 1, 1, 128000, 2, VDD_6, 128000, 0, 2, -1 }, | ||
| 133 | { 528000, ACPU_PLL_2, 2, 1, 132000, 3, VDD_7, 128000, 0, 5, -1 }, | ||
| 134 | { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, | ||
| 135 | }; | ||
| 136 | #endif | ||
| 137 | |||
| 138 | |||
| 139 | #ifdef CONFIG_CPU_FREQ_TABLE | ||
| 140 | static struct cpufreq_frequency_table freq_table[] = { | ||
| 141 | { 0, 122880 }, | ||
| 142 | { 1, 128000 }, | ||
| 143 | { 2, 245760 }, | ||
| 144 | { 3, 384000 }, | ||
| 145 | { 4, 528000 }, | ||
| 146 | { 5, CPUFREQ_TABLE_END }, | ||
| 147 | }; | ||
| 148 | #endif | ||
| 149 | |||
| 150 | static int pc_pll_request(unsigned id, unsigned on) | ||
| 151 | { | ||
| 152 | int res; | ||
| 153 | on = !!on; | ||
| 154 | |||
| 155 | #if PERF_SWITCH_DEBUG | ||
| 156 | if (on) | ||
| 157 | printk(KERN_DEBUG "Enabling PLL %d\n", id); | ||
| 158 | else | ||
| 159 | printk(KERN_DEBUG "Disabling PLL %d\n", id); | ||
| 160 | #endif | ||
| 161 | |||
| 162 | res = msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on); | ||
| 163 | if (res < 0) | ||
| 164 | return res; | ||
| 165 | |||
| 166 | #if PERF_SWITCH_DEBUG | ||
| 167 | if (on) | ||
| 168 | printk(KERN_DEBUG "PLL %d enabled\n", id); | ||
| 169 | else | ||
| 170 | printk(KERN_DEBUG "PLL %d disabled\n", id); | ||
| 171 | #endif | ||
| 172 | return res; | ||
| 173 | } | ||
| 174 | |||
| 175 | |||
| 176 | /*---------------------------------------------------------------------------- | ||
| 177 | * ARM11 'owned' clock control | ||
| 178 | *---------------------------------------------------------------------------*/ | ||
| 179 | |||
| 180 | unsigned long acpuclk_power_collapse(void) { | ||
| 181 | int ret = acpuclk_get_rate(); | ||
| 182 | ret *= 1000; | ||
| 183 | if (ret > drv_state.power_collapse_khz) | ||
| 184 | acpuclk_set_rate(drv_state.power_collapse_khz, 1); | ||
| 185 | return ret; | ||
| 186 | } | ||
| 187 | |||
| 188 | unsigned long acpuclk_get_wfi_rate(void) | ||
| 189 | { | ||
| 190 | return drv_state.wait_for_irq_khz; | ||
| 191 | } | ||
| 192 | |||
| 193 | unsigned long acpuclk_wait_for_irq(void) { | ||
| 194 | int ret = acpuclk_get_rate(); | ||
| 195 | ret *= 1000; | ||
| 196 | if (ret > drv_state.wait_for_irq_khz) | ||
| 197 | acpuclk_set_rate(drv_state.wait_for_irq_khz, 1); | ||
| 198 | return ret; | ||
| 199 | } | ||
| 200 | |||
| 201 | static int acpuclk_set_vdd_level(int vdd) | ||
| 202 | { | ||
| 203 | uint32_t current_vdd; | ||
| 204 | |||
| 205 | current_vdd = readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x07; | ||
| 206 | |||
| 207 | #if PERF_SWITCH_DEBUG | ||
| 208 | printk(KERN_DEBUG "acpuclock: Switching VDD from %u -> %d\n", | ||
| 209 | current_vdd, vdd); | ||
| 210 | #endif | ||
| 211 | writel((1 << 7) | (vdd << 3), A11S_VDD_SVS_PLEVEL_ADDR); | ||
| 212 | udelay(drv_state.vdd_switch_time_us); | ||
| 213 | if ((readl(A11S_VDD_SVS_PLEVEL_ADDR) & 0x7) != vdd) { | ||
| 214 | #if PERF_SWITCH_DEBUG | ||
| 215 | printk(KERN_ERR "acpuclock: VDD set failed\n"); | ||
| 216 | #endif | ||
| 217 | return -EIO; | ||
| 218 | } | ||
| 219 | |||
| 220 | #if PERF_SWITCH_DEBUG | ||
| 221 | printk(KERN_DEBUG "acpuclock: VDD switched\n"); | ||
| 222 | #endif | ||
| 223 | return 0; | ||
| 224 | } | ||
| 225 | |||
| 226 | /* Set proper dividers for the given clock speed. */ | ||
| 227 | static void acpuclk_set_div(const struct clkctl_acpu_speed *hunt_s) { | ||
| 228 | uint32_t reg_clkctl, reg_clksel, clk_div; | ||
| 229 | |||
| 230 | /* AHB_CLK_DIV */ | ||
| 231 | clk_div = (readl(A11S_CLK_SEL_ADDR) >> 1) & 0x03; | ||
| 232 | /* | ||
| 233 | * If the new clock divider is higher than the previous, then | ||
| 234 | * program the divider before switching the clock | ||
| 235 | */ | ||
| 236 | if (hunt_s->ahbclk_div > clk_div) { | ||
| 237 | reg_clksel = readl(A11S_CLK_SEL_ADDR); | ||
| 238 | reg_clksel &= ~(0x3 << 1); | ||
| 239 | reg_clksel |= (hunt_s->ahbclk_div << 1); | ||
| 240 | writel(reg_clksel, A11S_CLK_SEL_ADDR); | ||
| 241 | } | ||
| 242 | if ((readl(A11S_CLK_SEL_ADDR) & 0x01) == 0) { | ||
| 243 | /* SRC0 */ | ||
| 244 | |||
| 245 | /* Program clock source */ | ||
| 246 | reg_clkctl = readl(A11S_CLK_CNTL_ADDR); | ||
| 247 | reg_clkctl &= ~(0x07 << 4); | ||
| 248 | reg_clkctl |= (hunt_s->a11clk_src_sel << 4); | ||
| 249 | writel(reg_clkctl, A11S_CLK_CNTL_ADDR); | ||
| 250 | |||
| 251 | /* Program clock divider */ | ||
| 252 | reg_clkctl = readl(A11S_CLK_CNTL_ADDR); | ||
| 253 | reg_clkctl &= ~0xf; | ||
| 254 | reg_clkctl |= hunt_s->a11clk_src_div; | ||
| 255 | writel(reg_clkctl, A11S_CLK_CNTL_ADDR); | ||
| 256 | |||
| 257 | /* Program clock source selection */ | ||
| 258 | reg_clksel = readl(A11S_CLK_SEL_ADDR); | ||
| 259 | reg_clksel |= 1; /* CLK_SEL_SRC1NO == SRC1 */ | ||
| 260 | writel(reg_clksel, A11S_CLK_SEL_ADDR); | ||
| 261 | } else { | ||
| 262 | /* SRC1 */ | ||
| 263 | |||
| 264 | /* Program clock source */ | ||
| 265 | reg_clkctl = readl(A11S_CLK_CNTL_ADDR); | ||
| 266 | reg_clkctl &= ~(0x07 << 12); | ||
| 267 | reg_clkctl |= (hunt_s->a11clk_src_sel << 12); | ||
| 268 | writel(reg_clkctl, A11S_CLK_CNTL_ADDR); | ||
| 269 | |||
| 270 | /* Program clock divider */ | ||
| 271 | reg_clkctl = readl(A11S_CLK_CNTL_ADDR); | ||
| 272 | reg_clkctl &= ~(0xf << 8); | ||
| 273 | reg_clkctl |= (hunt_s->a11clk_src_div << 8); | ||
| 274 | writel(reg_clkctl, A11S_CLK_CNTL_ADDR); | ||
| 275 | |||
| 276 | /* Program clock source selection */ | ||
| 277 | reg_clksel = readl(A11S_CLK_SEL_ADDR); | ||
| 278 | reg_clksel &= ~1; /* CLK_SEL_SRC1NO == SRC0 */ | ||
| 279 | writel(reg_clksel, A11S_CLK_SEL_ADDR); | ||
| 280 | } | ||
| 281 | |||
| 282 | /* | ||
| 283 | * If the new clock divider is lower than the previous, then | ||
| 284 | * program the divider after switching the clock | ||
| 285 | */ | ||
| 286 | if (hunt_s->ahbclk_div < clk_div) { | ||
| 287 | reg_clksel = readl(A11S_CLK_SEL_ADDR); | ||
| 288 | reg_clksel &= ~(0x3 << 1); | ||
| 289 | reg_clksel |= (hunt_s->ahbclk_div << 1); | ||
| 290 | writel(reg_clksel, A11S_CLK_SEL_ADDR); | ||
| 291 | } | ||
| 292 | } | ||
| 293 | |||
| 294 | int acpuclk_set_rate(unsigned long rate, int for_power_collapse) | ||
| 295 | { | ||
| 296 | uint32_t reg_clkctl; | ||
| 297 | struct clkctl_acpu_speed *cur_s, *tgt_s, *strt_s; | ||
| 298 | int rc = 0; | ||
| 299 | unsigned int plls_enabled = 0, pll; | ||
| 300 | |||
| 301 | strt_s = cur_s = drv_state.current_speed; | ||
| 302 | |||
| 303 | WARN_ONCE(cur_s == NULL, "acpuclk_set_rate: not initialized\n"); | ||
| 304 | if (cur_s == NULL) | ||
| 305 | return -ENOENT; | ||
| 306 | |||
| 307 | if (rate == (cur_s->a11clk_khz * 1000)) | ||
| 308 | return 0; | ||
| 309 | |||
| 310 | for (tgt_s = acpu_freq_tbl; tgt_s->a11clk_khz != 0; tgt_s++) { | ||
| 311 | if (tgt_s->a11clk_khz == (rate / 1000)) | ||
| 312 | break; | ||
| 313 | } | ||
| 314 | |||
| 315 | if (tgt_s->a11clk_khz == 0) | ||
| 316 | return -EINVAL; | ||
| 317 | |||
| 318 | /* Choose the highest speed speed at or below 'rate' with same PLL. */ | ||
| 319 | if (for_power_collapse && tgt_s->a11clk_khz < cur_s->a11clk_khz) { | ||
| 320 | while (tgt_s->pll != ACPU_PLL_TCXO && tgt_s->pll != cur_s->pll) | ||
| 321 | tgt_s--; | ||
| 322 | } | ||
| 323 | |||
| 324 | if (strt_s->pll != ACPU_PLL_TCXO) | ||
| 325 | plls_enabled |= 1 << strt_s->pll; | ||
| 326 | |||
| 327 | if (!for_power_collapse) { | ||
| 328 | mutex_lock(&drv_state.lock); | ||
| 329 | if (strt_s->pll != tgt_s->pll && tgt_s->pll != ACPU_PLL_TCXO) { | ||
| 330 | rc = pc_pll_request(tgt_s->pll, 1); | ||
| 331 | if (rc < 0) { | ||
| 332 | pr_err("PLL%d enable failed (%d)\n", | ||
| 333 | tgt_s->pll, rc); | ||
| 334 | goto out; | ||
| 335 | } | ||
| 336 | plls_enabled |= 1 << tgt_s->pll; | ||
| 337 | } | ||
| 338 | /* Increase VDD if needed. */ | ||
| 339 | if (tgt_s->vdd > cur_s->vdd) { | ||
| 340 | if ((rc = acpuclk_set_vdd_level(tgt_s->vdd)) < 0) { | ||
| 341 | printk(KERN_ERR "Unable to switch ACPU vdd\n"); | ||
| 342 | goto out; | ||
| 343 | } | ||
| 344 | } | ||
| 345 | } | ||
| 346 | |||
| 347 | /* Set wait states for CPU inbetween frequency changes */ | ||
| 348 | reg_clkctl = readl(A11S_CLK_CNTL_ADDR); | ||
| 349 | reg_clkctl |= (100 << 16); /* set WT_ST_CNT */ | ||
| 350 | writel(reg_clkctl, A11S_CLK_CNTL_ADDR); | ||
| 351 | |||
| 352 | #if PERF_SWITCH_DEBUG | ||
| 353 | printk(KERN_INFO "acpuclock: Switching from ACPU rate %u -> %u\n", | ||
| 354 | strt_s->a11clk_khz * 1000, tgt_s->a11clk_khz * 1000); | ||
| 355 | #endif | ||
| 356 | |||
| 357 | while (cur_s != tgt_s) { | ||
| 358 | /* | ||
| 359 | * Always jump to target freq if within 256mhz, regulardless of | ||
| 360 | * PLL. If differnece is greater, use the predefinied | ||
| 361 | * steppings in the table. | ||
| 362 | */ | ||
| 363 | int d = abs((int)(cur_s->a11clk_khz - tgt_s->a11clk_khz)); | ||
| 364 | if (d > drv_state.max_speed_delta_khz) { | ||
| 365 | /* Step up or down depending on target vs current. */ | ||
| 366 | int clk_index = tgt_s->a11clk_khz > cur_s->a11clk_khz ? | ||
| 367 | cur_s->up : cur_s->down; | ||
| 368 | if (clk_index < 0) { /* This should not happen. */ | ||
| 369 | printk(KERN_ERR "cur:%u target: %u\n", | ||
| 370 | cur_s->a11clk_khz, tgt_s->a11clk_khz); | ||
| 371 | rc = -EINVAL; | ||
| 372 | goto out; | ||
| 373 | } | ||
| 374 | cur_s = &acpu_freq_tbl[clk_index]; | ||
| 375 | } else { | ||
| 376 | cur_s = tgt_s; | ||
| 377 | } | ||
| 378 | #if PERF_SWITCH_STEP_DEBUG | ||
| 379 | printk(KERN_DEBUG "%s: STEP khz = %u, pll = %d\n", | ||
| 380 | __FUNCTION__, cur_s->a11clk_khz, cur_s->pll); | ||
| 381 | #endif | ||
| 382 | if (!for_power_collapse&& cur_s->pll != ACPU_PLL_TCXO | ||
| 383 | && !(plls_enabled & (1 << cur_s->pll))) { | ||
| 384 | rc = pc_pll_request(cur_s->pll, 1); | ||
| 385 | if (rc < 0) { | ||
| 386 | pr_err("PLL%d enable failed (%d)\n", | ||
| 387 | cur_s->pll, rc); | ||
| 388 | goto out; | ||
| 389 | } | ||
| 390 | plls_enabled |= 1 << cur_s->pll; | ||
| 391 | } | ||
| 392 | |||
| 393 | acpuclk_set_div(cur_s); | ||
| 394 | drv_state.current_speed = cur_s; | ||
| 395 | /* Re-adjust lpj for the new clock speed. */ | ||
| 396 | loops_per_jiffy = cur_s->lpj; | ||
| 397 | udelay(drv_state.acpu_switch_time_us); | ||
| 398 | } | ||
| 399 | |||
| 400 | /* Nothing else to do for power collapse. */ | ||
| 401 | if (for_power_collapse) | ||
| 402 | return 0; | ||
| 403 | |||
| 404 | /* Disable PLLs we are not using anymore. */ | ||
| 405 | plls_enabled &= ~(1 << tgt_s->pll); | ||
| 406 | for (pll = ACPU_PLL_0; pll <= ACPU_PLL_2; pll++) | ||
| 407 | if (plls_enabled & (1 << pll)) { | ||
| 408 | rc = pc_pll_request(pll, 0); | ||
| 409 | if (rc < 0) { | ||
| 410 | pr_err("PLL%d disable failed (%d)\n", pll, rc); | ||
| 411 | goto out; | ||
| 412 | } | ||
| 413 | } | ||
| 414 | |||
| 415 | /* Change the AXI bus frequency if we can. */ | ||
| 416 | if (strt_s->axiclk_khz != tgt_s->axiclk_khz) { | ||
| 417 | rc = clk_set_rate(ebi1_clk, tgt_s->axiclk_khz * 1000); | ||
| 418 | if (rc < 0) | ||
| 419 | pr_err("Setting AXI min rate failed!\n"); | ||
| 420 | } | ||
| 421 | |||
| 422 | /* Drop VDD level if we can. */ | ||
| 423 | if (tgt_s->vdd < strt_s->vdd) { | ||
| 424 | if (acpuclk_set_vdd_level(tgt_s->vdd) < 0) | ||
| 425 | printk(KERN_ERR "acpuclock: Unable to drop ACPU vdd\n"); | ||
| 426 | } | ||
| 427 | |||
| 428 | #if PERF_SWITCH_DEBUG | ||
| 429 | printk(KERN_DEBUG "%s: ACPU speed change complete\n", __FUNCTION__); | ||
| 430 | #endif | ||
| 431 | out: | ||
| 432 | if (!for_power_collapse) | ||
| 433 | mutex_unlock(&drv_state.lock); | ||
| 434 | return rc; | ||
| 435 | } | ||
| 436 | |||
| 437 | static void __init acpuclk_init(void) | ||
| 438 | { | ||
| 439 | struct clkctl_acpu_speed *speed; | ||
| 440 | uint32_t div, sel; | ||
| 441 | int rc; | ||
| 442 | |||
| 443 | /* | ||
| 444 | * Determine the rate of ACPU clock | ||
| 445 | */ | ||
| 446 | |||
| 447 | if (!(readl(A11S_CLK_SEL_ADDR) & 0x01)) { /* CLK_SEL_SRC1N0 */ | ||
| 448 | /* CLK_SRC0_SEL */ | ||
| 449 | sel = (readl(A11S_CLK_CNTL_ADDR) >> 12) & 0x7; | ||
| 450 | /* CLK_SRC0_DIV */ | ||
| 451 | div = (readl(A11S_CLK_CNTL_ADDR) >> 8) & 0x0f; | ||
| 452 | } else { | ||
| 453 | /* CLK_SRC1_SEL */ | ||
| 454 | sel = (readl(A11S_CLK_CNTL_ADDR) >> 4) & 0x07; | ||
| 455 | /* CLK_SRC1_DIV */ | ||
| 456 | div = readl(A11S_CLK_CNTL_ADDR) & 0x0f; | ||
| 457 | } | ||
| 458 | |||
| 459 | for (speed = acpu_freq_tbl; speed->a11clk_khz != 0; speed++) { | ||
| 460 | if (speed->a11clk_src_sel == sel | ||
| 461 | && (speed->a11clk_src_div == div)) | ||
| 462 | break; | ||
| 463 | } | ||
| 464 | if (speed->a11clk_khz == 0) { | ||
| 465 | printk(KERN_WARNING "Warning - ACPU clock reports invalid speed\n"); | ||
| 466 | return; | ||
| 467 | } | ||
| 468 | |||
| 469 | drv_state.current_speed = speed; | ||
| 470 | |||
| 471 | rc = clk_set_rate(ebi1_clk, speed->axiclk_khz * 1000); | ||
| 472 | if (rc < 0) | ||
| 473 | pr_err("Setting AXI min rate failed!\n"); | ||
| 474 | |||
| 475 | printk(KERN_INFO "ACPU running at %d KHz\n", speed->a11clk_khz); | ||
| 476 | } | ||
| 477 | |||
| 478 | unsigned long acpuclk_get_rate(void) | ||
| 479 | { | ||
| 480 | WARN_ONCE(drv_state.current_speed == NULL, | ||
| 481 | "acpuclk_get_rate: not initialized\n"); | ||
| 482 | if (drv_state.current_speed) | ||
| 483 | return drv_state.current_speed->a11clk_khz; | ||
| 484 | else | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | uint32_t acpuclk_get_switch_time(void) | ||
| 489 | { | ||
| 490 | return drv_state.acpu_switch_time_us; | ||
| 491 | } | ||
| 492 | |||
| 493 | /*---------------------------------------------------------------------------- | ||
| 494 | * Clock driver initialization | ||
| 495 | *---------------------------------------------------------------------------*/ | ||
| 496 | |||
| 497 | /* Initalize the lpj field in the acpu_freq_tbl. */ | ||
| 498 | static void __init lpj_init(void) | ||
| 499 | { | ||
| 500 | int i; | ||
| 501 | const struct clkctl_acpu_speed *base_clk = drv_state.current_speed; | ||
| 502 | for (i = 0; acpu_freq_tbl[i].a11clk_khz; i++) { | ||
| 503 | acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy, | ||
| 504 | base_clk->a11clk_khz, | ||
| 505 | acpu_freq_tbl[i].a11clk_khz); | ||
| 506 | } | ||
| 507 | } | ||
| 508 | |||
| 509 | void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata) | ||
| 510 | { | ||
| 511 | pr_info("acpu_clock_init()\n"); | ||
| 512 | |||
| 513 | ebi1_clk = clk_get(NULL, "ebi1_clk"); | ||
| 514 | |||
| 515 | mutex_init(&drv_state.lock); | ||
| 516 | drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us; | ||
| 517 | drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz; | ||
| 518 | drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us; | ||
| 519 | drv_state.power_collapse_khz = clkdata->power_collapse_khz; | ||
| 520 | drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz; | ||
| 521 | acpuclk_init(); | ||
| 522 | lpj_init(); | ||
| 523 | #ifdef CONFIG_CPU_FREQ_TABLE | ||
| 524 | cpufreq_frequency_table_get_attr(freq_table, smp_processor_id()); | ||
| 525 | #endif | ||
| 526 | } | ||
diff --git a/arch/arm/mach-msm/acpuclock.h b/arch/arm/mach-msm/acpuclock.h new file mode 100644 index 000000000000..415de2eb9a5e --- /dev/null +++ b/arch/arm/mach-msm/acpuclock.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /* arch/arm/mach-msm/acpuclock.h | ||
| 2 | * | ||
| 3 | * MSM architecture clock driver header | ||
| 4 | * | ||
| 5 | * Copyright (C) 2007 Google, Inc. | ||
| 6 | * Copyright (c) 2007 QUALCOMM Incorporated | ||
| 7 | * Author: San Mehat <san@android.com> | ||
| 8 | * | ||
| 9 | * This software is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2, as published by the Free Software Foundation, and | ||
| 11 | * may be copied, distributed, and modified under those terms. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef __ARCH_ARM_MACH_MSM_ACPUCLOCK_H | ||
| 21 | #define __ARCH_ARM_MACH_MSM_ACPUCLOCK_H | ||
| 22 | |||
| 23 | int acpuclk_set_rate(unsigned long rate, int for_power_collapse); | ||
| 24 | unsigned long acpuclk_get_rate(void); | ||
| 25 | uint32_t acpuclk_get_switch_time(void); | ||
| 26 | unsigned long acpuclk_wait_for_irq(void); | ||
| 27 | unsigned long acpuclk_power_collapse(void); | ||
| 28 | unsigned long acpuclk_get_wfi_rate(void); | ||
| 29 | |||
| 30 | |||
| 31 | #endif | ||
| 32 | |||
diff --git a/arch/arm/mach-msm/board-halibut.c b/arch/arm/mach-msm/board-halibut.c index e61967dde9a1..7bd72e8f127e 100644 --- a/arch/arm/mach-msm/board-halibut.c +++ b/arch/arm/mach-msm/board-halibut.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <asm/mach/arch.h> | 26 | #include <asm/mach/arch.h> |
| 27 | #include <asm/mach/map.h> | 27 | #include <asm/mach/map.h> |
| 28 | #include <asm/mach/flash.h> | 28 | #include <asm/mach/flash.h> |
| 29 | #include <asm/setup.h> | ||
| 29 | 30 | ||
| 30 | #include <mach/irqs.h> | 31 | #include <mach/irqs.h> |
| 31 | #include <mach/board.h> | 32 | #include <mach/board.h> |
| @@ -77,14 +78,28 @@ static void __init halibut_init(void) | |||
| 77 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 78 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
| 78 | } | 79 | } |
| 79 | 80 | ||
| 81 | static void __init halibut_fixup(struct machine_desc *desc, struct tag *tags, | ||
| 82 | char **cmdline, struct meminfo *mi) | ||
| 83 | { | ||
| 84 | mi->nr_banks=1; | ||
| 85 | mi->bank[0].start = PHYS_OFFSET; | ||
| 86 | mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); | ||
| 87 | mi->bank[0].size = (101*1024*1024); | ||
| 88 | } | ||
| 89 | |||
| 80 | static void __init halibut_map_io(void) | 90 | static void __init halibut_map_io(void) |
| 81 | { | 91 | { |
| 82 | msm_map_common_io(); | 92 | msm_map_common_io(); |
| 83 | msm_clock_init(); | 93 | msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); |
| 84 | } | 94 | } |
| 85 | 95 | ||
| 86 | MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") | 96 | MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)") |
| 97 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 98 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 99 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 100 | #endif | ||
| 87 | .boot_params = 0x10000100, | 101 | .boot_params = 0x10000100, |
| 102 | .fixup = halibut_fixup, | ||
| 88 | .map_io = halibut_map_io, | 103 | .map_io = halibut_map_io, |
| 89 | .init_irq = halibut_init_irq, | 104 | .init_irq = halibut_init_irq, |
| 90 | .init_machine = halibut_init, | 105 | .init_machine = halibut_init, |
diff --git a/arch/arm/mach-msm/board-mahimahi.c b/arch/arm/mach-msm/board-mahimahi.c new file mode 100644 index 000000000000..bcbefdfe7b5e --- /dev/null +++ b/arch/arm/mach-msm/board-mahimahi.c | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | /* linux/arch/arm/mach-msm/board-mahimahi.c | ||
| 2 | * | ||
| 3 | * Copyright (C) 2009 Google, Inc. | ||
| 4 | * Copyright (C) 2009 HTC Corporation. | ||
| 5 | * Author: Dima Zavin <dima@android.com> | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/gpio.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/input.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | #include <linux/kernel.h> | ||
| 24 | #include <linux/platform_device.h> | ||
| 25 | |||
| 26 | #include <asm/mach-types.h> | ||
| 27 | #include <asm/mach/arch.h> | ||
| 28 | #include <asm/mach/map.h> | ||
| 29 | #include <asm/setup.h> | ||
| 30 | |||
| 31 | #include <mach/board.h> | ||
| 32 | #include <mach/hardware.h> | ||
| 33 | #include <mach/system.h> | ||
| 34 | |||
| 35 | #include "board-mahimahi.h" | ||
| 36 | #include "devices.h" | ||
| 37 | #include "proc_comm.h" | ||
| 38 | |||
| 39 | static uint debug_uart; | ||
| 40 | |||
| 41 | module_param_named(debug_uart, debug_uart, uint, 0); | ||
| 42 | |||
| 43 | static struct platform_device *devices[] __initdata = { | ||
| 44 | #if !defined(CONFIG_MSM_SERIAL_DEBUGGER) | ||
| 45 | &msm_device_uart1, | ||
| 46 | #endif | ||
| 47 | &msm_device_uart_dm1, | ||
| 48 | &msm_device_nand, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static void __init mahimahi_init(void) | ||
| 52 | { | ||
| 53 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void __init mahimahi_fixup(struct machine_desc *desc, struct tag *tags, | ||
| 57 | char **cmdline, struct meminfo *mi) | ||
| 58 | { | ||
| 59 | mi->nr_banks = 2; | ||
| 60 | mi->bank[0].start = PHYS_OFFSET; | ||
| 61 | mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); | ||
| 62 | mi->bank[0].size = (219*1024*1024); | ||
| 63 | mi->bank[1].start = MSM_HIGHMEM_BASE; | ||
| 64 | mi->bank[1].node = PHYS_TO_NID(MSM_HIGHMEM_BASE); | ||
| 65 | mi->bank[1].size = MSM_HIGHMEM_SIZE; | ||
| 66 | } | ||
| 67 | |||
| 68 | static void __init mahimahi_map_io(void) | ||
| 69 | { | ||
| 70 | msm_map_common_io(); | ||
| 71 | msm_clock_init(); | ||
| 72 | } | ||
| 73 | |||
| 74 | extern struct sys_timer msm_timer; | ||
| 75 | |||
| 76 | MACHINE_START(MAHIMAHI, "mahimahi") | ||
| 77 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 78 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 79 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 80 | #endif | ||
| 81 | .boot_params = 0x20000100, | ||
| 82 | .fixup = mahimahi_fixup, | ||
| 83 | .map_io = mahimahi_map_io, | ||
| 84 | .init_irq = msm_init_irq, | ||
| 85 | .init_machine = mahimahi_init, | ||
| 86 | .timer = &msm_timer, | ||
| 87 | MACHINE_END | ||
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c new file mode 100644 index 000000000000..cccb9f3c9d01 --- /dev/null +++ b/arch/arm/mach-msm/board-msm7x27.c | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Google, Inc. | ||
| 3 | * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/kernel.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/input.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/bootmem.h> | ||
| 24 | #include <linux/power_supply.h> | ||
| 25 | |||
| 26 | #include <mach/hardware.h> | ||
| 27 | #include <asm/mach-types.h> | ||
| 28 | #include <asm/mach/arch.h> | ||
| 29 | #include <asm/mach/map.h> | ||
| 30 | #include <asm/mach/flash.h> | ||
| 31 | #include <asm/setup.h> | ||
| 32 | #ifdef CONFIG_CACHE_L2X0 | ||
| 33 | #include <asm/hardware/cache-l2x0.h> | ||
| 34 | #endif | ||
| 35 | |||
| 36 | #include <mach/vreg.h> | ||
| 37 | #include <mach/mpp.h> | ||
| 38 | #include <mach/gpio.h> | ||
| 39 | #include <mach/board.h> | ||
| 40 | #include <mach/msm_iomap.h> | ||
| 41 | |||
| 42 | #include <linux/mtd/nand.h> | ||
| 43 | #include <linux/mtd/partitions.h> | ||
| 44 | |||
| 45 | #include "devices.h" | ||
| 46 | #include "socinfo.h" | ||
| 47 | #include "clock.h" | ||
| 48 | |||
| 49 | static struct resource smc91x_resources[] = { | ||
| 50 | [0] = { | ||
| 51 | .start = 0x9C004300, | ||
| 52 | .end = 0x9C0043ff, | ||
| 53 | .flags = IORESOURCE_MEM, | ||
| 54 | }, | ||
| 55 | [1] = { | ||
| 56 | .start = MSM_GPIO_TO_INT(132), | ||
| 57 | .end = MSM_GPIO_TO_INT(132), | ||
| 58 | .flags = IORESOURCE_IRQ, | ||
| 59 | }, | ||
| 60 | }; | ||
| 61 | |||
| 62 | static struct platform_device smc91x_device = { | ||
| 63 | .name = "smc91x", | ||
| 64 | .id = 0, | ||
| 65 | .num_resources = ARRAY_SIZE(smc91x_resources), | ||
| 66 | .resource = smc91x_resources, | ||
| 67 | }; | ||
| 68 | |||
| 69 | static struct platform_device *devices[] __initdata = { | ||
| 70 | &msm_device_uart3, | ||
| 71 | &msm_device_smd, | ||
| 72 | &msm_device_dmov, | ||
| 73 | &msm_device_nand, | ||
| 74 | &smc91x_device, | ||
| 75 | }; | ||
| 76 | |||
| 77 | extern struct sys_timer msm_timer; | ||
| 78 | |||
| 79 | static void __init msm7x2x_init_irq(void) | ||
| 80 | { | ||
| 81 | msm_init_irq(); | ||
| 82 | } | ||
| 83 | |||
| 84 | static void __init msm7x2x_init(void) | ||
| 85 | { | ||
| 86 | if (socinfo_init() < 0) | ||
| 87 | BUG(); | ||
| 88 | |||
| 89 | if (machine_is_msm7x25_ffa() || machine_is_msm7x27_ffa()) { | ||
| 90 | smc91x_resources[0].start = 0x98000300; | ||
| 91 | smc91x_resources[0].end = 0x980003ff; | ||
| 92 | smc91x_resources[1].start = MSM_GPIO_TO_INT(85); | ||
| 93 | smc91x_resources[1].end = MSM_GPIO_TO_INT(85); | ||
| 94 | if (gpio_tlmm_config(GPIO_CFG(85, 0, | ||
| 95 | GPIO_INPUT, | ||
| 96 | GPIO_PULL_DOWN, | ||
| 97 | GPIO_2MA), | ||
| 98 | GPIO_ENABLE)) { | ||
| 99 | printk(KERN_ERR | ||
| 100 | "%s: Err: Config GPIO-85 INT\n", | ||
| 101 | __func__); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 106 | } | ||
| 107 | |||
| 108 | static void __init msm7x2x_map_io(void) | ||
| 109 | { | ||
| 110 | msm_map_common_io(); | ||
| 111 | /* Technically dependent on the SoC but using machine_is | ||
| 112 | * macros since socinfo is not available this early and there | ||
| 113 | * are plans to restructure the code which will eliminate the | ||
| 114 | * need for socinfo. | ||
| 115 | */ | ||
| 116 | if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) | ||
| 117 | msm_clock_init(msm_clocks_7x27, msm_num_clocks_7x27); | ||
| 118 | |||
| 119 | if (machine_is_msm7x25_surf() || machine_is_msm7x25_ffa()) | ||
| 120 | msm_clock_init(msm_clocks_7x25, msm_num_clocks_7x25); | ||
| 121 | |||
| 122 | #ifdef CONFIG_CACHE_L2X0 | ||
| 123 | if (machine_is_msm7x27_surf() || machine_is_msm7x27_ffa()) { | ||
| 124 | /* 7x27 has 256KB L2 cache: | ||
| 125 | 64Kb/Way and 4-Way Associativity; | ||
| 126 | R/W latency: 3 cycles; | ||
| 127 | evmon/parity/share disabled. */ | ||
| 128 | l2x0_init(MSM_L2CC_BASE, 0x00068012, 0xfe000000); | ||
| 129 | } | ||
| 130 | #endif | ||
| 131 | } | ||
| 132 | |||
| 133 | MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF") | ||
| 134 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 135 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 136 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 137 | #endif | ||
| 138 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 139 | .map_io = msm7x2x_map_io, | ||
| 140 | .init_irq = msm7x2x_init_irq, | ||
| 141 | .init_machine = msm7x2x_init, | ||
| 142 | .timer = &msm_timer, | ||
| 143 | MACHINE_END | ||
| 144 | |||
| 145 | MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA") | ||
| 146 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 147 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 148 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 149 | #endif | ||
| 150 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 151 | .map_io = msm7x2x_map_io, | ||
| 152 | .init_irq = msm7x2x_init_irq, | ||
| 153 | .init_machine = msm7x2x_init, | ||
| 154 | .timer = &msm_timer, | ||
| 155 | MACHINE_END | ||
| 156 | |||
| 157 | MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF") | ||
| 158 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 159 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 160 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 161 | #endif | ||
| 162 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 163 | .map_io = msm7x2x_map_io, | ||
| 164 | .init_irq = msm7x2x_init_irq, | ||
| 165 | .init_machine = msm7x2x_init, | ||
| 166 | .timer = &msm_timer, | ||
| 167 | MACHINE_END | ||
| 168 | |||
| 169 | MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA") | ||
| 170 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 171 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 172 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 173 | #endif | ||
| 174 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 175 | .map_io = msm7x2x_map_io, | ||
| 176 | .init_irq = msm7x2x_init_irq, | ||
| 177 | .init_machine = msm7x2x_init, | ||
| 178 | .timer = &msm_timer, | ||
| 179 | MACHINE_END | ||
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c new file mode 100644 index 000000000000..bac1f3c38a3b --- /dev/null +++ b/arch/arm/mach-msm/board-msm7x30.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License version 2 and | ||
| 5 | * only version 2 as published by the Free Software Foundation. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 15 | * 02110-1301, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/bootmem.h> | ||
| 24 | #include <linux/io.h> | ||
| 25 | #include <linux/smsc911x.h> | ||
| 26 | |||
| 27 | #include <asm/mach-types.h> | ||
| 28 | #include <asm/mach/arch.h> | ||
| 29 | #include <asm/setup.h> | ||
| 30 | |||
| 31 | #include <mach/gpio.h> | ||
| 32 | #include <mach/board.h> | ||
| 33 | #include <mach/memory.h> | ||
| 34 | #include <mach/msm_iomap.h> | ||
| 35 | #include <mach/dma.h> | ||
| 36 | |||
| 37 | #include <mach/vreg.h> | ||
| 38 | #include "devices.h" | ||
| 39 | #include "proc_comm.h" | ||
| 40 | |||
| 41 | extern struct sys_timer msm_timer; | ||
| 42 | |||
| 43 | #ifdef CONFIG_SERIAL_MSM_CONSOLE | ||
| 44 | static struct msm_gpio uart2_config_data[] = { | ||
| 45 | { GPIO_CFG(49, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"}, | ||
| 46 | { GPIO_CFG(50, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"}, | ||
| 47 | { GPIO_CFG(51, 2, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"}, | ||
| 48 | { GPIO_CFG(52, 2, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"}, | ||
| 49 | }; | ||
| 50 | |||
| 51 | static void msm7x30_init_uart2(void) | ||
| 52 | { | ||
| 53 | msm_gpios_request_enable(uart2_config_data, | ||
| 54 | ARRAY_SIZE(uart2_config_data)); | ||
| 55 | |||
| 56 | } | ||
| 57 | #endif | ||
| 58 | |||
| 59 | static struct platform_device *devices[] __initdata = { | ||
| 60 | #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER) | ||
| 61 | &msm_device_uart2, | ||
| 62 | #endif | ||
| 63 | |||
| 64 | }; | ||
| 65 | |||
| 66 | static void __init msm7x30_init_irq(void) | ||
| 67 | { | ||
| 68 | msm_init_irq(); | ||
| 69 | } | ||
| 70 | |||
| 71 | static void __init msm7x30_init(void) | ||
| 72 | { | ||
| 73 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 74 | #ifdef CONFIG_SERIAL_MSM_CONSOLE | ||
| 75 | msm7x30_init_uart2(); | ||
| 76 | #endif | ||
| 77 | |||
| 78 | } | ||
| 79 | |||
| 80 | static void __init msm7x30_map_io(void) | ||
| 81 | { | ||
| 82 | msm_map_msm7x30_io(); | ||
| 83 | msm_clock_init(msm_clocks_7x30, msm_num_clocks_7x30); | ||
| 84 | } | ||
| 85 | |||
| 86 | MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF") | ||
| 87 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 88 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 89 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 90 | #endif | ||
| 91 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 92 | .map_io = msm7x30_map_io, | ||
| 93 | .init_irq = msm7x30_init_irq, | ||
| 94 | .init_machine = msm7x30_init, | ||
| 95 | .timer = &msm_timer, | ||
| 96 | MACHINE_END | ||
| 97 | |||
| 98 | MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA") | ||
| 99 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 100 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 101 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 102 | #endif | ||
| 103 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 104 | .map_io = msm7x30_map_io, | ||
| 105 | .init_irq = msm7x30_init_irq, | ||
| 106 | .init_machine = msm7x30_init, | ||
| 107 | .timer = &msm_timer, | ||
| 108 | MACHINE_END | ||
| 109 | |||
| 110 | MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID") | ||
| 111 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 112 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 113 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 114 | #endif | ||
| 115 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 116 | .map_io = msm7x30_map_io, | ||
| 117 | .init_irq = msm7x30_init_irq, | ||
| 118 | .init_machine = msm7x30_init, | ||
| 119 | .timer = &msm_timer, | ||
| 120 | MACHINE_END | ||
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c new file mode 100644 index 000000000000..ec4606643d2c --- /dev/null +++ b/arch/arm/mach-msm/board-qsd8x50.c | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License version 2 and | ||
| 5 | * only version 2 as published by the Free Software Foundation. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 15 | * 02110-1301, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/irq.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/bootmem.h> | ||
| 23 | #include <linux/delay.h> | ||
| 24 | |||
| 25 | #include <asm/mach-types.h> | ||
| 26 | #include <asm/mach/arch.h> | ||
| 27 | #include <asm/io.h> | ||
| 28 | #include <asm/setup.h> | ||
| 29 | |||
| 30 | #include <mach/board.h> | ||
| 31 | #include <mach/irqs.h> | ||
| 32 | #include <mach/sirc.h> | ||
| 33 | #include <mach/gpio.h> | ||
| 34 | |||
| 35 | #include "devices.h" | ||
| 36 | |||
| 37 | extern struct sys_timer msm_timer; | ||
| 38 | |||
| 39 | static struct msm_gpio uart3_config_data[] = { | ||
| 40 | { GPIO_CFG(86, 1, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"}, | ||
| 41 | { GPIO_CFG(87, 1, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"}, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct platform_device *devices[] __initdata = { | ||
| 45 | &msm_device_uart3, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static void msm8x50_init_uart3(void) | ||
| 49 | { | ||
| 50 | msm_gpios_request_enable(uart3_config_data, | ||
| 51 | ARRAY_SIZE(uart3_config_data)); | ||
| 52 | } | ||
| 53 | |||
| 54 | static void __init qsd8x50_map_io(void) | ||
| 55 | { | ||
| 56 | msm_map_qsd8x50_io(); | ||
| 57 | msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50); | ||
| 58 | } | ||
| 59 | |||
| 60 | static void __init qsd8x50_init_irq(void) | ||
| 61 | { | ||
| 62 | msm_init_irq(); | ||
| 63 | msm_init_sirc(); | ||
| 64 | } | ||
| 65 | |||
| 66 | static void __init qsd8x50_init(void) | ||
| 67 | { | ||
| 68 | msm8x50_init_uart3(); | ||
| 69 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 70 | } | ||
| 71 | |||
| 72 | MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF") | ||
| 73 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 74 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 75 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 76 | #endif | ||
| 77 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 78 | .map_io = qsd8x50_map_io, | ||
| 79 | .init_irq = qsd8x50_init_irq, | ||
| 80 | .init_machine = qsd8x50_init, | ||
| 81 | .timer = &msm_timer, | ||
| 82 | MACHINE_END | ||
| 83 | |||
| 84 | MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5") | ||
| 85 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 86 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 87 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 88 | #endif | ||
| 89 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 90 | .map_io = qsd8x50_map_io, | ||
| 91 | .init_irq = qsd8x50_init_irq, | ||
| 92 | .init_machine = qsd8x50_init, | ||
| 93 | .timer = &msm_timer, | ||
| 94 | MACHINE_END | ||
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c new file mode 100644 index 000000000000..2bc1b9d5623e --- /dev/null +++ b/arch/arm/mach-msm/board-sapphire.c | |||
| @@ -0,0 +1,118 @@ | |||
| 1 | /* linux/arch/arm/mach-msm/board-sapphire.c | ||
| 2 | * Copyright (C) 2007-2009 HTC Corporation. | ||
| 3 | * Author: Thomas Tsai <thomas_tsai@htc.com> | ||
| 4 | * | ||
| 5 | * This software is licensed under the terms of the GNU General Public | ||
| 6 | * License version 2, as published by the Free Software Foundation, and | ||
| 7 | * may be copied, distributed, and modified under those terms. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/input.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/irq.h> | ||
| 21 | #include <linux/sysdev.h> | ||
| 22 | |||
| 23 | #include <linux/delay.h> | ||
| 24 | |||
| 25 | #include <asm/gpio.h> | ||
| 26 | #include <mach/hardware.h> | ||
| 27 | #include <asm/mach-types.h> | ||
| 28 | #include <asm/mach/arch.h> | ||
| 29 | #include <asm/mach/map.h> | ||
| 30 | #include <asm/mach/flash.h> | ||
| 31 | #include <asm/system.h> | ||
| 32 | #include <mach/system.h> | ||
| 33 | #include <mach/vreg.h> | ||
| 34 | #include <mach/board.h> | ||
| 35 | |||
| 36 | #include <asm/io.h> | ||
| 37 | #include <asm/delay.h> | ||
| 38 | #include <asm/setup.h> | ||
| 39 | |||
| 40 | #include <linux/mtd/nand.h> | ||
| 41 | #include <linux/mtd/partitions.h> | ||
| 42 | |||
| 43 | #include "gpio_chip.h" | ||
| 44 | #include "board-sapphire.h" | ||
| 45 | #include "proc_comm.h" | ||
| 46 | #include "devices.h" | ||
| 47 | |||
| 48 | void msm_init_irq(void); | ||
| 49 | void msm_init_gpio(void); | ||
| 50 | |||
| 51 | static struct platform_device *devices[] __initdata = { | ||
| 52 | &msm_device_smd, | ||
| 53 | &msm_device_dmov, | ||
| 54 | &msm_device_nand, | ||
| 55 | &msm_device_uart1, | ||
| 56 | &msm_device_uart3, | ||
| 57 | }; | ||
| 58 | |||
| 59 | extern struct sys_timer msm_timer; | ||
| 60 | |||
| 61 | static void __init sapphire_init_irq(void) | ||
| 62 | { | ||
| 63 | msm_init_irq(); | ||
| 64 | } | ||
| 65 | |||
| 66 | static void __init sapphire_init(void) | ||
| 67 | { | ||
| 68 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 69 | } | ||
| 70 | |||
| 71 | static struct map_desc sapphire_io_desc[] __initdata = { | ||
| 72 | { | ||
| 73 | .virtual = SAPPHIRE_CPLD_BASE, | ||
| 74 | .pfn = __phys_to_pfn(SAPPHIRE_CPLD_START), | ||
| 75 | .length = SAPPHIRE_CPLD_SIZE, | ||
| 76 | .type = MT_DEVICE_NONSHARED | ||
| 77 | } | ||
| 78 | }; | ||
| 79 | |||
| 80 | static void __init sapphire_fixup(struct machine_desc *desc, struct tag *tags, | ||
| 81 | char **cmdline, struct meminfo *mi) | ||
| 82 | { | ||
| 83 | int smi_sz = parse_tag_smi((const struct tag *)tags); | ||
| 84 | |||
| 85 | mi->nr_banks = 1; | ||
| 86 | mi->bank[0].start = PHYS_OFFSET; | ||
| 87 | mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET); | ||
| 88 | if (smi_sz == 32) { | ||
| 89 | mi->bank[0].size = (84*1024*1024); | ||
| 90 | } else if (smi_sz == 64) { | ||
| 91 | mi->bank[0].size = (101*1024*1024); | ||
| 92 | } else { | ||
| 93 | /* Give a default value when not get smi size */ | ||
| 94 | smi_sz = 64; | ||
| 95 | mi->bank[0].size = (101*1024*1024); | ||
| 96 | } | ||
| 97 | } | ||
| 98 | |||
| 99 | static void __init sapphire_map_io(void) | ||
| 100 | { | ||
| 101 | msm_map_common_io(); | ||
| 102 | iotable_init(sapphire_io_desc, ARRAY_SIZE(sapphire_io_desc)); | ||
| 103 | msm_clock_init(); | ||
| 104 | } | ||
| 105 | |||
| 106 | MACHINE_START(SAPPHIRE, "sapphire") | ||
| 107 | /* Maintainer: Brian Swetland <swetland@google.com> */ | ||
| 108 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 109 | .phys_io = MSM_DEBUG_UART_PHYS, | ||
| 110 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | ||
| 111 | #endif | ||
| 112 | .boot_params = PHYS_OFFSET + 0x100, | ||
| 113 | .fixup = sapphire_fixup, | ||
| 114 | .map_io = sapphire_map_io, | ||
| 115 | .init_irq = sapphire_init_irq, | ||
| 116 | .init_machine = sapphire_init, | ||
| 117 | .timer = &msm_timer, | ||
| 118 | MACHINE_END | ||
diff --git a/arch/arm/mach-msm/board-dream.c b/arch/arm/mach-msm/board-trout.c index 21afa8513168..dca5a5f062dc 100644 --- a/arch/arm/mach-msm/board-dream.c +++ b/arch/arm/mach-msm/board-trout.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* linux/arch/arm/mach-msm/board-dream.c | 1 | /* linux/arch/arm/mach-msm/board-trout.c |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2009 Google, Inc. | 3 | * Copyright (C) 2009 Google, Inc. |
| 4 | * Author: Brian Swetland <swetland@google.com> | 4 | * Author: Brian Swetland <swetland@google.com> |
| @@ -28,7 +28,7 @@ | |||
| 28 | #include <mach/msm_iomap.h> | 28 | #include <mach/msm_iomap.h> |
| 29 | 29 | ||
| 30 | #include "devices.h" | 30 | #include "devices.h" |
| 31 | #include "board-dream.h" | 31 | #include "board-trout.h" |
| 32 | 32 | ||
| 33 | static struct platform_device *devices[] __initdata = { | 33 | static struct platform_device *devices[] __initdata = { |
| 34 | &msm_device_uart3, | 34 | &msm_device_uart3, |
| @@ -78,12 +78,14 @@ static void __init trout_map_io(void) | |||
| 78 | writeb(0x80, TROUT_CPLD_BASE + 0x00); | 78 | writeb(0x80, TROUT_CPLD_BASE + 0x00); |
| 79 | #endif | 79 | #endif |
| 80 | 80 | ||
| 81 | msm_clock_init(); | 81 | msm_clock_init(msm_clocks_7x01a, msm_num_clocks_7x01a); |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | MACHINE_START(TROUT, "HTC Dream") | 84 | MACHINE_START(TROUT, "HTC Dream") |
| 85 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 85 | .phys_io = MSM_DEBUG_UART_PHYS, | 86 | .phys_io = MSM_DEBUG_UART_PHYS, |
| 86 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, | 87 | .io_pg_offst = ((MSM_DEBUG_UART_BASE) >> 18) & 0xfffc, |
| 88 | #endif | ||
| 87 | .boot_params = 0x10000100, | 89 | .boot_params = 0x10000100, |
| 88 | .fixup = trout_fixup, | 90 | .fixup = trout_fixup, |
| 89 | .map_io = trout_map_io, | 91 | .map_io = trout_map_io, |
diff --git a/arch/arm/mach-msm/board-dream.h b/arch/arm/mach-msm/board-trout.h index 4f345a5a0a61..4f345a5a0a61 100644 --- a/arch/arm/mach-msm/board-dream.h +++ b/arch/arm/mach-msm/board-trout.h | |||
diff --git a/arch/arm/mach-msm/clock-7x01a.c b/arch/arm/mach-msm/clock-7x01a.c deleted file mode 100644 index 62230a3428ee..000000000000 --- a/arch/arm/mach-msm/clock-7x01a.c +++ /dev/null | |||
| @@ -1,126 +0,0 @@ | |||
| 1 | /* arch/arm/mach-msm/clock-7x01a.c | ||
| 2 | * | ||
| 3 | * Clock tables for MSM7X01A | ||
| 4 | * | ||
| 5 | * Copyright (C) 2007 Google, Inc. | ||
| 6 | * Copyright (c) 2007 QUALCOMM Incorporated | ||
| 7 | * | ||
| 8 | * This software is licensed under the terms of the GNU General Public | ||
| 9 | * License version 2, as published by the Free Software Foundation, and | ||
| 10 | * may be copied, distributed, and modified under those terms. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | |||
| 22 | #include "clock.h" | ||
| 23 | #include "devices.h" | ||
| 24 | |||
| 25 | /* clock IDs used by the modem processor */ | ||
| 26 | |||
| 27 | #define ACPU_CLK 0 /* Applications processor clock */ | ||
| 28 | #define ADM_CLK 1 /* Applications data mover clock */ | ||
| 29 | #define ADSP_CLK 2 /* ADSP clock */ | ||
| 30 | #define EBI1_CLK 3 /* External bus interface 1 clock */ | ||
| 31 | #define EBI2_CLK 4 /* External bus interface 2 clock */ | ||
| 32 | #define ECODEC_CLK 5 /* External CODEC clock */ | ||
| 33 | #define EMDH_CLK 6 /* External MDDI host clock */ | ||
| 34 | #define GP_CLK 7 /* General purpose clock */ | ||
| 35 | #define GRP_CLK 8 /* Graphics clock */ | ||
| 36 | #define I2C_CLK 9 /* I2C clock */ | ||
| 37 | #define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ | ||
| 38 | #define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ | ||
| 39 | #define IMEM_CLK 12 /* Internal graphics memory clock */ | ||
| 40 | #define MDC_CLK 13 /* MDDI client clock */ | ||
| 41 | #define MDP_CLK 14 /* Mobile display processor clock */ | ||
| 42 | #define PBUS_CLK 15 /* Peripheral bus clock */ | ||
| 43 | #define PCM_CLK 16 /* PCM clock */ | ||
| 44 | #define PMDH_CLK 17 /* Primary MDDI host clock */ | ||
| 45 | #define SDAC_CLK 18 /* Stereo DAC clock */ | ||
| 46 | #define SDC1_CLK 19 /* Secure Digital Card clocks */ | ||
| 47 | #define SDC1_PCLK 20 | ||
| 48 | #define SDC2_CLK 21 | ||
| 49 | #define SDC2_PCLK 22 | ||
| 50 | #define SDC3_CLK 23 | ||
| 51 | #define SDC3_PCLK 24 | ||
| 52 | #define SDC4_CLK 25 | ||
| 53 | #define SDC4_PCLK 26 | ||
| 54 | #define TSIF_CLK 27 /* Transport Stream Interface clocks */ | ||
| 55 | #define TSIF_REF_CLK 28 | ||
| 56 | #define TV_DAC_CLK 29 /* TV clocks */ | ||
| 57 | #define TV_ENC_CLK 30 | ||
| 58 | #define UART1_CLK 31 /* UART clocks */ | ||
| 59 | #define UART2_CLK 32 | ||
| 60 | #define UART3_CLK 33 | ||
| 61 | #define UART1DM_CLK 34 | ||
| 62 | #define UART2DM_CLK 35 | ||
| 63 | #define USB_HS_CLK 36 /* High speed USB core clock */ | ||
| 64 | #define USB_HS_PCLK 37 /* High speed USB pbus clock */ | ||
| 65 | #define USB_OTG_CLK 38 /* Full speed USB clock */ | ||
| 66 | #define VDC_CLK 39 /* Video controller clock */ | ||
| 67 | #define VFE_CLK 40 /* Camera / Video Front End clock */ | ||
| 68 | #define VFE_MDC_CLK 41 /* VFE MDDI client clock */ | ||
| 69 | |||
| 70 | #define NR_CLKS 42 | ||
| 71 | |||
| 72 | #define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \ | ||
| 73 | .name = clk_name, \ | ||
| 74 | .id = clk_id, \ | ||
| 75 | .flags = clk_flags, \ | ||
| 76 | .dev = clk_dev, \ | ||
| 77 | } | ||
| 78 | |||
| 79 | #define OFF CLKFLAG_AUTO_OFF | ||
| 80 | #define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET | ||
| 81 | |||
| 82 | struct clk msm_clocks[] = { | ||
| 83 | CLOCK("adm_clk", ADM_CLK, NULL, 0), | ||
| 84 | CLOCK("adsp_clk", ADSP_CLK, NULL, 0), | ||
| 85 | CLOCK("ebi1_clk", EBI1_CLK, NULL, 0), | ||
| 86 | CLOCK("ebi2_clk", EBI2_CLK, NULL, 0), | ||
| 87 | CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0), | ||
| 88 | CLOCK("emdh_clk", EMDH_CLK, NULL, OFF), | ||
| 89 | CLOCK("gp_clk", GP_CLK, NULL, 0), | ||
| 90 | CLOCK("grp_clk", GRP_CLK, NULL, OFF), | ||
| 91 | CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), | ||
| 92 | CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), | ||
| 93 | CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), | ||
| 94 | CLOCK("imem_clk", IMEM_CLK, NULL, OFF), | ||
| 95 | CLOCK("mdc_clk", MDC_CLK, NULL, 0), | ||
| 96 | CLOCK("mdp_clk", MDP_CLK, NULL, OFF), | ||
| 97 | CLOCK("pbus_clk", PBUS_CLK, NULL, 0), | ||
| 98 | CLOCK("pcm_clk", PCM_CLK, NULL, 0), | ||
| 99 | CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX), | ||
| 100 | CLOCK("sdac_clk", SDAC_CLK, NULL, OFF), | ||
| 101 | CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), | ||
| 102 | CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF), | ||
| 103 | CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), | ||
| 104 | CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF), | ||
| 105 | CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), | ||
| 106 | CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF), | ||
| 107 | CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), | ||
| 108 | CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF), | ||
| 109 | CLOCK("tsif_clk", TSIF_CLK, NULL, 0), | ||
| 110 | CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), | ||
| 111 | CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0), | ||
| 112 | CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0), | ||
| 113 | CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), | ||
| 114 | CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), | ||
| 115 | CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), | ||
| 116 | CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF), | ||
| 117 | CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0), | ||
| 118 | CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), | ||
| 119 | CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF), | ||
| 120 | CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0), | ||
| 121 | CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX), | ||
| 122 | CLOCK("vfe_clk", VFE_CLK, NULL, OFF), | ||
| 123 | CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), | ||
| 124 | }; | ||
| 125 | |||
| 126 | unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks); | ||
diff --git a/arch/arm/mach-msm/clock-7x30.h b/arch/arm/mach-msm/clock-7x30.h new file mode 100644 index 000000000000..e16f72f32829 --- /dev/null +++ b/arch/arm/mach-msm/clock-7x30.h | |||
| @@ -0,0 +1,168 @@ | |||
| 1 | /* Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * Redistribution and use in source and binary forms, with or without | ||
| 4 | * modification, are permitted provided that the following conditions are | ||
| 5 | * met: | ||
| 6 | * * Redistributions of source code must retain the above copyright | ||
| 7 | * notice, this list of conditions and the following disclaimer. | ||
| 8 | * * Redistributions in binary form must reproduce the above | ||
| 9 | * copyright notice, this list of conditions and the following | ||
| 10 | * disclaimer in the documentation and/or other materials provided | ||
| 11 | * with the distribution. | ||
| 12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived | ||
| 14 | * from this software without specific prior written permission. | ||
| 15 | * | ||
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef __ARCH_ARM_MACH_MSM_CLOCK_7X30_H | ||
| 31 | #define __ARCH_ARM_MACH_MSM_CLOCK_7X30_H | ||
| 32 | |||
| 33 | enum { | ||
| 34 | L_7X30_NONE_CLK = -1, | ||
| 35 | L_7X30_ADM_CLK, | ||
| 36 | L_7X30_I2C_CLK, | ||
| 37 | L_7X30_I2C_2_CLK, | ||
| 38 | L_7X30_QUP_I2C_CLK, | ||
| 39 | L_7X30_UART1DM_CLK, | ||
| 40 | L_7X30_UART1DM_P_CLK, | ||
| 41 | L_7X30_UART2DM_CLK, | ||
| 42 | L_7X30_UART2DM_P_CLK, | ||
| 43 | L_7X30_EMDH_CLK, | ||
| 44 | L_7X30_EMDH_P_CLK, | ||
| 45 | L_7X30_PMDH_CLK, | ||
| 46 | L_7X30_PMDH_P_CLK, | ||
| 47 | L_7X30_GRP_2D_CLK, | ||
| 48 | L_7X30_GRP_2D_P_CLK, | ||
| 49 | L_7X30_GRP_3D_SRC_CLK, | ||
| 50 | L_7X30_GRP_3D_CLK, | ||
| 51 | L_7X30_GRP_3D_P_CLK, | ||
| 52 | L_7X30_IMEM_CLK, | ||
| 53 | L_7X30_SDC1_CLK, | ||
| 54 | L_7X30_SDC1_P_CLK, | ||
| 55 | L_7X30_SDC2_CLK, | ||
| 56 | L_7X30_SDC2_P_CLK, | ||
| 57 | L_7X30_SDC3_CLK, | ||
| 58 | L_7X30_SDC3_P_CLK, | ||
| 59 | L_7X30_SDC4_CLK, | ||
| 60 | L_7X30_SDC4_P_CLK, | ||
| 61 | L_7X30_MDP_CLK, | ||
| 62 | L_7X30_MDP_P_CLK, | ||
| 63 | L_7X30_MDP_LCDC_PCLK_CLK, | ||
| 64 | L_7X30_MDP_LCDC_PAD_PCLK_CLK, | ||
| 65 | L_7X30_MDP_VSYNC_CLK, | ||
| 66 | L_7X30_MI2S_CODEC_RX_M_CLK, | ||
| 67 | L_7X30_MI2S_CODEC_RX_S_CLK, | ||
| 68 | L_7X30_MI2S_CODEC_TX_M_CLK, | ||
| 69 | L_7X30_MI2S_CODEC_TX_S_CLK, | ||
| 70 | L_7X30_MI2S_M_CLK, | ||
| 71 | L_7X30_MI2S_S_CLK, | ||
| 72 | L_7X30_LPA_CODEC_CLK, | ||
| 73 | L_7X30_LPA_CORE_CLK, | ||
| 74 | L_7X30_LPA_P_CLK, | ||
| 75 | L_7X30_MIDI_CLK, | ||
| 76 | L_7X30_MDC_CLK, | ||
| 77 | L_7X30_ROTATOR_IMEM_CLK, | ||
| 78 | L_7X30_ROTATOR_P_CLK, | ||
| 79 | L_7X30_SDAC_M_CLK, | ||
| 80 | L_7X30_SDAC_CLK, | ||
| 81 | L_7X30_UART1_CLK, | ||
| 82 | L_7X30_UART2_CLK, | ||
| 83 | L_7X30_UART3_CLK, | ||
| 84 | L_7X30_TV_CLK, | ||
| 85 | L_7X30_TV_DAC_CLK, | ||
| 86 | L_7X30_TV_ENC_CLK, | ||
| 87 | L_7X30_HDMI_CLK, | ||
| 88 | L_7X30_TSIF_REF_CLK, | ||
| 89 | L_7X30_TSIF_P_CLK, | ||
| 90 | L_7X30_USB_HS_SRC_CLK, | ||
| 91 | L_7X30_USB_HS_CLK, | ||
| 92 | L_7X30_USB_HS_CORE_CLK, | ||
| 93 | L_7X30_USB_HS_P_CLK, | ||
| 94 | L_7X30_USB_HS2_CLK, | ||
| 95 | L_7X30_USB_HS2_CORE_CLK, | ||
| 96 | L_7X30_USB_HS2_P_CLK, | ||
| 97 | L_7X30_USB_HS3_CLK, | ||
| 98 | L_7X30_USB_HS3_CORE_CLK, | ||
| 99 | L_7X30_USB_HS3_P_CLK, | ||
| 100 | L_7X30_VFE_CLK, | ||
| 101 | L_7X30_VFE_P_CLK, | ||
| 102 | L_7X30_VFE_MDC_CLK, | ||
| 103 | L_7X30_VFE_CAMIF_CLK, | ||
| 104 | L_7X30_CAMIF_PAD_P_CLK, | ||
| 105 | L_7X30_CAM_M_CLK, | ||
| 106 | L_7X30_JPEG_CLK, | ||
| 107 | L_7X30_JPEG_P_CLK, | ||
| 108 | L_7X30_VPE_CLK, | ||
| 109 | L_7X30_MFC_CLK, | ||
| 110 | L_7X30_MFC_DIV2_CLK, | ||
| 111 | L_7X30_MFC_P_CLK, | ||
| 112 | L_7X30_SPI_CLK, | ||
| 113 | L_7X30_SPI_P_CLK, | ||
| 114 | L_7X30_CSI0_CLK, | ||
| 115 | L_7X30_CSI0_VFE_CLK, | ||
| 116 | L_7X30_CSI0_P_CLK, | ||
| 117 | L_7X30_CSI1_CLK, | ||
| 118 | L_7X30_CSI1_VFE_CLK, | ||
| 119 | L_7X30_CSI1_P_CLK, | ||
| 120 | L_7X30_GLBL_ROOT_CLK, | ||
| 121 | |||
| 122 | L_7X30_AXI_LI_VG_CLK, | ||
| 123 | L_7X30_AXI_LI_GRP_CLK, | ||
| 124 | L_7X30_AXI_LI_JPEG_CLK, | ||
| 125 | L_7X30_AXI_GRP_2D_CLK, | ||
| 126 | L_7X30_AXI_MFC_CLK, | ||
| 127 | L_7X30_AXI_VPE_CLK, | ||
| 128 | L_7X30_AXI_LI_VFE_CLK, | ||
| 129 | L_7X30_AXI_LI_APPS_CLK, | ||
| 130 | L_7X30_AXI_MDP_CLK, | ||
| 131 | L_7X30_AXI_IMEM_CLK, | ||
| 132 | L_7X30_AXI_LI_ADSP_A_CLK, | ||
| 133 | L_7X30_AXI_ROTATOR_CLK, | ||
| 134 | |||
| 135 | L_7X30_NR_CLKS | ||
| 136 | }; | ||
| 137 | |||
| 138 | struct clk_ops; | ||
| 139 | extern struct clk_ops clk_ops_7x30; | ||
| 140 | |||
| 141 | struct clk_ops *clk_7x30_is_local(uint32_t id); | ||
| 142 | int clk_7x30_init(void); | ||
| 143 | |||
| 144 | void pll_enable(uint32_t pll); | ||
| 145 | void pll_disable(uint32_t pll); | ||
| 146 | |||
| 147 | extern int internal_pwr_rail_ctl_auto(unsigned rail_id, bool enable); | ||
| 148 | |||
| 149 | #define CLK_7X30(clk_name, clk_id, clk_dev, clk_flags) { \ | ||
| 150 | .name = clk_name, \ | ||
| 151 | .id = L_7X30_##clk_id, \ | ||
| 152 | .remote_id = P_##clk_id, \ | ||
| 153 | .flags = clk_flags, \ | ||
| 154 | .dev = clk_dev, \ | ||
| 155 | .dbg_name = #clk_id, \ | ||
| 156 | } | ||
| 157 | |||
| 158 | #define CLK_7X30S(clk_name, l_id, r_id, clk_dev, clk_flags) { \ | ||
| 159 | .name = clk_name, \ | ||
| 160 | .id = L_7X30_##l_id, \ | ||
| 161 | .remote_id = P_##r_id, \ | ||
| 162 | .flags = clk_flags, \ | ||
| 163 | .dev = clk_dev, \ | ||
| 164 | .dbg_name = #l_id, \ | ||
| 165 | } | ||
| 166 | |||
| 167 | #endif | ||
| 168 | |||
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c new file mode 100644 index 000000000000..a3b45627eb4a --- /dev/null +++ b/arch/arm/mach-msm/clock-pcom.c | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Google, Inc. | ||
| 3 | * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * | ||
| 5 | * This software is licensed under the terms of the GNU General Public | ||
| 6 | * License version 2, as published by the Free Software Foundation, and | ||
| 7 | * may be copied, distributed, and modified under those terms. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/ctype.h> | ||
| 18 | #include <linux/stddef.h> | ||
| 19 | #include <mach/clk.h> | ||
| 20 | |||
| 21 | #include "proc_comm.h" | ||
| 22 | #include "clock.h" | ||
| 23 | |||
| 24 | /* | ||
| 25 | * glue for the proc_comm interface | ||
| 26 | */ | ||
| 27 | int pc_clk_enable(unsigned id) | ||
| 28 | { | ||
| 29 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); | ||
| 30 | if (rc < 0) | ||
| 31 | return rc; | ||
| 32 | else | ||
| 33 | return (int)id < 0 ? -EINVAL : 0; | ||
| 34 | } | ||
| 35 | |||
| 36 | void pc_clk_disable(unsigned id) | ||
| 37 | { | ||
| 38 | msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); | ||
| 39 | } | ||
| 40 | |||
| 41 | int pc_clk_reset(unsigned id, enum clk_reset_action action) | ||
| 42 | { | ||
| 43 | int rc; | ||
| 44 | |||
| 45 | if (action == CLK_RESET_ASSERT) | ||
| 46 | rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_ASSERT, &id, NULL); | ||
| 47 | else | ||
| 48 | rc = msm_proc_comm(PCOM_CLKCTL_RPC_RESET_DEASSERT, &id, NULL); | ||
| 49 | |||
| 50 | if (rc < 0) | ||
| 51 | return rc; | ||
| 52 | else | ||
| 53 | return (int)id < 0 ? -EINVAL : 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | int pc_clk_set_rate(unsigned id, unsigned rate) | ||
| 57 | { | ||
| 58 | /* The rate _might_ be rounded off to the nearest KHz value by the | ||
| 59 | * remote function. So a return value of 0 doesn't necessarily mean | ||
| 60 | * that the exact rate was set successfully. | ||
| 61 | */ | ||
| 62 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); | ||
| 63 | if (rc < 0) | ||
| 64 | return rc; | ||
| 65 | else | ||
| 66 | return (int)id < 0 ? -EINVAL : 0; | ||
| 67 | } | ||
| 68 | |||
| 69 | int pc_clk_set_min_rate(unsigned id, unsigned rate) | ||
| 70 | { | ||
| 71 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate); | ||
| 72 | if (rc < 0) | ||
| 73 | return rc; | ||
| 74 | else | ||
| 75 | return (int)id < 0 ? -EINVAL : 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | int pc_clk_set_max_rate(unsigned id, unsigned rate) | ||
| 79 | { | ||
| 80 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate); | ||
| 81 | if (rc < 0) | ||
| 82 | return rc; | ||
| 83 | else | ||
| 84 | return (int)id < 0 ? -EINVAL : 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | int pc_clk_set_flags(unsigned id, unsigned flags) | ||
| 88 | { | ||
| 89 | int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags); | ||
| 90 | if (rc < 0) | ||
| 91 | return rc; | ||
| 92 | else | ||
| 93 | return (int)id < 0 ? -EINVAL : 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | unsigned pc_clk_get_rate(unsigned id) | ||
| 97 | { | ||
| 98 | if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) | ||
| 99 | return 0; | ||
| 100 | else | ||
| 101 | return id; | ||
| 102 | } | ||
| 103 | |||
| 104 | unsigned pc_clk_is_enabled(unsigned id) | ||
| 105 | { | ||
| 106 | if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) | ||
| 107 | return 0; | ||
| 108 | else | ||
| 109 | return id; | ||
| 110 | } | ||
| 111 | |||
| 112 | long pc_clk_round_rate(unsigned id, unsigned rate) | ||
| 113 | { | ||
| 114 | |||
| 115 | /* Not really supported; pc_clk_set_rate() does rounding on it's own. */ | ||
| 116 | return rate; | ||
| 117 | } | ||
| 118 | |||
| 119 | struct clk_ops clk_ops_pcom = { | ||
| 120 | .enable = pc_clk_enable, | ||
| 121 | .disable = pc_clk_disable, | ||
| 122 | .auto_off = pc_clk_disable, | ||
| 123 | .reset = pc_clk_reset, | ||
| 124 | .set_rate = pc_clk_set_rate, | ||
| 125 | .set_min_rate = pc_clk_set_min_rate, | ||
| 126 | .set_max_rate = pc_clk_set_max_rate, | ||
| 127 | .set_flags = pc_clk_set_flags, | ||
| 128 | .get_rate = pc_clk_get_rate, | ||
| 129 | .is_enabled = pc_clk_is_enabled, | ||
| 130 | .round_rate = pc_clk_round_rate, | ||
| 131 | }; | ||
diff --git a/arch/arm/mach-msm/clock-pcom.h b/arch/arm/mach-msm/clock-pcom.h new file mode 100644 index 000000000000..17d027b23501 --- /dev/null +++ b/arch/arm/mach-msm/clock-pcom.h | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | /* Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * Redistribution and use in source and binary forms, with or without | ||
| 4 | * modification, are permitted provided that the following conditions are | ||
| 5 | * met: | ||
| 6 | * * Redistributions of source code must retain the above copyright | ||
| 7 | * notice, this list of conditions and the following disclaimer. | ||
| 8 | * * Redistributions in binary form must reproduce the above | ||
| 9 | * copyright notice, this list of conditions and the following | ||
| 10 | * disclaimer in the documentation and/or other materials provided | ||
| 11 | * with the distribution. | ||
| 12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived | ||
| 14 | * from this software without specific prior written permission. | ||
| 15 | * | ||
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H | ||
| 31 | #define __ARCH_ARM_MACH_MSM_CLOCK_PCOM_H | ||
| 32 | |||
| 33 | /* clock IDs used by the modem processor */ | ||
| 34 | |||
| 35 | #define P_ACPU_CLK 0 /* Applications processor clock */ | ||
| 36 | #define P_ADM_CLK 1 /* Applications data mover clock */ | ||
| 37 | #define P_ADSP_CLK 2 /* ADSP clock */ | ||
| 38 | #define P_EBI1_CLK 3 /* External bus interface 1 clock */ | ||
| 39 | #define P_EBI2_CLK 4 /* External bus interface 2 clock */ | ||
| 40 | #define P_ECODEC_CLK 5 /* External CODEC clock */ | ||
| 41 | #define P_EMDH_CLK 6 /* External MDDI host clock */ | ||
| 42 | #define P_GP_CLK 7 /* General purpose clock */ | ||
| 43 | #define P_GRP_3D_CLK 8 /* Graphics clock */ | ||
| 44 | #define P_I2C_CLK 9 /* I2C clock */ | ||
| 45 | #define P_ICODEC_RX_CLK 10 /* Internal CODEX RX clock */ | ||
| 46 | #define P_ICODEC_TX_CLK 11 /* Internal CODEX TX clock */ | ||
| 47 | #define P_IMEM_CLK 12 /* Internal graphics memory clock */ | ||
| 48 | #define P_MDC_CLK 13 /* MDDI client clock */ | ||
| 49 | #define P_MDP_CLK 14 /* Mobile display processor clock */ | ||
| 50 | #define P_PBUS_CLK 15 /* Peripheral bus clock */ | ||
| 51 | #define P_PCM_CLK 16 /* PCM clock */ | ||
| 52 | #define P_PMDH_CLK 17 /* Primary MDDI host clock */ | ||
| 53 | #define P_SDAC_CLK 18 /* Stereo DAC clock */ | ||
| 54 | #define P_SDC1_CLK 19 /* Secure Digital Card clocks */ | ||
| 55 | #define P_SDC1_P_CLK 20 | ||
| 56 | #define P_SDC2_CLK 21 | ||
| 57 | #define P_SDC2_P_CLK 22 | ||
| 58 | #define P_SDC3_CLK 23 | ||
| 59 | #define P_SDC3_P_CLK 24 | ||
| 60 | #define P_SDC4_CLK 25 | ||
| 61 | #define P_SDC4_P_CLK 26 | ||
| 62 | #define P_TSIF_CLK 27 /* Transport Stream Interface clocks */ | ||
| 63 | #define P_TSIF_REF_CLK 28 | ||
| 64 | #define P_TV_DAC_CLK 29 /* TV clocks */ | ||
| 65 | #define P_TV_ENC_CLK 30 | ||
| 66 | #define P_UART1_CLK 31 /* UART clocks */ | ||
| 67 | #define P_UART2_CLK 32 | ||
| 68 | #define P_UART3_CLK 33 | ||
| 69 | #define P_UART1DM_CLK 34 | ||
| 70 | #define P_UART2DM_CLK 35 | ||
| 71 | #define P_USB_HS_CLK 36 /* High speed USB core clock */ | ||
| 72 | #define P_USB_HS_P_CLK 37 /* High speed USB pbus clock */ | ||
| 73 | #define P_USB_OTG_CLK 38 /* Full speed USB clock */ | ||
| 74 | #define P_VDC_CLK 39 /* Video controller clock */ | ||
| 75 | #define P_VFE_MDC_CLK 40 /* Camera / Video Front End clock */ | ||
| 76 | #define P_VFE_CLK 41 /* VFE MDDI client clock */ | ||
| 77 | #define P_MDP_LCDC_PCLK_CLK 42 | ||
| 78 | #define P_MDP_LCDC_PAD_PCLK_CLK 43 | ||
| 79 | #define P_MDP_VSYNC_CLK 44 | ||
| 80 | #define P_SPI_CLK 45 | ||
| 81 | #define P_VFE_AXI_CLK 46 | ||
| 82 | #define P_USB_HS2_CLK 47 /* High speed USB 2 core clock */ | ||
| 83 | #define P_USB_HS2_P_CLK 48 /* High speed USB 2 pbus clock */ | ||
| 84 | #define P_USB_HS3_CLK 49 /* High speed USB 3 core clock */ | ||
| 85 | #define P_USB_HS3_P_CLK 50 /* High speed USB 3 pbus clock */ | ||
| 86 | #define P_GRP_3D_P_CLK 51 /* Graphics pbus clock */ | ||
| 87 | #define P_USB_PHY_CLK 52 /* USB PHY clock */ | ||
| 88 | #define P_USB_HS_CORE_CLK 53 /* High speed USB 1 core clock */ | ||
| 89 | #define P_USB_HS2_CORE_CLK 54 /* High speed USB 2 core clock */ | ||
| 90 | #define P_USB_HS3_CORE_CLK 55 /* High speed USB 3 core clock */ | ||
| 91 | #define P_CAM_M_CLK 56 | ||
| 92 | #define P_CAMIF_PAD_P_CLK 57 | ||
| 93 | #define P_GRP_2D_CLK 58 | ||
| 94 | #define P_GRP_2D_P_CLK 59 | ||
| 95 | #define P_I2S_CLK 60 | ||
| 96 | #define P_JPEG_CLK 61 | ||
| 97 | #define P_JPEG_P_CLK 62 | ||
| 98 | #define P_LPA_CODEC_CLK 63 | ||
| 99 | #define P_LPA_CORE_CLK 64 | ||
| 100 | #define P_LPA_P_CLK 65 | ||
| 101 | #define P_MDC_IO_CLK 66 | ||
| 102 | #define P_MDC_P_CLK 67 | ||
| 103 | #define P_MFC_CLK 68 | ||
| 104 | #define P_MFC_DIV2_CLK 69 | ||
| 105 | #define P_MFC_P_CLK 70 | ||
| 106 | #define P_QUP_I2C_CLK 71 | ||
| 107 | #define P_ROTATOR_IMEM_CLK 72 | ||
| 108 | #define P_ROTATOR_P_CLK 73 | ||
| 109 | #define P_VFE_CAMIF_CLK 74 | ||
| 110 | #define P_VFE_P_CLK 75 | ||
| 111 | #define P_VPE_CLK 76 | ||
| 112 | #define P_I2C_2_CLK 77 | ||
| 113 | #define P_MI2S_CODEC_RX_S_CLK 78 | ||
| 114 | #define P_MI2S_CODEC_RX_M_CLK 79 | ||
| 115 | #define P_MI2S_CODEC_TX_S_CLK 80 | ||
| 116 | #define P_MI2S_CODEC_TX_M_CLK 81 | ||
| 117 | #define P_PMDH_P_CLK 82 | ||
| 118 | #define P_EMDH_P_CLK 83 | ||
| 119 | #define P_SPI_P_CLK 84 | ||
| 120 | #define P_TSIF_P_CLK 85 | ||
| 121 | #define P_MDP_P_CLK 86 | ||
| 122 | #define P_SDAC_M_CLK 87 | ||
| 123 | #define P_MI2S_S_CLK 88 | ||
| 124 | #define P_MI2S_M_CLK 89 | ||
| 125 | #define P_AXI_ROTATOR_CLK 90 | ||
| 126 | #define P_HDMI_CLK 91 | ||
| 127 | #define P_CSI0_CLK 92 | ||
| 128 | #define P_CSI0_VFE_CLK 93 | ||
| 129 | #define P_CSI0_P_CLK 94 | ||
| 130 | #define P_CSI1_CLK 95 | ||
| 131 | #define P_CSI1_VFE_CLK 96 | ||
| 132 | #define P_CSI1_P_CLK 97 | ||
| 133 | #define P_GSBI_CLK 98 | ||
| 134 | #define P_GSBI_P_CLK 99 | ||
| 135 | |||
| 136 | #define P_NR_CLKS 100 | ||
| 137 | |||
| 138 | struct clk_ops; | ||
| 139 | extern struct clk_ops clk_ops_pcom; | ||
| 140 | |||
| 141 | int pc_clk_reset(unsigned id, enum clk_reset_action action); | ||
| 142 | |||
| 143 | #define CLK_PCOM(clk_name, clk_id, clk_dev, clk_flags) { \ | ||
| 144 | .name = clk_name, \ | ||
| 145 | .id = P_##clk_id, \ | ||
| 146 | .remote_id = P_##clk_id, \ | ||
| 147 | .ops = &clk_ops_pcom, \ | ||
| 148 | .flags = clk_flags, \ | ||
| 149 | .dev = clk_dev, \ | ||
| 150 | .dbg_name = #clk_id, \ | ||
| 151 | } | ||
| 152 | |||
| 153 | #endif | ||
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index 3b1ce36f1032..9cb1276ab749 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* arch/arm/mach-msm/clock.c | 1 | /* arch/arm/mach-msm/clock.c |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2007 Google, Inc. | 3 | * Copyright (C) 2007 Google, Inc. |
| 4 | * Copyright (c) 2007 QUALCOMM Incorporated | 4 | * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. |
| 5 | * | 5 | * |
| 6 | * This software is licensed under the terms of the GNU General Public | 6 | * This software is licensed under the terms of the GNU General Public |
| 7 | * License version 2, as published by the Free Software Foundation, and | 7 | * License version 2, as published by the Free Software Foundation, and |
| @@ -22,68 +22,27 @@ | |||
| 22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
| 23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
| 24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
| 25 | #include <linux/debugfs.h> | ||
| 26 | #include <linux/ctype.h> | ||
| 27 | #include <linux/pm_qos_params.h> | ||
| 28 | #include <mach/clk.h> | ||
| 25 | 29 | ||
| 26 | #include "clock.h" | 30 | #include "clock.h" |
| 27 | #include "proc_comm.h" | 31 | #include "proc_comm.h" |
| 32 | #include "clock-7x30.h" | ||
| 28 | 33 | ||
| 29 | static DEFINE_MUTEX(clocks_mutex); | 34 | static DEFINE_MUTEX(clocks_mutex); |
| 30 | static DEFINE_SPINLOCK(clocks_lock); | 35 | static DEFINE_SPINLOCK(clocks_lock); |
| 31 | static LIST_HEAD(clocks); | 36 | static LIST_HEAD(clocks); |
| 37 | struct clk *msm_clocks; | ||
| 38 | unsigned msm_num_clocks; | ||
| 32 | 39 | ||
| 33 | /* | 40 | /* |
| 34 | * glue for the proc_comm interface | 41 | * Bitmap of enabled clocks, excluding ACPU which is always |
| 42 | * enabled | ||
| 35 | */ | 43 | */ |
| 36 | static inline int pc_clk_enable(unsigned id) | 44 | static DECLARE_BITMAP(clock_map_enabled, NR_CLKS); |
| 37 | { | 45 | static DEFINE_SPINLOCK(clock_map_lock); |
| 38 | return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL); | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline void pc_clk_disable(unsigned id) | ||
| 42 | { | ||
| 43 | msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL); | ||
| 44 | } | ||
| 45 | |||
| 46 | static inline int pc_clk_set_rate(unsigned id, unsigned rate) | ||
| 47 | { | ||
| 48 | return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate); | ||
| 49 | } | ||
| 50 | |||
| 51 | static inline int pc_clk_set_min_rate(unsigned id, unsigned rate) | ||
| 52 | { | ||
| 53 | return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate); | ||
| 54 | } | ||
| 55 | |||
| 56 | static inline int pc_clk_set_max_rate(unsigned id, unsigned rate) | ||
| 57 | { | ||
| 58 | return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate); | ||
| 59 | } | ||
| 60 | |||
| 61 | static inline int pc_clk_set_flags(unsigned id, unsigned flags) | ||
| 62 | { | ||
| 63 | return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags); | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline unsigned pc_clk_get_rate(unsigned id) | ||
| 67 | { | ||
| 68 | if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL)) | ||
| 69 | return 0; | ||
| 70 | else | ||
| 71 | return id; | ||
| 72 | } | ||
| 73 | |||
| 74 | static inline unsigned pc_clk_is_enabled(unsigned id) | ||
| 75 | { | ||
| 76 | if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL)) | ||
| 77 | return 0; | ||
| 78 | else | ||
| 79 | return id; | ||
| 80 | } | ||
| 81 | |||
| 82 | static inline int pc_pll_request(unsigned id, unsigned on) | ||
| 83 | { | ||
| 84 | on = !!on; | ||
| 85 | return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on); | ||
| 86 | } | ||
| 87 | 46 | ||
| 88 | /* | 47 | /* |
| 89 | * Standard clock functions defined in include/linux/clk.h | 48 | * Standard clock functions defined in include/linux/clk.h |
| @@ -119,8 +78,12 @@ int clk_enable(struct clk *clk) | |||
| 119 | unsigned long flags; | 78 | unsigned long flags; |
| 120 | spin_lock_irqsave(&clocks_lock, flags); | 79 | spin_lock_irqsave(&clocks_lock, flags); |
| 121 | clk->count++; | 80 | clk->count++; |
| 122 | if (clk->count == 1) | 81 | if (clk->count == 1) { |
| 123 | pc_clk_enable(clk->id); | 82 | clk->ops->enable(clk->id); |
| 83 | spin_lock(&clock_map_lock); | ||
| 84 | clock_map_enabled[BIT_WORD(clk->id)] |= BIT_MASK(clk->id); | ||
| 85 | spin_unlock(&clock_map_lock); | ||
| 86 | } | ||
| 124 | spin_unlock_irqrestore(&clocks_lock, flags); | 87 | spin_unlock_irqrestore(&clocks_lock, flags); |
| 125 | return 0; | 88 | return 0; |
| 126 | } | 89 | } |
| @@ -132,31 +95,54 @@ void clk_disable(struct clk *clk) | |||
| 132 | spin_lock_irqsave(&clocks_lock, flags); | 95 | spin_lock_irqsave(&clocks_lock, flags); |
| 133 | BUG_ON(clk->count == 0); | 96 | BUG_ON(clk->count == 0); |
| 134 | clk->count--; | 97 | clk->count--; |
| 135 | if (clk->count == 0) | 98 | if (clk->count == 0) { |
| 136 | pc_clk_disable(clk->id); | 99 | clk->ops->disable(clk->id); |
| 100 | spin_lock(&clock_map_lock); | ||
| 101 | clock_map_enabled[BIT_WORD(clk->id)] &= ~BIT_MASK(clk->id); | ||
| 102 | spin_unlock(&clock_map_lock); | ||
| 103 | } | ||
| 137 | spin_unlock_irqrestore(&clocks_lock, flags); | 104 | spin_unlock_irqrestore(&clocks_lock, flags); |
| 138 | } | 105 | } |
| 139 | EXPORT_SYMBOL(clk_disable); | 106 | EXPORT_SYMBOL(clk_disable); |
| 140 | 107 | ||
| 108 | int clk_reset(struct clk *clk, enum clk_reset_action action) | ||
| 109 | { | ||
| 110 | if (!clk->ops->reset) | ||
| 111 | clk->ops->reset = &pc_clk_reset; | ||
| 112 | return clk->ops->reset(clk->remote_id, action); | ||
| 113 | } | ||
| 114 | EXPORT_SYMBOL(clk_reset); | ||
| 115 | |||
| 141 | unsigned long clk_get_rate(struct clk *clk) | 116 | unsigned long clk_get_rate(struct clk *clk) |
| 142 | { | 117 | { |
| 143 | return pc_clk_get_rate(clk->id); | 118 | return clk->ops->get_rate(clk->id); |
| 144 | } | 119 | } |
| 145 | EXPORT_SYMBOL(clk_get_rate); | 120 | EXPORT_SYMBOL(clk_get_rate); |
| 146 | 121 | ||
| 147 | int clk_set_rate(struct clk *clk, unsigned long rate) | 122 | int clk_set_rate(struct clk *clk, unsigned long rate) |
| 148 | { | 123 | { |
| 149 | int ret; | 124 | return clk->ops->set_rate(clk->id, rate); |
| 150 | if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) { | ||
| 151 | ret = pc_clk_set_max_rate(clk->id, rate); | ||
| 152 | if (ret) | ||
| 153 | return ret; | ||
| 154 | return pc_clk_set_min_rate(clk->id, rate); | ||
| 155 | } | ||
| 156 | return pc_clk_set_rate(clk->id, rate); | ||
| 157 | } | 125 | } |
| 158 | EXPORT_SYMBOL(clk_set_rate); | 126 | EXPORT_SYMBOL(clk_set_rate); |
| 159 | 127 | ||
| 128 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
| 129 | { | ||
| 130 | return clk->ops->round_rate(clk->id, rate); | ||
| 131 | } | ||
| 132 | EXPORT_SYMBOL(clk_round_rate); | ||
| 133 | |||
| 134 | int clk_set_min_rate(struct clk *clk, unsigned long rate) | ||
| 135 | { | ||
| 136 | return clk->ops->set_min_rate(clk->id, rate); | ||
| 137 | } | ||
| 138 | EXPORT_SYMBOL(clk_set_min_rate); | ||
| 139 | |||
| 140 | int clk_set_max_rate(struct clk *clk, unsigned long rate) | ||
| 141 | { | ||
| 142 | return clk->ops->set_max_rate(clk->id, rate); | ||
| 143 | } | ||
| 144 | EXPORT_SYMBOL(clk_set_max_rate); | ||
| 145 | |||
| 160 | int clk_set_parent(struct clk *clk, struct clk *parent) | 146 | int clk_set_parent(struct clk *clk, struct clk *parent) |
| 161 | { | 147 | { |
| 162 | return -ENOSYS; | 148 | return -ENOSYS; |
| @@ -173,22 +159,153 @@ int clk_set_flags(struct clk *clk, unsigned long flags) | |||
| 173 | { | 159 | { |
| 174 | if (clk == NULL || IS_ERR(clk)) | 160 | if (clk == NULL || IS_ERR(clk)) |
| 175 | return -EINVAL; | 161 | return -EINVAL; |
| 176 | return pc_clk_set_flags(clk->id, flags); | 162 | return clk->ops->set_flags(clk->id, flags); |
| 177 | } | 163 | } |
| 178 | EXPORT_SYMBOL(clk_set_flags); | 164 | EXPORT_SYMBOL(clk_set_flags); |
| 179 | 165 | ||
| 166 | /* EBI1 is the only shared clock that several clients want to vote on as of | ||
| 167 | * this commit. If this changes in the future, then it might be better to | ||
| 168 | * make clk_min_rate handle the voting or make ebi1_clk_set_min_rate more | ||
| 169 | * generic to support different clocks. | ||
| 170 | */ | ||
| 171 | static struct clk *ebi1_clk; | ||
| 180 | 172 | ||
| 181 | void __init msm_clock_init(void) | 173 | static void __init set_clock_ops(struct clk *clk) |
| 174 | { | ||
| 175 | if (!clk->ops) { | ||
| 176 | clk->ops = &clk_ops_pcom; | ||
| 177 | clk->id = clk->remote_id; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 | void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks) | ||
| 182 | { | 182 | { |
| 183 | unsigned n; | 183 | unsigned n; |
| 184 | 184 | ||
| 185 | spin_lock_init(&clocks_lock); | 185 | spin_lock_init(&clocks_lock); |
| 186 | mutex_lock(&clocks_mutex); | 186 | mutex_lock(&clocks_mutex); |
| 187 | for (n = 0; n < msm_num_clocks; n++) | 187 | msm_clocks = clock_tbl; |
| 188 | msm_num_clocks = num_clocks; | ||
| 189 | for (n = 0; n < msm_num_clocks; n++) { | ||
| 190 | set_clock_ops(&msm_clocks[n]); | ||
| 188 | list_add_tail(&msm_clocks[n].list, &clocks); | 191 | list_add_tail(&msm_clocks[n].list, &clocks); |
| 192 | } | ||
| 189 | mutex_unlock(&clocks_mutex); | 193 | mutex_unlock(&clocks_mutex); |
| 194 | |||
| 195 | ebi1_clk = clk_get(NULL, "ebi1_clk"); | ||
| 196 | BUG_ON(ebi1_clk == NULL); | ||
| 197 | |||
| 198 | } | ||
| 199 | |||
| 200 | #if defined(CONFIG_DEBUG_FS) | ||
| 201 | static struct clk *msm_clock_get_nth(unsigned index) | ||
| 202 | { | ||
| 203 | if (index < msm_num_clocks) | ||
| 204 | return msm_clocks + index; | ||
| 205 | else | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | static int clock_debug_rate_set(void *data, u64 val) | ||
| 210 | { | ||
| 211 | struct clk *clock = data; | ||
| 212 | int ret; | ||
| 213 | |||
| 214 | /* Only increases to max rate will succeed, but that's actually good | ||
| 215 | * for debugging purposes. So we don't check for error. */ | ||
| 216 | if (clock->flags & CLK_MAX) | ||
| 217 | clk_set_max_rate(clock, val); | ||
| 218 | if (clock->flags & CLK_MIN) | ||
| 219 | ret = clk_set_min_rate(clock, val); | ||
| 220 | else | ||
| 221 | ret = clk_set_rate(clock, val); | ||
| 222 | if (ret != 0) | ||
| 223 | printk(KERN_ERR "clk_set%s_rate failed (%d)\n", | ||
| 224 | (clock->flags & CLK_MIN) ? "_min" : "", ret); | ||
| 225 | return ret; | ||
| 226 | } | ||
| 227 | |||
| 228 | static int clock_debug_rate_get(void *data, u64 *val) | ||
| 229 | { | ||
| 230 | struct clk *clock = data; | ||
| 231 | *val = clk_get_rate(clock); | ||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | static int clock_debug_enable_set(void *data, u64 val) | ||
| 236 | { | ||
| 237 | struct clk *clock = data; | ||
| 238 | int rc = 0; | ||
| 239 | |||
| 240 | if (val) | ||
| 241 | rc = clock->ops->enable(clock->id); | ||
| 242 | else | ||
| 243 | clock->ops->disable(clock->id); | ||
| 244 | |||
| 245 | return rc; | ||
| 190 | } | 246 | } |
| 191 | 247 | ||
| 248 | static int clock_debug_enable_get(void *data, u64 *val) | ||
| 249 | { | ||
| 250 | struct clk *clock = data; | ||
| 251 | |||
| 252 | *val = clock->ops->is_enabled(clock->id); | ||
| 253 | |||
| 254 | return 0; | ||
| 255 | } | ||
| 256 | |||
| 257 | static int clock_debug_local_get(void *data, u64 *val) | ||
| 258 | { | ||
| 259 | struct clk *clock = data; | ||
| 260 | |||
| 261 | *val = clock->ops != &clk_ops_pcom; | ||
| 262 | |||
| 263 | return 0; | ||
| 264 | } | ||
| 265 | |||
| 266 | DEFINE_SIMPLE_ATTRIBUTE(clock_rate_fops, clock_debug_rate_get, | ||
| 267 | clock_debug_rate_set, "%llu\n"); | ||
| 268 | DEFINE_SIMPLE_ATTRIBUTE(clock_enable_fops, clock_debug_enable_get, | ||
| 269 | clock_debug_enable_set, "%llu\n"); | ||
| 270 | DEFINE_SIMPLE_ATTRIBUTE(clock_local_fops, clock_debug_local_get, | ||
| 271 | NULL, "%llu\n"); | ||
| 272 | |||
| 273 | static int __init clock_debug_init(void) | ||
| 274 | { | ||
| 275 | struct dentry *dent_rate, *dent_enable, *dent_local; | ||
| 276 | struct clk *clock; | ||
| 277 | unsigned n = 0; | ||
| 278 | char temp[50], *ptr; | ||
| 279 | |||
| 280 | dent_rate = debugfs_create_dir("clk_rate", 0); | ||
| 281 | if (IS_ERR(dent_rate)) | ||
| 282 | return PTR_ERR(dent_rate); | ||
| 283 | |||
| 284 | dent_enable = debugfs_create_dir("clk_enable", 0); | ||
| 285 | if (IS_ERR(dent_enable)) | ||
| 286 | return PTR_ERR(dent_enable); | ||
| 287 | |||
| 288 | dent_local = debugfs_create_dir("clk_local", NULL); | ||
| 289 | if (IS_ERR(dent_local)) | ||
| 290 | return PTR_ERR(dent_local); | ||
| 291 | |||
| 292 | while ((clock = msm_clock_get_nth(n++)) != 0) { | ||
| 293 | strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1); | ||
| 294 | for (ptr = temp; *ptr; ptr++) | ||
| 295 | *ptr = tolower(*ptr); | ||
| 296 | debugfs_create_file(temp, 0644, dent_rate, | ||
| 297 | clock, &clock_rate_fops); | ||
| 298 | debugfs_create_file(temp, 0644, dent_enable, | ||
| 299 | clock, &clock_enable_fops); | ||
| 300 | debugfs_create_file(temp, S_IRUGO, dent_local, | ||
| 301 | clock, &clock_local_fops); | ||
| 302 | } | ||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | device_initcall(clock_debug_init); | ||
| 307 | #endif | ||
| 308 | |||
| 192 | /* The bootloader and/or AMSS may have left various clocks enabled. | 309 | /* The bootloader and/or AMSS may have left various clocks enabled. |
| 193 | * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have | 310 | * Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have |
| 194 | * not been explicitly enabled by a clk_enable() call. | 311 | * not been explicitly enabled by a clk_enable() call. |
| @@ -205,7 +322,7 @@ static int __init clock_late_init(void) | |||
| 205 | spin_lock_irqsave(&clocks_lock, flags); | 322 | spin_lock_irqsave(&clocks_lock, flags); |
| 206 | if (!clk->count) { | 323 | if (!clk->count) { |
| 207 | count++; | 324 | count++; |
| 208 | pc_clk_disable(clk->id); | 325 | clk->ops->auto_off(clk->id); |
| 209 | } | 326 | } |
| 210 | spin_unlock_irqrestore(&clocks_lock, flags); | 327 | spin_unlock_irqrestore(&clocks_lock, flags); |
| 211 | } | 328 | } |
| @@ -216,3 +333,4 @@ static int __init clock_late_init(void) | |||
| 216 | } | 333 | } |
| 217 | 334 | ||
| 218 | late_initcall(clock_late_init); | 335 | late_initcall(clock_late_init); |
| 336 | |||
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h index f875e1544e5f..c270b552ed13 100644 --- a/arch/arm/mach-msm/clock.h +++ b/arch/arm/mach-msm/clock.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* arch/arm/mach-msm/clock.h | 1 | /* arch/arm/mach-msm/clock.h |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2007 Google, Inc. | 3 | * Copyright (C) 2007 Google, Inc. |
| 4 | * Copyright (c) 2007 QUALCOMM Incorporated | 4 | * Copyright (c) 2007-2010, Code Aurora Forum. All rights reserved. |
| 5 | * | 5 | * |
| 6 | * This software is licensed under the terms of the GNU General Public | 6 | * This software is licensed under the terms of the GNU General Public |
| 7 | * License version 2, as published by the Free Software Foundation, and | 7 | * License version 2, as published by the Free Software Foundation, and |
| @@ -18,6 +18,10 @@ | |||
| 18 | #define __ARCH_ARM_MACH_MSM_CLOCK_H | 18 | #define __ARCH_ARM_MACH_MSM_CLOCK_H |
| 19 | 19 | ||
| 20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 21 | #include <mach/clk.h> | ||
| 22 | |||
| 23 | #include "clock-pcom.h" | ||
| 24 | #include "clock-7x30.h" | ||
| 21 | 25 | ||
| 22 | #define CLKFLAG_INVERT 0x00000001 | 26 | #define CLKFLAG_INVERT 0x00000001 |
| 23 | #define CLKFLAG_NOINVERT 0x00000002 | 27 | #define CLKFLAG_NOINVERT 0x00000002 |
| @@ -25,14 +29,32 @@ | |||
| 25 | #define CLKFLAG_NORESET 0x00000008 | 29 | #define CLKFLAG_NORESET 0x00000008 |
| 26 | 30 | ||
| 27 | #define CLK_FIRST_AVAILABLE_FLAG 0x00000100 | 31 | #define CLK_FIRST_AVAILABLE_FLAG 0x00000100 |
| 28 | #define CLKFLAG_USE_MIN_MAX_TO_SET 0x00000200 | 32 | #define CLKFLAG_AUTO_OFF 0x00000200 |
| 29 | #define CLKFLAG_AUTO_OFF 0x00000400 | 33 | #define CLKFLAG_MIN 0x00000400 |
| 34 | #define CLKFLAG_MAX 0x00000800 | ||
| 35 | |||
| 36 | struct clk_ops { | ||
| 37 | int (*enable)(unsigned id); | ||
| 38 | void (*disable)(unsigned id); | ||
| 39 | void (*auto_off)(unsigned id); | ||
| 40 | int (*reset)(unsigned id, enum clk_reset_action action); | ||
| 41 | int (*set_rate)(unsigned id, unsigned rate); | ||
| 42 | int (*set_min_rate)(unsigned id, unsigned rate); | ||
| 43 | int (*set_max_rate)(unsigned id, unsigned rate); | ||
| 44 | int (*set_flags)(unsigned id, unsigned flags); | ||
| 45 | unsigned (*get_rate)(unsigned id); | ||
| 46 | unsigned (*is_enabled)(unsigned id); | ||
| 47 | long (*round_rate)(unsigned id, unsigned rate); | ||
| 48 | }; | ||
| 30 | 49 | ||
| 31 | struct clk { | 50 | struct clk { |
| 32 | uint32_t id; | 51 | uint32_t id; |
| 52 | uint32_t remote_id; | ||
| 33 | uint32_t count; | 53 | uint32_t count; |
| 34 | uint32_t flags; | 54 | uint32_t flags; |
| 35 | const char *name; | 55 | const char *name; |
| 56 | struct clk_ops *ops; | ||
| 57 | const char *dbg_name; | ||
| 36 | struct list_head list; | 58 | struct list_head list; |
| 37 | struct device *dev; | 59 | struct device *dev; |
| 38 | }; | 60 | }; |
| @@ -41,8 +63,47 @@ struct clk { | |||
| 41 | #define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) | 63 | #define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) |
| 42 | #define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) | 64 | #define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) |
| 43 | 65 | ||
| 44 | extern struct clk msm_clocks[]; | 66 | #ifdef CONFIG_DEBUG_FS |
| 45 | extern unsigned msm_num_clocks; | 67 | #define CLOCK_DBG_NAME(x) .dbg_name = x, |
| 68 | #else | ||
| 69 | #define CLOCK_DBG_NAME(x) | ||
| 70 | #endif | ||
| 71 | |||
| 72 | #define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \ | ||
| 73 | .name = clk_name, \ | ||
| 74 | .id = clk_id, \ | ||
| 75 | .flags = clk_flags, \ | ||
| 76 | .dev = clk_dev, \ | ||
| 77 | CLOCK_DBG_NAME(#clk_id) \ | ||
| 78 | } | ||
| 79 | |||
| 80 | #define OFF CLKFLAG_AUTO_OFF | ||
| 81 | #define CLK_MIN CLKFLAG_MIN | ||
| 82 | #define CLK_MAX CLKFLAG_MAX | ||
| 83 | #define CLK_MINMAX (CLK_MIN | CLK_MAX) | ||
| 84 | #define NR_CLKS P_NR_CLKS | ||
| 85 | |||
| 86 | enum { | ||
| 87 | PLL_0 = 0, | ||
| 88 | PLL_1, | ||
| 89 | PLL_2, | ||
| 90 | PLL_3, | ||
| 91 | PLL_4, | ||
| 92 | PLL_5, | ||
| 93 | PLL_6, | ||
| 94 | NUM_PLL | ||
| 95 | }; | ||
| 96 | |||
| 97 | enum clkvote_client { | ||
| 98 | CLKVOTE_ACPUCLK = 0, | ||
| 99 | CLKVOTE_PMQOS, | ||
| 100 | CLKVOTE_MAX, | ||
| 101 | }; | ||
| 102 | |||
| 103 | int msm_clock_require_tcxo(unsigned long *reason, int nbits); | ||
| 104 | int msm_clock_get_name(uint32_t id, char *name, uint32_t size); | ||
| 105 | int ebi1_clk_set_min_rate(enum clkvote_client client, unsigned long rate); | ||
| 106 | unsigned long clk_get_max_axi_khz(void); | ||
| 46 | 107 | ||
| 47 | #endif | 108 | #endif |
| 48 | 109 | ||
diff --git a/arch/arm/mach-msm/devices.c b/arch/arm/mach-msm/devices-msm7x00.c index 31b6b30e98bf..fde9d8f69f10 100644 --- a/arch/arm/mach-msm/devices.c +++ b/arch/arm/mach-msm/devices-msm7x00.c | |||
| @@ -24,6 +24,10 @@ | |||
| 24 | #include <linux/mtd/nand.h> | 24 | #include <linux/mtd/nand.h> |
| 25 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
| 26 | 26 | ||
| 27 | |||
| 28 | #include "clock.h" | ||
| 29 | #include <mach/mmc.h> | ||
| 30 | |||
| 27 | static struct resource resources_uart1[] = { | 31 | static struct resource resources_uart1[] = { |
| 28 | { | 32 | { |
| 29 | .start = INT_UART1, | 33 | .start = INT_UART1, |
| @@ -163,8 +167,19 @@ static struct resource resources_sdc1[] = { | |||
| 163 | }, | 167 | }, |
| 164 | { | 168 | { |
| 165 | .start = INT_SDC1_0, | 169 | .start = INT_SDC1_0, |
| 170 | .end = INT_SDC1_0, | ||
| 171 | .flags = IORESOURCE_IRQ, | ||
| 172 | .name = "cmd_irq", | ||
| 173 | }, | ||
| 174 | { | ||
| 175 | .start = INT_SDC1_1, | ||
| 166 | .end = INT_SDC1_1, | 176 | .end = INT_SDC1_1, |
| 167 | .flags = IORESOURCE_IRQ, | 177 | .flags = IORESOURCE_IRQ, |
| 178 | .name = "pio_irq", | ||
| 179 | }, | ||
| 180 | { | ||
| 181 | .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, | ||
| 182 | .name = "status_irq" | ||
| 168 | }, | 183 | }, |
| 169 | { | 184 | { |
| 170 | .start = 8, | 185 | .start = 8, |
| @@ -181,8 +196,19 @@ static struct resource resources_sdc2[] = { | |||
| 181 | }, | 196 | }, |
| 182 | { | 197 | { |
| 183 | .start = INT_SDC2_0, | 198 | .start = INT_SDC2_0, |
| 199 | .end = INT_SDC2_0, | ||
| 200 | .flags = IORESOURCE_IRQ, | ||
| 201 | .name = "cmd_irq", | ||
| 202 | }, | ||
| 203 | { | ||
| 204 | .start = INT_SDC2_1, | ||
| 184 | .end = INT_SDC2_1, | 205 | .end = INT_SDC2_1, |
| 185 | .flags = IORESOURCE_IRQ, | 206 | .flags = IORESOURCE_IRQ, |
| 207 | .name = "pio_irq", | ||
| 208 | }, | ||
| 209 | { | ||
| 210 | .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, | ||
| 211 | .name = "status_irq" | ||
| 186 | }, | 212 | }, |
| 187 | { | 213 | { |
| 188 | .start = 8, | 214 | .start = 8, |
| @@ -199,8 +225,19 @@ static struct resource resources_sdc3[] = { | |||
| 199 | }, | 225 | }, |
| 200 | { | 226 | { |
| 201 | .start = INT_SDC3_0, | 227 | .start = INT_SDC3_0, |
| 228 | .end = INT_SDC3_0, | ||
| 229 | .flags = IORESOURCE_IRQ, | ||
| 230 | .name = "cmd_irq", | ||
| 231 | }, | ||
| 232 | { | ||
| 233 | .start = INT_SDC3_1, | ||
| 202 | .end = INT_SDC3_1, | 234 | .end = INT_SDC3_1, |
| 203 | .flags = IORESOURCE_IRQ, | 235 | .flags = IORESOURCE_IRQ, |
| 236 | .name = "pio_irq", | ||
| 237 | }, | ||
| 238 | { | ||
| 239 | .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, | ||
| 240 | .name = "status_irq" | ||
| 204 | }, | 241 | }, |
| 205 | { | 242 | { |
| 206 | .start = 8, | 243 | .start = 8, |
| @@ -217,8 +254,19 @@ static struct resource resources_sdc4[] = { | |||
| 217 | }, | 254 | }, |
| 218 | { | 255 | { |
| 219 | .start = INT_SDC4_0, | 256 | .start = INT_SDC4_0, |
| 257 | .end = INT_SDC4_0, | ||
| 258 | .flags = IORESOURCE_IRQ, | ||
| 259 | .name = "cmd_irq", | ||
| 260 | }, | ||
| 261 | { | ||
| 262 | .start = INT_SDC4_1, | ||
| 220 | .end = INT_SDC4_1, | 263 | .end = INT_SDC4_1, |
| 221 | .flags = IORESOURCE_IRQ, | 264 | .flags = IORESOURCE_IRQ, |
| 265 | .name = "pio_irq", | ||
| 266 | }, | ||
| 267 | { | ||
| 268 | .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, | ||
| 269 | .name = "status_irq" | ||
| 222 | }, | 270 | }, |
| 223 | { | 271 | { |
| 224 | .start = 8, | 272 | .start = 8, |
| @@ -266,3 +314,80 @@ struct platform_device msm_device_sdc4 = { | |||
| 266 | .coherent_dma_mask = 0xffffffff, | 314 | .coherent_dma_mask = 0xffffffff, |
| 267 | }, | 315 | }, |
| 268 | }; | 316 | }; |
| 317 | |||
| 318 | static struct platform_device *msm_sdcc_devices[] __initdata = { | ||
| 319 | &msm_device_sdc1, | ||
| 320 | &msm_device_sdc2, | ||
| 321 | &msm_device_sdc3, | ||
| 322 | &msm_device_sdc4, | ||
| 323 | }; | ||
| 324 | |||
| 325 | int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat, | ||
| 326 | unsigned int stat_irq, unsigned long stat_irq_flags) | ||
| 327 | { | ||
| 328 | struct platform_device *pdev; | ||
| 329 | struct resource *res; | ||
| 330 | |||
| 331 | if (controller < 1 || controller > 4) | ||
| 332 | return -EINVAL; | ||
| 333 | |||
| 334 | pdev = msm_sdcc_devices[controller-1]; | ||
| 335 | pdev->dev.platform_data = plat; | ||
| 336 | |||
| 337 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq"); | ||
| 338 | if (!res) | ||
| 339 | return -EINVAL; | ||
| 340 | else if (stat_irq) { | ||
| 341 | res->start = res->end = stat_irq; | ||
| 342 | res->flags &= ~IORESOURCE_DISABLED; | ||
| 343 | res->flags |= stat_irq_flags; | ||
| 344 | } | ||
| 345 | |||
| 346 | return platform_device_register(pdev); | ||
| 347 | } | ||
| 348 | |||
| 349 | struct clk msm_clocks_7x01a[] = { | ||
| 350 | CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), | ||
| 351 | CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), | ||
| 352 | CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, 0), | ||
| 353 | CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0), | ||
| 354 | CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), | ||
| 355 | CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF), | ||
| 356 | CLK_PCOM("gp_clk", GP_CLK, NULL, 0), | ||
| 357 | CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, OFF), | ||
| 358 | CLK_PCOM("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), | ||
| 359 | CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), | ||
| 360 | CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), | ||
| 361 | CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), | ||
| 362 | CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), | ||
| 363 | CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), | ||
| 364 | CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0), | ||
| 365 | CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), | ||
| 366 | CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ), | ||
| 367 | CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), | ||
| 368 | CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), | ||
| 369 | CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF), | ||
| 370 | CLK_PCOM("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), | ||
| 371 | CLK_PCOM("sdc_pclk", SDC2_P_CLK, &msm_device_sdc2.dev, OFF), | ||
| 372 | CLK_PCOM("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), | ||
| 373 | CLK_PCOM("sdc_pclk", SDC3_P_CLK, &msm_device_sdc3.dev, OFF), | ||
| 374 | CLK_PCOM("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), | ||
| 375 | CLK_PCOM("sdc_pclk", SDC4_P_CLK, &msm_device_sdc4.dev, OFF), | ||
| 376 | CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0), | ||
| 377 | CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), | ||
| 378 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), | ||
| 379 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), | ||
| 380 | CLK_PCOM("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), | ||
| 381 | CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), | ||
| 382 | CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), | ||
| 383 | CLK_PCOM("uart1dm_clk", UART1DM_CLK, NULL, OFF), | ||
| 384 | CLK_PCOM("uart2dm_clk", UART2DM_CLK, NULL, 0), | ||
| 385 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), | ||
| 386 | CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, &msm_device_hsusb.dev, OFF), | ||
| 387 | CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0), | ||
| 388 | CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF ), | ||
| 389 | CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF), | ||
| 390 | CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), | ||
| 391 | }; | ||
| 392 | |||
| 393 | unsigned msm_num_clocks_7x01a = ARRAY_SIZE(msm_clocks_7x01a); | ||
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c new file mode 100644 index 000000000000..b449e8ad2904 --- /dev/null +++ b/arch/arm/mach-msm/devices-msm7x30.c | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008 Google, Inc. | ||
| 3 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * | ||
| 5 | * This software is licensed under the terms of the GNU General Public | ||
| 6 | * License version 2, as published by the Free Software Foundation, and | ||
| 7 | * may be copied, distributed, and modified under those terms. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | |||
| 19 | #include <linux/dma-mapping.h> | ||
| 20 | #include <mach/irqs.h> | ||
| 21 | #include <mach/msm_iomap.h> | ||
| 22 | #include <mach/dma.h> | ||
| 23 | #include <mach/board.h> | ||
| 24 | |||
| 25 | #include "devices.h" | ||
| 26 | #include "smd_private.h" | ||
| 27 | |||
| 28 | #include <asm/mach/flash.h> | ||
| 29 | |||
| 30 | #include "clock-pcom.h" | ||
| 31 | |||
| 32 | #include <mach/mmc.h> | ||
| 33 | |||
| 34 | static struct resource resources_uart2[] = { | ||
| 35 | { | ||
| 36 | .start = INT_UART2, | ||
| 37 | .end = INT_UART2, | ||
| 38 | .flags = IORESOURCE_IRQ, | ||
| 39 | }, | ||
| 40 | { | ||
| 41 | .start = MSM_UART2_PHYS, | ||
| 42 | .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1, | ||
| 43 | .flags = IORESOURCE_MEM, | ||
| 44 | }, | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct platform_device msm_device_uart2 = { | ||
| 48 | .name = "msm_serial", | ||
| 49 | .id = 1, | ||
| 50 | .num_resources = ARRAY_SIZE(resources_uart2), | ||
| 51 | .resource = resources_uart2, | ||
| 52 | }; | ||
| 53 | |||
| 54 | struct clk msm_clocks_7x30[] = { | ||
| 55 | CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), | ||
| 56 | CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), | ||
| 57 | CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0), | ||
| 58 | CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF), | ||
| 59 | CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN), | ||
| 60 | CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), | ||
| 61 | CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX), | ||
| 62 | CLK_PCOM("emdh_pclk", EMDH_P_CLK, NULL, OFF), | ||
| 63 | CLK_PCOM("gp_clk", GP_CLK, NULL, 0), | ||
| 64 | CLK_PCOM("grp_2d_clk", GRP_2D_CLK, NULL, 0), | ||
| 65 | CLK_PCOM("grp_2d_pclk", GRP_2D_P_CLK, NULL, 0), | ||
| 66 | CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0), | ||
| 67 | CLK_PCOM("grp_pclk", GRP_3D_P_CLK, NULL, 0), | ||
| 68 | CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK, NULL, 0), | ||
| 69 | CLK_PCOM("hdmi_clk", HDMI_CLK, NULL, 0), | ||
| 70 | CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), | ||
| 71 | CLK_PCOM("jpeg_clk", JPEG_CLK, NULL, OFF), | ||
| 72 | CLK_PCOM("jpeg_pclk", JPEG_P_CLK, NULL, OFF), | ||
| 73 | CLK_PCOM("lpa_codec_clk", LPA_CODEC_CLK, NULL, 0), | ||
| 74 | CLK_PCOM("lpa_core_clk", LPA_CORE_CLK, NULL, 0), | ||
| 75 | CLK_PCOM("lpa_pclk", LPA_P_CLK, NULL, 0), | ||
| 76 | CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), | ||
| 77 | CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX), | ||
| 78 | CLK_PCOM("mddi_pclk", PMDH_P_CLK, NULL, 0), | ||
| 79 | CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), | ||
| 80 | CLK_PCOM("mdp_pclk", MDP_P_CLK, NULL, 0), | ||
| 81 | CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0), | ||
| 82 | CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0), | ||
| 83 | CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0), | ||
| 84 | CLK_PCOM("mfc_clk", MFC_CLK, NULL, 0), | ||
| 85 | CLK_PCOM("mfc_div2_clk", MFC_DIV2_CLK, NULL, 0), | ||
| 86 | CLK_PCOM("mfc_pclk", MFC_P_CLK, NULL, 0), | ||
| 87 | CLK_PCOM("mi2s_m_clk", MI2S_M_CLK, NULL, 0), | ||
| 88 | CLK_PCOM("mi2s_s_clk", MI2S_S_CLK, NULL, 0), | ||
| 89 | CLK_PCOM("mi2s_codec_rx_m_clk", MI2S_CODEC_RX_M_CLK, NULL, 0), | ||
| 90 | CLK_PCOM("mi2s_codec_rx_s_clk", MI2S_CODEC_RX_S_CLK, NULL, 0), | ||
| 91 | CLK_PCOM("mi2s_codec_tx_m_clk", MI2S_CODEC_TX_M_CLK, NULL, 0), | ||
| 92 | CLK_PCOM("mi2s_codec_tx_s_clk", MI2S_CODEC_TX_S_CLK, NULL, 0), | ||
| 93 | CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN), | ||
| 94 | CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), | ||
| 95 | CLK_PCOM("rotator_clk", AXI_ROTATOR_CLK, NULL, 0), | ||
| 96 | CLK_PCOM("rotator_imem_clk", ROTATOR_IMEM_CLK, NULL, OFF), | ||
| 97 | CLK_PCOM("rotator_pclk", ROTATOR_P_CLK, NULL, OFF), | ||
| 98 | CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), | ||
| 99 | CLK_PCOM("spi_clk", SPI_CLK, NULL, 0), | ||
| 100 | CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, 0), | ||
| 101 | CLK_7X30S("tv_src_clk", TV_CLK, TV_ENC_CLK, NULL, 0), | ||
| 102 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), | ||
| 103 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), | ||
| 104 | CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), | ||
| 105 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), | ||
| 106 | CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF), | ||
| 107 | CLK_PCOM("usb_hs_core_clk", USB_HS_CORE_CLK, NULL, OFF), | ||
| 108 | CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF), | ||
| 109 | CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF), | ||
| 110 | CLK_PCOM("usb_hs2_core_clk", USB_HS2_CORE_CLK, NULL, OFF), | ||
| 111 | CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF), | ||
| 112 | CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF), | ||
| 113 | CLK_PCOM("usb_hs3_core_clk", USB_HS3_CORE_CLK, NULL, OFF), | ||
| 114 | CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN), | ||
| 115 | CLK_PCOM("vfe_camif_clk", VFE_CAMIF_CLK, NULL, 0), | ||
| 116 | CLK_PCOM("vfe_clk", VFE_CLK, NULL, 0), | ||
| 117 | CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, 0), | ||
| 118 | CLK_PCOM("vfe_pclk", VFE_P_CLK, NULL, OFF), | ||
| 119 | CLK_PCOM("vpe_clk", VPE_CLK, NULL, 0), | ||
| 120 | |||
| 121 | /* 7x30 v2 hardware only. */ | ||
| 122 | CLK_PCOM("csi_clk", CSI0_CLK, NULL, 0), | ||
| 123 | CLK_PCOM("csi_pclk", CSI0_P_CLK, NULL, 0), | ||
| 124 | CLK_PCOM("csi_vfe_clk", CSI0_VFE_CLK, NULL, 0), | ||
| 125 | }; | ||
| 126 | |||
| 127 | unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30); | ||
| 128 | |||
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c new file mode 100644 index 000000000000..4d4a50785e34 --- /dev/null +++ b/arch/arm/mach-msm/devices-qsd8x50.c | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2008 Google, Inc. | ||
| 3 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * | ||
| 5 | * This software is licensed under the terms of the GNU General Public | ||
| 6 | * License version 2, as published by the Free Software Foundation, and | ||
| 7 | * may be copied, distributed, and modified under those terms. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/platform_device.h> | ||
| 18 | |||
| 19 | #include <linux/dma-mapping.h> | ||
| 20 | #include <mach/irqs.h> | ||
| 21 | #include <mach/msm_iomap.h> | ||
| 22 | #include <mach/dma.h> | ||
| 23 | #include <mach/board.h> | ||
| 24 | |||
| 25 | #include "devices.h" | ||
| 26 | |||
| 27 | #include <asm/mach/flash.h> | ||
| 28 | |||
| 29 | #include <mach/mmc.h> | ||
| 30 | |||
| 31 | static struct resource resources_uart3[] = { | ||
| 32 | { | ||
| 33 | .start = INT_UART3, | ||
| 34 | .end = INT_UART3, | ||
| 35 | .flags = IORESOURCE_IRQ, | ||
| 36 | }, | ||
| 37 | { | ||
| 38 | .start = MSM_UART3_PHYS, | ||
| 39 | .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1, | ||
| 40 | .flags = IORESOURCE_MEM, | ||
| 41 | }, | ||
| 42 | }; | ||
| 43 | |||
| 44 | struct platform_device msm_device_uart3 = { | ||
| 45 | .name = "msm_serial", | ||
| 46 | .id = 2, | ||
| 47 | .num_resources = ARRAY_SIZE(resources_uart3), | ||
| 48 | .resource = resources_uart3, | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct clk msm_clocks_8x50[] = { | ||
| 52 | CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), | ||
| 53 | CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, CLK_MIN), | ||
| 54 | CLK_PCOM("ebi2_clk", EBI2_CLK, NULL, 0), | ||
| 55 | CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), | ||
| 56 | CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | CLK_MINMAX), | ||
| 57 | CLK_PCOM("gp_clk", GP_CLK, NULL, 0), | ||
| 58 | CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0), | ||
| 59 | CLK_PCOM("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), | ||
| 60 | CLK_PCOM("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), | ||
| 61 | CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), | ||
| 62 | CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), | ||
| 63 | CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX), | ||
| 64 | CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), | ||
| 65 | CLK_PCOM("mdp_lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, 0), | ||
| 66 | CLK_PCOM("mdp_lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, 0), | ||
| 67 | CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0), | ||
| 68 | CLK_PCOM("pbus_clk", PBUS_CLK, NULL, CLK_MIN), | ||
| 69 | CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), | ||
| 70 | CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), | ||
| 71 | CLK_PCOM("spi_clk", SPI_CLK, NULL, 0), | ||
| 72 | CLK_PCOM("tsif_clk", TSIF_CLK, NULL, 0), | ||
| 73 | CLK_PCOM("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), | ||
| 74 | CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), | ||
| 75 | CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), | ||
| 76 | CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), | ||
| 77 | CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), | ||
| 78 | CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF), | ||
| 79 | CLK_PCOM("usb_otg_clk", USB_OTG_CLK, NULL, 0), | ||
| 80 | CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | CLK_MIN), | ||
| 81 | CLK_PCOM("vfe_clk", VFE_CLK, NULL, OFF), | ||
| 82 | CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), | ||
| 83 | CLK_PCOM("vfe_axi_clk", VFE_AXI_CLK, NULL, OFF), | ||
| 84 | CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, OFF), | ||
| 85 | CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, OFF), | ||
| 86 | CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, OFF), | ||
| 87 | CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, OFF), | ||
| 88 | CLK_PCOM("usb_phy_clk", USB_PHY_CLK, NULL, 0), | ||
| 89 | }; | ||
| 90 | |||
| 91 | unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50); | ||
| 92 | |||
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 0744c4a27d6a..568443e76423 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H | 16 | #ifndef __ARCH_ARM_MACH_MSM_DEVICES_H |
| 17 | #define __ARCH_ARM_MACH_MSM_DEVICES_H | 17 | #define __ARCH_ARM_MACH_MSM_DEVICES_H |
| 18 | 18 | ||
| 19 | #include "clock.h" | ||
| 20 | |||
| 19 | extern struct platform_device msm_device_uart1; | 21 | extern struct platform_device msm_device_uart1; |
| 20 | extern struct platform_device msm_device_uart2; | 22 | extern struct platform_device msm_device_uart2; |
| 21 | extern struct platform_device msm_device_uart3; | 23 | extern struct platform_device msm_device_uart3; |
| @@ -33,4 +35,13 @@ extern struct platform_device msm_device_smd; | |||
| 33 | 35 | ||
| 34 | extern struct platform_device msm_device_nand; | 36 | extern struct platform_device msm_device_nand; |
| 35 | 37 | ||
| 38 | extern struct clk msm_clocks_7x01a[]; | ||
| 39 | extern unsigned msm_num_clocks_7x01a; | ||
| 40 | |||
| 41 | extern struct clk msm_clocks_7x30[]; | ||
| 42 | extern unsigned msm_num_clocks_7x30; | ||
| 43 | |||
| 44 | extern struct clk msm_clocks_8x50[]; | ||
| 45 | extern unsigned msm_num_clocks_8x50; | ||
| 46 | |||
| 36 | #endif | 47 | #endif |
diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index f5420f9585c5..3d725ae518e4 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | * | 13 | * |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/clk.h> | ||
| 17 | #include <linux/err.h> | ||
| 16 | #include <linux/io.h> | 18 | #include <linux/io.h> |
| 17 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 18 | #include <mach/dma.h> | 20 | #include <mach/dma.h> |
| @@ -26,6 +28,7 @@ enum { | |||
| 26 | }; | 28 | }; |
| 27 | 29 | ||
| 28 | static DEFINE_SPINLOCK(msm_dmov_lock); | 30 | static DEFINE_SPINLOCK(msm_dmov_lock); |
| 31 | static struct clk *msm_dmov_clk; | ||
| 29 | static unsigned int channel_active; | 32 | static unsigned int channel_active; |
| 30 | static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; | 33 | static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT]; |
| 31 | static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; | 34 | static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT]; |
| @@ -54,6 +57,9 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) | |||
| 54 | unsigned int status; | 57 | unsigned int status; |
| 55 | 58 | ||
| 56 | spin_lock_irqsave(&msm_dmov_lock, irq_flags); | 59 | spin_lock_irqsave(&msm_dmov_lock, irq_flags); |
| 60 | if (!channel_active) | ||
| 61 | clk_enable(msm_dmov_clk); | ||
| 62 | dsb(); | ||
| 57 | status = readl(DMOV_STATUS(id)); | 63 | status = readl(DMOV_STATUS(id)); |
| 58 | if (list_empty(&ready_commands[id]) && | 64 | if (list_empty(&ready_commands[id]) && |
| 59 | (status & DMOV_STATUS_CMD_PTR_RDY)) { | 65 | (status & DMOV_STATUS_CMD_PTR_RDY)) { |
| @@ -70,6 +76,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd) | |||
| 70 | channel_active |= 1U << id; | 76 | channel_active |= 1U << id; |
| 71 | writel(cmd->cmdptr, DMOV_CMD_PTR(id)); | 77 | writel(cmd->cmdptr, DMOV_CMD_PTR(id)); |
| 72 | } else { | 78 | } else { |
| 79 | if (!channel_active) | ||
| 80 | clk_disable(msm_dmov_clk); | ||
| 73 | if (list_empty(&active_commands[id])) | 81 | if (list_empty(&active_commands[id])) |
| 74 | PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status); | 82 | PRINT_ERROR("msm_dmov_enqueue_cmd(%d), error datamover stalled, status %x\n", id, status); |
| 75 | 83 | ||
| @@ -165,6 +173,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) | |||
| 165 | "for %p, result %x\n", id, cmd, ch_result); | 173 | "for %p, result %x\n", id, cmd, ch_result); |
| 166 | if (cmd) { | 174 | if (cmd) { |
| 167 | list_del(&cmd->list); | 175 | list_del(&cmd->list); |
| 176 | dsb(); | ||
| 168 | cmd->complete_func(cmd, ch_result, NULL); | 177 | cmd->complete_func(cmd, ch_result, NULL); |
| 169 | } | 178 | } |
| 170 | } | 179 | } |
| @@ -181,6 +190,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) | |||
| 181 | PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); | 190 | PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); |
| 182 | if (cmd) { | 191 | if (cmd) { |
| 183 | list_del(&cmd->list); | 192 | list_del(&cmd->list); |
| 193 | dsb(); | ||
| 184 | cmd->complete_func(cmd, ch_result, &errdata); | 194 | cmd->complete_func(cmd, ch_result, &errdata); |
| 185 | } | 195 | } |
| 186 | } | 196 | } |
| @@ -198,6 +208,7 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) | |||
| 198 | PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); | 208 | PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]); |
| 199 | if (cmd) { | 209 | if (cmd) { |
| 200 | list_del(&cmd->list); | 210 | list_del(&cmd->list); |
| 211 | dsb(); | ||
| 201 | cmd->complete_func(cmd, ch_result, &errdata); | 212 | cmd->complete_func(cmd, ch_result, &errdata); |
| 202 | } | 213 | } |
| 203 | /* this does not seem to work, once we get an error */ | 214 | /* this does not seem to work, once we get an error */ |
| @@ -219,8 +230,10 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id) | |||
| 219 | PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); | 230 | PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status); |
| 220 | } | 231 | } |
| 221 | 232 | ||
| 222 | if (!channel_active) | 233 | if (!channel_active) { |
| 223 | disable_irq(INT_ADM_AARM); | 234 | disable_irq_nosync(INT_ADM_AARM); |
| 235 | clk_disable(msm_dmov_clk); | ||
| 236 | } | ||
| 224 | 237 | ||
| 225 | spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); | 238 | spin_unlock_irqrestore(&msm_dmov_lock, irq_flags); |
| 226 | return IRQ_HANDLED; | 239 | return IRQ_HANDLED; |
| @@ -230,11 +243,17 @@ static int __init msm_init_datamover(void) | |||
| 230 | { | 243 | { |
| 231 | int i; | 244 | int i; |
| 232 | int ret; | 245 | int ret; |
| 246 | struct clk *clk; | ||
| 247 | |||
| 233 | for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) { | 248 | for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) { |
| 234 | INIT_LIST_HEAD(&ready_commands[i]); | 249 | INIT_LIST_HEAD(&ready_commands[i]); |
| 235 | INIT_LIST_HEAD(&active_commands[i]); | 250 | INIT_LIST_HEAD(&active_commands[i]); |
| 236 | writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i)); | 251 | writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i)); |
| 237 | } | 252 | } |
| 253 | clk = clk_get(NULL, "adm_clk"); | ||
| 254 | if (IS_ERR(clk)) | ||
| 255 | return PTR_ERR(clk); | ||
| 256 | msm_dmov_clk = clk; | ||
| 238 | ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL); | 257 | ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL); |
| 239 | if (ret) | 258 | if (ret) |
| 240 | return ret; | 259 | return ret; |
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c new file mode 100644 index 000000000000..bc32c845c7b0 --- /dev/null +++ b/arch/arm/mach-msm/gpio.c | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | /* linux/arch/arm/mach-msm/gpio.c | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | ||
| 4 | * Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/module.h> | ||
| 18 | #include <mach/gpio.h> | ||
| 19 | #include "proc_comm.h" | ||
| 20 | |||
| 21 | int gpio_tlmm_config(unsigned config, unsigned disable) | ||
| 22 | { | ||
| 23 | return msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, &disable); | ||
| 24 | } | ||
| 25 | EXPORT_SYMBOL(gpio_tlmm_config); | ||
| 26 | |||
| 27 | int msm_gpios_enable(const struct msm_gpio *table, int size) | ||
| 28 | { | ||
| 29 | int rc; | ||
| 30 | int i; | ||
| 31 | const struct msm_gpio *g; | ||
| 32 | for (i = 0; i < size; i++) { | ||
| 33 | g = table + i; | ||
| 34 | rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE); | ||
| 35 | if (rc) { | ||
| 36 | pr_err("gpio_tlmm_config(0x%08x, GPIO_ENABLE)" | ||
| 37 | " <%s> failed: %d\n", | ||
| 38 | g->gpio_cfg, g->label ?: "?", rc); | ||
| 39 | pr_err("pin %d func %d dir %d pull %d drvstr %d\n", | ||
| 40 | GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg), | ||
| 41 | GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg), | ||
| 42 | GPIO_DRVSTR(g->gpio_cfg)); | ||
| 43 | goto err; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | return 0; | ||
| 47 | err: | ||
| 48 | msm_gpios_disable(table, i); | ||
| 49 | return rc; | ||
| 50 | } | ||
| 51 | EXPORT_SYMBOL(msm_gpios_enable); | ||
| 52 | |||
| 53 | void msm_gpios_disable(const struct msm_gpio *table, int size) | ||
| 54 | { | ||
| 55 | int rc; | ||
| 56 | int i; | ||
| 57 | const struct msm_gpio *g; | ||
| 58 | for (i = size-1; i >= 0; i--) { | ||
| 59 | g = table + i; | ||
| 60 | rc = gpio_tlmm_config(g->gpio_cfg, GPIO_DISABLE); | ||
| 61 | if (rc) { | ||
| 62 | pr_err("gpio_tlmm_config(0x%08x, GPIO_DISABLE)" | ||
| 63 | " <%s> failed: %d\n", | ||
| 64 | g->gpio_cfg, g->label ?: "?", rc); | ||
| 65 | pr_err("pin %d func %d dir %d pull %d drvstr %d\n", | ||
| 66 | GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg), | ||
| 67 | GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg), | ||
| 68 | GPIO_DRVSTR(g->gpio_cfg)); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | } | ||
| 72 | EXPORT_SYMBOL(msm_gpios_disable); | ||
| 73 | |||
| 74 | int msm_gpios_request_enable(const struct msm_gpio *table, int size) | ||
| 75 | { | ||
| 76 | int rc = msm_gpios_enable(table, size); | ||
| 77 | return rc; | ||
| 78 | } | ||
| 79 | EXPORT_SYMBOL(msm_gpios_request_enable); | ||
| 80 | |||
| 81 | void msm_gpios_disable_free(const struct msm_gpio *table, int size) | ||
| 82 | { | ||
| 83 | msm_gpios_disable(table, size); | ||
| 84 | } | ||
| 85 | EXPORT_SYMBOL(msm_gpios_disable_free); | ||
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index 264d62e519f3..e302fbdc439b 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h | |||
| @@ -21,18 +21,24 @@ | |||
| 21 | 21 | ||
| 22 | /* platform device data structures */ | 22 | /* platform device data structures */ |
| 23 | 23 | ||
| 24 | struct msm_mddi_platform_data | 24 | struct msm_acpu_clock_platform_data |
| 25 | { | 25 | { |
| 26 | void (*panel_power)(int on); | 26 | uint32_t acpu_switch_time_us; |
| 27 | unsigned has_vsync_irq:1; | 27 | uint32_t max_speed_delta_khz; |
| 28 | uint32_t vdd_switch_time_us; | ||
| 29 | unsigned long power_collapse_khz; | ||
| 30 | unsigned long wait_for_irq_khz; | ||
| 28 | }; | 31 | }; |
| 29 | 32 | ||
| 33 | struct clk; | ||
| 34 | |||
| 30 | /* common init routines for use by arch/arm/mach-msm/board-*.c */ | 35 | /* common init routines for use by arch/arm/mach-msm/board-*.c */ |
| 31 | 36 | ||
| 32 | void __init msm_add_devices(void); | 37 | void __init msm_add_devices(void); |
| 33 | void __init msm_map_common_io(void); | 38 | void __init msm_map_common_io(void); |
| 34 | void __init msm_init_irq(void); | 39 | void __init msm_init_irq(void); |
| 35 | void __init msm_init_gpio(void); | 40 | void __init msm_init_gpio(void); |
| 36 | void __init msm_clock_init(void); | 41 | void __init msm_clock_init(struct clk *clock_tbl, unsigned num_clocks); |
| 42 | void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *); | ||
| 37 | 43 | ||
| 38 | #endif | 44 | #endif |
diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h new file mode 100644 index 000000000000..c05ca40478c7 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/clk.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * Redistribution and use in source and binary forms, with or without | ||
| 4 | * modification, are permitted provided that the following conditions are | ||
| 5 | * met: | ||
| 6 | * * Redistributions of source code must retain the above copyright | ||
| 7 | * notice, this list of conditions and the following disclaimer. | ||
| 8 | * * Redistributions in binary form must reproduce the above | ||
| 9 | * copyright notice, this list of conditions and the following | ||
| 10 | * disclaimer in the documentation and/or other materials provided | ||
| 11 | * with the distribution. | ||
| 12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived | ||
| 14 | * from this software without specific prior written permission. | ||
| 15 | * | ||
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | #ifndef __MACH_CLK_H | ||
| 30 | #define __MACH_CLK_H | ||
| 31 | |||
| 32 | /* Magic rate value for use with PM QOS to request the board's maximum | ||
| 33 | * supported AXI rate. PM QOS will only pass positive s32 rate values | ||
| 34 | * through to the clock driver, so INT_MAX is used. | ||
| 35 | */ | ||
| 36 | #define MSM_AXI_MAX_FREQ LONG_MAX | ||
| 37 | |||
| 38 | enum clk_reset_action { | ||
| 39 | CLK_RESET_DEASSERT = 0, | ||
| 40 | CLK_RESET_ASSERT = 1 | ||
| 41 | }; | ||
| 42 | |||
| 43 | struct clk; | ||
| 44 | |||
| 45 | /* Rate is minimum clock rate in Hz */ | ||
| 46 | int clk_set_min_rate(struct clk *clk, unsigned long rate); | ||
| 47 | |||
| 48 | /* Rate is maximum clock rate in Hz */ | ||
| 49 | int clk_set_max_rate(struct clk *clk, unsigned long rate); | ||
| 50 | |||
| 51 | /* Assert/Deassert reset to a hardware block associated with a clock */ | ||
| 52 | int clk_reset(struct clk *clk, enum clk_reset_action action); | ||
| 53 | |||
| 54 | /* Set clock-specific configuration parameters */ | ||
| 55 | int clk_set_flags(struct clk *clk, unsigned long flags); | ||
| 56 | |||
| 57 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h index 5ab5bdffab07..04c51cc04f31 100644 --- a/arch/arm/mach-msm/include/mach/dma.h +++ b/arch/arm/mach-msm/include/mach/dma.h | |||
| @@ -41,40 +41,42 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr); | |||
| 41 | #define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) | 41 | #define DMOV_SD2(off, ch) (MSM_DMOV_BASE + 0x0800 + (off) + ((ch) << 2)) |
| 42 | #define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) | 42 | #define DMOV_SD3(off, ch) (MSM_DMOV_BASE + 0x0C00 + (off) + ((ch) << 2)) |
| 43 | 43 | ||
| 44 | /* only security domain 3 is available to the ARM11 | 44 | #if defined(CONFIG_ARCH_MSM7X30) |
| 45 | * SD0 -> mARM trusted, SD1 -> mARM nontrusted, SD2 -> aDSP, SD3 -> aARM | 45 | #define DMOV_SD_AARM DMOV_SD2 |
| 46 | */ | 46 | #else |
| 47 | #define DMOV_SD_AARM DMOV_SD3 | ||
| 48 | #endif | ||
| 47 | 49 | ||
| 48 | #define DMOV_CMD_PTR(ch) DMOV_SD3(0x000, ch) | 50 | #define DMOV_CMD_PTR(ch) DMOV_SD_AARM(0x000, ch) |
| 49 | #define DMOV_CMD_LIST (0 << 29) /* does not work */ | 51 | #define DMOV_CMD_LIST (0 << 29) /* does not work */ |
| 50 | #define DMOV_CMD_PTR_LIST (1 << 29) /* works */ | 52 | #define DMOV_CMD_PTR_LIST (1 << 29) /* works */ |
| 51 | #define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ | 53 | #define DMOV_CMD_INPUT_CFG (2 << 29) /* untested */ |
| 52 | #define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ | 54 | #define DMOV_CMD_OUTPUT_CFG (3 << 29) /* untested */ |
| 53 | #define DMOV_CMD_ADDR(addr) ((addr) >> 3) | 55 | #define DMOV_CMD_ADDR(addr) ((addr) >> 3) |
| 54 | 56 | ||
| 55 | #define DMOV_RSLT(ch) DMOV_SD3(0x040, ch) | 57 | #define DMOV_RSLT(ch) DMOV_SD_AARM(0x040, ch) |
| 56 | #define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ | 58 | #define DMOV_RSLT_VALID (1 << 31) /* 0 == host has empties result fifo */ |
| 57 | #define DMOV_RSLT_ERROR (1 << 3) | 59 | #define DMOV_RSLT_ERROR (1 << 3) |
| 58 | #define DMOV_RSLT_FLUSH (1 << 2) | 60 | #define DMOV_RSLT_FLUSH (1 << 2) |
| 59 | #define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ | 61 | #define DMOV_RSLT_DONE (1 << 1) /* top pointer done */ |
| 60 | #define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ | 62 | #define DMOV_RSLT_USER (1 << 0) /* command with FR force result */ |
| 61 | 63 | ||
| 62 | #define DMOV_FLUSH0(ch) DMOV_SD3(0x080, ch) | 64 | #define DMOV_FLUSH0(ch) DMOV_SD_AARM(0x080, ch) |
| 63 | #define DMOV_FLUSH1(ch) DMOV_SD3(0x0C0, ch) | 65 | #define DMOV_FLUSH1(ch) DMOV_SD_AARM(0x0C0, ch) |
| 64 | #define DMOV_FLUSH2(ch) DMOV_SD3(0x100, ch) | 66 | #define DMOV_FLUSH2(ch) DMOV_SD_AARM(0x100, ch) |
| 65 | #define DMOV_FLUSH3(ch) DMOV_SD3(0x140, ch) | 67 | #define DMOV_FLUSH3(ch) DMOV_SD_AARM(0x140, ch) |
| 66 | #define DMOV_FLUSH4(ch) DMOV_SD3(0x180, ch) | 68 | #define DMOV_FLUSH4(ch) DMOV_SD_AARM(0x180, ch) |
| 67 | #define DMOV_FLUSH5(ch) DMOV_SD3(0x1C0, ch) | 69 | #define DMOV_FLUSH5(ch) DMOV_SD_AARM(0x1C0, ch) |
| 68 | 70 | ||
| 69 | #define DMOV_STATUS(ch) DMOV_SD3(0x200, ch) | 71 | #define DMOV_STATUS(ch) DMOV_SD_AARM(0x200, ch) |
| 70 | #define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) | 72 | #define DMOV_STATUS_RSLT_COUNT(n) (((n) >> 29)) |
| 71 | #define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) | 73 | #define DMOV_STATUS_CMD_COUNT(n) (((n) >> 27) & 3) |
| 72 | #define DMOV_STATUS_RSLT_VALID (1 << 1) | 74 | #define DMOV_STATUS_RSLT_VALID (1 << 1) |
| 73 | #define DMOV_STATUS_CMD_PTR_RDY (1 << 0) | 75 | #define DMOV_STATUS_CMD_PTR_RDY (1 << 0) |
| 74 | 76 | ||
| 75 | #define DMOV_ISR DMOV_SD3(0x380, 0) | 77 | #define DMOV_ISR DMOV_SD_AARM(0x380, 0) |
| 76 | 78 | ||
| 77 | #define DMOV_CONFIG(ch) DMOV_SD3(0x300, ch) | 79 | #define DMOV_CONFIG(ch) DMOV_SD_AARM(0x300, ch) |
| 78 | #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) | 80 | #define DMOV_CONFIG_FORCE_TOP_PTR_RSLT (1 << 2) |
| 79 | #define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1) | 81 | #define DMOV_CONFIG_FORCE_FLUSH_RSLT (1 << 1) |
| 80 | #define DMOV_CONFIG_IRQ_EN (1 << 0) | 82 | #define DMOV_CONFIG_IRQ_EN (1 << 0) |
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h new file mode 100644 index 000000000000..262b441b4374 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/gpio.h | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Google, Inc. | ||
| 3 | * Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Mike Lockwood <lockwood@android.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | #ifndef __ASM_ARCH_MSM_GPIO_H | ||
| 17 | #define __ASM_ARCH_MSM_GPIO_H | ||
| 18 | |||
| 19 | /** | ||
| 20 | * struct msm_gpio - GPIO pin description | ||
| 21 | * @gpio_cfg - configuration bitmap, as per gpio_tlmm_config() | ||
| 22 | * @label - textual label | ||
| 23 | * | ||
| 24 | * Usually, GPIO's are operated by sets. | ||
| 25 | * This struct accumulate all GPIO information in single source | ||
| 26 | * and facilitete group operations provided by msm_gpios_xxx() | ||
| 27 | */ | ||
| 28 | struct msm_gpio { | ||
| 29 | u32 gpio_cfg; | ||
| 30 | const char *label; | ||
| 31 | }; | ||
| 32 | |||
| 33 | /** | ||
| 34 | * msm_gpios_request_enable() - request and enable set of GPIOs | ||
| 35 | * | ||
| 36 | * Request and configure set of GPIO's | ||
| 37 | * In case of error, all operations rolled back. | ||
| 38 | * Return error code. | ||
| 39 | * | ||
| 40 | * @table: GPIO table | ||
| 41 | * @size: number of entries in @table | ||
| 42 | */ | ||
| 43 | int msm_gpios_request_enable(const struct msm_gpio *table, int size); | ||
| 44 | |||
| 45 | /** | ||
| 46 | * msm_gpios_disable_free() - disable and free set of GPIOs | ||
| 47 | * | ||
| 48 | * @table: GPIO table | ||
| 49 | * @size: number of entries in @table | ||
| 50 | */ | ||
| 51 | void msm_gpios_disable_free(const struct msm_gpio *table, int size); | ||
| 52 | |||
| 53 | /** | ||
| 54 | * msm_gpios_request() - request set of GPIOs | ||
| 55 | * In case of error, all operations rolled back. | ||
| 56 | * Return error code. | ||
| 57 | * | ||
| 58 | * @table: GPIO table | ||
| 59 | * @size: number of entries in @table | ||
| 60 | */ | ||
| 61 | int msm_gpios_request(const struct msm_gpio *table, int size); | ||
| 62 | |||
| 63 | /** | ||
| 64 | * msm_gpios_free() - free set of GPIOs | ||
| 65 | * | ||
| 66 | * @table: GPIO table | ||
| 67 | * @size: number of entries in @table | ||
| 68 | */ | ||
| 69 | void msm_gpios_free(const struct msm_gpio *table, int size); | ||
| 70 | |||
| 71 | /** | ||
| 72 | * msm_gpios_enable() - enable set of GPIOs | ||
| 73 | * In case of error, all operations rolled back. | ||
| 74 | * Return error code. | ||
| 75 | * | ||
| 76 | * @table: GPIO table | ||
| 77 | * @size: number of entries in @table | ||
| 78 | */ | ||
| 79 | int msm_gpios_enable(const struct msm_gpio *table, int size); | ||
| 80 | |||
| 81 | /** | ||
| 82 | * msm_gpios_disable() - disable set of GPIOs | ||
| 83 | * | ||
| 84 | * @table: GPIO table | ||
| 85 | * @size: number of entries in @table | ||
| 86 | */ | ||
| 87 | void msm_gpios_disable(const struct msm_gpio *table, int size); | ||
| 88 | |||
| 89 | /* GPIO TLMM (Top Level Multiplexing) Definitions */ | ||
| 90 | |||
| 91 | /* GPIO TLMM: Function -- GPIO specific */ | ||
| 92 | |||
| 93 | /* GPIO TLMM: Direction */ | ||
| 94 | enum { | ||
| 95 | GPIO_INPUT, | ||
| 96 | GPIO_OUTPUT, | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* GPIO TLMM: Pullup/Pulldown */ | ||
| 100 | enum { | ||
| 101 | GPIO_NO_PULL, | ||
| 102 | GPIO_PULL_DOWN, | ||
| 103 | GPIO_KEEPER, | ||
| 104 | GPIO_PULL_UP, | ||
| 105 | }; | ||
| 106 | |||
| 107 | /* GPIO TLMM: Drive Strength */ | ||
| 108 | enum { | ||
| 109 | GPIO_2MA, | ||
| 110 | GPIO_4MA, | ||
| 111 | GPIO_6MA, | ||
| 112 | GPIO_8MA, | ||
| 113 | GPIO_10MA, | ||
| 114 | GPIO_12MA, | ||
| 115 | GPIO_14MA, | ||
| 116 | GPIO_16MA, | ||
| 117 | }; | ||
| 118 | |||
| 119 | enum { | ||
| 120 | GPIO_ENABLE, | ||
| 121 | GPIO_DISABLE, | ||
| 122 | }; | ||
| 123 | |||
| 124 | #define GPIO_CFG(gpio, func, dir, pull, drvstr) \ | ||
| 125 | ((((gpio) & 0x3FF) << 4) | \ | ||
| 126 | ((func) & 0xf) | \ | ||
| 127 | (((dir) & 0x1) << 14) | \ | ||
| 128 | (((pull) & 0x3) << 15) | \ | ||
| 129 | (((drvstr) & 0xF) << 17)) | ||
| 130 | |||
| 131 | /** | ||
| 132 | * extract GPIO pin from bit-field used for gpio_tlmm_config | ||
| 133 | */ | ||
| 134 | #define GPIO_PIN(gpio_cfg) (((gpio_cfg) >> 4) & 0x3ff) | ||
| 135 | #define GPIO_FUNC(gpio_cfg) (((gpio_cfg) >> 0) & 0xf) | ||
| 136 | #define GPIO_DIR(gpio_cfg) (((gpio_cfg) >> 14) & 0x1) | ||
| 137 | #define GPIO_PULL(gpio_cfg) (((gpio_cfg) >> 15) & 0x3) | ||
| 138 | #define GPIO_DRVSTR(gpio_cfg) (((gpio_cfg) >> 17) & 0xf) | ||
| 139 | |||
| 140 | int gpio_tlmm_config(unsigned config, unsigned disable); | ||
| 141 | |||
| 142 | #endif /* __ASM_ARCH_MSM_GPIO_H */ | ||
diff --git a/arch/arm/mach-msm/include/mach/io.h b/arch/arm/mach-msm/include/mach/io.h index aab964591db4..c35b29f9ac0f 100644 --- a/arch/arm/mach-msm/include/mach/io.h +++ b/arch/arm/mach-msm/include/mach/io.h | |||
| @@ -26,4 +26,9 @@ void __iomem *__msm_ioremap(unsigned long phys_addr, size_t size, unsigned int m | |||
| 26 | #define __io(a) __typesafe_io(a) | 26 | #define __io(a) __typesafe_io(a) |
| 27 | #define __mem_pci(a) (a) | 27 | #define __mem_pci(a) (a) |
| 28 | 28 | ||
| 29 | void msm_map_qsd8x50_io(void); | ||
| 30 | void msm_map_msm7x30_io(void); | ||
| 31 | |||
| 32 | extern unsigned int msm_shared_ram_phys; | ||
| 33 | |||
| 29 | #endif | 34 | #endif |
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x00.h b/arch/arm/mach-msm/include/mach/irqs-7x00.h new file mode 100644 index 000000000000..f1fe70612fe9 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/irqs-7x00.h | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Google, Inc. | ||
| 3 | * Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef __ASM_ARCH_MSM_IRQS_7X00_H | ||
| 8 | #define __ASM_ARCH_MSM_IRQS_7X00_H | ||
| 9 | |||
| 10 | /* MSM ARM11 Interrupt Numbers */ | ||
| 11 | /* See 80-VE113-1 A, pp219-221 */ | ||
| 12 | |||
| 13 | #define INT_A9_M2A_0 0 | ||
| 14 | #define INT_A9_M2A_1 1 | ||
| 15 | #define INT_A9_M2A_2 2 | ||
| 16 | #define INT_A9_M2A_3 3 | ||
| 17 | #define INT_A9_M2A_4 4 | ||
| 18 | #define INT_A9_M2A_5 5 | ||
| 19 | #define INT_A9_M2A_6 6 | ||
| 20 | #define INT_GP_TIMER_EXP 7 | ||
| 21 | #define INT_DEBUG_TIMER_EXP 8 | ||
| 22 | #define INT_UART1 9 | ||
| 23 | #define INT_UART2 10 | ||
| 24 | #define INT_UART3 11 | ||
| 25 | #define INT_UART1_RX 12 | ||
| 26 | #define INT_UART2_RX 13 | ||
| 27 | #define INT_UART3_RX 14 | ||
| 28 | #define INT_USB_OTG 15 | ||
| 29 | #define INT_MDDI_PRI 16 | ||
| 30 | #define INT_MDDI_EXT 17 | ||
| 31 | #define INT_MDDI_CLIENT 18 | ||
| 32 | #define INT_MDP 19 | ||
| 33 | #define INT_GRAPHICS 20 | ||
| 34 | #define INT_ADM_AARM 21 | ||
| 35 | #define INT_ADSP_A11 22 | ||
| 36 | #define INT_ADSP_A9_A11 23 | ||
| 37 | #define INT_SDC1_0 24 | ||
| 38 | #define INT_SDC1_1 25 | ||
| 39 | #define INT_SDC2_0 26 | ||
| 40 | #define INT_SDC2_1 27 | ||
| 41 | #define INT_KEYSENSE 28 | ||
| 42 | #define INT_TCHSCRN_SSBI 29 | ||
| 43 | #define INT_TCHSCRN1 30 | ||
| 44 | #define INT_TCHSCRN2 31 | ||
| 45 | |||
| 46 | #define INT_GPIO_GROUP1 (32 + 0) | ||
| 47 | #define INT_GPIO_GROUP2 (32 + 1) | ||
| 48 | #define INT_PWB_I2C (32 + 2) | ||
| 49 | #define INT_SOFTRESET (32 + 3) | ||
| 50 | #define INT_NAND_WR_ER_DONE (32 + 4) | ||
| 51 | #define INT_NAND_OP_DONE (32 + 5) | ||
| 52 | #define INT_PBUS_ARM11 (32 + 6) | ||
| 53 | #define INT_AXI_MPU_SMI (32 + 7) | ||
| 54 | #define INT_AXI_MPU_EBI1 (32 + 8) | ||
| 55 | #define INT_AD_HSSD (32 + 9) | ||
| 56 | #define INT_ARM11_PMU (32 + 10) | ||
| 57 | #define INT_ARM11_DMA (32 + 11) | ||
| 58 | #define INT_TSIF_IRQ (32 + 12) | ||
| 59 | #define INT_UART1DM_IRQ (32 + 13) | ||
| 60 | #define INT_UART1DM_RX (32 + 14) | ||
| 61 | #define INT_USB_HS (32 + 15) | ||
| 62 | #define INT_SDC3_0 (32 + 16) | ||
| 63 | #define INT_SDC3_1 (32 + 17) | ||
| 64 | #define INT_SDC4_0 (32 + 18) | ||
| 65 | #define INT_SDC4_1 (32 + 19) | ||
| 66 | #define INT_UART2DM_RX (32 + 20) | ||
| 67 | #define INT_UART2DM_IRQ (32 + 21) | ||
| 68 | |||
| 69 | /* 22-31 are reserved */ | ||
| 70 | |||
| 71 | #define NR_MSM_IRQS 64 | ||
| 72 | #define NR_GPIO_IRQS 122 | ||
| 73 | #define NR_BOARD_IRQS 64 | ||
| 74 | |||
| 75 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/irqs-7x30.h b/arch/arm/mach-msm/include/mach/irqs-7x30.h new file mode 100644 index 000000000000..67c5396514fe --- /dev/null +++ b/arch/arm/mach-msm/include/mach/irqs-7x30.h | |||
| @@ -0,0 +1,170 @@ | |||
| 1 | /* Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * Redistribution and use in source and binary forms, with or without | ||
| 4 | * modification, are permitted provided that the following conditions are | ||
| 5 | * met: | ||
| 6 | * * Redistributions of source code must retain the above copyright | ||
| 7 | * notice, this list of conditions and the following disclaimer. | ||
| 8 | * * Redistributions in binary form must reproduce the above | ||
| 9 | * copyright notice, this list of conditions and the following | ||
| 10 | * disclaimer in the documentation and/or other materials provided | ||
| 11 | * with the distribution. | ||
| 12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived | ||
| 14 | * from this software without specific prior written permission. | ||
| 15 | * | ||
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef __ASM_ARCH_MSM_IRQS_7X30_H | ||
| 31 | #define __ASM_ARCH_MSM_IRQS_7X30_H | ||
| 32 | |||
| 33 | /* MSM ACPU Interrupt Numbers */ | ||
| 34 | |||
| 35 | #define INT_DEBUG_TIMER_EXP 0 | ||
| 36 | #define INT_GPT0_TIMER_EXP 1 | ||
| 37 | #define INT_GPT1_TIMER_EXP 2 | ||
| 38 | #define INT_WDT0_ACCSCSSBARK 3 | ||
| 39 | #define INT_WDT1_ACCSCSSBARK 4 | ||
| 40 | #define INT_AVS_SVIC 5 | ||
| 41 | #define INT_AVS_SVIC_SW_DONE 6 | ||
| 42 | #define INT_SC_DBG_RX_FULL 7 | ||
| 43 | #define INT_SC_DBG_TX_EMPTY 8 | ||
| 44 | #define INT_ARM11_PM 9 | ||
| 45 | #define INT_AVS_REQ_DOWN 10 | ||
| 46 | #define INT_AVS_REQ_UP 11 | ||
| 47 | #define INT_SC_ACG 12 | ||
| 48 | /* SCSS_VICFIQSTS0[13:15] are RESERVED */ | ||
| 49 | #define INT_L2_SVICCPUIRPTREQ 16 | ||
| 50 | #define INT_L2_SVICDMANSIRPTREQ 17 | ||
| 51 | #define INT_L2_SVICDMASIRPTREQ 18 | ||
| 52 | #define INT_L2_SVICSLVIRPTREQ 19 | ||
| 53 | #define INT_AD5A_MPROC_APPS_0 20 | ||
| 54 | #define INT_AD5A_MPROC_APPS_1 21 | ||
| 55 | #define INT_A9_M2A_0 22 | ||
| 56 | #define INT_A9_M2A_1 23 | ||
| 57 | #define INT_A9_M2A_2 24 | ||
| 58 | #define INT_A9_M2A_3 25 | ||
| 59 | #define INT_A9_M2A_4 26 | ||
| 60 | #define INT_A9_M2A_5 27 | ||
| 61 | #define INT_A9_M2A_6 28 | ||
| 62 | #define INT_A9_M2A_7 29 | ||
| 63 | #define INT_A9_M2A_8 30 | ||
| 64 | #define INT_A9_M2A_9 31 | ||
| 65 | |||
| 66 | #define INT_AXI_EBI1_SC (32 + 0) | ||
| 67 | #define INT_IMEM_ERR (32 + 1) | ||
| 68 | #define INT_AXI_EBI0_SC (32 + 2) | ||
| 69 | #define INT_PBUS_SC_IRQC (32 + 3) | ||
| 70 | #define INT_PERPH_BUS_BPM (32 + 4) | ||
| 71 | #define INT_CC_TEMP_SENSE (32 + 5) | ||
| 72 | #define INT_UXMC_EBI0 (32 + 6) | ||
| 73 | #define INT_UXMC_EBI1 (32 + 7) | ||
| 74 | #define INT_EBI2_OP_DONE (32 + 8) | ||
| 75 | #define INT_EBI2_WR_ER_DONE (32 + 9) | ||
| 76 | #define INT_TCSR_SPSS_CE (32 + 10) | ||
| 77 | #define INT_EMDH (32 + 11) | ||
| 78 | #define INT_PMDH (32 + 12) | ||
| 79 | #define INT_MDC (32 + 13) | ||
| 80 | #define INT_MIDI_TO_SUPSS (32 + 14) | ||
| 81 | #define INT_LPA_2 (32 + 15) | ||
| 82 | #define INT_GPIO_GROUP1_SECURE (32 + 16) | ||
| 83 | #define INT_GPIO_GROUP2_SECURE (32 + 17) | ||
| 84 | #define INT_GPIO_GROUP1 (32 + 18) | ||
| 85 | #define INT_GPIO_GROUP2 (32 + 19) | ||
| 86 | #define INT_MPRPH_SOFTRESET (32 + 20) | ||
| 87 | #define INT_PWB_I2C (32 + 21) | ||
| 88 | #define INT_PWB_I2C_2 (32 + 22) | ||
| 89 | #define INT_TSSC_SAMPLE (32 + 23) | ||
| 90 | #define INT_TSSC_PENUP (32 + 24) | ||
| 91 | #define INT_TCHSCRN_SSBI (32 + 25) | ||
| 92 | #define INT_FM_RDS (32 + 26) | ||
| 93 | #define INT_KEYSENSE (32 + 27) | ||
| 94 | #define INT_USB_OTG_HS (32 + 28) | ||
| 95 | #define INT_USB_OTG_HS2 (32 + 29) | ||
| 96 | #define INT_USB_OTG_HS3 (32 + 30) | ||
| 97 | #define INT_CSI (32 + 31) | ||
| 98 | |||
| 99 | #define INT_SPI_OUTPUT (64 + 0) | ||
| 100 | #define INT_SPI_INPUT (64 + 1) | ||
| 101 | #define INT_SPI_ERROR (64 + 2) | ||
| 102 | #define INT_UART1 (64 + 3) | ||
| 103 | #define INT_UART1_RX (64 + 4) | ||
| 104 | #define INT_UART2 (64 + 5) | ||
| 105 | #define INT_UART2_RX (64 + 6) | ||
| 106 | #define INT_UART3 (64 + 7) | ||
| 107 | #define INT_UART3_RX (64 + 8) | ||
| 108 | #define INT_UART1DM_IRQ (64 + 9) | ||
| 109 | #define INT_UART1DM_RX (64 + 10) | ||
| 110 | #define INT_UART2DM_IRQ (64 + 11) | ||
| 111 | #define INT_UART2DM_RX (64 + 12) | ||
| 112 | #define INT_TSIF (64 + 13) | ||
| 113 | #define INT_ADM_SC1 (64 + 14) | ||
| 114 | #define INT_ADM_SC2 (64 + 15) | ||
| 115 | #define INT_MDP (64 + 16) | ||
| 116 | #define INT_VPE (64 + 17) | ||
| 117 | #define INT_GRP_2D (64 + 18) | ||
| 118 | #define INT_GRP_3D (64 + 19) | ||
| 119 | #define INT_ROTATOR (64 + 20) | ||
| 120 | #define INT_MFC720 (64 + 21) | ||
| 121 | #define INT_JPEG (64 + 22) | ||
| 122 | #define INT_VFE (64 + 23) | ||
| 123 | #define INT_TV_ENC (64 + 24) | ||
| 124 | #define INT_PMIC_SSBI (64 + 25) | ||
| 125 | #define INT_MPM_1 (64 + 26) | ||
| 126 | #define INT_TCSR_SPSS_SAMPLE (64 + 27) | ||
| 127 | #define INT_TCSR_SPSS_PENUP (64 + 28) | ||
| 128 | #define INT_MPM_2 (64 + 29) | ||
| 129 | #define INT_SDC1_0 (64 + 30) | ||
| 130 | #define INT_SDC1_1 (64 + 31) | ||
| 131 | |||
| 132 | #define INT_SDC3_0 (96 + 0) | ||
| 133 | #define INT_SDC3_1 (96 + 1) | ||
| 134 | #define INT_SDC2_0 (96 + 2) | ||
| 135 | #define INT_SDC2_1 (96 + 3) | ||
| 136 | #define INT_SDC4_0 (96 + 4) | ||
| 137 | #define INT_SDC4_1 (96 + 5) | ||
| 138 | #define INT_PWB_QUP_IN (96 + 6) | ||
| 139 | #define INT_PWB_QUP_OUT (96 + 7) | ||
| 140 | #define INT_PWB_QUP_ERR (96 + 8) | ||
| 141 | #define INT_SCSS_WDT0_BITE (96 + 9) | ||
| 142 | /* SCSS_VICFIQSTS3[10:31] are RESERVED */ | ||
| 143 | |||
| 144 | /* Retrofit universal macro names */ | ||
| 145 | #define INT_ADM_AARM INT_ADM_SC2 | ||
| 146 | #define INT_USB_HS INT_USB_OTG_HS | ||
| 147 | #define INT_USB_OTG INT_USB_OTG_HS | ||
| 148 | #define INT_TCHSCRN1 INT_TSSC_SAMPLE | ||
| 149 | #define INT_TCHSCRN2 INT_TSSC_PENUP | ||
| 150 | #define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP | ||
| 151 | #define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0 | ||
| 152 | #define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1 | ||
| 153 | #define INT_MDDI_EXT INT_EMDH | ||
| 154 | #define INT_MDDI_PRI INT_PMDH | ||
| 155 | #define INT_MDDI_CLIENT INT_MDC | ||
| 156 | #define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE | ||
| 157 | #define INT_NAND_OP_DONE INT_EBI2_OP_DONE | ||
| 158 | |||
| 159 | #define NR_MSM_IRQS 128 | ||
| 160 | #define NR_GPIO_IRQS 182 | ||
| 161 | #define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS) | ||
| 162 | #define NR_PMIC8058_GPIO_IRQS 40 | ||
| 163 | #define NR_PMIC8058_MPP_IRQS 12 | ||
| 164 | #define NR_PMIC8058_MISC_IRQS 8 | ||
| 165 | #define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\ | ||
| 166 | NR_PMIC8058_MPP_IRQS +\ | ||
| 167 | NR_PMIC8058_MISC_IRQS) | ||
| 168 | #define NR_BOARD_IRQS NR_PMIC8058_IRQS | ||
| 169 | |||
| 170 | #endif /* __ASM_ARCH_MSM_IRQS_7X30_H */ | ||
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x50.h b/arch/arm/mach-msm/include/mach/irqs-8x50.h new file mode 100644 index 000000000000..de3d8fe24e4e --- /dev/null +++ b/arch/arm/mach-msm/include/mach/irqs-8x50.h | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * Redistribution and use in source and binary forms, with or without | ||
| 4 | * modification, are permitted provided that the following conditions are | ||
| 5 | * met: | ||
| 6 | * * Redistributions of source code must retain the above copyright | ||
| 7 | * notice, this list of conditions and the following disclaimer. | ||
| 8 | * * Redistributions in binary form must reproduce the above | ||
| 9 | * copyright notice, this list of conditions and the following | ||
| 10 | * disclaimer in the documentation and/or other materials provided | ||
| 11 | * with the distribution. | ||
| 12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived | ||
| 14 | * from this software without specific prior written permission. | ||
| 15 | * | ||
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef __ASM_ARCH_MSM_IRQS_8XXX_H | ||
| 31 | #define __ASM_ARCH_MSM_IRQS_8XXX_H | ||
| 32 | |||
| 33 | /* MSM ACPU Interrupt Numbers */ | ||
| 34 | |||
| 35 | #define INT_A9_M2A_0 0 | ||
| 36 | #define INT_A9_M2A_1 1 | ||
| 37 | #define INT_A9_M2A_2 2 | ||
| 38 | #define INT_A9_M2A_3 3 | ||
| 39 | #define INT_A9_M2A_4 4 | ||
| 40 | #define INT_A9_M2A_5 5 | ||
| 41 | #define INT_A9_M2A_6 6 | ||
| 42 | #define INT_GP_TIMER_EXP 7 | ||
| 43 | #define INT_DEBUG_TIMER_EXP 8 | ||
| 44 | #define INT_SIRC_0 9 | ||
| 45 | #define INT_SDC3_0 10 | ||
| 46 | #define INT_SDC3_1 11 | ||
| 47 | #define INT_SDC4_0 12 | ||
| 48 | #define INT_SDC4_1 13 | ||
| 49 | #define INT_AD6_EXT_VFR 14 | ||
| 50 | #define INT_USB_OTG 15 | ||
| 51 | #define INT_MDDI_PRI 16 | ||
| 52 | #define INT_MDDI_EXT 17 | ||
| 53 | #define INT_MDDI_CLIENT 18 | ||
| 54 | #define INT_MDP 19 | ||
| 55 | #define INT_GRAPHICS 20 | ||
| 56 | #define INT_ADM_AARM 21 | ||
| 57 | #define INT_ADSP_A11 22 | ||
| 58 | #define INT_ADSP_A9_A11 23 | ||
| 59 | #define INT_SDC1_0 24 | ||
| 60 | #define INT_SDC1_1 25 | ||
| 61 | #define INT_SDC2_0 26 | ||
| 62 | #define INT_SDC2_1 27 | ||
| 63 | #define INT_KEYSENSE 28 | ||
| 64 | #define INT_TCHSCRN_SSBI 29 | ||
| 65 | #define INT_TCHSCRN1 30 | ||
| 66 | #define INT_TCHSCRN2 31 | ||
| 67 | |||
| 68 | #define INT_TCSR_MPRPH_SC1 (32 + 0) | ||
| 69 | #define INT_USB_FS2 (32 + 1) | ||
| 70 | #define INT_PWB_I2C (32 + 2) | ||
| 71 | #define INT_SOFTRESET (32 + 3) | ||
| 72 | #define INT_NAND_WR_ER_DONE (32 + 4) | ||
| 73 | #define INT_NAND_OP_DONE (32 + 5) | ||
| 74 | #define INT_TCSR_MPRPH_SC2 (32 + 6) | ||
| 75 | #define INT_OP_PEN (32 + 7) | ||
| 76 | #define INT_AD_HSSD (32 + 8) | ||
| 77 | #define INT_ARM11_PM (32 + 9) | ||
| 78 | #define INT_SDMA_NON_SECURE (32 + 10) | ||
| 79 | #define INT_TSIF_IRQ (32 + 11) | ||
| 80 | #define INT_UART1DM_IRQ (32 + 12) | ||
| 81 | #define INT_UART1DM_RX (32 + 13) | ||
| 82 | #define INT_SDMA_SECURE (32 + 14) | ||
| 83 | #define INT_SI2S_SLAVE (32 + 15) | ||
| 84 | #define INT_SC_I2CPU (32 + 16) | ||
| 85 | #define INT_SC_DBG_RDTRFULL (32 + 17) | ||
| 86 | #define INT_SC_DBG_WDTRFULL (32 + 18) | ||
| 87 | #define INT_SCPLL_CTL_DONE (32 + 19) | ||
| 88 | #define INT_UART2DM_IRQ (32 + 20) | ||
| 89 | #define INT_UART2DM_RX (32 + 21) | ||
| 90 | #define INT_VDC_MEC (32 + 22) | ||
| 91 | #define INT_VDC_DB (32 + 23) | ||
| 92 | #define INT_VDC_AXI (32 + 24) | ||
| 93 | #define INT_VFE (32 + 25) | ||
| 94 | #define INT_USB_HS (32 + 26) | ||
| 95 | #define INT_AUDIO_OUT0 (32 + 27) | ||
| 96 | #define INT_AUDIO_OUT1 (32 + 28) | ||
| 97 | #define INT_CRYPTO (32 + 29) | ||
| 98 | #define INT_AD6M_IDLE (32 + 30) | ||
| 99 | #define INT_SIRC_1 (32 + 31) | ||
| 100 | |||
| 101 | #define NR_GPIO_IRQS 165 | ||
| 102 | #define NR_MSM_IRQS 64 | ||
| 103 | #define NR_BOARD_IRQS 64 | ||
| 104 | |||
| 105 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h index 9dd4cf8a2693..164d355c96ea 100644 --- a/arch/arm/mach-msm/include/mach/irqs.h +++ b/arch/arm/mach-msm/include/mach/irqs.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* arch/arm/mach-msm/include/mach/irqs.h | 1 | /* |
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | 2 | * Copyright (C) 2007 Google, Inc. |
| 3 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | 4 | * Author: Brian Swetland <swetland@google.com> |
| 5 | * | 5 | * |
| 6 | * This software is licensed under the terms of the GNU General Public | 6 | * This software is licensed under the terms of the GNU General Public |
| @@ -17,74 +17,21 @@ | |||
| 17 | #ifndef __ASM_ARCH_MSM_IRQS_H | 17 | #ifndef __ASM_ARCH_MSM_IRQS_H |
| 18 | #define __ASM_ARCH_MSM_IRQS_H | 18 | #define __ASM_ARCH_MSM_IRQS_H |
| 19 | 19 | ||
| 20 | /* MSM ARM11 Interrupt Numbers */ | ||
| 21 | /* See 80-VE113-1 A, pp219-221 */ | ||
| 22 | |||
| 23 | #define INT_A9_M2A_0 0 | ||
| 24 | #define INT_A9_M2A_1 1 | ||
| 25 | #define INT_A9_M2A_2 2 | ||
| 26 | #define INT_A9_M2A_3 3 | ||
| 27 | #define INT_A9_M2A_4 4 | ||
| 28 | #define INT_A9_M2A_5 5 | ||
| 29 | #define INT_A9_M2A_6 6 | ||
| 30 | #define INT_GP_TIMER_EXP 7 | ||
| 31 | #define INT_DEBUG_TIMER_EXP 8 | ||
| 32 | #define INT_UART1 9 | ||
| 33 | #define INT_UART2 10 | ||
| 34 | #define INT_UART3 11 | ||
| 35 | #define INT_UART1_RX 12 | ||
| 36 | #define INT_UART2_RX 13 | ||
| 37 | #define INT_UART3_RX 14 | ||
| 38 | #define INT_USB_OTG 15 | ||
| 39 | #define INT_MDDI_PRI 16 | ||
| 40 | #define INT_MDDI_EXT 17 | ||
| 41 | #define INT_MDDI_CLIENT 18 | ||
| 42 | #define INT_MDP 19 | ||
| 43 | #define INT_GRAPHICS 20 | ||
| 44 | #define INT_ADM_AARM 21 | ||
| 45 | #define INT_ADSP_A11 22 | ||
| 46 | #define INT_ADSP_A9_A11 23 | ||
| 47 | #define INT_SDC1_0 24 | ||
| 48 | #define INT_SDC1_1 25 | ||
| 49 | #define INT_SDC2_0 26 | ||
| 50 | #define INT_SDC2_1 27 | ||
| 51 | #define INT_KEYSENSE 28 | ||
| 52 | #define INT_TCHSCRN_SSBI 29 | ||
| 53 | #define INT_TCHSCRN1 30 | ||
| 54 | #define INT_TCHSCRN2 31 | ||
| 55 | |||
| 56 | #define INT_GPIO_GROUP1 (32 + 0) | ||
| 57 | #define INT_GPIO_GROUP2 (32 + 1) | ||
| 58 | #define INT_PWB_I2C (32 + 2) | ||
| 59 | #define INT_SOFTRESET (32 + 3) | ||
| 60 | #define INT_NAND_WR_ER_DONE (32 + 4) | ||
| 61 | #define INT_NAND_OP_DONE (32 + 5) | ||
| 62 | #define INT_PBUS_ARM11 (32 + 6) | ||
| 63 | #define INT_AXI_MPU_SMI (32 + 7) | ||
| 64 | #define INT_AXI_MPU_EBI1 (32 + 8) | ||
| 65 | #define INT_AD_HSSD (32 + 9) | ||
| 66 | #define INT_ARM11_PMU (32 + 10) | ||
| 67 | #define INT_ARM11_DMA (32 + 11) | ||
| 68 | #define INT_TSIF_IRQ (32 + 12) | ||
| 69 | #define INT_UART1DM_IRQ (32 + 13) | ||
| 70 | #define INT_UART1DM_RX (32 + 14) | ||
| 71 | #define INT_USB_HS (32 + 15) | ||
| 72 | #define INT_SDC3_0 (32 + 16) | ||
| 73 | #define INT_SDC3_1 (32 + 17) | ||
| 74 | #define INT_SDC4_0 (32 + 18) | ||
| 75 | #define INT_SDC4_1 (32 + 19) | ||
| 76 | #define INT_UART2DM_RX (32 + 20) | ||
| 77 | #define INT_UART2DM_IRQ (32 + 21) | ||
| 78 | |||
| 79 | /* 22-31 are reserved */ | ||
| 80 | |||
| 81 | #define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) | 20 | #define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) |
| 82 | 21 | ||
| 83 | #define NR_MSM_IRQS 64 | 22 | #if defined(CONFIG_ARCH_MSM7X30) |
| 84 | #define NR_GPIO_IRQS 122 | 23 | #include "irqs-7x30.h" |
| 85 | #define NR_BOARD_IRQS 64 | 24 | #elif defined(CONFIG_ARCH_QSD8X50) |
| 86 | #define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) | 25 | #include "irqs-8x50.h" |
| 26 | #include "sirc.h" | ||
| 27 | #elif defined(CONFIG_ARCH_MSM_ARM11) | ||
| 28 | #include "irqs-7x00.h" | ||
| 29 | #else | ||
| 30 | #error "Unknown architecture specification" | ||
| 31 | #endif | ||
| 87 | 32 | ||
| 33 | #define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) | ||
| 88 | #define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n)) | 34 | #define MSM_GPIO_TO_INT(n) (NR_MSM_IRQS + (n)) |
| 35 | #define MSM_INT_TO_REG(base, irq) (base + irq / 32) | ||
| 89 | 36 | ||
| 90 | #endif | 37 | #endif |
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h index f4698baec976..50c7847e6002 100644 --- a/arch/arm/mach-msm/include/mach/memory.h +++ b/arch/arm/mach-msm/include/mach/memory.h | |||
| @@ -17,7 +17,15 @@ | |||
| 17 | #define __ASM_ARCH_MEMORY_H | 17 | #define __ASM_ARCH_MEMORY_H |
| 18 | 18 | ||
| 19 | /* physical offset of RAM */ | 19 | /* physical offset of RAM */ |
| 20 | #if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A) | ||
| 21 | #define PHYS_OFFSET UL(0x00000000) | ||
| 22 | #elif defined(CONFIG_ARCH_QSD8X50) | ||
| 23 | #define PHYS_OFFSET UL(0x20000000) | ||
| 24 | #elif defined(CONFIG_ARCH_MSM7X30) | ||
| 25 | #define PHYS_OFFSET UL(0x00200000) | ||
| 26 | #else | ||
| 20 | #define PHYS_OFFSET UL(0x10000000) | 27 | #define PHYS_OFFSET UL(0x10000000) |
| 28 | #endif | ||
| 21 | 29 | ||
| 22 | #endif | 30 | #endif |
| 23 | 31 | ||
diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h new file mode 100644 index 000000000000..1f4fc81b3d8f --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_fb.h | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | /* arch/arm/mach-msm/include/mach/msm_fb.h | ||
| 2 | * | ||
| 3 | * Internal shared definitions for various MSM framebuffer parts. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2007 Google Incorporated | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef _MSM_FB_H_ | ||
| 18 | #define _MSM_FB_H_ | ||
| 19 | |||
| 20 | #include <linux/device.h> | ||
| 21 | |||
| 22 | struct mddi_info; | ||
| 23 | |||
| 24 | struct msm_fb_data { | ||
| 25 | int xres; /* x resolution in pixels */ | ||
| 26 | int yres; /* y resolution in pixels */ | ||
| 27 | int width; /* disply width in mm */ | ||
| 28 | int height; /* display height in mm */ | ||
| 29 | unsigned output_format; | ||
| 30 | }; | ||
| 31 | |||
| 32 | struct msmfb_callback { | ||
| 33 | void (*func)(struct msmfb_callback *); | ||
| 34 | }; | ||
| 35 | |||
| 36 | enum { | ||
| 37 | MSM_MDDI_PMDH_INTERFACE, | ||
| 38 | MSM_MDDI_EMDH_INTERFACE, | ||
| 39 | MSM_EBI2_INTERFACE, | ||
| 40 | }; | ||
| 41 | |||
| 42 | #define MSMFB_CAP_PARTIAL_UPDATES (1 << 0) | ||
| 43 | |||
| 44 | struct msm_panel_data { | ||
| 45 | /* turns off the fb memory */ | ||
| 46 | int (*suspend)(struct msm_panel_data *); | ||
| 47 | /* turns on the fb memory */ | ||
| 48 | int (*resume)(struct msm_panel_data *); | ||
| 49 | /* turns off the panel */ | ||
| 50 | int (*blank)(struct msm_panel_data *); | ||
| 51 | /* turns on the panel */ | ||
| 52 | int (*unblank)(struct msm_panel_data *); | ||
| 53 | void (*wait_vsync)(struct msm_panel_data *); | ||
| 54 | void (*request_vsync)(struct msm_panel_data *, struct msmfb_callback *); | ||
| 55 | void (*clear_vsync)(struct msm_panel_data *); | ||
| 56 | /* from the enum above */ | ||
| 57 | unsigned interface_type; | ||
| 58 | /* data to be passed to the fb driver */ | ||
| 59 | struct msm_fb_data *fb_data; | ||
| 60 | |||
| 61 | /* capabilities supported by the panel */ | ||
| 62 | uint32_t caps; | ||
| 63 | }; | ||
| 64 | |||
| 65 | struct msm_mddi_client_data { | ||
| 66 | void (*suspend)(struct msm_mddi_client_data *); | ||
| 67 | void (*resume)(struct msm_mddi_client_data *); | ||
| 68 | void (*activate_link)(struct msm_mddi_client_data *); | ||
| 69 | void (*remote_write)(struct msm_mddi_client_data *, uint32_t val, | ||
| 70 | uint32_t reg); | ||
| 71 | uint32_t (*remote_read)(struct msm_mddi_client_data *, uint32_t reg); | ||
| 72 | void (*auto_hibernate)(struct msm_mddi_client_data *, int); | ||
| 73 | /* custom data that needs to be passed from the board file to a | ||
| 74 | * particular client */ | ||
| 75 | void *private_client_data; | ||
| 76 | struct resource *fb_resource; | ||
| 77 | /* from the list above */ | ||
| 78 | unsigned interface_type; | ||
| 79 | }; | ||
| 80 | |||
| 81 | struct msm_mddi_platform_data { | ||
| 82 | unsigned int clk_rate; | ||
| 83 | void (*power_client)(struct msm_mddi_client_data *, int on); | ||
| 84 | |||
| 85 | /* fixup the mfr name, product id */ | ||
| 86 | void (*fixup)(uint16_t *mfr_name, uint16_t *product_id); | ||
| 87 | |||
| 88 | struct resource *fb_resource; /*optional*/ | ||
| 89 | /* number of clients in the list that follows */ | ||
| 90 | int num_clients; | ||
| 91 | /* array of client information of clients */ | ||
| 92 | struct { | ||
| 93 | unsigned product_id; /* mfr id in top 16 bits, product id | ||
| 94 | * in lower 16 bits | ||
| 95 | */ | ||
| 96 | char *name; /* the device name will be the platform | ||
| 97 | * device name registered for the client, | ||
| 98 | * it should match the name of the associated | ||
| 99 | * driver | ||
| 100 | */ | ||
| 101 | unsigned id; /* id for mddi client device node, will also | ||
| 102 | * be used as device id of panel devices, if | ||
| 103 | * the client device will have multiple panels | ||
| 104 | * space must be left here for them | ||
| 105 | */ | ||
| 106 | void *client_data; /* required private client data */ | ||
| 107 | unsigned int clk_rate; /* optional: if the client requires a | ||
| 108 | * different mddi clk rate | ||
| 109 | */ | ||
| 110 | } client_platform_data[]; | ||
| 111 | }; | ||
| 112 | |||
| 113 | struct mdp_blit_req; | ||
| 114 | struct fb_info; | ||
| 115 | struct mdp_device { | ||
| 116 | struct device dev; | ||
| 117 | void (*dma)(struct mdp_device *mpd, uint32_t addr, | ||
| 118 | uint32_t stride, uint32_t w, uint32_t h, uint32_t x, | ||
| 119 | uint32_t y, struct msmfb_callback *callback, int interface); | ||
| 120 | void (*dma_wait)(struct mdp_device *mdp); | ||
| 121 | int (*blit)(struct mdp_device *mdp, struct fb_info *fb, | ||
| 122 | struct mdp_blit_req *req); | ||
| 123 | void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id); | ||
| 124 | }; | ||
| 125 | |||
| 126 | struct class_interface; | ||
| 127 | int register_mdp_client(struct class_interface *class_intf); | ||
| 128 | |||
| 129 | /**** private client data structs go below this line ***/ | ||
| 130 | |||
| 131 | struct msm_mddi_bridge_platform_data { | ||
| 132 | /* from board file */ | ||
| 133 | int (*init)(struct msm_mddi_bridge_platform_data *, | ||
| 134 | struct msm_mddi_client_data *); | ||
| 135 | int (*uninit)(struct msm_mddi_bridge_platform_data *, | ||
| 136 | struct msm_mddi_client_data *); | ||
| 137 | /* passed to panel for use by the fb driver */ | ||
| 138 | int (*blank)(struct msm_mddi_bridge_platform_data *, | ||
| 139 | struct msm_mddi_client_data *); | ||
| 140 | int (*unblank)(struct msm_mddi_bridge_platform_data *, | ||
| 141 | struct msm_mddi_client_data *); | ||
| 142 | struct msm_fb_data fb_data; | ||
| 143 | }; | ||
| 144 | |||
| 145 | |||
| 146 | |||
| 147 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h new file mode 100644 index 000000000000..cfff0e74f128 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x00.h | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | /* arch/arm/mach-msm/include/mach/msm_iomap.h | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * | ||
| 16 | * The MSM peripherals are spread all over across 768MB of physical | ||
| 17 | * space, which makes just having a simple IO_ADDRESS macro to slide | ||
| 18 | * them into the right virtual location rough. Instead, we will | ||
| 19 | * provide a master phys->virt mapping for peripherals here. | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef __ASM_ARCH_MSM_IOMAP_7X00_H | ||
| 24 | #define __ASM_ARCH_MSM_IOMAP_7X00_H | ||
| 25 | |||
| 26 | #include <asm/sizes.h> | ||
| 27 | |||
| 28 | /* Physical base address and size of peripherals. | ||
| 29 | * Ordered by the virtual base addresses they will be mapped at. | ||
| 30 | * | ||
| 31 | * MSM_VIC_BASE must be an value that can be loaded via a "mov" | ||
| 32 | * instruction, otherwise entry-macro.S will not compile. | ||
| 33 | * | ||
| 34 | * If you add or remove entries here, you'll want to edit the | ||
| 35 | * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your | ||
| 36 | * changes. | ||
| 37 | * | ||
| 38 | */ | ||
| 39 | |||
| 40 | #ifdef __ASSEMBLY__ | ||
| 41 | #define IOMEM(x) x | ||
| 42 | #else | ||
| 43 | #define IOMEM(x) ((void __force __iomem *)(x)) | ||
| 44 | #endif | ||
| 45 | |||
| 46 | #define MSM_VIC_BASE IOMEM(0xE0000000) | ||
| 47 | #define MSM_VIC_PHYS 0xC0000000 | ||
| 48 | #define MSM_VIC_SIZE SZ_4K | ||
| 49 | |||
| 50 | #define MSM_CSR_BASE IOMEM(0xE0001000) | ||
| 51 | #define MSM_CSR_PHYS 0xC0100000 | ||
| 52 | #define MSM_CSR_SIZE SZ_4K | ||
| 53 | |||
| 54 | #define MSM_GPT_PHYS MSM_CSR_PHYS | ||
| 55 | #define MSM_GPT_BASE MSM_CSR_BASE | ||
| 56 | #define MSM_GPT_SIZE SZ_4K | ||
| 57 | |||
| 58 | #define MSM_DMOV_BASE IOMEM(0xE0002000) | ||
| 59 | #define MSM_DMOV_PHYS 0xA9700000 | ||
| 60 | #define MSM_DMOV_SIZE SZ_4K | ||
| 61 | |||
| 62 | #define MSM_GPIO1_BASE IOMEM(0xE0003000) | ||
| 63 | #define MSM_GPIO1_PHYS 0xA9200000 | ||
| 64 | #define MSM_GPIO1_SIZE SZ_4K | ||
| 65 | |||
| 66 | #define MSM_GPIO2_BASE IOMEM(0xE0004000) | ||
| 67 | #define MSM_GPIO2_PHYS 0xA9300000 | ||
| 68 | #define MSM_GPIO2_SIZE SZ_4K | ||
| 69 | |||
| 70 | #define MSM_CLK_CTL_BASE IOMEM(0xE0005000) | ||
| 71 | #define MSM_CLK_CTL_PHYS 0xA8600000 | ||
| 72 | #define MSM_CLK_CTL_SIZE SZ_4K | ||
| 73 | |||
| 74 | #define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) | ||
| 75 | #define MSM_SHARED_RAM_PHYS 0x01F00000 | ||
| 76 | #define MSM_SHARED_RAM_SIZE SZ_1M | ||
| 77 | |||
| 78 | #define MSM_UART1_PHYS 0xA9A00000 | ||
| 79 | #define MSM_UART1_SIZE SZ_4K | ||
| 80 | |||
| 81 | #define MSM_UART2_PHYS 0xA9B00000 | ||
| 82 | #define MSM_UART2_SIZE SZ_4K | ||
| 83 | |||
| 84 | #define MSM_UART3_PHYS 0xA9C00000 | ||
| 85 | #define MSM_UART3_SIZE SZ_4K | ||
| 86 | |||
| 87 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 88 | #define MSM_DEBUG_UART_BASE 0xE1000000 | ||
| 89 | #if CONFIG_MSM_DEBUG_UART == 1 | ||
| 90 | #define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS | ||
| 91 | #elif CONFIG_MSM_DEBUG_UART == 2 | ||
| 92 | #define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS | ||
| 93 | #elif CONFIG_MSM_DEBUG_UART == 3 | ||
| 94 | #define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS | ||
| 95 | #endif | ||
| 96 | #define MSM_DEBUG_UART_SIZE SZ_4K | ||
| 97 | #endif | ||
| 98 | |||
| 99 | #define MSM_SDC1_PHYS 0xA0400000 | ||
| 100 | #define MSM_SDC1_SIZE SZ_4K | ||
| 101 | |||
| 102 | #define MSM_SDC2_PHYS 0xA0500000 | ||
| 103 | #define MSM_SDC2_SIZE SZ_4K | ||
| 104 | |||
| 105 | #define MSM_SDC3_PHYS 0xA0600000 | ||
| 106 | #define MSM_SDC3_SIZE SZ_4K | ||
| 107 | |||
| 108 | #define MSM_SDC4_PHYS 0xA0700000 | ||
| 109 | #define MSM_SDC4_SIZE SZ_4K | ||
| 110 | |||
| 111 | #define MSM_I2C_PHYS 0xA9900000 | ||
| 112 | #define MSM_I2C_SIZE SZ_4K | ||
| 113 | |||
| 114 | #define MSM_HSUSB_PHYS 0xA0800000 | ||
| 115 | #define MSM_HSUSB_SIZE SZ_4K | ||
| 116 | |||
| 117 | #define MSM_PMDH_PHYS 0xAA600000 | ||
| 118 | #define MSM_PMDH_SIZE SZ_4K | ||
| 119 | |||
| 120 | #define MSM_EMDH_PHYS 0xAA700000 | ||
| 121 | #define MSM_EMDH_SIZE SZ_4K | ||
| 122 | |||
| 123 | #define MSM_MDP_PHYS 0xAA200000 | ||
| 124 | #define MSM_MDP_SIZE 0x000F0000 | ||
| 125 | |||
| 126 | #define MSM_MDC_PHYS 0xAA500000 | ||
| 127 | #define MSM_MDC_SIZE SZ_1M | ||
| 128 | |||
| 129 | #define MSM_AD5_PHYS 0xAC000000 | ||
| 130 | #define MSM_AD5_SIZE (SZ_1M*13) | ||
| 131 | |||
| 132 | |||
| 133 | #if defined(CONFIG_ARCH_MSM7X30) | ||
| 134 | #define MSM_GCC_BASE IOMEM(0xF8009000) | ||
| 135 | #define MSM_GCC_PHYS 0xC0182000 | ||
| 136 | #define MSM_GCC_SIZE SZ_4K | ||
| 137 | #endif | ||
| 138 | |||
| 139 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h new file mode 100644 index 000000000000..8a00c2defbc1 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_iomap-7x30.h | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Google, Inc. | ||
| 3 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * | ||
| 16 | * The MSM peripherals are spread all over across 768MB of physical | ||
| 17 | * space, which makes just having a simple IO_ADDRESS macro to slide | ||
| 18 | * them into the right virtual location rough. Instead, we will | ||
| 19 | * provide a master phys->virt mapping for peripherals here. | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef __ASM_ARCH_MSM_IOMAP_7X30_H | ||
| 24 | #define __ASM_ARCH_MSM_IOMAP_7X30_H | ||
| 25 | |||
| 26 | /* Physical base address and size of peripherals. | ||
| 27 | * Ordered by the virtual base addresses they will be mapped at. | ||
| 28 | * | ||
| 29 | * MSM_VIC_BASE must be an value that can be loaded via a "mov" | ||
| 30 | * instruction, otherwise entry-macro.S will not compile. | ||
| 31 | * | ||
| 32 | * If you add or remove entries here, you'll want to edit the | ||
| 33 | * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your | ||
| 34 | * changes. | ||
| 35 | * | ||
| 36 | */ | ||
| 37 | |||
| 38 | #define MSM_VIC_BASE IOMEM(0xE0000000) | ||
| 39 | #define MSM_VIC_PHYS 0xC0080000 | ||
| 40 | #define MSM_VIC_SIZE SZ_4K | ||
| 41 | |||
| 42 | #define MSM_CSR_BASE IOMEM(0xE0001000) | ||
| 43 | #define MSM_CSR_PHYS 0xC0100000 | ||
| 44 | #define MSM_CSR_SIZE SZ_4K | ||
| 45 | |||
| 46 | #define MSM_TMR_PHYS MSM_CSR_PHYS | ||
| 47 | #define MSM_TMR_BASE MSM_CSR_BASE | ||
| 48 | #define MSM_TMR_SIZE SZ_4K | ||
| 49 | |||
| 50 | #define MSM_GPT_BASE (MSM_TMR_BASE + 0x4) | ||
| 51 | #define MSM_DGT_BASE (MSM_TMR_BASE + 0x24) | ||
| 52 | |||
| 53 | #define MSM_DMOV_BASE IOMEM(0xE0002000) | ||
| 54 | #define MSM_DMOV_PHYS 0xAC400000 | ||
| 55 | #define MSM_DMOV_SIZE SZ_4K | ||
| 56 | |||
| 57 | #define MSM_GPIO1_BASE IOMEM(0xE0003000) | ||
| 58 | #define MSM_GPIO1_PHYS 0xAC001000 | ||
| 59 | #define MSM_GPIO1_SIZE SZ_4K | ||
| 60 | |||
| 61 | #define MSM_GPIO2_BASE IOMEM(0xE0004000) | ||
| 62 | #define MSM_GPIO2_PHYS 0xAC101000 | ||
| 63 | #define MSM_GPIO2_SIZE SZ_4K | ||
| 64 | |||
| 65 | #define MSM_CLK_CTL_BASE IOMEM(0xE0005000) | ||
| 66 | #define MSM_CLK_CTL_PHYS 0xAB800000 | ||
| 67 | #define MSM_CLK_CTL_SIZE SZ_4K | ||
| 68 | |||
| 69 | #define MSM_CLK_CTL_SH2_BASE IOMEM(0xE0006000) | ||
| 70 | #define MSM_CLK_CTL_SH2_PHYS 0xABA01000 | ||
| 71 | #define MSM_CLK_CTL_SH2_SIZE SZ_4K | ||
| 72 | |||
| 73 | #define MSM_ACC_BASE IOMEM(0xE0007000) | ||
| 74 | #define MSM_ACC_PHYS 0xC0101000 | ||
| 75 | #define MSM_ACC_SIZE SZ_4K | ||
| 76 | |||
| 77 | #define MSM_SAW_BASE IOMEM(0xE0008000) | ||
| 78 | #define MSM_SAW_PHYS 0xC0102000 | ||
| 79 | #define MSM_SAW_SIZE SZ_4K | ||
| 80 | |||
| 81 | #define MSM_GCC_BASE IOMEM(0xE0009000) | ||
| 82 | #define MSM_GCC_PHYS 0xC0182000 | ||
| 83 | #define MSM_GCC_SIZE SZ_4K | ||
| 84 | |||
| 85 | #define MSM_TCSR_BASE IOMEM(0xE000A000) | ||
| 86 | #define MSM_TCSR_PHYS 0xAB600000 | ||
| 87 | #define MSM_TCSR_SIZE SZ_4K | ||
| 88 | |||
| 89 | #define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) | ||
| 90 | #define MSM_SHARED_RAM_PHYS 0x00100000 | ||
| 91 | #define MSM_SHARED_RAM_SIZE SZ_1M | ||
| 92 | |||
| 93 | #define MSM_UART1_PHYS 0xACA00000 | ||
| 94 | #define MSM_UART1_SIZE SZ_4K | ||
| 95 | |||
| 96 | #define MSM_UART2_PHYS 0xACB00000 | ||
| 97 | #define MSM_UART2_SIZE SZ_4K | ||
| 98 | |||
| 99 | #define MSM_UART3_PHYS 0xACC00000 | ||
| 100 | #define MSM_UART3_SIZE SZ_4K | ||
| 101 | |||
| 102 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 103 | #define MSM_DEBUG_UART_BASE 0xE1000000 | ||
| 104 | #if CONFIG_MSM_DEBUG_UART == 1 | ||
| 105 | #define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS | ||
| 106 | #elif CONFIG_MSM_DEBUG_UART == 2 | ||
| 107 | #define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS | ||
| 108 | #elif CONFIG_MSM_DEBUG_UART == 3 | ||
| 109 | #define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS | ||
| 110 | #endif | ||
| 111 | #define MSM_DEBUG_UART_SIZE SZ_4K | ||
| 112 | #endif | ||
| 113 | |||
| 114 | #define MSM_MDC_BASE IOMEM(0xE0200000) | ||
| 115 | #define MSM_MDC_PHYS 0xAA500000 | ||
| 116 | #define MSM_MDC_SIZE SZ_1M | ||
| 117 | |||
| 118 | #define MSM_AD5_BASE IOMEM(0xE0300000) | ||
| 119 | #define MSM_AD5_PHYS 0xA7000000 | ||
| 120 | #define MSM_AD5_SIZE (SZ_1M*13) | ||
| 121 | |||
| 122 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h new file mode 100644 index 000000000000..acc819eb76e5 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x50.h | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Google, Inc. | ||
| 3 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * | ||
| 16 | * The MSM peripherals are spread all over across 768MB of physical | ||
| 17 | * space, which makes just having a simple IO_ADDRESS macro to slide | ||
| 18 | * them into the right virtual location rough. Instead, we will | ||
| 19 | * provide a master phys->virt mapping for peripherals here. | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #ifndef __ASM_ARCH_MSM_IOMAP_8X50_H | ||
| 24 | #define __ASM_ARCH_MSM_IOMAP_8X50_H | ||
| 25 | |||
| 26 | /* Physical base address and size of peripherals. | ||
| 27 | * Ordered by the virtual base addresses they will be mapped at. | ||
| 28 | * | ||
| 29 | * MSM_VIC_BASE must be an value that can be loaded via a "mov" | ||
| 30 | * instruction, otherwise entry-macro.S will not compile. | ||
| 31 | * | ||
| 32 | * If you add or remove entries here, you'll want to edit the | ||
| 33 | * msm_io_desc array in arch/arm/mach-msm/io.c to reflect your | ||
| 34 | * changes. | ||
| 35 | * | ||
| 36 | */ | ||
| 37 | |||
| 38 | #define MSM_VIC_BASE IOMEM(0xE0000000) | ||
| 39 | #define MSM_VIC_PHYS 0xAC000000 | ||
| 40 | #define MSM_VIC_SIZE SZ_4K | ||
| 41 | |||
| 42 | #define MSM_CSR_BASE IOMEM(0xE0001000) | ||
| 43 | #define MSM_CSR_PHYS 0xAC100000 | ||
| 44 | #define MSM_CSR_SIZE SZ_4K | ||
| 45 | |||
| 46 | #define MSM_TMR_PHYS MSM_CSR_PHYS | ||
| 47 | #define MSM_TMR_BASE MSM_CSR_BASE | ||
| 48 | #define MSM_TMR_SIZE SZ_4K | ||
| 49 | |||
| 50 | #define MSM_GPT_BASE MSM_TMR_BASE | ||
| 51 | #define MSM_DGT_BASE (MSM_TMR_BASE + 0x10) | ||
| 52 | |||
| 53 | #define MSM_DMOV_BASE IOMEM(0xE0002000) | ||
| 54 | #define MSM_DMOV_PHYS 0xA9700000 | ||
| 55 | #define MSM_DMOV_SIZE SZ_4K | ||
| 56 | |||
| 57 | #define MSM_GPIO1_BASE IOMEM(0xE0003000) | ||
| 58 | #define MSM_GPIO1_PHYS 0xA9000000 | ||
| 59 | #define MSM_GPIO1_SIZE SZ_4K | ||
| 60 | |||
| 61 | #define MSM_GPIO2_BASE IOMEM(0xE0004000) | ||
| 62 | #define MSM_GPIO2_PHYS 0xA9100000 | ||
| 63 | #define MSM_GPIO2_SIZE SZ_4K | ||
| 64 | |||
| 65 | #define MSM_CLK_CTL_BASE IOMEM(0xE0005000) | ||
| 66 | #define MSM_CLK_CTL_PHYS 0xA8600000 | ||
| 67 | #define MSM_CLK_CTL_SIZE SZ_4K | ||
| 68 | |||
| 69 | #define MSM_SIRC_BASE IOMEM(0xE1006000) | ||
| 70 | #define MSM_SIRC_PHYS 0xAC200000 | ||
| 71 | #define MSM_SIRC_SIZE SZ_4K | ||
| 72 | |||
| 73 | #define MSM_SCPLL_BASE IOMEM(0xE1007000) | ||
| 74 | #define MSM_SCPLL_PHYS 0xA8800000 | ||
| 75 | #define MSM_SCPLL_SIZE SZ_4K | ||
| 76 | |||
| 77 | #ifdef CONFIG_MSM_SOC_REV_A | ||
| 78 | #define MSM_SMI_BASE 0xE0000000 | ||
| 79 | #else | ||
| 80 | #define MSM_SMI_BASE 0x00000000 | ||
| 81 | #endif | ||
| 82 | |||
| 83 | #define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) | ||
| 84 | #define MSM_SHARED_RAM_PHYS (MSM_SMI_BASE + 0x00100000) | ||
| 85 | #define MSM_SHARED_RAM_SIZE SZ_1M | ||
| 86 | |||
| 87 | #define MSM_UART1_PHYS 0xA9A00000 | ||
| 88 | #define MSM_UART1_SIZE SZ_4K | ||
| 89 | |||
| 90 | #define MSM_UART2_PHYS 0xA9B00000 | ||
| 91 | #define MSM_UART2_SIZE SZ_4K | ||
| 92 | |||
| 93 | #define MSM_UART3_PHYS 0xA9C00000 | ||
| 94 | #define MSM_UART3_SIZE SZ_4K | ||
| 95 | |||
| 96 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 97 | #define MSM_DEBUG_UART_BASE 0xE1000000 | ||
| 98 | #if CONFIG_MSM_DEBUG_UART == 1 | ||
| 99 | #define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS | ||
| 100 | #elif CONFIG_MSM_DEBUG_UART == 2 | ||
| 101 | #define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS | ||
| 102 | #elif CONFIG_MSM_DEBUG_UART == 3 | ||
| 103 | #define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS | ||
| 104 | #endif | ||
| 105 | #define MSM_DEBUG_UART_SIZE SZ_4K | ||
| 106 | #endif | ||
| 107 | |||
| 108 | #define MSM_MDC_BASE IOMEM(0xE0200000) | ||
| 109 | #define MSM_MDC_PHYS 0xAA500000 | ||
| 110 | #define MSM_MDC_SIZE SZ_1M | ||
| 111 | |||
| 112 | #define MSM_AD5_BASE IOMEM(0xE0300000) | ||
| 113 | #define MSM_AD5_PHYS 0xAC000000 | ||
| 114 | #define MSM_AD5_SIZE (SZ_1M*13) | ||
| 115 | |||
| 116 | |||
| 117 | #define MSM_I2C_SIZE SZ_4K | ||
| 118 | #define MSM_I2C_PHYS 0xA9900000 | ||
| 119 | |||
| 120 | #define MSM_HSUSB_PHYS 0xA0800000 | ||
| 121 | #define MSM_HSUSB_SIZE SZ_1K | ||
| 122 | |||
| 123 | #define MSM_NAND_PHYS 0xA0A00000 | ||
| 124 | |||
| 125 | |||
| 126 | #define MSM_TSIF_PHYS (0xa0100000) | ||
| 127 | #define MSM_TSIF_SIZE (0x200) | ||
| 128 | |||
| 129 | #define MSM_TSSC_PHYS 0xAA300000 | ||
| 130 | |||
| 131 | #define MSM_UART1DM_PHYS 0xA0200000 | ||
| 132 | #define MSM_UART2DM_PHYS 0xA0900000 | ||
| 133 | |||
| 134 | |||
| 135 | #define MSM_SDC1_PHYS 0xA0400000 | ||
| 136 | #define MSM_SDC1_SIZE SZ_4K | ||
| 137 | |||
| 138 | #define MSM_SDC2_PHYS 0xA0500000 | ||
| 139 | #define MSM_SDC2_SIZE SZ_4K | ||
| 140 | |||
| 141 | #define MSM_SDC3_PHYS 0xA0600000 | ||
| 142 | #define MSM_SDC3_SIZE SZ_4K | ||
| 143 | |||
| 144 | #define MSM_SDC4_PHYS 0xA0700000 | ||
| 145 | #define MSM_SDC4_SIZE SZ_4K | ||
| 146 | |||
| 147 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h index 9dae1a98c77a..e6b1821cc4ea 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* arch/arm/mach-msm/include/mach/msm_iomap.h | 1 | /* |
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | 2 | * Copyright (C) 2007 Google, Inc. |
| 3 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | 4 | * Author: Brian Swetland <swetland@google.com> |
| 5 | * | 5 | * |
| 6 | * This software is licensed under the terms of the GNU General Public | 6 | * This software is licensed under the terms of the GNU General Public |
| @@ -43,91 +43,12 @@ | |||
| 43 | #define IOMEM(x) ((void __force __iomem *)(x)) | 43 | #define IOMEM(x) ((void __force __iomem *)(x)) |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | #define MSM_VIC_BASE IOMEM(0xE0000000) | 46 | #if defined(CONFIG_ARCH_MSM7X30) |
| 47 | #define MSM_VIC_PHYS 0xC0000000 | 47 | #include "msm_iomap-7x30.h" |
| 48 | #define MSM_VIC_SIZE SZ_4K | 48 | #elif defined(CONFIG_ARCH_QSD8X50) |
| 49 | 49 | #include "msm_iomap-8x50.h" | |
| 50 | #define MSM_CSR_BASE IOMEM(0xE0001000) | 50 | #else |
| 51 | #define MSM_CSR_PHYS 0xC0100000 | 51 | #include "msm_iomap-7x00.h" |
| 52 | #define MSM_CSR_SIZE SZ_4K | ||
| 53 | |||
| 54 | #define MSM_GPT_PHYS MSM_CSR_PHYS | ||
| 55 | #define MSM_GPT_BASE MSM_CSR_BASE | ||
| 56 | #define MSM_GPT_SIZE SZ_4K | ||
| 57 | |||
| 58 | #define MSM_DMOV_BASE IOMEM(0xE0002000) | ||
| 59 | #define MSM_DMOV_PHYS 0xA9700000 | ||
| 60 | #define MSM_DMOV_SIZE SZ_4K | ||
| 61 | |||
| 62 | #define MSM_GPIO1_BASE IOMEM(0xE0003000) | ||
| 63 | #define MSM_GPIO1_PHYS 0xA9200000 | ||
| 64 | #define MSM_GPIO1_SIZE SZ_4K | ||
| 65 | |||
| 66 | #define MSM_GPIO2_BASE IOMEM(0xE0004000) | ||
| 67 | #define MSM_GPIO2_PHYS 0xA9300000 | ||
| 68 | #define MSM_GPIO2_SIZE SZ_4K | ||
| 69 | |||
| 70 | #define MSM_CLK_CTL_BASE IOMEM(0xE0005000) | ||
| 71 | #define MSM_CLK_CTL_PHYS 0xA8600000 | ||
| 72 | #define MSM_CLK_CTL_SIZE SZ_4K | ||
| 73 | |||
| 74 | #define MSM_SHARED_RAM_BASE IOMEM(0xE0100000) | ||
| 75 | #define MSM_SHARED_RAM_PHYS 0x01F00000 | ||
| 76 | #define MSM_SHARED_RAM_SIZE SZ_1M | ||
| 77 | |||
| 78 | #define MSM_UART1_PHYS 0xA9A00000 | ||
| 79 | #define MSM_UART1_SIZE SZ_4K | ||
| 80 | |||
| 81 | #define MSM_UART2_PHYS 0xA9B00000 | ||
| 82 | #define MSM_UART2_SIZE SZ_4K | ||
| 83 | |||
| 84 | #define MSM_UART3_PHYS 0xA9C00000 | ||
| 85 | #define MSM_UART3_SIZE SZ_4K | ||
| 86 | |||
| 87 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 88 | #define MSM_DEBUG_UART_BASE 0xE1000000 | ||
| 89 | #if CONFIG_MSM_DEBUG_UART == 1 | ||
| 90 | #define MSM_DEBUG_UART_PHYS MSM_UART1_PHYS | ||
| 91 | #elif CONFIG_MSM_DEBUG_UART == 2 | ||
| 92 | #define MSM_DEBUG_UART_PHYS MSM_UART2_PHYS | ||
| 93 | #elif CONFIG_MSM_DEBUG_UART == 3 | ||
| 94 | #define MSM_DEBUG_UART_PHYS MSM_UART3_PHYS | ||
| 95 | #endif | ||
| 96 | #define MSM_DEBUG_UART_SIZE SZ_4K | ||
| 97 | #endif | 52 | #endif |
| 98 | 53 | ||
| 99 | #define MSM_SDC1_PHYS 0xA0400000 | ||
| 100 | #define MSM_SDC1_SIZE SZ_4K | ||
| 101 | |||
| 102 | #define MSM_SDC2_PHYS 0xA0500000 | ||
| 103 | #define MSM_SDC2_SIZE SZ_4K | ||
| 104 | |||
| 105 | #define MSM_SDC3_PHYS 0xA0600000 | ||
| 106 | #define MSM_SDC3_SIZE SZ_4K | ||
| 107 | |||
| 108 | #define MSM_SDC4_PHYS 0xA0700000 | ||
| 109 | #define MSM_SDC4_SIZE SZ_4K | ||
| 110 | |||
| 111 | #define MSM_I2C_PHYS 0xA9900000 | ||
| 112 | #define MSM_I2C_SIZE SZ_4K | ||
| 113 | |||
| 114 | #define MSM_HSUSB_PHYS 0xA0800000 | ||
| 115 | #define MSM_HSUSB_SIZE SZ_4K | ||
| 116 | |||
| 117 | #define MSM_PMDH_PHYS 0xAA600000 | ||
| 118 | #define MSM_PMDH_SIZE SZ_4K | ||
| 119 | |||
| 120 | #define MSM_EMDH_PHYS 0xAA700000 | ||
| 121 | #define MSM_EMDH_SIZE SZ_4K | ||
| 122 | |||
| 123 | #define MSM_MDP_PHYS 0xAA200000 | ||
| 124 | #define MSM_MDP_SIZE 0x000F0000 | ||
| 125 | |||
| 126 | #define MSM_MDC_PHYS 0xAA500000 | ||
| 127 | #define MSM_MDC_SIZE SZ_1M | ||
| 128 | |||
| 129 | #define MSM_AD5_PHYS 0xAC000000 | ||
| 130 | #define MSM_AD5_SIZE (SZ_1M*13) | ||
| 131 | |||
| 132 | |||
| 133 | #endif | 54 | #endif |
diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h new file mode 100644 index 000000000000..029463ec8756 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/msm_smd.h | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | /* linux/include/asm-arm/arch-msm/msm_smd.h | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #ifndef __ASM_ARCH_MSM_SMD_H | ||
| 18 | #define __ASM_ARCH_MSM_SMD_H | ||
| 19 | |||
| 20 | typedef struct smd_channel smd_channel_t; | ||
| 21 | |||
| 22 | extern int (*msm_check_for_modem_crash)(void); | ||
| 23 | |||
| 24 | /* warning: notify() may be called before open returns */ | ||
| 25 | int smd_open(const char *name, smd_channel_t **ch, void *priv, | ||
| 26 | void (*notify)(void *priv, unsigned event)); | ||
| 27 | |||
| 28 | #define SMD_EVENT_DATA 1 | ||
| 29 | #define SMD_EVENT_OPEN 2 | ||
| 30 | #define SMD_EVENT_CLOSE 3 | ||
| 31 | |||
| 32 | int smd_close(smd_channel_t *ch); | ||
| 33 | |||
| 34 | /* passing a null pointer for data reads and discards */ | ||
| 35 | int smd_read(smd_channel_t *ch, void *data, int len); | ||
| 36 | |||
| 37 | /* Write to stream channels may do a partial write and return | ||
| 38 | ** the length actually written. | ||
| 39 | ** Write to packet channels will never do a partial write -- | ||
| 40 | ** it will return the requested length written or an error. | ||
| 41 | */ | ||
| 42 | int smd_write(smd_channel_t *ch, const void *data, int len); | ||
| 43 | int smd_write_atomic(smd_channel_t *ch, const void *data, int len); | ||
| 44 | |||
| 45 | int smd_write_avail(smd_channel_t *ch); | ||
| 46 | int smd_read_avail(smd_channel_t *ch); | ||
| 47 | |||
| 48 | /* Returns the total size of the current packet being read. | ||
| 49 | ** Returns 0 if no packets available or a stream channel. | ||
| 50 | */ | ||
| 51 | int smd_cur_packet_size(smd_channel_t *ch); | ||
| 52 | |||
| 53 | /* used for tty unthrottling and the like -- causes the notify() | ||
| 54 | ** callback to be called from the same lock context as is used | ||
| 55 | ** when it is called from channel updates | ||
| 56 | */ | ||
| 57 | void smd_kick(smd_channel_t *ch); | ||
| 58 | |||
| 59 | |||
| 60 | #if 0 | ||
| 61 | /* these are interruptable waits which will block you until the specified | ||
| 62 | ** number of bytes are readable or writable. | ||
| 63 | */ | ||
| 64 | int smd_wait_until_readable(smd_channel_t *ch, int bytes); | ||
| 65 | int smd_wait_until_writable(smd_channel_t *ch, int bytes); | ||
| 66 | #endif | ||
| 67 | |||
| 68 | typedef enum { | ||
| 69 | SMD_PORT_DS = 0, | ||
| 70 | SMD_PORT_DIAG, | ||
| 71 | SMD_PORT_RPC_CALL, | ||
| 72 | SMD_PORT_RPC_REPLY, | ||
| 73 | SMD_PORT_BT, | ||
| 74 | SMD_PORT_CONTROL, | ||
| 75 | SMD_PORT_MEMCPY_SPARE1, | ||
| 76 | SMD_PORT_DATA1, | ||
| 77 | SMD_PORT_DATA2, | ||
| 78 | SMD_PORT_DATA3, | ||
| 79 | SMD_PORT_DATA4, | ||
| 80 | SMD_PORT_DATA5, | ||
| 81 | SMD_PORT_DATA6, | ||
| 82 | SMD_PORT_DATA7, | ||
| 83 | SMD_PORT_DATA8, | ||
| 84 | SMD_PORT_DATA9, | ||
| 85 | SMD_PORT_DATA10, | ||
| 86 | SMD_PORT_DATA11, | ||
| 87 | SMD_PORT_DATA12, | ||
| 88 | SMD_PORT_DATA13, | ||
| 89 | SMD_PORT_DATA14, | ||
| 90 | SMD_PORT_DATA15, | ||
| 91 | SMD_PORT_DATA16, | ||
| 92 | SMD_PORT_DATA17, | ||
| 93 | SMD_PORT_DATA18, | ||
| 94 | SMD_PORT_DATA19, | ||
| 95 | SMD_PORT_DATA20, | ||
| 96 | SMD_PORT_GPS_NMEA, | ||
| 97 | SMD_PORT_BRIDGE_1, | ||
| 98 | SMD_PORT_BRIDGE_2, | ||
| 99 | SMD_PORT_BRIDGE_3, | ||
| 100 | SMD_PORT_BRIDGE_4, | ||
| 101 | SMD_PORT_BRIDGE_5, | ||
| 102 | SMD_PORT_LOOPBACK, | ||
| 103 | SMD_PORT_CS_APPS_MODEM, | ||
| 104 | SMD_PORT_CS_APPS_DSP, | ||
| 105 | SMD_PORT_CS_MODEM_DSP, | ||
| 106 | SMD_NUM_PORTS, | ||
| 107 | } smd_port_id_type; | ||
| 108 | |||
| 109 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/sirc.h b/arch/arm/mach-msm/include/mach/sirc.h new file mode 100644 index 000000000000..7281337ee28d --- /dev/null +++ b/arch/arm/mach-msm/include/mach/sirc.h | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * Redistribution and use in source and binary forms, with or without | ||
| 4 | * modification, are permitted provided that the following conditions are | ||
| 5 | * met: | ||
| 6 | * * Redistributions of source code must retain the above copyright | ||
| 7 | * notice, this list of conditions and the following disclaimer. | ||
| 8 | * * Redistributions in binary form must reproduce the above | ||
| 9 | * copyright notice, this list of conditions and the following | ||
| 10 | * disclaimer in the documentation and/or other materials provided | ||
| 11 | * with the distribution. | ||
| 12 | * * Neither the name of Code Aurora Forum, Inc. nor the names of its | ||
| 13 | * contributors may be used to endorse or promote products derived | ||
| 14 | * from this software without specific prior written permission. | ||
| 15 | * | ||
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | ||
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | ||
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | ||
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | ||
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | ||
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | * | ||
| 28 | */ | ||
| 29 | |||
| 30 | #ifndef __ASM_ARCH_MSM_SIRC_H | ||
| 31 | #define __ASM_ARCH_MSM_SIRC_H | ||
| 32 | |||
| 33 | struct sirc_regs_t { | ||
| 34 | void *int_enable; | ||
| 35 | void *int_enable_clear; | ||
| 36 | void *int_enable_set; | ||
| 37 | void *int_type; | ||
| 38 | void *int_polarity; | ||
| 39 | void *int_clear; | ||
| 40 | }; | ||
| 41 | |||
| 42 | struct sirc_cascade_regs { | ||
| 43 | void *int_status; | ||
| 44 | unsigned int cascade_irq; | ||
| 45 | }; | ||
| 46 | |||
| 47 | void msm_init_sirc(void); | ||
| 48 | void msm_sirc_enter_sleep(void); | ||
| 49 | void msm_sirc_exit_sleep(void); | ||
| 50 | |||
| 51 | #if defined(CONFIG_ARCH_MSM_SCORPION) | ||
| 52 | |||
| 53 | #include <mach/msm_iomap.h> | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Secondary interrupt controller interrupts | ||
| 57 | */ | ||
| 58 | |||
| 59 | #define FIRST_SIRC_IRQ (NR_MSM_IRQS + NR_GPIO_IRQS) | ||
| 60 | |||
| 61 | #define INT_UART1 (FIRST_SIRC_IRQ + 0) | ||
| 62 | #define INT_UART2 (FIRST_SIRC_IRQ + 1) | ||
| 63 | #define INT_UART3 (FIRST_SIRC_IRQ + 2) | ||
| 64 | #define INT_UART1_RX (FIRST_SIRC_IRQ + 3) | ||
| 65 | #define INT_UART2_RX (FIRST_SIRC_IRQ + 4) | ||
| 66 | #define INT_UART3_RX (FIRST_SIRC_IRQ + 5) | ||
| 67 | #define INT_SPI_INPUT (FIRST_SIRC_IRQ + 6) | ||
| 68 | #define INT_SPI_OUTPUT (FIRST_SIRC_IRQ + 7) | ||
| 69 | #define INT_SPI_ERROR (FIRST_SIRC_IRQ + 8) | ||
| 70 | #define INT_GPIO_GROUP1 (FIRST_SIRC_IRQ + 9) | ||
| 71 | #define INT_GPIO_GROUP2 (FIRST_SIRC_IRQ + 10) | ||
| 72 | #define INT_GPIO_GROUP1_SECURE (FIRST_SIRC_IRQ + 11) | ||
| 73 | #define INT_GPIO_GROUP2_SECURE (FIRST_SIRC_IRQ + 12) | ||
| 74 | #define INT_AVS_SVIC (FIRST_SIRC_IRQ + 13) | ||
| 75 | #define INT_AVS_REQ_UP (FIRST_SIRC_IRQ + 14) | ||
| 76 | #define INT_AVS_REQ_DOWN (FIRST_SIRC_IRQ + 15) | ||
| 77 | #define INT_PBUS_ERR (FIRST_SIRC_IRQ + 16) | ||
| 78 | #define INT_AXI_ERR (FIRST_SIRC_IRQ + 17) | ||
| 79 | #define INT_SMI_ERR (FIRST_SIRC_IRQ + 18) | ||
| 80 | #define INT_EBI1_ERR (FIRST_SIRC_IRQ + 19) | ||
| 81 | #define INT_IMEM_ERR (FIRST_SIRC_IRQ + 20) | ||
| 82 | #define INT_TEMP_SENSOR (FIRST_SIRC_IRQ + 21) | ||
| 83 | #define INT_TV_ENC (FIRST_SIRC_IRQ + 22) | ||
| 84 | #define INT_GRP2D (FIRST_SIRC_IRQ + 23) | ||
| 85 | #define INT_GSBI_QUP (FIRST_SIRC_IRQ + 24) | ||
| 86 | #define INT_SC_ACG (FIRST_SIRC_IRQ + 25) | ||
| 87 | #define INT_WDT0 (FIRST_SIRC_IRQ + 26) | ||
| 88 | #define INT_WDT1 (FIRST_SIRC_IRQ + 27) | ||
| 89 | |||
| 90 | #if defined(CONFIG_MSM_SOC_REV_A) | ||
| 91 | #define NR_SIRC_IRQS 28 | ||
| 92 | #define SIRC_MASK 0x0FFFFFFF | ||
| 93 | #else | ||
| 94 | #define NR_SIRC_IRQS 23 | ||
| 95 | #define SIRC_MASK 0x007FFFFF | ||
| 96 | #endif | ||
| 97 | |||
| 98 | #define LAST_SIRC_IRQ (FIRST_SIRC_IRQ + NR_SIRC_IRQS - 1) | ||
| 99 | |||
| 100 | #define SPSS_SIRC_INT_SELECT (MSM_SIRC_BASE + 0x00) | ||
| 101 | #define SPSS_SIRC_INT_ENABLE (MSM_SIRC_BASE + 0x04) | ||
| 102 | #define SPSS_SIRC_INT_ENABLE_CLEAR (MSM_SIRC_BASE + 0x08) | ||
| 103 | #define SPSS_SIRC_INT_ENABLE_SET (MSM_SIRC_BASE + 0x0C) | ||
| 104 | #define SPSS_SIRC_INT_TYPE (MSM_SIRC_BASE + 0x10) | ||
| 105 | #define SPSS_SIRC_INT_POLARITY (MSM_SIRC_BASE + 0x14) | ||
| 106 | #define SPSS_SIRC_SECURITY (MSM_SIRC_BASE + 0x18) | ||
| 107 | #define SPSS_SIRC_IRQ_STATUS (MSM_SIRC_BASE + 0x1C) | ||
| 108 | #define SPSS_SIRC_IRQ1_STATUS (MSM_SIRC_BASE + 0x20) | ||
| 109 | #define SPSS_SIRC_RAW_STATUS (MSM_SIRC_BASE + 0x24) | ||
| 110 | #define SPSS_SIRC_INT_CLEAR (MSM_SIRC_BASE + 0x28) | ||
| 111 | #define SPSS_SIRC_SOFT_INT (MSM_SIRC_BASE + 0x2C) | ||
| 112 | |||
| 113 | #endif | ||
| 114 | |||
| 115 | #endif | ||
diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h index 574ccc493daf..d2e83f42ba16 100644 --- a/arch/arm/mach-msm/include/mach/system.h +++ b/arch/arm/mach-msm/include/mach/system.h | |||
| @@ -21,3 +21,8 @@ static inline void arch_reset(char mode, const char *cmd) | |||
| 21 | { | 21 | { |
| 22 | for (;;) ; /* depends on IPC w/ other core */ | 22 | for (;;) ; /* depends on IPC w/ other core */ |
| 23 | } | 23 | } |
| 24 | |||
| 25 | /* low level hardware reset hook -- for example, hitting the | ||
| 26 | * PSHOLD line on the PMIC to hard reset the system | ||
| 27 | */ | ||
| 28 | extern void (*msm_hw_reset_hook)(void); | ||
diff --git a/arch/arm/mach-msm/include/mach/vreg.h b/arch/arm/mach-msm/include/mach/vreg.h index 9f9e25cb718e..6626e7864e28 100644 --- a/arch/arm/mach-msm/include/mach/vreg.h +++ b/arch/arm/mach-msm/include/mach/vreg.h | |||
| @@ -23,7 +23,7 @@ struct vreg *vreg_get(struct device *dev, const char *id); | |||
| 23 | void vreg_put(struct vreg *vreg); | 23 | void vreg_put(struct vreg *vreg); |
| 24 | 24 | ||
| 25 | int vreg_enable(struct vreg *vreg); | 25 | int vreg_enable(struct vreg *vreg); |
| 26 | void vreg_disable(struct vreg *vreg); | 26 | int vreg_disable(struct vreg *vreg); |
| 27 | int vreg_set_level(struct vreg *vreg, unsigned mv); | 27 | int vreg_set_level(struct vreg *vreg, unsigned mv); |
| 28 | 28 | ||
| 29 | #endif | 29 | #endif |
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index 05f96b780aa6..1c05060b5f3b 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | /* arch/arm/mach-msm/io.c | 1 | /* arch/arm/mach-msm/io.c |
| 2 | * | 2 | * |
| 3 | * MSM7K io support | 3 | * MSM7K, QSD io support |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2007 Google, Inc. | 5 | * Copyright (C) 2007 Google, Inc. |
| 6 | * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved. | ||
| 6 | * Author: Brian Swetland <swetland@google.com> | 7 | * Author: Brian Swetland <swetland@google.com> |
| 7 | * | 8 | * |
| 8 | * This software is licensed under the terms of the GNU General Public | 9 | * This software is licensed under the terms of the GNU General Public |
| @@ -34,6 +35,8 @@ | |||
| 34 | .type = MT_DEVICE_NONSHARED, \ | 35 | .type = MT_DEVICE_NONSHARED, \ |
| 35 | } | 36 | } |
| 36 | 37 | ||
| 38 | #if defined(CONFIG_ARCH_MSM7X00A) || defined(CONFIG_ARCH_MSM7X27) \ | ||
| 39 | || defined(CONFIG_ARCH_MSM7X25) | ||
| 37 | static struct map_desc msm_io_desc[] __initdata = { | 40 | static struct map_desc msm_io_desc[] __initdata = { |
| 38 | MSM_DEVICE(VIC), | 41 | MSM_DEVICE(VIC), |
| 39 | MSM_DEVICE(CSR), | 42 | MSM_DEVICE(CSR), |
| @@ -45,9 +48,12 @@ static struct map_desc msm_io_desc[] __initdata = { | |||
| 45 | #ifdef CONFIG_MSM_DEBUG_UART | 48 | #ifdef CONFIG_MSM_DEBUG_UART |
| 46 | MSM_DEVICE(DEBUG_UART), | 49 | MSM_DEVICE(DEBUG_UART), |
| 47 | #endif | 50 | #endif |
| 51 | #ifdef CONFIG_ARCH_MSM7X30 | ||
| 52 | MSM_DEVICE(GCC), | ||
| 53 | #endif | ||
| 48 | { | 54 | { |
| 49 | .virtual = (unsigned long) MSM_SHARED_RAM_BASE, | 55 | .virtual = (unsigned long) MSM_SHARED_RAM_BASE, |
| 50 | .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), | 56 | .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), |
| 51 | .length = MSM_SHARED_RAM_SIZE, | 57 | .length = MSM_SHARED_RAM_SIZE, |
| 52 | .type = MT_DEVICE, | 58 | .type = MT_DEVICE, |
| 53 | }, | 59 | }, |
| @@ -60,9 +66,72 @@ void __init msm_map_common_io(void) | |||
| 60 | * pages are peripheral interface or not. | 66 | * pages are peripheral interface or not. |
| 61 | */ | 67 | */ |
| 62 | asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0)); | 68 | asm("mcr p15, 0, %0, c15, c2, 4" : : "r" (0)); |
| 63 | |||
| 64 | iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc)); | 69 | iotable_init(msm_io_desc, ARRAY_SIZE(msm_io_desc)); |
| 65 | } | 70 | } |
| 71 | #endif | ||
| 72 | |||
| 73 | #ifdef CONFIG_ARCH_QSD8X50 | ||
| 74 | static struct map_desc qsd8x50_io_desc[] __initdata = { | ||
| 75 | MSM_DEVICE(VIC), | ||
| 76 | MSM_DEVICE(CSR), | ||
| 77 | MSM_DEVICE(TMR), | ||
| 78 | MSM_DEVICE(DMOV), | ||
| 79 | MSM_DEVICE(GPIO1), | ||
| 80 | MSM_DEVICE(GPIO2), | ||
| 81 | MSM_DEVICE(CLK_CTL), | ||
| 82 | MSM_DEVICE(SIRC), | ||
| 83 | MSM_DEVICE(SCPLL), | ||
| 84 | MSM_DEVICE(AD5), | ||
| 85 | MSM_DEVICE(MDC), | ||
| 86 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 87 | MSM_DEVICE(DEBUG_UART), | ||
| 88 | #endif | ||
| 89 | { | ||
| 90 | .virtual = (unsigned long) MSM_SHARED_RAM_BASE, | ||
| 91 | .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), | ||
| 92 | .length = MSM_SHARED_RAM_SIZE, | ||
| 93 | .type = MT_DEVICE, | ||
| 94 | }, | ||
| 95 | }; | ||
| 96 | |||
| 97 | void __init msm_map_qsd8x50_io(void) | ||
| 98 | { | ||
| 99 | iotable_init(qsd8x50_io_desc, ARRAY_SIZE(qsd8x50_io_desc)); | ||
| 100 | } | ||
| 101 | #endif /* CONFIG_ARCH_QSD8X50 */ | ||
| 102 | |||
| 103 | #ifdef CONFIG_ARCH_MSM7X30 | ||
| 104 | static struct map_desc msm7x30_io_desc[] __initdata = { | ||
| 105 | MSM_DEVICE(VIC), | ||
| 106 | MSM_DEVICE(CSR), | ||
| 107 | MSM_DEVICE(TMR), | ||
| 108 | MSM_DEVICE(DMOV), | ||
| 109 | MSM_DEVICE(GPIO1), | ||
| 110 | MSM_DEVICE(GPIO2), | ||
| 111 | MSM_DEVICE(CLK_CTL), | ||
| 112 | MSM_DEVICE(CLK_CTL_SH2), | ||
| 113 | MSM_DEVICE(AD5), | ||
| 114 | MSM_DEVICE(MDC), | ||
| 115 | MSM_DEVICE(ACC), | ||
| 116 | MSM_DEVICE(SAW), | ||
| 117 | MSM_DEVICE(GCC), | ||
| 118 | MSM_DEVICE(TCSR), | ||
| 119 | #ifdef CONFIG_MSM_DEBUG_UART | ||
| 120 | MSM_DEVICE(DEBUG_UART), | ||
| 121 | #endif | ||
| 122 | { | ||
| 123 | .virtual = (unsigned long) MSM_SHARED_RAM_BASE, | ||
| 124 | .pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS), | ||
| 125 | .length = MSM_SHARED_RAM_SIZE, | ||
| 126 | .type = MT_DEVICE, | ||
| 127 | }, | ||
| 128 | }; | ||
| 129 | |||
| 130 | void __init msm_map_msm7x30_io(void) | ||
| 131 | { | ||
| 132 | iotable_init(msm7x30_io_desc, ARRAY_SIZE(msm7x30_io_desc)); | ||
| 133 | } | ||
| 134 | #endif /* CONFIG_ARCH_MSM7X30 */ | ||
| 66 | 135 | ||
| 67 | void __iomem * | 136 | void __iomem * |
| 68 | __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) | 137 | __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) |
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c new file mode 100644 index 000000000000..99f2c3473033 --- /dev/null +++ b/arch/arm/mach-msm/irq-vic.c | |||
| @@ -0,0 +1,365 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2007 Google, Inc. | ||
| 3 | * Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 4 | * | ||
| 5 | * This software is licensed under the terms of the GNU General Public | ||
| 6 | * License version 2, as published by the Free Software Foundation, and | ||
| 7 | * may be copied, distributed, and modified under those terms. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/sched.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/ptrace.h> | ||
| 21 | #include <linux/timer.h> | ||
| 22 | #include <linux/irq.h> | ||
| 23 | #include <linux/io.h> | ||
| 24 | |||
| 25 | #include <asm/cacheflush.h> | ||
| 26 | |||
| 27 | #include <mach/hardware.h> | ||
| 28 | |||
| 29 | #include <mach/msm_iomap.h> | ||
| 30 | |||
| 31 | #include "smd_private.h" | ||
| 32 | |||
| 33 | enum { | ||
| 34 | IRQ_DEBUG_SLEEP_INT_TRIGGER = 1U << 0, | ||
| 35 | IRQ_DEBUG_SLEEP_INT = 1U << 1, | ||
| 36 | IRQ_DEBUG_SLEEP_ABORT = 1U << 2, | ||
| 37 | IRQ_DEBUG_SLEEP = 1U << 3, | ||
| 38 | IRQ_DEBUG_SLEEP_REQUEST = 1U << 4, | ||
| 39 | }; | ||
| 40 | static int msm_irq_debug_mask; | ||
| 41 | module_param_named(debug_mask, msm_irq_debug_mask, int, | ||
| 42 | S_IRUGO | S_IWUSR | S_IWGRP); | ||
| 43 | |||
| 44 | #define VIC_REG(off) (MSM_VIC_BASE + (off)) | ||
| 45 | #define VIC_INT_TO_REG_ADDR(base, irq) (base + (irq / 32) * 4) | ||
| 46 | #define VIC_INT_TO_REG_INDEX(irq) ((irq >> 5) & 3) | ||
| 47 | |||
| 48 | #define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ | ||
| 49 | #define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ | ||
| 50 | #define VIC_INT_SELECT2 VIC_REG(0x0008) /* 1: FIQ, 0: IRQ */ | ||
| 51 | #define VIC_INT_SELECT3 VIC_REG(0x000C) /* 1: FIQ, 0: IRQ */ | ||
| 52 | #define VIC_INT_EN0 VIC_REG(0x0010) | ||
| 53 | #define VIC_INT_EN1 VIC_REG(0x0014) | ||
| 54 | #define VIC_INT_EN2 VIC_REG(0x0018) | ||
| 55 | #define VIC_INT_EN3 VIC_REG(0x001C) | ||
| 56 | #define VIC_INT_ENCLEAR0 VIC_REG(0x0020) | ||
| 57 | #define VIC_INT_ENCLEAR1 VIC_REG(0x0024) | ||
| 58 | #define VIC_INT_ENCLEAR2 VIC_REG(0x0028) | ||
| 59 | #define VIC_INT_ENCLEAR3 VIC_REG(0x002C) | ||
| 60 | #define VIC_INT_ENSET0 VIC_REG(0x0030) | ||
| 61 | #define VIC_INT_ENSET1 VIC_REG(0x0034) | ||
| 62 | #define VIC_INT_ENSET2 VIC_REG(0x0038) | ||
| 63 | #define VIC_INT_ENSET3 VIC_REG(0x003C) | ||
| 64 | #define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ | ||
| 65 | #define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ | ||
| 66 | #define VIC_INT_TYPE2 VIC_REG(0x0048) /* 1: EDGE, 0: LEVEL */ | ||
| 67 | #define VIC_INT_TYPE3 VIC_REG(0x004C) /* 1: EDGE, 0: LEVEL */ | ||
| 68 | #define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ | ||
| 69 | #define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ | ||
| 70 | #define VIC_INT_POLARITY2 VIC_REG(0x0058) /* 1: NEG, 0: POS */ | ||
| 71 | #define VIC_INT_POLARITY3 VIC_REG(0x005C) /* 1: NEG, 0: POS */ | ||
| 72 | #define VIC_NO_PEND_VAL VIC_REG(0x0060) | ||
| 73 | |||
| 74 | #if defined(CONFIG_ARCH_MSM_SCORPION) | ||
| 75 | #define VIC_NO_PEND_VAL_FIQ VIC_REG(0x0064) | ||
| 76 | #define VIC_INT_MASTEREN VIC_REG(0x0068) /* 1: IRQ, 2: FIQ */ | ||
| 77 | #define VIC_CONFIG VIC_REG(0x006C) /* 1: USE SC VIC */ | ||
| 78 | #else | ||
| 79 | #define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */ | ||
| 80 | #define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */ | ||
| 81 | #define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */ | ||
| 82 | #endif | ||
| 83 | |||
| 84 | #define VIC_IRQ_STATUS0 VIC_REG(0x0080) | ||
| 85 | #define VIC_IRQ_STATUS1 VIC_REG(0x0084) | ||
| 86 | #define VIC_IRQ_STATUS2 VIC_REG(0x0088) | ||
| 87 | #define VIC_IRQ_STATUS3 VIC_REG(0x008C) | ||
| 88 | #define VIC_FIQ_STATUS0 VIC_REG(0x0090) | ||
| 89 | #define VIC_FIQ_STATUS1 VIC_REG(0x0094) | ||
| 90 | #define VIC_FIQ_STATUS2 VIC_REG(0x0098) | ||
| 91 | #define VIC_FIQ_STATUS3 VIC_REG(0x009C) | ||
| 92 | #define VIC_RAW_STATUS0 VIC_REG(0x00A0) | ||
| 93 | #define VIC_RAW_STATUS1 VIC_REG(0x00A4) | ||
| 94 | #define VIC_RAW_STATUS2 VIC_REG(0x00A8) | ||
| 95 | #define VIC_RAW_STATUS3 VIC_REG(0x00AC) | ||
| 96 | #define VIC_INT_CLEAR0 VIC_REG(0x00B0) | ||
| 97 | #define VIC_INT_CLEAR1 VIC_REG(0x00B4) | ||
| 98 | #define VIC_INT_CLEAR2 VIC_REG(0x00B8) | ||
| 99 | #define VIC_INT_CLEAR3 VIC_REG(0x00BC) | ||
| 100 | #define VIC_SOFTINT0 VIC_REG(0x00C0) | ||
| 101 | #define VIC_SOFTINT1 VIC_REG(0x00C4) | ||
| 102 | #define VIC_SOFTINT2 VIC_REG(0x00C8) | ||
| 103 | #define VIC_SOFTINT3 VIC_REG(0x00CC) | ||
| 104 | #define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ | ||
| 105 | #define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ | ||
| 106 | #define VIC_IRQ_VEC_WR VIC_REG(0x00D8) | ||
| 107 | |||
| 108 | #if defined(CONFIG_ARCH_MSM_SCORPION) | ||
| 109 | #define VIC_FIQ_VEC_RD VIC_REG(0x00DC) | ||
| 110 | #define VIC_FIQ_VEC_PEND_RD VIC_REG(0x00E0) | ||
| 111 | #define VIC_FIQ_VEC_WR VIC_REG(0x00E4) | ||
| 112 | #define VIC_IRQ_IN_SERVICE VIC_REG(0x00E8) | ||
| 113 | #define VIC_IRQ_IN_STACK VIC_REG(0x00EC) | ||
| 114 | #define VIC_FIQ_IN_SERVICE VIC_REG(0x00F0) | ||
| 115 | #define VIC_FIQ_IN_STACK VIC_REG(0x00F4) | ||
| 116 | #define VIC_TEST_BUS_SEL VIC_REG(0x00F8) | ||
| 117 | #define VIC_IRQ_CTRL_CONFIG VIC_REG(0x00FC) | ||
| 118 | #else | ||
| 119 | #define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0) | ||
| 120 | #define VIC_IRQ_IN_STACK VIC_REG(0x00E4) | ||
| 121 | #define VIC_TEST_BUS_SEL VIC_REG(0x00E8) | ||
| 122 | #endif | ||
| 123 | |||
| 124 | #define VIC_VECTPRIORITY(n) VIC_REG(0x0200+((n) * 4)) | ||
| 125 | #define VIC_VECTADDR(n) VIC_REG(0x0400+((n) * 4)) | ||
| 126 | |||
| 127 | #if defined(CONFIG_ARCH_MSM7X30) | ||
| 128 | #define VIC_NUM_REGS 4 | ||
| 129 | #else | ||
| 130 | #define VIC_NUM_REGS 2 | ||
| 131 | #endif | ||
| 132 | |||
| 133 | #if VIC_NUM_REGS == 2 | ||
| 134 | #define DPRINT_REGS(base_reg, format, ...) \ | ||
| 135 | printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \ | ||
| 136 | readl(base_reg ## 0), readl(base_reg ## 1)) | ||
| 137 | #define DPRINT_ARRAY(array, format, ...) \ | ||
| 138 | printk(KERN_INFO format " %x %x\n", ##__VA_ARGS__, \ | ||
| 139 | array[0], array[1]) | ||
| 140 | #elif VIC_NUM_REGS == 4 | ||
| 141 | #define DPRINT_REGS(base_reg, format, ...) \ | ||
| 142 | printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \ | ||
| 143 | readl(base_reg ## 0), readl(base_reg ## 1), \ | ||
| 144 | readl(base_reg ## 2), readl(base_reg ## 3)) | ||
| 145 | #define DPRINT_ARRAY(array, format, ...) \ | ||
| 146 | printk(KERN_INFO format " %x %x %x %x\n", ##__VA_ARGS__, \ | ||
| 147 | array[0], array[1], \ | ||
| 148 | array[2], array[3]) | ||
| 149 | #else | ||
| 150 | #error "VIC_NUM_REGS set to illegal value" | ||
| 151 | #endif | ||
| 152 | |||
| 153 | static uint32_t msm_irq_smsm_wake_enable[2]; | ||
| 154 | static struct { | ||
| 155 | uint32_t int_en[2]; | ||
| 156 | uint32_t int_type; | ||
| 157 | uint32_t int_polarity; | ||
| 158 | uint32_t int_select; | ||
| 159 | } msm_irq_shadow_reg[VIC_NUM_REGS]; | ||
| 160 | static uint32_t msm_irq_idle_disable[VIC_NUM_REGS]; | ||
| 161 | |||
| 162 | #define SMSM_FAKE_IRQ (0xff) | ||
| 163 | static uint8_t msm_irq_to_smsm[NR_IRQS] = { | ||
| 164 | [INT_MDDI_EXT] = 1, | ||
| 165 | [INT_MDDI_PRI] = 2, | ||
| 166 | [INT_MDDI_CLIENT] = 3, | ||
| 167 | [INT_USB_OTG] = 4, | ||
| 168 | |||
| 169 | [INT_PWB_I2C] = 5, | ||
| 170 | [INT_SDC1_0] = 6, | ||
| 171 | [INT_SDC1_1] = 7, | ||
| 172 | [INT_SDC2_0] = 8, | ||
| 173 | |||
| 174 | [INT_SDC2_1] = 9, | ||
| 175 | [INT_ADSP_A9_A11] = 10, | ||
| 176 | [INT_UART1] = 11, | ||
| 177 | [INT_UART2] = 12, | ||
| 178 | |||
| 179 | [INT_UART3] = 13, | ||
| 180 | [INT_UART1_RX] = 14, | ||
| 181 | [INT_UART2_RX] = 15, | ||
| 182 | [INT_UART3_RX] = 16, | ||
| 183 | |||
| 184 | [INT_UART1DM_IRQ] = 17, | ||
| 185 | [INT_UART1DM_RX] = 18, | ||
| 186 | [INT_KEYSENSE] = 19, | ||
| 187 | #if !defined(CONFIG_ARCH_MSM7X30) | ||
| 188 | [INT_AD_HSSD] = 20, | ||
| 189 | #endif | ||
| 190 | |||
| 191 | [INT_NAND_WR_ER_DONE] = 21, | ||
| 192 | [INT_NAND_OP_DONE] = 22, | ||
| 193 | [INT_TCHSCRN1] = 23, | ||
| 194 | [INT_TCHSCRN2] = 24, | ||
| 195 | |||
| 196 | [INT_TCHSCRN_SSBI] = 25, | ||
| 197 | [INT_USB_HS] = 26, | ||
| 198 | [INT_UART2DM_RX] = 27, | ||
| 199 | [INT_UART2DM_IRQ] = 28, | ||
| 200 | |||
| 201 | [INT_SDC4_1] = 29, | ||
| 202 | [INT_SDC4_0] = 30, | ||
| 203 | [INT_SDC3_1] = 31, | ||
| 204 | [INT_SDC3_0] = 32, | ||
| 205 | |||
| 206 | /* fake wakeup interrupts */ | ||
| 207 | [INT_GPIO_GROUP1] = SMSM_FAKE_IRQ, | ||
| 208 | [INT_GPIO_GROUP2] = SMSM_FAKE_IRQ, | ||
| 209 | [INT_A9_M2A_0] = SMSM_FAKE_IRQ, | ||
| 210 | [INT_A9_M2A_1] = SMSM_FAKE_IRQ, | ||
| 211 | [INT_A9_M2A_5] = SMSM_FAKE_IRQ, | ||
| 212 | [INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ, | ||
| 213 | [INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ, | ||
| 214 | [INT_ADSP_A11] = SMSM_FAKE_IRQ, | ||
| 215 | #ifdef CONFIG_ARCH_QSD8X50 | ||
| 216 | [INT_SIRC_0] = SMSM_FAKE_IRQ, | ||
| 217 | [INT_SIRC_1] = SMSM_FAKE_IRQ, | ||
| 218 | #endif | ||
| 219 | }; | ||
| 220 | |||
| 221 | static inline void msm_irq_write_all_regs(void __iomem *base, unsigned int val) | ||
| 222 | { | ||
| 223 | int i; | ||
| 224 | |||
| 225 | for (i = 0; i < VIC_NUM_REGS; i++) | ||
| 226 | writel(val, base + (i * 4)); | ||
| 227 | } | ||
| 228 | |||
| 229 | static void msm_irq_ack(unsigned int irq) | ||
| 230 | { | ||
| 231 | void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_CLEAR0, irq); | ||
| 232 | irq = 1 << (irq & 31); | ||
| 233 | writel(irq, reg); | ||
| 234 | } | ||
| 235 | |||
| 236 | static void msm_irq_mask(unsigned int irq) | ||
| 237 | { | ||
| 238 | void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENCLEAR0, irq); | ||
| 239 | unsigned index = VIC_INT_TO_REG_INDEX(irq); | ||
| 240 | uint32_t mask = 1UL << (irq & 31); | ||
| 241 | int smsm_irq = msm_irq_to_smsm[irq]; | ||
| 242 | |||
| 243 | msm_irq_shadow_reg[index].int_en[0] &= ~mask; | ||
| 244 | writel(mask, reg); | ||
| 245 | if (smsm_irq == 0) | ||
| 246 | msm_irq_idle_disable[index] &= ~mask; | ||
| 247 | else { | ||
| 248 | mask = 1UL << (smsm_irq - 1); | ||
| 249 | msm_irq_smsm_wake_enable[0] &= ~mask; | ||
| 250 | } | ||
| 251 | } | ||
| 252 | |||
| 253 | static void msm_irq_unmask(unsigned int irq) | ||
| 254 | { | ||
| 255 | void __iomem *reg = VIC_INT_TO_REG_ADDR(VIC_INT_ENSET0, irq); | ||
| 256 | unsigned index = VIC_INT_TO_REG_INDEX(irq); | ||
| 257 | uint32_t mask = 1UL << (irq & 31); | ||
| 258 | int smsm_irq = msm_irq_to_smsm[irq]; | ||
| 259 | |||
| 260 | msm_irq_shadow_reg[index].int_en[0] |= mask; | ||
| 261 | writel(mask, reg); | ||
| 262 | |||
| 263 | if (smsm_irq == 0) | ||
| 264 | msm_irq_idle_disable[index] |= mask; | ||
| 265 | else { | ||
| 266 | mask = 1UL << (smsm_irq - 1); | ||
| 267 | msm_irq_smsm_wake_enable[0] |= mask; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | static int msm_irq_set_wake(unsigned int irq, unsigned int on) | ||
| 272 | { | ||
| 273 | unsigned index = VIC_INT_TO_REG_INDEX(irq); | ||
| 274 | uint32_t mask = 1UL << (irq & 31); | ||
| 275 | int smsm_irq = msm_irq_to_smsm[irq]; | ||
| 276 | |||
| 277 | if (smsm_irq == 0) { | ||
| 278 | printk(KERN_ERR "msm_irq_set_wake: bad wakeup irq %d\n", irq); | ||
| 279 | return -EINVAL; | ||
| 280 | } | ||
| 281 | if (on) | ||
| 282 | msm_irq_shadow_reg[index].int_en[1] |= mask; | ||
| 283 | else | ||
| 284 | msm_irq_shadow_reg[index].int_en[1] &= ~mask; | ||
| 285 | |||
| 286 | if (smsm_irq == SMSM_FAKE_IRQ) | ||
| 287 | return 0; | ||
| 288 | |||
| 289 | mask = 1UL << (smsm_irq - 1); | ||
| 290 | if (on) | ||
| 291 | msm_irq_smsm_wake_enable[1] |= mask; | ||
| 292 | else | ||
| 293 | msm_irq_smsm_wake_enable[1] &= ~mask; | ||
| 294 | return 0; | ||
| 295 | } | ||
| 296 | |||
| 297 | static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) | ||
| 298 | { | ||
| 299 | void __iomem *treg = VIC_INT_TO_REG_ADDR(VIC_INT_TYPE0, irq); | ||
| 300 | void __iomem *preg = VIC_INT_TO_REG_ADDR(VIC_INT_POLARITY0, irq); | ||
| 301 | unsigned index = VIC_INT_TO_REG_INDEX(irq); | ||
| 302 | int b = 1 << (irq & 31); | ||
| 303 | uint32_t polarity; | ||
| 304 | uint32_t type; | ||
| 305 | |||
| 306 | polarity = msm_irq_shadow_reg[index].int_polarity; | ||
| 307 | if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) | ||
| 308 | polarity |= b; | ||
| 309 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) | ||
| 310 | polarity &= ~b; | ||
| 311 | writel(polarity, preg); | ||
| 312 | msm_irq_shadow_reg[index].int_polarity = polarity; | ||
| 313 | |||
| 314 | type = msm_irq_shadow_reg[index].int_type; | ||
| 315 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { | ||
| 316 | type |= b; | ||
| 317 | irq_desc[irq].handle_irq = handle_edge_irq; | ||
| 318 | } | ||
| 319 | if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { | ||
| 320 | type &= ~b; | ||
| 321 | irq_desc[irq].handle_irq = handle_level_irq; | ||
| 322 | } | ||
| 323 | writel(type, treg); | ||
| 324 | msm_irq_shadow_reg[index].int_type = type; | ||
| 325 | return 0; | ||
| 326 | } | ||
| 327 | |||
| 328 | static struct irq_chip msm_irq_chip = { | ||
| 329 | .name = "msm", | ||
| 330 | .disable = msm_irq_mask, | ||
| 331 | .ack = msm_irq_ack, | ||
| 332 | .mask = msm_irq_mask, | ||
| 333 | .unmask = msm_irq_unmask, | ||
| 334 | .set_wake = msm_irq_set_wake, | ||
| 335 | .set_type = msm_irq_set_type, | ||
| 336 | }; | ||
| 337 | |||
| 338 | void __init msm_init_irq(void) | ||
| 339 | { | ||
| 340 | unsigned n; | ||
| 341 | |||
| 342 | /* select level interrupts */ | ||
| 343 | msm_irq_write_all_regs(VIC_INT_TYPE0, 0); | ||
| 344 | |||
| 345 | /* select highlevel interrupts */ | ||
| 346 | msm_irq_write_all_regs(VIC_INT_POLARITY0, 0); | ||
| 347 | |||
| 348 | /* select IRQ for all INTs */ | ||
| 349 | msm_irq_write_all_regs(VIC_INT_SELECT0, 0); | ||
| 350 | |||
| 351 | /* disable all INTs */ | ||
| 352 | msm_irq_write_all_regs(VIC_INT_EN0, 0); | ||
| 353 | |||
| 354 | /* don't use vic */ | ||
| 355 | writel(0, VIC_CONFIG); | ||
| 356 | |||
| 357 | /* enable interrupt controller */ | ||
| 358 | writel(3, VIC_INT_MASTEREN); | ||
| 359 | |||
| 360 | for (n = 0; n < NR_MSM_IRQS; n++) { | ||
| 361 | set_irq_chip(n, &msm_irq_chip); | ||
| 362 | set_irq_handler(n, handle_level_irq); | ||
| 363 | set_irq_flags(n, IRQF_VALID); | ||
| 364 | } | ||
| 365 | } | ||
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c index 69ca0dd79bdf..6c8d5f8caef3 100644 --- a/arch/arm/mach-msm/irq.c +++ b/arch/arm/mach-msm/irq.c | |||
| @@ -101,11 +101,11 @@ static int msm_irq_set_type(unsigned int irq, unsigned int flow_type) | |||
| 101 | 101 | ||
| 102 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { | 102 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { |
| 103 | writel(readl(treg) | b, treg); | 103 | writel(readl(treg) | b, treg); |
| 104 | set_irq_handler(irq, handle_edge_irq); | 104 | irq_desc[irq].handle_irq = handle_edge_irq; |
| 105 | } | 105 | } |
| 106 | if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { | 106 | if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { |
| 107 | writel(readl(treg) & (~b), treg); | 107 | writel(readl(treg) & (~b), treg); |
| 108 | set_irq_handler(irq, handle_level_irq); | 108 | irq_desc[irq].handle_irq = handle_level_irq; |
| 109 | } | 109 | } |
| 110 | return 0; | 110 | return 0; |
| 111 | } | 111 | } |
diff --git a/arch/arm/mach-msm/last_radio_log.c b/arch/arm/mach-msm/last_radio_log.c new file mode 100644 index 000000000000..b64ba5a98686 --- /dev/null +++ b/arch/arm/mach-msm/last_radio_log.c | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /* arch/arm/mach-msm/last_radio_log.c | ||
| 2 | * | ||
| 3 | * Extract the log from a modem crash though SMEM | ||
| 4 | * | ||
| 5 | * Copyright (C) 2007 Google, Inc. | ||
| 6 | * | ||
| 7 | * This software is licensed under the terms of the GNU General Public | ||
| 8 | * License version 2, as published by the Free Software Foundation, and | ||
| 9 | * may be copied, distributed, and modified under those terms. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/fs.h> | ||
| 21 | #include <linux/proc_fs.h> | ||
| 22 | #include <linux/uaccess.h> | ||
| 23 | |||
| 24 | #include "smd_private.h" | ||
| 25 | |||
| 26 | static void *radio_log_base; | ||
| 27 | static size_t radio_log_size; | ||
| 28 | |||
| 29 | extern void *smem_item(unsigned id, unsigned *size); | ||
| 30 | |||
| 31 | static ssize_t last_radio_log_read(struct file *file, char __user *buf, | ||
| 32 | size_t len, loff_t *offset) | ||
| 33 | { | ||
| 34 | loff_t pos = *offset; | ||
| 35 | ssize_t count; | ||
| 36 | |||
| 37 | if (pos >= radio_log_size) | ||
| 38 | return 0; | ||
| 39 | |||
| 40 | count = min(len, (size_t)(radio_log_size - pos)); | ||
| 41 | if (copy_to_user(buf, radio_log_base + pos, count)) { | ||
| 42 | pr_err("%s: copy to user failed\n", __func__); | ||
| 43 | return -EFAULT; | ||
| 44 | } | ||
| 45 | |||
| 46 | *offset += count; | ||
| 47 | return count; | ||
| 48 | } | ||
| 49 | |||
| 50 | static struct file_operations last_radio_log_fops = { | ||
| 51 | .read = last_radio_log_read | ||
| 52 | }; | ||
| 53 | |||
| 54 | void msm_init_last_radio_log(struct module *owner) | ||
| 55 | { | ||
| 56 | struct proc_dir_entry *entry; | ||
| 57 | |||
| 58 | if (last_radio_log_fops.owner) { | ||
| 59 | pr_err("%s: already claimed\n", __func__); | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | |||
| 63 | radio_log_base = smem_item(SMEM_CLKREGIM_BSP, &radio_log_size); | ||
| 64 | if (!radio_log_base) { | ||
| 65 | pr_err("%s: could not retrieve SMEM_CLKREGIM_BSP\n", __func__); | ||
| 66 | return; | ||
| 67 | } | ||
| 68 | |||
| 69 | entry = create_proc_entry("last_radio_log", S_IFREG | S_IRUGO, NULL); | ||
| 70 | if (!entry) { | ||
| 71 | pr_err("%s: could not create proc entry for radio log\n", | ||
| 72 | __func__); | ||
| 73 | return; | ||
| 74 | } | ||
| 75 | |||
| 76 | pr_err("%s: last radio log is %d bytes long\n", __func__, | ||
| 77 | radio_log_size); | ||
| 78 | last_radio_log_fops.owner = owner; | ||
| 79 | entry->proc_fops = &last_radio_log_fops; | ||
| 80 | entry->size = radio_log_size; | ||
| 81 | } | ||
| 82 | EXPORT_SYMBOL(msm_init_last_radio_log); | ||
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c index 915ee704ed3c..67e701c7f183 100644 --- a/arch/arm/mach-msm/proc_comm.c +++ b/arch/arm/mach-msm/proc_comm.c | |||
| @@ -23,11 +23,18 @@ | |||
| 23 | 23 | ||
| 24 | #include "proc_comm.h" | 24 | #include "proc_comm.h" |
| 25 | 25 | ||
| 26 | #define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4) | 26 | static inline void msm_a2m_int(uint32_t irq) |
| 27 | { | ||
| 28 | #if defined(CONFIG_ARCH_MSM7X30) | ||
| 29 | writel(1 << irq, MSM_GCC_BASE + 0x8); | ||
| 30 | #else | ||
| 31 | writel(1, MSM_CSR_BASE + 0x400 + (irq * 4)); | ||
| 32 | #endif | ||
| 33 | } | ||
| 27 | 34 | ||
| 28 | static inline void notify_other_proc_comm(void) | 35 | static inline void notify_other_proc_comm(void) |
| 29 | { | 36 | { |
| 30 | writel(1, MSM_A2M_INT(6)); | 37 | msm_a2m_int(6); |
| 31 | } | 38 | } |
| 32 | 39 | ||
| 33 | #define APP_COMMAND 0x00 | 40 | #define APP_COMMAND 0x00 |
| @@ -107,4 +114,17 @@ int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2) | |||
| 107 | return ret; | 114 | return ret; |
| 108 | } | 115 | } |
| 109 | 116 | ||
| 110 | 117 | /* | |
| 118 | * We need to wait for the ARM9 to at least partially boot | ||
| 119 | * up before we can continue. Since the ARM9 does resource | ||
| 120 | * allocation, if we dont' wait we could end up crashing or in | ||
| 121 | * and unknown state. This function should be called early to | ||
| 122 | * wait on the ARM9. | ||
| 123 | */ | ||
| 124 | void __init proc_comm_boot_wait(void) | ||
| 125 | { | ||
| 126 | void __iomem *base = MSM_SHARED_RAM_BASE; | ||
| 127 | |||
| 128 | proc_comm_wait_for(base + MDM_STATUS, PCOM_READY); | ||
| 129 | |||
| 130 | } | ||
diff --git a/arch/arm/mach-msm/proc_comm.h b/arch/arm/mach-msm/proc_comm.h index 834760f25692..12da4cacd4a8 100644 --- a/arch/arm/mach-msm/proc_comm.h +++ b/arch/arm/mach-msm/proc_comm.h | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | #ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_ | 16 | #ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_ |
| 17 | #define _ARCH_ARM_MACH_MSM_PROC_COMM_H_ | 17 | #define _ARCH_ARM_MACH_MSM_PROC_COMM_H_ |
| 18 | 18 | ||
| 19 | #include <linux/init.h> | ||
| 20 | |||
| 19 | enum { | 21 | enum { |
| 20 | PCOM_CMD_IDLE = 0x0, | 22 | PCOM_CMD_IDLE = 0x0, |
| 21 | PCOM_CMD_DONE, | 23 | PCOM_CMD_DONE, |
| @@ -62,19 +64,104 @@ enum { | |||
| 62 | PCOM_RESET_CHIP_IMM, | 64 | PCOM_RESET_CHIP_IMM, |
| 63 | PCOM_PM_VID_EN, | 65 | PCOM_PM_VID_EN, |
| 64 | PCOM_VREG_PULLDOWN, | 66 | PCOM_VREG_PULLDOWN, |
| 67 | PCOM_GET_MODEM_VERSION, | ||
| 68 | PCOM_CLK_REGIME_SEC_RESET, | ||
| 69 | PCOM_CLK_REGIME_SEC_RESET_ASSERT, | ||
| 70 | PCOM_CLK_REGIME_SEC_RESET_DEASSERT, | ||
| 71 | PCOM_CLK_REGIME_SEC_PLL_REQUEST_WRP, | ||
| 72 | PCOM_CLK_REGIME_SEC_ENABLE, | ||
| 73 | PCOM_CLK_REGIME_SEC_DISABLE, | ||
| 74 | PCOM_CLK_REGIME_SEC_IS_ON, | ||
| 75 | PCOM_CLK_REGIME_SEC_SEL_CLK_INV, | ||
| 76 | PCOM_CLK_REGIME_SEC_SEL_CLK_SRC, | ||
| 77 | PCOM_CLK_REGIME_SEC_SEL_CLK_DIV, | ||
| 78 | PCOM_CLK_REGIME_SEC_ICODEC_CLK_ENABLE, | ||
| 79 | PCOM_CLK_REGIME_SEC_ICODEC_CLK_DISABLE, | ||
| 80 | PCOM_CLK_REGIME_SEC_SEL_SPEED, | ||
| 81 | PCOM_CLK_REGIME_SEC_CONFIG_GP_CLK_WRP, | ||
| 82 | PCOM_CLK_REGIME_SEC_CONFIG_MDH_CLK_WRP, | ||
| 83 | PCOM_CLK_REGIME_SEC_USB_XTAL_ON, | ||
| 84 | PCOM_CLK_REGIME_SEC_USB_XTAL_OFF, | ||
| 85 | PCOM_CLK_REGIME_SEC_SET_QDSP_DME_MODE, | ||
| 86 | PCOM_CLK_REGIME_SEC_SWITCH_ADSP_CLK, | ||
| 87 | PCOM_CLK_REGIME_SEC_GET_MAX_ADSP_CLK_KHZ, | ||
| 88 | PCOM_CLK_REGIME_SEC_GET_I2C_CLK_KHZ, | ||
| 89 | PCOM_CLK_REGIME_SEC_MSM_GET_CLK_FREQ_KHZ, | ||
| 90 | PCOM_CLK_REGIME_SEC_SEL_VFE_SRC, | ||
| 91 | PCOM_CLK_REGIME_SEC_MSM_SEL_CAMCLK, | ||
| 92 | PCOM_CLK_REGIME_SEC_MSM_SEL_LCDCLK, | ||
| 93 | PCOM_CLK_REGIME_SEC_VFE_RAIL_OFF, | ||
| 94 | PCOM_CLK_REGIME_SEC_VFE_RAIL_ON, | ||
| 95 | PCOM_CLK_REGIME_SEC_GRP_RAIL_OFF, | ||
| 96 | PCOM_CLK_REGIME_SEC_GRP_RAIL_ON, | ||
| 97 | PCOM_CLK_REGIME_SEC_VDC_RAIL_OFF, | ||
| 98 | PCOM_CLK_REGIME_SEC_VDC_RAIL_ON, | ||
| 99 | PCOM_CLK_REGIME_SEC_LCD_CTRL, | ||
| 100 | PCOM_CLK_REGIME_SEC_REGISTER_FOR_CPU_RESOURCE, | ||
| 101 | PCOM_CLK_REGIME_SEC_DEREGISTER_FOR_CPU_RESOURCE, | ||
| 102 | PCOM_CLK_REGIME_SEC_RESOURCE_REQUEST_WRP, | ||
| 103 | PCOM_CLK_REGIME_MSM_SEC_SEL_CLK_OWNER, | ||
| 104 | PCOM_CLK_REGIME_SEC_DEVMAN_REQUEST_WRP, | ||
| 105 | PCOM_GPIO_CONFIG, | ||
| 106 | PCOM_GPIO_CONFIGURE_GROUP, | ||
| 107 | PCOM_GPIO_TLMM_SET_PORT, | ||
| 108 | PCOM_GPIO_TLMM_CONFIG_EX, | ||
| 109 | PCOM_SET_FTM_BOOT_COUNT, | ||
| 110 | PCOM_RESERVED0, | ||
| 111 | PCOM_RESERVED1, | ||
| 112 | PCOM_CUSTOMER_CMD1, | ||
| 113 | PCOM_CUSTOMER_CMD2, | ||
| 114 | PCOM_CUSTOMER_CMD3, | ||
| 115 | PCOM_CLK_REGIME_ENTER_APPSBL_CHG_MODE, | ||
| 116 | PCOM_CLK_REGIME_EXIT_APPSBL_CHG_MODE, | ||
| 117 | PCOM_CLK_REGIME_SEC_RAIL_DISABLE, | ||
| 118 | PCOM_CLK_REGIME_SEC_RAIL_ENABLE, | ||
| 119 | PCOM_CLK_REGIME_SEC_RAIL_CONTROL, | ||
| 120 | PCOM_SET_SW_WATCHDOG_STATE, | ||
| 121 | PCOM_PM_MPP_CONFIG_DIGITAL_INPUT, | ||
| 122 | PCOM_PM_MPP_CONFIG_I_SINK, | ||
| 123 | PCOM_RESERVED_101, | ||
| 124 | PCOM_MSM_HSUSB_PHY_RESET, | ||
| 125 | PCOM_GET_BATT_MV_LEVEL, | ||
| 126 | PCOM_CHG_USB_IS_PC_CONNECTED, | ||
| 127 | PCOM_CHG_USB_IS_CHARGER_CONNECTED, | ||
| 128 | PCOM_CHG_USB_IS_DISCONNECTED, | ||
| 129 | PCOM_CHG_USB_IS_AVAILABLE, | ||
| 130 | PCOM_CLK_REGIME_SEC_MSM_SEL_FREQ, | ||
| 131 | PCOM_CLK_REGIME_SEC_SET_PCLK_AXI_POLICY, | ||
| 132 | PCOM_CLKCTL_RPC_RESET_ASSERT, | ||
| 133 | PCOM_CLKCTL_RPC_RESET_DEASSERT, | ||
| 134 | PCOM_CLKCTL_RPC_RAIL_ON, | ||
| 135 | PCOM_CLKCTL_RPC_RAIL_OFF, | ||
| 136 | PCOM_CLKCTL_RPC_RAIL_ENABLE, | ||
| 137 | PCOM_CLKCTL_RPC_RAIL_DISABLE, | ||
| 138 | PCOM_CLKCTL_RPC_RAIL_CONTROL, | ||
| 139 | PCOM_CLKCTL_RPC_MIN_MSMC1, | ||
| 65 | PCOM_NUM_CMDS, | 140 | PCOM_NUM_CMDS, |
| 66 | }; | 141 | }; |
| 67 | 142 | ||
| 68 | enum { | 143 | enum { |
| 69 | PCOM_INVALID_STATUS = 0x0, | 144 | PCOM_INVALID_STATUS = 0x0, |
| 70 | PCOM_READY, | 145 | PCOM_READY, |
| 71 | PCOM_CMD_RUNNING, | 146 | PCOM_CMD_RUNNING, |
| 72 | PCOM_CMD_SUCCESS, | 147 | PCOM_CMD_SUCCESS, |
| 73 | PCOM_CMD_FAIL, | 148 | PCOM_CMD_FAIL, |
| 149 | PCOM_CMD_FAIL_FALSE_RETURNED, | ||
| 150 | PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_SERVER, | ||
| 151 | PCOM_CMD_FAIL_CMD_OUT_OF_BOUNDS_CLIENT, | ||
| 152 | PCOM_CMD_FAIL_CMD_UNREGISTERED, | ||
| 153 | PCOM_CMD_FAIL_CMD_LOCKED, | ||
| 154 | PCOM_CMD_FAIL_SERVER_NOT_YET_READY, | ||
| 155 | PCOM_CMD_FAIL_BAD_DESTINATION, | ||
| 156 | PCOM_CMD_FAIL_SERVER_RESET, | ||
| 157 | PCOM_CMD_FAIL_SMSM_NOT_INIT, | ||
| 158 | PCOM_CMD_FAIL_PROC_COMM_BUSY, | ||
| 159 | PCOM_CMD_FAIL_PROC_COMM_NOT_INIT, | ||
| 160 | |||
| 74 | }; | 161 | }; |
| 75 | 162 | ||
| 76 | /* List of VREGs that support the Pull Down Resistor setting. */ | 163 | /* List of VREGs that support the Pull Down Resistor setting. */ |
| 77 | enum { | 164 | enum vreg_pdown_id { |
| 78 | PM_VREG_PDOWN_MSMA_ID, | 165 | PM_VREG_PDOWN_MSMA_ID, |
| 79 | PM_VREG_PDOWN_MSMP_ID, | 166 | PM_VREG_PDOWN_MSMP_ID, |
| 80 | PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */ | 167 | PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */ |
| @@ -131,6 +218,11 @@ enum { | |||
| 131 | PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID | 218 | PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID |
| 132 | }; | 219 | }; |
| 133 | 220 | ||
| 221 | enum { | ||
| 222 | PCOM_CLKRGM_APPS_RESET_USB_PHY = 34, | ||
| 223 | PCOM_CLKRGM_APPS_RESET_USBH = 37, | ||
| 224 | }; | ||
| 225 | |||
| 134 | /* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */ | 226 | /* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */ |
| 135 | 227 | ||
| 136 | #define GPIO_ENABLE 0 | 228 | #define GPIO_ENABLE 0 |
| @@ -161,5 +253,6 @@ enum { | |||
| 161 | (((drvstr) & 0xF) << 17)) | 253 | (((drvstr) & 0xF) << 17)) |
| 162 | 254 | ||
| 163 | int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2); | 255 | int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2); |
| 256 | void __init proc_comm_boot_wait(void); | ||
| 164 | 257 | ||
| 165 | #endif | 258 | #endif |
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c new file mode 100644 index 000000000000..b0794524ba6e --- /dev/null +++ b/arch/arm/mach-msm/sirc.c | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | /* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License version 2 and | ||
| 5 | * only version 2 as published by the Free Software Foundation. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
| 15 | * 02110-1301, USA. | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/io.h> | ||
| 20 | #include <linux/irq.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <asm/irq.h> | ||
| 23 | |||
| 24 | static unsigned int int_enable; | ||
| 25 | static unsigned int wake_enable; | ||
| 26 | |||
| 27 | static struct sirc_regs_t sirc_regs = { | ||
| 28 | .int_enable = SPSS_SIRC_INT_ENABLE, | ||
| 29 | .int_enable_clear = SPSS_SIRC_INT_ENABLE_CLEAR, | ||
| 30 | .int_enable_set = SPSS_SIRC_INT_ENABLE_SET, | ||
| 31 | .int_type = SPSS_SIRC_INT_TYPE, | ||
| 32 | .int_polarity = SPSS_SIRC_INT_POLARITY, | ||
| 33 | .int_clear = SPSS_SIRC_INT_CLEAR, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static struct sirc_cascade_regs sirc_reg_table[] = { | ||
| 37 | { | ||
| 38 | .int_status = SPSS_SIRC_IRQ_STATUS, | ||
| 39 | .cascade_irq = INT_SIRC_0, | ||
| 40 | } | ||
| 41 | }; | ||
| 42 | |||
| 43 | static unsigned int save_type; | ||
| 44 | static unsigned int save_polarity; | ||
| 45 | |||
| 46 | /* Mask off the given interrupt. Keep the int_enable mask in sync with | ||
| 47 | the enable reg, so it can be restored after power collapse. */ | ||
| 48 | static void sirc_irq_mask(unsigned int irq) | ||
| 49 | { | ||
| 50 | unsigned int mask; | ||
| 51 | |||
| 52 | |||
| 53 | mask = 1 << (irq - FIRST_SIRC_IRQ); | ||
| 54 | writel(mask, sirc_regs.int_enable_clear); | ||
| 55 | int_enable &= ~mask; | ||
| 56 | return; | ||
| 57 | } | ||
| 58 | |||
| 59 | /* Unmask the given interrupt. Keep the int_enable mask in sync with | ||
| 60 | the enable reg, so it can be restored after power collapse. */ | ||
| 61 | static void sirc_irq_unmask(unsigned int irq) | ||
| 62 | { | ||
| 63 | unsigned int mask; | ||
| 64 | |||
| 65 | mask = 1 << (irq - FIRST_SIRC_IRQ); | ||
| 66 | writel(mask, sirc_regs.int_enable_set); | ||
| 67 | int_enable |= mask; | ||
| 68 | return; | ||
| 69 | } | ||
| 70 | |||
| 71 | static void sirc_irq_ack(unsigned int irq) | ||
| 72 | { | ||
| 73 | unsigned int mask; | ||
| 74 | |||
| 75 | mask = 1 << (irq - FIRST_SIRC_IRQ); | ||
| 76 | writel(mask, sirc_regs.int_clear); | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 80 | static int sirc_irq_set_wake(unsigned int irq, unsigned int on) | ||
| 81 | { | ||
| 82 | unsigned int mask; | ||
| 83 | |||
| 84 | /* Used to set the interrupt enable mask during power collapse. */ | ||
| 85 | mask = 1 << (irq - FIRST_SIRC_IRQ); | ||
| 86 | if (on) | ||
| 87 | wake_enable |= mask; | ||
| 88 | else | ||
| 89 | wake_enable &= ~mask; | ||
| 90 | |||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static int sirc_irq_set_type(unsigned int irq, unsigned int flow_type) | ||
| 95 | { | ||
| 96 | unsigned int mask; | ||
| 97 | unsigned int val; | ||
| 98 | |||
| 99 | mask = 1 << (irq - FIRST_SIRC_IRQ); | ||
| 100 | val = readl(sirc_regs.int_polarity); | ||
| 101 | |||
| 102 | if (flow_type & (IRQF_TRIGGER_LOW | IRQF_TRIGGER_FALLING)) | ||
| 103 | val |= mask; | ||
| 104 | else | ||
| 105 | val &= ~mask; | ||
| 106 | |||
| 107 | writel(val, sirc_regs.int_polarity); | ||
| 108 | |||
| 109 | val = readl(sirc_regs.int_type); | ||
| 110 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { | ||
| 111 | val |= mask; | ||
| 112 | irq_desc[irq].handle_irq = handle_edge_irq; | ||
| 113 | } else { | ||
| 114 | val &= ~mask; | ||
| 115 | irq_desc[irq].handle_irq = handle_level_irq; | ||
| 116 | } | ||
| 117 | |||
| 118 | writel(val, sirc_regs.int_type); | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | /* Finds the pending interrupt on the passed cascade irq and redrives it */ | ||
| 124 | static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 125 | { | ||
| 126 | unsigned int reg = 0; | ||
| 127 | unsigned int sirq; | ||
| 128 | unsigned int status; | ||
| 129 | |||
| 130 | while ((reg < ARRAY_SIZE(sirc_reg_table)) && | ||
| 131 | (sirc_reg_table[reg].cascade_irq != irq)) | ||
| 132 | reg++; | ||
| 133 | |||
| 134 | status = readl(sirc_reg_table[reg].int_status); | ||
| 135 | status &= SIRC_MASK; | ||
| 136 | if (status == 0) | ||
| 137 | return; | ||
| 138 | |||
| 139 | for (sirq = 0; | ||
| 140 | (sirq < NR_SIRC_IRQS) && ((status & (1U << sirq)) == 0); | ||
| 141 | sirq++) | ||
| 142 | ; | ||
| 143 | generic_handle_irq(sirq+FIRST_SIRC_IRQ); | ||
| 144 | |||
| 145 | desc->chip->ack(irq); | ||
| 146 | } | ||
| 147 | |||
| 148 | static struct irq_chip sirc_irq_chip = { | ||
| 149 | .name = "sirc", | ||
| 150 | .ack = sirc_irq_ack, | ||
| 151 | .mask = sirc_irq_mask, | ||
| 152 | .unmask = sirc_irq_unmask, | ||
| 153 | .set_wake = sirc_irq_set_wake, | ||
| 154 | .set_type = sirc_irq_set_type, | ||
| 155 | }; | ||
| 156 | |||
| 157 | void __init msm_init_sirc(void) | ||
| 158 | { | ||
| 159 | int i; | ||
| 160 | |||
| 161 | int_enable = 0; | ||
| 162 | wake_enable = 0; | ||
| 163 | |||
| 164 | for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) { | ||
| 165 | set_irq_chip(i, &sirc_irq_chip); | ||
| 166 | set_irq_handler(i, handle_edge_irq); | ||
| 167 | set_irq_flags(i, IRQF_VALID); | ||
| 168 | } | ||
| 169 | |||
| 170 | for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) { | ||
| 171 | set_irq_chained_handler(sirc_reg_table[i].cascade_irq, | ||
| 172 | sirc_irq_handler); | ||
| 173 | set_irq_wake(sirc_reg_table[i].cascade_irq, 1); | ||
| 174 | } | ||
| 175 | return; | ||
| 176 | } | ||
| 177 | |||
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c new file mode 100644 index 000000000000..cf11d414b425 --- /dev/null +++ b/arch/arm/mach-msm/smd.c | |||
| @@ -0,0 +1,1046 @@ | |||
| 1 | /* arch/arm/mach-msm/smd.c | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/platform_device.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/fs.h> | ||
| 20 | #include <linux/cdev.h> | ||
| 21 | #include <linux/device.h> | ||
| 22 | #include <linux/wait.h> | ||
| 23 | #include <linux/interrupt.h> | ||
| 24 | #include <linux/irq.h> | ||
| 25 | #include <linux/list.h> | ||
| 26 | #include <linux/slab.h> | ||
| 27 | #include <linux/debugfs.h> | ||
| 28 | #include <linux/delay.h> | ||
| 29 | |||
| 30 | #include <mach/msm_smd.h> | ||
| 31 | #include <mach/system.h> | ||
| 32 | |||
| 33 | #include "smd_private.h" | ||
| 34 | #include "proc_comm.h" | ||
| 35 | |||
| 36 | #if defined(CONFIG_ARCH_QSD8X50) | ||
| 37 | #define CONFIG_QDSP6 1 | ||
| 38 | #endif | ||
| 39 | |||
| 40 | void (*msm_hw_reset_hook)(void); | ||
| 41 | |||
| 42 | #define MODULE_NAME "msm_smd" | ||
| 43 | |||
| 44 | enum { | ||
| 45 | MSM_SMD_DEBUG = 1U << 0, | ||
| 46 | MSM_SMSM_DEBUG = 1U << 0, | ||
| 47 | }; | ||
| 48 | |||
| 49 | static int msm_smd_debug_mask; | ||
| 50 | |||
| 51 | struct shared_info { | ||
| 52 | int ready; | ||
| 53 | unsigned state; | ||
| 54 | }; | ||
| 55 | |||
| 56 | static unsigned dummy_state[SMSM_STATE_COUNT]; | ||
| 57 | |||
| 58 | static struct shared_info smd_info = { | ||
| 59 | .state = (unsigned) &dummy_state, | ||
| 60 | }; | ||
| 61 | |||
| 62 | module_param_named(debug_mask, msm_smd_debug_mask, | ||
| 63 | int, S_IRUGO | S_IWUSR | S_IWGRP); | ||
| 64 | |||
| 65 | static unsigned last_heap_free = 0xffffffff; | ||
| 66 | |||
| 67 | static inline void notify_other_smsm(void) | ||
| 68 | { | ||
| 69 | msm_a2m_int(5); | ||
| 70 | #ifdef CONFIG_QDSP6 | ||
| 71 | msm_a2m_int(8); | ||
| 72 | #endif | ||
| 73 | } | ||
| 74 | |||
| 75 | static inline void notify_modem_smd(void) | ||
| 76 | { | ||
| 77 | msm_a2m_int(0); | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline void notify_dsp_smd(void) | ||
| 81 | { | ||
| 82 | msm_a2m_int(8); | ||
| 83 | } | ||
| 84 | |||
| 85 | static void smd_diag(void) | ||
| 86 | { | ||
| 87 | char *x; | ||
| 88 | |||
| 89 | x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); | ||
| 90 | if (x != 0) { | ||
| 91 | x[SZ_DIAG_ERR_MSG - 1] = 0; | ||
| 92 | pr_info("smem: DIAG '%s'\n", x); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | /* call when SMSM_RESET flag is set in the A9's smsm_state */ | ||
| 97 | static void handle_modem_crash(void) | ||
| 98 | { | ||
| 99 | pr_err("ARM9 has CRASHED\n"); | ||
| 100 | smd_diag(); | ||
| 101 | |||
| 102 | /* hard reboot if possible */ | ||
| 103 | if (msm_hw_reset_hook) | ||
| 104 | msm_hw_reset_hook(); | ||
| 105 | |||
| 106 | /* in this case the modem or watchdog should reboot us */ | ||
| 107 | for (;;) | ||
| 108 | ; | ||
| 109 | } | ||
| 110 | |||
| 111 | uint32_t raw_smsm_get_state(enum smsm_state_item item) | ||
| 112 | { | ||
| 113 | return readl(smd_info.state + item * 4); | ||
| 114 | } | ||
| 115 | |||
| 116 | static int check_for_modem_crash(void) | ||
| 117 | { | ||
| 118 | if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) { | ||
| 119 | handle_modem_crash(); | ||
| 120 | return -1; | ||
| 121 | } | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | /* the spinlock is used to synchronize between the | ||
| 126 | * irq handler and code that mutates the channel | ||
| 127 | * list or fiddles with channel state | ||
| 128 | */ | ||
| 129 | DEFINE_SPINLOCK(smd_lock); | ||
| 130 | DEFINE_SPINLOCK(smem_lock); | ||
| 131 | |||
| 132 | /* the mutex is used during open() and close() | ||
| 133 | * operations to avoid races while creating or | ||
| 134 | * destroying smd_channel structures | ||
| 135 | */ | ||
| 136 | static DEFINE_MUTEX(smd_creation_mutex); | ||
| 137 | |||
| 138 | static int smd_initialized; | ||
| 139 | |||
| 140 | LIST_HEAD(smd_ch_closed_list); | ||
| 141 | LIST_HEAD(smd_ch_list_modem); | ||
| 142 | LIST_HEAD(smd_ch_list_dsp); | ||
| 143 | |||
| 144 | static unsigned char smd_ch_allocated[64]; | ||
| 145 | static struct work_struct probe_work; | ||
| 146 | |||
| 147 | /* how many bytes are available for reading */ | ||
| 148 | static int smd_stream_read_avail(struct smd_channel *ch) | ||
| 149 | { | ||
| 150 | return (ch->recv->head - ch->recv->tail) & ch->fifo_mask; | ||
| 151 | } | ||
| 152 | |||
| 153 | /* how many bytes we are free to write */ | ||
| 154 | static int smd_stream_write_avail(struct smd_channel *ch) | ||
| 155 | { | ||
| 156 | return ch->fifo_mask - | ||
| 157 | ((ch->send->head - ch->send->tail) & ch->fifo_mask); | ||
| 158 | } | ||
| 159 | |||
| 160 | static int smd_packet_read_avail(struct smd_channel *ch) | ||
| 161 | { | ||
| 162 | if (ch->current_packet) { | ||
| 163 | int n = smd_stream_read_avail(ch); | ||
| 164 | if (n > ch->current_packet) | ||
| 165 | n = ch->current_packet; | ||
| 166 | return n; | ||
| 167 | } else { | ||
| 168 | return 0; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 172 | static int smd_packet_write_avail(struct smd_channel *ch) | ||
| 173 | { | ||
| 174 | int n = smd_stream_write_avail(ch); | ||
| 175 | return n > SMD_HEADER_SIZE ? n - SMD_HEADER_SIZE : 0; | ||
| 176 | } | ||
| 177 | |||
| 178 | static int ch_is_open(struct smd_channel *ch) | ||
| 179 | { | ||
| 180 | return (ch->recv->state == SMD_SS_OPENED) && | ||
| 181 | (ch->send->state == SMD_SS_OPENED); | ||
| 182 | } | ||
| 183 | |||
| 184 | /* provide a pointer and length to readable data in the fifo */ | ||
| 185 | static unsigned ch_read_buffer(struct smd_channel *ch, void **ptr) | ||
| 186 | { | ||
| 187 | unsigned head = ch->recv->head; | ||
| 188 | unsigned tail = ch->recv->tail; | ||
| 189 | *ptr = (void *) (ch->recv_data + tail); | ||
| 190 | |||
| 191 | if (tail <= head) | ||
| 192 | return head - tail; | ||
| 193 | else | ||
| 194 | return ch->fifo_size - tail; | ||
| 195 | } | ||
| 196 | |||
| 197 | /* advance the fifo read pointer after data from ch_read_buffer is consumed */ | ||
| 198 | static void ch_read_done(struct smd_channel *ch, unsigned count) | ||
| 199 | { | ||
| 200 | BUG_ON(count > smd_stream_read_avail(ch)); | ||
| 201 | ch->recv->tail = (ch->recv->tail + count) & ch->fifo_mask; | ||
| 202 | ch->send->fTAIL = 1; | ||
| 203 | } | ||
| 204 | |||
| 205 | /* basic read interface to ch_read_{buffer,done} used | ||
| 206 | * by smd_*_read() and update_packet_state() | ||
| 207 | * will read-and-discard if the _data pointer is null | ||
| 208 | */ | ||
| 209 | static int ch_read(struct smd_channel *ch, void *_data, int len) | ||
| 210 | { | ||
| 211 | void *ptr; | ||
| 212 | unsigned n; | ||
| 213 | unsigned char *data = _data; | ||
| 214 | int orig_len = len; | ||
| 215 | |||
| 216 | while (len > 0) { | ||
| 217 | n = ch_read_buffer(ch, &ptr); | ||
| 218 | if (n == 0) | ||
| 219 | break; | ||
| 220 | |||
| 221 | if (n > len) | ||
| 222 | n = len; | ||
| 223 | if (_data) | ||
| 224 | memcpy(data, ptr, n); | ||
| 225 | |||
| 226 | data += n; | ||
| 227 | len -= n; | ||
| 228 | ch_read_done(ch, n); | ||
| 229 | } | ||
| 230 | |||
| 231 | return orig_len - len; | ||
| 232 | } | ||
| 233 | |||
| 234 | static void update_stream_state(struct smd_channel *ch) | ||
| 235 | { | ||
| 236 | /* streams have no special state requiring updating */ | ||
| 237 | } | ||
| 238 | |||
| 239 | static void update_packet_state(struct smd_channel *ch) | ||
| 240 | { | ||
| 241 | unsigned hdr[5]; | ||
| 242 | int r; | ||
| 243 | |||
| 244 | /* can't do anything if we're in the middle of a packet */ | ||
| 245 | if (ch->current_packet != 0) | ||
| 246 | return; | ||
| 247 | |||
| 248 | /* don't bother unless we can get the full header */ | ||
| 249 | if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE) | ||
| 250 | return; | ||
| 251 | |||
| 252 | r = ch_read(ch, hdr, SMD_HEADER_SIZE); | ||
| 253 | BUG_ON(r != SMD_HEADER_SIZE); | ||
| 254 | |||
| 255 | ch->current_packet = hdr[0]; | ||
| 256 | } | ||
| 257 | |||
| 258 | /* provide a pointer and length to next free space in the fifo */ | ||
| 259 | static unsigned ch_write_buffer(struct smd_channel *ch, void **ptr) | ||
| 260 | { | ||
| 261 | unsigned head = ch->send->head; | ||
| 262 | unsigned tail = ch->send->tail; | ||
| 263 | *ptr = (void *) (ch->send_data + head); | ||
| 264 | |||
| 265 | if (head < tail) { | ||
| 266 | return tail - head - 1; | ||
| 267 | } else { | ||
| 268 | if (tail == 0) | ||
| 269 | return ch->fifo_size - head - 1; | ||
| 270 | else | ||
| 271 | return ch->fifo_size - head; | ||
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 | /* advace the fifo write pointer after freespace | ||
| 276 | * from ch_write_buffer is filled | ||
| 277 | */ | ||
| 278 | static void ch_write_done(struct smd_channel *ch, unsigned count) | ||
| 279 | { | ||
| 280 | BUG_ON(count > smd_stream_write_avail(ch)); | ||
| 281 | ch->send->head = (ch->send->head + count) & ch->fifo_mask; | ||
| 282 | ch->send->fHEAD = 1; | ||
| 283 | } | ||
| 284 | |||
| 285 | static void ch_set_state(struct smd_channel *ch, unsigned n) | ||
| 286 | { | ||
| 287 | if (n == SMD_SS_OPENED) { | ||
| 288 | ch->send->fDSR = 1; | ||
| 289 | ch->send->fCTS = 1; | ||
| 290 | ch->send->fCD = 1; | ||
| 291 | } else { | ||
| 292 | ch->send->fDSR = 0; | ||
| 293 | ch->send->fCTS = 0; | ||
| 294 | ch->send->fCD = 0; | ||
| 295 | } | ||
| 296 | ch->send->state = n; | ||
| 297 | ch->send->fSTATE = 1; | ||
| 298 | ch->notify_other_cpu(); | ||
| 299 | } | ||
| 300 | |||
| 301 | static void do_smd_probe(void) | ||
| 302 | { | ||
| 303 | struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; | ||
| 304 | if (shared->heap_info.free_offset != last_heap_free) { | ||
| 305 | last_heap_free = shared->heap_info.free_offset; | ||
| 306 | schedule_work(&probe_work); | ||
| 307 | } | ||
| 308 | } | ||
| 309 | |||
| 310 | static void smd_state_change(struct smd_channel *ch, | ||
| 311 | unsigned last, unsigned next) | ||
| 312 | { | ||
| 313 | ch->last_state = next; | ||
| 314 | |||
| 315 | pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next); | ||
| 316 | |||
| 317 | switch (next) { | ||
| 318 | case SMD_SS_OPENING: | ||
| 319 | ch->recv->tail = 0; | ||
| 320 | case SMD_SS_OPENED: | ||
| 321 | if (ch->send->state != SMD_SS_OPENED) | ||
| 322 | ch_set_state(ch, SMD_SS_OPENED); | ||
| 323 | ch->notify(ch->priv, SMD_EVENT_OPEN); | ||
| 324 | break; | ||
| 325 | case SMD_SS_FLUSHING: | ||
| 326 | case SMD_SS_RESET: | ||
| 327 | /* we should force them to close? */ | ||
| 328 | default: | ||
| 329 | ch->notify(ch->priv, SMD_EVENT_CLOSE); | ||
| 330 | } | ||
| 331 | } | ||
| 332 | |||
| 333 | static void handle_smd_irq(struct list_head *list, void (*notify)(void)) | ||
| 334 | { | ||
| 335 | unsigned long flags; | ||
| 336 | struct smd_channel *ch; | ||
| 337 | int do_notify = 0; | ||
| 338 | unsigned ch_flags; | ||
| 339 | unsigned tmp; | ||
| 340 | |||
| 341 | spin_lock_irqsave(&smd_lock, flags); | ||
| 342 | list_for_each_entry(ch, list, ch_list) { | ||
| 343 | ch_flags = 0; | ||
| 344 | if (ch_is_open(ch)) { | ||
| 345 | if (ch->recv->fHEAD) { | ||
| 346 | ch->recv->fHEAD = 0; | ||
| 347 | ch_flags |= 1; | ||
| 348 | do_notify |= 1; | ||
| 349 | } | ||
| 350 | if (ch->recv->fTAIL) { | ||
| 351 | ch->recv->fTAIL = 0; | ||
| 352 | ch_flags |= 2; | ||
| 353 | do_notify |= 1; | ||
| 354 | } | ||
| 355 | if (ch->recv->fSTATE) { | ||
| 356 | ch->recv->fSTATE = 0; | ||
| 357 | ch_flags |= 4; | ||
| 358 | do_notify |= 1; | ||
| 359 | } | ||
| 360 | } | ||
| 361 | tmp = ch->recv->state; | ||
| 362 | if (tmp != ch->last_state) | ||
| 363 | smd_state_change(ch, ch->last_state, tmp); | ||
| 364 | if (ch_flags) { | ||
| 365 | ch->update_state(ch); | ||
| 366 | ch->notify(ch->priv, SMD_EVENT_DATA); | ||
| 367 | } | ||
| 368 | } | ||
| 369 | if (do_notify) | ||
| 370 | notify(); | ||
| 371 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 372 | do_smd_probe(); | ||
| 373 | } | ||
| 374 | |||
| 375 | static irqreturn_t smd_modem_irq_handler(int irq, void *data) | ||
| 376 | { | ||
| 377 | handle_smd_irq(&smd_ch_list_modem, notify_modem_smd); | ||
| 378 | return IRQ_HANDLED; | ||
| 379 | } | ||
| 380 | |||
| 381 | #if defined(CONFIG_QDSP6) | ||
| 382 | static irqreturn_t smd_dsp_irq_handler(int irq, void *data) | ||
| 383 | { | ||
| 384 | handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd); | ||
| 385 | return IRQ_HANDLED; | ||
| 386 | } | ||
| 387 | #endif | ||
| 388 | |||
| 389 | static void smd_fake_irq_handler(unsigned long arg) | ||
| 390 | { | ||
| 391 | handle_smd_irq(&smd_ch_list_modem, notify_modem_smd); | ||
| 392 | handle_smd_irq(&smd_ch_list_dsp, notify_dsp_smd); | ||
| 393 | } | ||
| 394 | |||
| 395 | static DECLARE_TASKLET(smd_fake_irq_tasklet, smd_fake_irq_handler, 0); | ||
| 396 | |||
| 397 | static inline int smd_need_int(struct smd_channel *ch) | ||
| 398 | { | ||
| 399 | if (ch_is_open(ch)) { | ||
| 400 | if (ch->recv->fHEAD || ch->recv->fTAIL || ch->recv->fSTATE) | ||
| 401 | return 1; | ||
| 402 | if (ch->recv->state != ch->last_state) | ||
| 403 | return 1; | ||
| 404 | } | ||
| 405 | return 0; | ||
| 406 | } | ||
| 407 | |||
| 408 | void smd_sleep_exit(void) | ||
| 409 | { | ||
| 410 | unsigned long flags; | ||
| 411 | struct smd_channel *ch; | ||
| 412 | int need_int = 0; | ||
| 413 | |||
| 414 | spin_lock_irqsave(&smd_lock, flags); | ||
| 415 | list_for_each_entry(ch, &smd_ch_list_modem, ch_list) { | ||
| 416 | if (smd_need_int(ch)) { | ||
| 417 | need_int = 1; | ||
| 418 | break; | ||
| 419 | } | ||
| 420 | } | ||
| 421 | list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) { | ||
| 422 | if (smd_need_int(ch)) { | ||
| 423 | need_int = 1; | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | } | ||
| 427 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 428 | do_smd_probe(); | ||
| 429 | |||
| 430 | if (need_int) { | ||
| 431 | if (msm_smd_debug_mask & MSM_SMD_DEBUG) | ||
| 432 | pr_info("smd_sleep_exit need interrupt\n"); | ||
| 433 | tasklet_schedule(&smd_fake_irq_tasklet); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | |||
| 438 | void smd_kick(smd_channel_t *ch) | ||
| 439 | { | ||
| 440 | unsigned long flags; | ||
| 441 | unsigned tmp; | ||
| 442 | |||
| 443 | spin_lock_irqsave(&smd_lock, flags); | ||
| 444 | ch->update_state(ch); | ||
| 445 | tmp = ch->recv->state; | ||
| 446 | if (tmp != ch->last_state) { | ||
| 447 | ch->last_state = tmp; | ||
| 448 | if (tmp == SMD_SS_OPENED) | ||
| 449 | ch->notify(ch->priv, SMD_EVENT_OPEN); | ||
| 450 | else | ||
| 451 | ch->notify(ch->priv, SMD_EVENT_CLOSE); | ||
| 452 | } | ||
| 453 | ch->notify(ch->priv, SMD_EVENT_DATA); | ||
| 454 | ch->notify_other_cpu(); | ||
| 455 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 456 | } | ||
| 457 | |||
| 458 | static int smd_is_packet(int chn, unsigned type) | ||
| 459 | { | ||
| 460 | type &= SMD_KIND_MASK; | ||
| 461 | if (type == SMD_KIND_PACKET) | ||
| 462 | return 1; | ||
| 463 | if (type == SMD_KIND_STREAM) | ||
| 464 | return 0; | ||
| 465 | |||
| 466 | /* older AMSS reports SMD_KIND_UNKNOWN always */ | ||
| 467 | if ((chn > 4) || (chn == 1)) | ||
| 468 | return 1; | ||
| 469 | else | ||
| 470 | return 0; | ||
| 471 | } | ||
| 472 | |||
| 473 | static int smd_stream_write(smd_channel_t *ch, const void *_data, int len) | ||
| 474 | { | ||
| 475 | void *ptr; | ||
| 476 | const unsigned char *buf = _data; | ||
| 477 | unsigned xfer; | ||
| 478 | int orig_len = len; | ||
| 479 | |||
| 480 | if (len < 0) | ||
| 481 | return -EINVAL; | ||
| 482 | |||
| 483 | while ((xfer = ch_write_buffer(ch, &ptr)) != 0) { | ||
| 484 | if (!ch_is_open(ch)) | ||
| 485 | break; | ||
| 486 | if (xfer > len) | ||
| 487 | xfer = len; | ||
| 488 | memcpy(ptr, buf, xfer); | ||
| 489 | ch_write_done(ch, xfer); | ||
| 490 | len -= xfer; | ||
| 491 | buf += xfer; | ||
| 492 | if (len == 0) | ||
| 493 | break; | ||
| 494 | } | ||
| 495 | |||
| 496 | ch->notify_other_cpu(); | ||
| 497 | |||
| 498 | return orig_len - len; | ||
| 499 | } | ||
| 500 | |||
| 501 | static int smd_packet_write(smd_channel_t *ch, const void *_data, int len) | ||
| 502 | { | ||
| 503 | unsigned hdr[5]; | ||
| 504 | |||
| 505 | if (len < 0) | ||
| 506 | return -EINVAL; | ||
| 507 | |||
| 508 | if (smd_stream_write_avail(ch) < (len + SMD_HEADER_SIZE)) | ||
| 509 | return -ENOMEM; | ||
| 510 | |||
| 511 | hdr[0] = len; | ||
| 512 | hdr[1] = hdr[2] = hdr[3] = hdr[4] = 0; | ||
| 513 | |||
| 514 | smd_stream_write(ch, hdr, sizeof(hdr)); | ||
| 515 | smd_stream_write(ch, _data, len); | ||
| 516 | |||
| 517 | return len; | ||
| 518 | } | ||
| 519 | |||
| 520 | static int smd_stream_read(smd_channel_t *ch, void *data, int len) | ||
| 521 | { | ||
| 522 | int r; | ||
| 523 | |||
| 524 | if (len < 0) | ||
| 525 | return -EINVAL; | ||
| 526 | |||
| 527 | r = ch_read(ch, data, len); | ||
| 528 | if (r > 0) | ||
| 529 | ch->notify_other_cpu(); | ||
| 530 | |||
| 531 | return r; | ||
| 532 | } | ||
| 533 | |||
| 534 | static int smd_packet_read(smd_channel_t *ch, void *data, int len) | ||
| 535 | { | ||
| 536 | unsigned long flags; | ||
| 537 | int r; | ||
| 538 | |||
| 539 | if (len < 0) | ||
| 540 | return -EINVAL; | ||
| 541 | |||
| 542 | if (len > ch->current_packet) | ||
| 543 | len = ch->current_packet; | ||
| 544 | |||
| 545 | r = ch_read(ch, data, len); | ||
| 546 | if (r > 0) | ||
| 547 | ch->notify_other_cpu(); | ||
| 548 | |||
| 549 | spin_lock_irqsave(&smd_lock, flags); | ||
| 550 | ch->current_packet -= r; | ||
| 551 | update_packet_state(ch); | ||
| 552 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 553 | |||
| 554 | return r; | ||
| 555 | } | ||
| 556 | |||
| 557 | static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) | ||
| 558 | { | ||
| 559 | struct smd_channel *ch; | ||
| 560 | |||
| 561 | ch = kzalloc(sizeof(struct smd_channel), GFP_KERNEL); | ||
| 562 | if (ch == 0) { | ||
| 563 | pr_err("smd_alloc_channel() out of memory\n"); | ||
| 564 | return -1; | ||
| 565 | } | ||
| 566 | ch->n = cid; | ||
| 567 | |||
| 568 | if (_smd_alloc_channel(ch)) { | ||
| 569 | kfree(ch); | ||
| 570 | return -1; | ||
| 571 | } | ||
| 572 | |||
| 573 | ch->fifo_mask = ch->fifo_size - 1; | ||
| 574 | ch->type = type; | ||
| 575 | |||
| 576 | if ((type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM) | ||
| 577 | ch->notify_other_cpu = notify_modem_smd; | ||
| 578 | else | ||
| 579 | ch->notify_other_cpu = notify_dsp_smd; | ||
| 580 | |||
| 581 | if (smd_is_packet(cid, type)) { | ||
| 582 | ch->read = smd_packet_read; | ||
| 583 | ch->write = smd_packet_write; | ||
| 584 | ch->read_avail = smd_packet_read_avail; | ||
| 585 | ch->write_avail = smd_packet_write_avail; | ||
| 586 | ch->update_state = update_packet_state; | ||
| 587 | } else { | ||
| 588 | ch->read = smd_stream_read; | ||
| 589 | ch->write = smd_stream_write; | ||
| 590 | ch->read_avail = smd_stream_read_avail; | ||
| 591 | ch->write_avail = smd_stream_write_avail; | ||
| 592 | ch->update_state = update_stream_state; | ||
| 593 | } | ||
| 594 | |||
| 595 | if ((type & 0xff) == 0) | ||
| 596 | memcpy(ch->name, "SMD_", 4); | ||
| 597 | else | ||
| 598 | memcpy(ch->name, "DSP_", 4); | ||
| 599 | memcpy(ch->name + 4, name, 20); | ||
| 600 | ch->name[23] = 0; | ||
| 601 | ch->pdev.name = ch->name; | ||
| 602 | ch->pdev.id = -1; | ||
| 603 | |||
| 604 | pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n", | ||
| 605 | ch->n, ch->fifo_size, ch->name); | ||
| 606 | |||
| 607 | mutex_lock(&smd_creation_mutex); | ||
| 608 | list_add(&ch->ch_list, &smd_ch_closed_list); | ||
| 609 | mutex_unlock(&smd_creation_mutex); | ||
| 610 | |||
| 611 | platform_device_register(&ch->pdev); | ||
| 612 | return 0; | ||
| 613 | } | ||
| 614 | |||
| 615 | static void smd_channel_probe_worker(struct work_struct *work) | ||
| 616 | { | ||
| 617 | struct smd_alloc_elm *shared; | ||
| 618 | unsigned ctype; | ||
| 619 | unsigned type; | ||
| 620 | unsigned n; | ||
| 621 | |||
| 622 | shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); | ||
| 623 | if (!shared) { | ||
| 624 | pr_err("smd: cannot find allocation table\n"); | ||
| 625 | return; | ||
| 626 | } | ||
| 627 | for (n = 0; n < 64; n++) { | ||
| 628 | if (smd_ch_allocated[n]) | ||
| 629 | continue; | ||
| 630 | if (!shared[n].ref_count) | ||
| 631 | continue; | ||
| 632 | if (!shared[n].name[0]) | ||
| 633 | continue; | ||
| 634 | ctype = shared[n].ctype; | ||
| 635 | type = ctype & SMD_TYPE_MASK; | ||
| 636 | |||
| 637 | /* DAL channels are stream but neither the modem, | ||
| 638 | * nor the DSP correctly indicate this. Fixup manually. | ||
| 639 | */ | ||
| 640 | if (!memcmp(shared[n].name, "DAL", 3)) | ||
| 641 | ctype = (ctype & (~SMD_KIND_MASK)) | SMD_KIND_STREAM; | ||
| 642 | |||
| 643 | type = shared[n].ctype & SMD_TYPE_MASK; | ||
| 644 | if ((type == SMD_TYPE_APPS_MODEM) || | ||
| 645 | (type == SMD_TYPE_APPS_DSP)) | ||
| 646 | if (!smd_alloc_channel(shared[n].name, shared[n].cid, ctype)) | ||
| 647 | smd_ch_allocated[n] = 1; | ||
| 648 | } | ||
| 649 | } | ||
| 650 | |||
| 651 | static void do_nothing_notify(void *priv, unsigned flags) | ||
| 652 | { | ||
| 653 | } | ||
| 654 | |||
| 655 | struct smd_channel *smd_get_channel(const char *name) | ||
| 656 | { | ||
| 657 | struct smd_channel *ch; | ||
| 658 | |||
| 659 | mutex_lock(&smd_creation_mutex); | ||
| 660 | list_for_each_entry(ch, &smd_ch_closed_list, ch_list) { | ||
| 661 | if (!strcmp(name, ch->name)) { | ||
| 662 | list_del(&ch->ch_list); | ||
| 663 | mutex_unlock(&smd_creation_mutex); | ||
| 664 | return ch; | ||
| 665 | } | ||
| 666 | } | ||
| 667 | mutex_unlock(&smd_creation_mutex); | ||
| 668 | |||
| 669 | return NULL; | ||
| 670 | } | ||
| 671 | |||
| 672 | int smd_open(const char *name, smd_channel_t **_ch, | ||
| 673 | void *priv, void (*notify)(void *, unsigned)) | ||
| 674 | { | ||
| 675 | struct smd_channel *ch; | ||
| 676 | unsigned long flags; | ||
| 677 | |||
| 678 | if (smd_initialized == 0) { | ||
| 679 | pr_info("smd_open() before smd_init()\n"); | ||
| 680 | return -ENODEV; | ||
| 681 | } | ||
| 682 | |||
| 683 | ch = smd_get_channel(name); | ||
| 684 | if (!ch) | ||
| 685 | return -ENODEV; | ||
| 686 | |||
| 687 | if (notify == 0) | ||
| 688 | notify = do_nothing_notify; | ||
| 689 | |||
| 690 | ch->notify = notify; | ||
| 691 | ch->current_packet = 0; | ||
| 692 | ch->last_state = SMD_SS_CLOSED; | ||
| 693 | ch->priv = priv; | ||
| 694 | |||
| 695 | *_ch = ch; | ||
| 696 | |||
| 697 | spin_lock_irqsave(&smd_lock, flags); | ||
| 698 | |||
| 699 | if ((ch->type & SMD_TYPE_MASK) == SMD_TYPE_APPS_MODEM) | ||
| 700 | list_add(&ch->ch_list, &smd_ch_list_modem); | ||
| 701 | else | ||
| 702 | list_add(&ch->ch_list, &smd_ch_list_dsp); | ||
| 703 | |||
| 704 | /* If the remote side is CLOSING, we need to get it to | ||
| 705 | * move to OPENING (which we'll do by moving from CLOSED to | ||
| 706 | * OPENING) and then get it to move from OPENING to | ||
| 707 | * OPENED (by doing the same state change ourselves). | ||
| 708 | * | ||
| 709 | * Otherwise, it should be OPENING and we can move directly | ||
| 710 | * to OPENED so that it will follow. | ||
| 711 | */ | ||
| 712 | if (ch->recv->state == SMD_SS_CLOSING) { | ||
| 713 | ch->send->head = 0; | ||
| 714 | ch_set_state(ch, SMD_SS_OPENING); | ||
| 715 | } else { | ||
| 716 | ch_set_state(ch, SMD_SS_OPENED); | ||
| 717 | } | ||
| 718 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 719 | smd_kick(ch); | ||
| 720 | |||
| 721 | return 0; | ||
| 722 | } | ||
| 723 | |||
| 724 | int smd_close(smd_channel_t *ch) | ||
| 725 | { | ||
| 726 | unsigned long flags; | ||
| 727 | |||
| 728 | pr_info("smd_close(%p)\n", ch); | ||
| 729 | |||
| 730 | if (ch == 0) | ||
| 731 | return -1; | ||
| 732 | |||
| 733 | spin_lock_irqsave(&smd_lock, flags); | ||
| 734 | ch->notify = do_nothing_notify; | ||
| 735 | list_del(&ch->ch_list); | ||
| 736 | ch_set_state(ch, SMD_SS_CLOSED); | ||
| 737 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 738 | |||
| 739 | mutex_lock(&smd_creation_mutex); | ||
| 740 | list_add(&ch->ch_list, &smd_ch_closed_list); | ||
| 741 | mutex_unlock(&smd_creation_mutex); | ||
| 742 | |||
| 743 | return 0; | ||
| 744 | } | ||
| 745 | |||
| 746 | int smd_read(smd_channel_t *ch, void *data, int len) | ||
| 747 | { | ||
| 748 | return ch->read(ch, data, len); | ||
| 749 | } | ||
| 750 | |||
| 751 | int smd_write(smd_channel_t *ch, const void *data, int len) | ||
| 752 | { | ||
| 753 | return ch->write(ch, data, len); | ||
| 754 | } | ||
| 755 | |||
| 756 | int smd_write_atomic(smd_channel_t *ch, const void *data, int len) | ||
| 757 | { | ||
| 758 | unsigned long flags; | ||
| 759 | int res; | ||
| 760 | spin_lock_irqsave(&smd_lock, flags); | ||
| 761 | res = ch->write(ch, data, len); | ||
| 762 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 763 | return res; | ||
| 764 | } | ||
| 765 | |||
| 766 | int smd_read_avail(smd_channel_t *ch) | ||
| 767 | { | ||
| 768 | return ch->read_avail(ch); | ||
| 769 | } | ||
| 770 | |||
| 771 | int smd_write_avail(smd_channel_t *ch) | ||
| 772 | { | ||
| 773 | return ch->write_avail(ch); | ||
| 774 | } | ||
| 775 | |||
| 776 | int smd_wait_until_readable(smd_channel_t *ch, int bytes) | ||
| 777 | { | ||
| 778 | return -1; | ||
| 779 | } | ||
| 780 | |||
| 781 | int smd_wait_until_writable(smd_channel_t *ch, int bytes) | ||
| 782 | { | ||
| 783 | return -1; | ||
| 784 | } | ||
| 785 | |||
| 786 | int smd_cur_packet_size(smd_channel_t *ch) | ||
| 787 | { | ||
| 788 | return ch->current_packet; | ||
| 789 | } | ||
| 790 | |||
| 791 | |||
| 792 | /* ------------------------------------------------------------------------- */ | ||
| 793 | |||
| 794 | void *smem_alloc(unsigned id, unsigned size) | ||
| 795 | { | ||
| 796 | return smem_find(id, size); | ||
| 797 | } | ||
| 798 | |||
| 799 | void *smem_item(unsigned id, unsigned *size) | ||
| 800 | { | ||
| 801 | struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; | ||
| 802 | struct smem_heap_entry *toc = shared->heap_toc; | ||
| 803 | |||
| 804 | if (id >= SMEM_NUM_ITEMS) | ||
| 805 | return 0; | ||
| 806 | |||
| 807 | if (toc[id].allocated) { | ||
| 808 | *size = toc[id].size; | ||
| 809 | return (void *) (MSM_SHARED_RAM_BASE + toc[id].offset); | ||
| 810 | } else { | ||
| 811 | *size = 0; | ||
| 812 | } | ||
| 813 | |||
| 814 | return 0; | ||
| 815 | } | ||
| 816 | |||
| 817 | void *smem_find(unsigned id, unsigned size_in) | ||
| 818 | { | ||
| 819 | unsigned size; | ||
| 820 | void *ptr; | ||
| 821 | |||
| 822 | ptr = smem_item(id, &size); | ||
| 823 | if (!ptr) | ||
| 824 | return 0; | ||
| 825 | |||
| 826 | size_in = ALIGN(size_in, 8); | ||
| 827 | if (size_in != size) { | ||
| 828 | pr_err("smem_find(%d, %d): wrong size %d\n", | ||
| 829 | id, size_in, size); | ||
| 830 | return 0; | ||
| 831 | } | ||
| 832 | |||
| 833 | return ptr; | ||
| 834 | } | ||
| 835 | |||
| 836 | static irqreturn_t smsm_irq_handler(int irq, void *data) | ||
| 837 | { | ||
| 838 | unsigned long flags; | ||
| 839 | unsigned apps, modm; | ||
| 840 | |||
| 841 | spin_lock_irqsave(&smem_lock, flags); | ||
| 842 | |||
| 843 | apps = raw_smsm_get_state(SMSM_STATE_APPS); | ||
| 844 | modm = raw_smsm_get_state(SMSM_STATE_MODEM); | ||
| 845 | |||
| 846 | if (msm_smd_debug_mask & MSM_SMSM_DEBUG) | ||
| 847 | pr_info("<SM %08x %08x>\n", apps, modm); | ||
| 848 | if (modm & SMSM_RESET) | ||
| 849 | handle_modem_crash(); | ||
| 850 | |||
| 851 | do_smd_probe(); | ||
| 852 | |||
| 853 | spin_unlock_irqrestore(&smem_lock, flags); | ||
| 854 | return IRQ_HANDLED; | ||
| 855 | } | ||
| 856 | |||
| 857 | int smsm_change_state(enum smsm_state_item item, | ||
| 858 | uint32_t clear_mask, uint32_t set_mask) | ||
| 859 | { | ||
| 860 | unsigned long addr = smd_info.state + item * 4; | ||
| 861 | unsigned long flags; | ||
| 862 | unsigned state; | ||
| 863 | |||
| 864 | if (!smd_info.ready) | ||
| 865 | return -EIO; | ||
| 866 | |||
| 867 | spin_lock_irqsave(&smem_lock, flags); | ||
| 868 | |||
| 869 | if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) | ||
| 870 | handle_modem_crash(); | ||
| 871 | |||
| 872 | state = (readl(addr) & ~clear_mask) | set_mask; | ||
| 873 | writel(state, addr); | ||
| 874 | |||
| 875 | if (msm_smd_debug_mask & MSM_SMSM_DEBUG) | ||
| 876 | pr_info("smsm_change_state %d %x\n", item, state); | ||
| 877 | notify_other_smsm(); | ||
| 878 | |||
| 879 | spin_unlock_irqrestore(&smem_lock, flags); | ||
| 880 | |||
| 881 | return 0; | ||
| 882 | } | ||
| 883 | |||
| 884 | uint32_t smsm_get_state(enum smsm_state_item item) | ||
| 885 | { | ||
| 886 | unsigned long flags; | ||
| 887 | uint32_t rv; | ||
| 888 | |||
| 889 | spin_lock_irqsave(&smem_lock, flags); | ||
| 890 | |||
| 891 | rv = readl(smd_info.state + item * 4); | ||
| 892 | |||
| 893 | if (item == SMSM_STATE_MODEM && (rv & SMSM_RESET)) | ||
| 894 | handle_modem_crash(); | ||
| 895 | |||
| 896 | spin_unlock_irqrestore(&smem_lock, flags); | ||
| 897 | |||
| 898 | return rv; | ||
| 899 | } | ||
| 900 | |||
| 901 | #ifdef CONFIG_ARCH_MSM_SCORPION | ||
| 902 | |||
| 903 | int smsm_set_sleep_duration(uint32_t delay) | ||
| 904 | { | ||
| 905 | struct msm_dem_slave_data *ptr; | ||
| 906 | |||
| 907 | ptr = smem_find(SMEM_APPS_DEM_SLAVE_DATA, sizeof(*ptr)); | ||
| 908 | if (ptr == NULL) { | ||
| 909 | pr_err("smsm_set_sleep_duration <SM NO APPS_DEM_SLAVE_DATA>\n"); | ||
| 910 | return -EIO; | ||
| 911 | } | ||
| 912 | if (msm_smd_debug_mask & MSM_SMSM_DEBUG) | ||
| 913 | pr_info("smsm_set_sleep_duration %d -> %d\n", | ||
| 914 | ptr->sleep_time, delay); | ||
| 915 | ptr->sleep_time = delay; | ||
| 916 | return 0; | ||
| 917 | } | ||
| 918 | |||
| 919 | #else | ||
| 920 | |||
| 921 | int smsm_set_sleep_duration(uint32_t delay) | ||
| 922 | { | ||
| 923 | uint32_t *ptr; | ||
| 924 | |||
| 925 | ptr = smem_find(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); | ||
| 926 | if (ptr == NULL) { | ||
| 927 | pr_err("smsm_set_sleep_duration <SM NO SLEEP_DELAY>\n"); | ||
| 928 | return -EIO; | ||
| 929 | } | ||
| 930 | if (msm_smd_debug_mask & MSM_SMSM_DEBUG) | ||
| 931 | pr_info("smsm_set_sleep_duration %d -> %d\n", | ||
| 932 | *ptr, delay); | ||
| 933 | *ptr = delay; | ||
| 934 | return 0; | ||
| 935 | } | ||
| 936 | |||
| 937 | #endif | ||
| 938 | |||
| 939 | int smd_core_init(void) | ||
| 940 | { | ||
| 941 | int r; | ||
| 942 | pr_info("smd_core_init()\n"); | ||
| 943 | |||
| 944 | /* wait for essential items to be initialized */ | ||
| 945 | for (;;) { | ||
| 946 | unsigned size; | ||
| 947 | void *state; | ||
| 948 | state = smem_item(SMEM_SMSM_SHARED_STATE, &size); | ||
| 949 | if (size == SMSM_V1_SIZE || size == SMSM_V2_SIZE) { | ||
| 950 | smd_info.state = (unsigned)state; | ||
| 951 | break; | ||
| 952 | } | ||
| 953 | } | ||
| 954 | |||
| 955 | smd_info.ready = 1; | ||
| 956 | |||
| 957 | r = request_irq(INT_A9_M2A_0, smd_modem_irq_handler, | ||
| 958 | IRQF_TRIGGER_RISING, "smd_dev", 0); | ||
| 959 | if (r < 0) | ||
| 960 | return r; | ||
| 961 | r = enable_irq_wake(INT_A9_M2A_0); | ||
| 962 | if (r < 0) | ||
| 963 | pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_0\n"); | ||
| 964 | |||
| 965 | r = request_irq(INT_A9_M2A_5, smsm_irq_handler, | ||
| 966 | IRQF_TRIGGER_RISING, "smsm_dev", 0); | ||
| 967 | if (r < 0) { | ||
| 968 | free_irq(INT_A9_M2A_0, 0); | ||
| 969 | return r; | ||
| 970 | } | ||
| 971 | r = enable_irq_wake(INT_A9_M2A_5); | ||
| 972 | if (r < 0) | ||
| 973 | pr_err("smd_core_init: enable_irq_wake failed for A9_M2A_5\n"); | ||
| 974 | |||
| 975 | #if defined(CONFIG_QDSP6) | ||
| 976 | r = request_irq(INT_ADSP_A11, smd_dsp_irq_handler, | ||
| 977 | IRQF_TRIGGER_RISING, "smd_dsp", 0); | ||
| 978 | if (r < 0) { | ||
| 979 | free_irq(INT_A9_M2A_0, 0); | ||
| 980 | free_irq(INT_A9_M2A_5, 0); | ||
| 981 | return r; | ||
| 982 | } | ||
| 983 | #endif | ||
| 984 | |||
| 985 | /* check for any SMD channels that may already exist */ | ||
| 986 | do_smd_probe(); | ||
| 987 | |||
| 988 | /* indicate that we're up and running */ | ||
| 989 | smsm_change_state(SMSM_STATE_APPS, | ||
| 990 | ~0, SMSM_INIT | SMSM_SMDINIT | SMSM_RPCINIT | SMSM_RUN); | ||
| 991 | #ifdef CONFIG_ARCH_MSM_SCORPION | ||
| 992 | smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0); | ||
| 993 | #endif | ||
| 994 | |||
| 995 | pr_info("smd_core_init() done\n"); | ||
| 996 | |||
| 997 | return 0; | ||
| 998 | } | ||
| 999 | |||
| 1000 | static int __init msm_smd_probe(struct platform_device *pdev) | ||
| 1001 | { | ||
| 1002 | pr_info("smd_init()\n"); | ||
| 1003 | |||
| 1004 | /* | ||
| 1005 | * If we haven't waited for the ARM9 to boot up till now, | ||
| 1006 | * then we need to wait here. Otherwise this should just | ||
| 1007 | * return immediately. | ||
| 1008 | */ | ||
| 1009 | proc_comm_boot_wait(); | ||
| 1010 | |||
| 1011 | INIT_WORK(&probe_work, smd_channel_probe_worker); | ||
| 1012 | |||
| 1013 | if (smd_core_init()) { | ||
| 1014 | pr_err("smd_core_init() failed\n"); | ||
| 1015 | return -1; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | do_smd_probe(); | ||
| 1019 | |||
| 1020 | msm_check_for_modem_crash = check_for_modem_crash; | ||
| 1021 | |||
| 1022 | msm_init_last_radio_log(THIS_MODULE); | ||
| 1023 | |||
| 1024 | smd_initialized = 1; | ||
| 1025 | |||
| 1026 | return 0; | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | static struct platform_driver msm_smd_driver = { | ||
| 1030 | .probe = msm_smd_probe, | ||
| 1031 | .driver = { | ||
| 1032 | .name = MODULE_NAME, | ||
| 1033 | .owner = THIS_MODULE, | ||
| 1034 | }, | ||
| 1035 | }; | ||
| 1036 | |||
| 1037 | static int __init msm_smd_init(void) | ||
| 1038 | { | ||
| 1039 | return platform_driver_register(&msm_smd_driver); | ||
| 1040 | } | ||
| 1041 | |||
| 1042 | module_init(msm_smd_init); | ||
| 1043 | |||
| 1044 | MODULE_DESCRIPTION("MSM Shared Memory Core"); | ||
| 1045 | MODULE_AUTHOR("Brian Swetland <swetland@google.com>"); | ||
| 1046 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c new file mode 100644 index 000000000000..3b2dd717b788 --- /dev/null +++ b/arch/arm/mach-msm/smd_debug.c | |||
| @@ -0,0 +1,315 @@ | |||
| 1 | /* arch/arm/mach-msm/smd_debug.c | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/debugfs.h> | ||
| 18 | #include <linux/list.h> | ||
| 19 | |||
| 20 | #include <mach/msm_iomap.h> | ||
| 21 | |||
| 22 | #include "smd_private.h" | ||
| 23 | |||
| 24 | #if defined(CONFIG_DEBUG_FS) | ||
| 25 | |||
| 26 | static char *chstate(unsigned n) | ||
| 27 | { | ||
| 28 | switch (n) { | ||
| 29 | case SMD_SS_CLOSED: | ||
| 30 | return "CLOSED"; | ||
| 31 | case SMD_SS_OPENING: | ||
| 32 | return "OPENING"; | ||
| 33 | case SMD_SS_OPENED: | ||
| 34 | return "OPENED"; | ||
| 35 | case SMD_SS_FLUSHING: | ||
| 36 | return "FLUSHING"; | ||
| 37 | case SMD_SS_CLOSING: | ||
| 38 | return "CLOSING"; | ||
| 39 | case SMD_SS_RESET: | ||
| 40 | return "RESET"; | ||
| 41 | case SMD_SS_RESET_OPENING: | ||
| 42 | return "ROPENING"; | ||
| 43 | default: | ||
| 44 | return "UNKNOWN"; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | |||
| 49 | static int dump_ch(char *buf, int max, struct smd_channel *ch) | ||
| 50 | { | ||
| 51 | volatile struct smd_half_channel *s = ch->send; | ||
| 52 | volatile struct smd_half_channel *r = ch->recv; | ||
| 53 | |||
| 54 | return scnprintf( | ||
| 55 | buf, max, | ||
| 56 | "ch%02d:" | ||
| 57 | " %8s(%05d/%05d) %c%c%c%c%c%c%c <->" | ||
| 58 | " %8s(%05d/%05d) %c%c%c%c%c%c%c '%s'\n", ch->n, | ||
| 59 | chstate(s->state), s->tail, s->head, | ||
| 60 | s->fDSR ? 'D' : 'd', | ||
| 61 | s->fCTS ? 'C' : 'c', | ||
| 62 | s->fCD ? 'C' : 'c', | ||
| 63 | s->fRI ? 'I' : 'i', | ||
| 64 | s->fHEAD ? 'W' : 'w', | ||
| 65 | s->fTAIL ? 'R' : 'r', | ||
| 66 | s->fSTATE ? 'S' : 's', | ||
| 67 | chstate(r->state), r->tail, r->head, | ||
| 68 | r->fDSR ? 'D' : 'd', | ||
| 69 | r->fCTS ? 'R' : 'r', | ||
| 70 | r->fCD ? 'C' : 'c', | ||
| 71 | r->fRI ? 'I' : 'i', | ||
| 72 | r->fHEAD ? 'W' : 'w', | ||
| 73 | r->fTAIL ? 'R' : 'r', | ||
| 74 | r->fSTATE ? 'S' : 's', | ||
| 75 | ch->name | ||
| 76 | ); | ||
| 77 | } | ||
| 78 | |||
| 79 | static int debug_read_stat(char *buf, int max) | ||
| 80 | { | ||
| 81 | char *msg; | ||
| 82 | int i = 0; | ||
| 83 | |||
| 84 | msg = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); | ||
| 85 | |||
| 86 | if (raw_smsm_get_state(SMSM_STATE_MODEM) & SMSM_RESET) | ||
| 87 | i += scnprintf(buf + i, max - i, | ||
| 88 | "smsm: ARM9 HAS CRASHED\n"); | ||
| 89 | |||
| 90 | i += scnprintf(buf + i, max - i, "smsm: a9: %08x a11: %08x\n", | ||
| 91 | raw_smsm_get_state(SMSM_STATE_MODEM), | ||
| 92 | raw_smsm_get_state(SMSM_STATE_APPS)); | ||
| 93 | #ifdef CONFIG_ARCH_MSM_SCORPION | ||
| 94 | i += scnprintf(buf + i, max - i, "smsm dem: apps: %08x modem: %08x " | ||
| 95 | "qdsp6: %08x power: %08x time: %08x\n", | ||
| 96 | raw_smsm_get_state(SMSM_STATE_APPS_DEM), | ||
| 97 | raw_smsm_get_state(SMSM_STATE_MODEM_DEM), | ||
| 98 | raw_smsm_get_state(SMSM_STATE_QDSP6_DEM), | ||
| 99 | raw_smsm_get_state(SMSM_STATE_POWER_MASTER_DEM), | ||
| 100 | raw_smsm_get_state(SMSM_STATE_TIME_MASTER_DEM)); | ||
| 101 | #endif | ||
| 102 | if (msg) { | ||
| 103 | msg[SZ_DIAG_ERR_MSG - 1] = 0; | ||
| 104 | i += scnprintf(buf + i, max - i, "diag: '%s'\n", msg); | ||
| 105 | } | ||
| 106 | return i; | ||
| 107 | } | ||
| 108 | |||
| 109 | static int debug_read_mem(char *buf, int max) | ||
| 110 | { | ||
| 111 | unsigned n; | ||
| 112 | struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; | ||
| 113 | struct smem_heap_entry *toc = shared->heap_toc; | ||
| 114 | int i = 0; | ||
| 115 | |||
| 116 | i += scnprintf(buf + i, max - i, | ||
| 117 | "heap: init=%d free=%d remain=%d\n", | ||
| 118 | shared->heap_info.initialized, | ||
| 119 | shared->heap_info.free_offset, | ||
| 120 | shared->heap_info.heap_remaining); | ||
| 121 | |||
| 122 | for (n = 0; n < SMEM_NUM_ITEMS; n++) { | ||
| 123 | if (toc[n].allocated == 0) | ||
| 124 | continue; | ||
| 125 | i += scnprintf(buf + i, max - i, | ||
| 126 | "%04d: offset %08x size %08x\n", | ||
| 127 | n, toc[n].offset, toc[n].size); | ||
| 128 | } | ||
| 129 | return i; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int debug_read_ch(char *buf, int max) | ||
| 133 | { | ||
| 134 | struct smd_channel *ch; | ||
| 135 | unsigned long flags; | ||
| 136 | int i = 0; | ||
| 137 | |||
| 138 | spin_lock_irqsave(&smd_lock, flags); | ||
| 139 | list_for_each_entry(ch, &smd_ch_list_dsp, ch_list) | ||
| 140 | i += dump_ch(buf + i, max - i, ch); | ||
| 141 | list_for_each_entry(ch, &smd_ch_list_modem, ch_list) | ||
| 142 | i += dump_ch(buf + i, max - i, ch); | ||
| 143 | list_for_each_entry(ch, &smd_ch_closed_list, ch_list) | ||
| 144 | i += dump_ch(buf + i, max - i, ch); | ||
| 145 | spin_unlock_irqrestore(&smd_lock, flags); | ||
| 146 | |||
| 147 | return i; | ||
| 148 | } | ||
| 149 | |||
| 150 | static int debug_read_version(char *buf, int max) | ||
| 151 | { | ||
| 152 | struct smem_shared *shared = (void *) MSM_SHARED_RAM_BASE; | ||
| 153 | unsigned version = shared->version[VERSION_MODEM]; | ||
| 154 | return sprintf(buf, "%d.%d\n", version >> 16, version & 0xffff); | ||
| 155 | } | ||
| 156 | |||
| 157 | static int debug_read_build_id(char *buf, int max) | ||
| 158 | { | ||
| 159 | unsigned size; | ||
| 160 | void *data; | ||
| 161 | |||
| 162 | data = smem_item(SMEM_HW_SW_BUILD_ID, &size); | ||
| 163 | if (!data) | ||
| 164 | return 0; | ||
| 165 | |||
| 166 | if (size >= max) | ||
| 167 | size = max; | ||
| 168 | memcpy(buf, data, size); | ||
| 169 | |||
| 170 | return size; | ||
| 171 | } | ||
| 172 | |||
| 173 | static int debug_read_alloc_tbl(char *buf, int max) | ||
| 174 | { | ||
| 175 | struct smd_alloc_elm *shared; | ||
| 176 | int n, i = 0; | ||
| 177 | |||
| 178 | shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); | ||
| 179 | |||
| 180 | for (n = 0; n < 64; n++) { | ||
| 181 | if (shared[n].ref_count == 0) | ||
| 182 | continue; | ||
| 183 | i += scnprintf(buf + i, max - i, | ||
| 184 | "%03d: %-20s cid=%02d type=%03d " | ||
| 185 | "kind=%02d ref_count=%d\n", | ||
| 186 | n, shared[n].name, shared[n].cid, | ||
| 187 | shared[n].ctype & 0xff, | ||
| 188 | (shared[n].ctype >> 8) & 0xf, | ||
| 189 | shared[n].ref_count); | ||
| 190 | } | ||
| 191 | |||
| 192 | return i; | ||
| 193 | } | ||
| 194 | |||
| 195 | #define DEBUG_BUFMAX 4096 | ||
| 196 | static char debug_buffer[DEBUG_BUFMAX]; | ||
| 197 | |||
| 198 | static ssize_t debug_read(struct file *file, char __user *buf, | ||
| 199 | size_t count, loff_t *ppos) | ||
| 200 | { | ||
| 201 | int (*fill)(char *buf, int max) = file->private_data; | ||
| 202 | int bsize = fill(debug_buffer, DEBUG_BUFMAX); | ||
| 203 | return simple_read_from_buffer(buf, count, ppos, debug_buffer, bsize); | ||
| 204 | } | ||
| 205 | |||
| 206 | static int debug_open(struct inode *inode, struct file *file) | ||
| 207 | { | ||
| 208 | file->private_data = inode->i_private; | ||
| 209 | return 0; | ||
| 210 | } | ||
| 211 | |||
| 212 | static const struct file_operations debug_ops = { | ||
| 213 | .read = debug_read, | ||
| 214 | .open = debug_open, | ||
| 215 | }; | ||
| 216 | |||
| 217 | static void debug_create(const char *name, mode_t mode, | ||
| 218 | struct dentry *dent, | ||
| 219 | int (*fill)(char *buf, int max)) | ||
| 220 | { | ||
| 221 | debugfs_create_file(name, mode, dent, fill, &debug_ops); | ||
| 222 | } | ||
| 223 | |||
| 224 | static int smd_debugfs_init(void) | ||
| 225 | { | ||
| 226 | struct dentry *dent; | ||
| 227 | |||
| 228 | dent = debugfs_create_dir("smd", 0); | ||
| 229 | if (IS_ERR(dent)) | ||
| 230 | return 1; | ||
| 231 | |||
| 232 | debug_create("ch", 0444, dent, debug_read_ch); | ||
| 233 | debug_create("stat", 0444, dent, debug_read_stat); | ||
| 234 | debug_create("mem", 0444, dent, debug_read_mem); | ||
| 235 | debug_create("version", 0444, dent, debug_read_version); | ||
| 236 | debug_create("tbl", 0444, dent, debug_read_alloc_tbl); | ||
| 237 | debug_create("build", 0444, dent, debug_read_build_id); | ||
| 238 | |||
| 239 | return 0; | ||
| 240 | } | ||
| 241 | |||
| 242 | late_initcall(smd_debugfs_init); | ||
| 243 | #endif | ||
| 244 | |||
| 245 | |||
| 246 | #define MAX_NUM_SLEEP_CLIENTS 64 | ||
| 247 | #define MAX_SLEEP_NAME_LEN 8 | ||
| 248 | |||
| 249 | #define NUM_GPIO_INT_REGISTERS 6 | ||
| 250 | #define GPIO_SMEM_NUM_GROUPS 2 | ||
| 251 | #define GPIO_SMEM_MAX_PC_INTERRUPTS 8 | ||
| 252 | |||
| 253 | struct tramp_gpio_save { | ||
| 254 | unsigned int enable; | ||
| 255 | unsigned int detect; | ||
| 256 | unsigned int polarity; | ||
| 257 | }; | ||
| 258 | |||
| 259 | struct tramp_gpio_smem { | ||
| 260 | uint16_t num_fired[GPIO_SMEM_NUM_GROUPS]; | ||
| 261 | uint16_t fired[GPIO_SMEM_NUM_GROUPS][GPIO_SMEM_MAX_PC_INTERRUPTS]; | ||
| 262 | uint32_t enabled[NUM_GPIO_INT_REGISTERS]; | ||
| 263 | uint32_t detection[NUM_GPIO_INT_REGISTERS]; | ||
| 264 | uint32_t polarity[NUM_GPIO_INT_REGISTERS]; | ||
| 265 | }; | ||
| 266 | |||
| 267 | |||
| 268 | void smsm_print_sleep_info(void) | ||
| 269 | { | ||
| 270 | unsigned long flags; | ||
| 271 | uint32_t *ptr; | ||
| 272 | struct tramp_gpio_smem *gpio; | ||
| 273 | struct smsm_interrupt_info *int_info; | ||
| 274 | |||
| 275 | |||
| 276 | spin_lock_irqsave(&smem_lock, flags); | ||
| 277 | |||
| 278 | ptr = smem_alloc(SMEM_SMSM_SLEEP_DELAY, sizeof(*ptr)); | ||
| 279 | if (ptr) | ||
| 280 | pr_info("SMEM_SMSM_SLEEP_DELAY: %x\n", *ptr); | ||
| 281 | |||
| 282 | ptr = smem_alloc(SMEM_SMSM_LIMIT_SLEEP, sizeof(*ptr)); | ||
| 283 | if (ptr) | ||
| 284 | pr_info("SMEM_SMSM_LIMIT_SLEEP: %x\n", *ptr); | ||
| 285 | |||
| 286 | ptr = smem_alloc(SMEM_SLEEP_POWER_COLLAPSE_DISABLED, sizeof(*ptr)); | ||
| 287 | if (ptr) | ||
| 288 | pr_info("SMEM_SLEEP_POWER_COLLAPSE_DISABLED: %x\n", *ptr); | ||
| 289 | |||
| 290 | #ifndef CONFIG_ARCH_MSM_SCORPION | ||
| 291 | int_info = smem_alloc(SMEM_SMSM_INT_INFO, sizeof(*int_info)); | ||
| 292 | if (int_info) | ||
| 293 | pr_info("SMEM_SMSM_INT_INFO %x %x %x\n", | ||
| 294 | int_info->interrupt_mask, | ||
| 295 | int_info->pending_interrupts, | ||
| 296 | int_info->wakeup_reason); | ||
| 297 | |||
| 298 | gpio = smem_alloc(SMEM_GPIO_INT, sizeof(*gpio)); | ||
| 299 | if (gpio) { | ||
| 300 | int i; | ||
| 301 | for (i = 0; i < NUM_GPIO_INT_REGISTERS; i++) | ||
| 302 | pr_info("SMEM_GPIO_INT: %d: e %x d %x p %x\n", | ||
| 303 | i, gpio->enabled[i], gpio->detection[i], | ||
| 304 | gpio->polarity[i]); | ||
| 305 | |||
| 306 | for (i = 0; i < GPIO_SMEM_NUM_GROUPS; i++) | ||
| 307 | pr_info("SMEM_GPIO_INT: %d: f %d: %d %d...\n", | ||
| 308 | i, gpio->num_fired[i], gpio->fired[i][0], | ||
| 309 | gpio->fired[i][1]); | ||
| 310 | } | ||
| 311 | #else | ||
| 312 | #endif | ||
| 313 | spin_unlock_irqrestore(&smem_lock, flags); | ||
| 314 | } | ||
| 315 | |||
diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h new file mode 100644 index 000000000000..727bfe68aa9b --- /dev/null +++ b/arch/arm/mach-msm/smd_private.h | |||
| @@ -0,0 +1,403 @@ | |||
| 1 | /* arch/arm/mach-msm/smd_private.h | ||
| 2 | * | ||
| 3 | * Copyright (C) 2007 Google, Inc. | ||
| 4 | * Copyright (c) 2007 QUALCOMM Incorporated | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | */ | ||
| 16 | #ifndef _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ | ||
| 17 | #define _ARCH_ARM_MACH_MSM_MSM_SMD_PRIVATE_H_ | ||
| 18 | |||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/spinlock.h> | ||
| 21 | #include <linux/list.h> | ||
| 22 | #include <linux/io.h> | ||
| 23 | |||
| 24 | #include <mach/msm_iomap.h> | ||
| 25 | |||
| 26 | struct smem_heap_info { | ||
| 27 | unsigned initialized; | ||
| 28 | unsigned free_offset; | ||
| 29 | unsigned heap_remaining; | ||
| 30 | unsigned reserved; | ||
| 31 | }; | ||
| 32 | |||
| 33 | struct smem_heap_entry { | ||
| 34 | unsigned allocated; | ||
| 35 | unsigned offset; | ||
| 36 | unsigned size; | ||
| 37 | unsigned reserved; | ||
| 38 | }; | ||
| 39 | |||
| 40 | struct smem_proc_comm { | ||
| 41 | unsigned command; | ||
| 42 | unsigned status; | ||
| 43 | unsigned data1; | ||
| 44 | unsigned data2; | ||
| 45 | }; | ||
| 46 | |||
| 47 | #define PC_APPS 0 | ||
| 48 | #define PC_MODEM 1 | ||
| 49 | |||
| 50 | #define VERSION_SMD 0 | ||
| 51 | #define VERSION_QDSP6 4 | ||
| 52 | #define VERSION_APPS_SBL 6 | ||
| 53 | #define VERSION_MODEM_SBL 7 | ||
| 54 | #define VERSION_APPS 8 | ||
| 55 | #define VERSION_MODEM 9 | ||
| 56 | |||
| 57 | struct smem_shared { | ||
| 58 | struct smem_proc_comm proc_comm[4]; | ||
| 59 | unsigned version[32]; | ||
| 60 | struct smem_heap_info heap_info; | ||
| 61 | struct smem_heap_entry heap_toc[512]; | ||
| 62 | }; | ||
| 63 | |||
| 64 | #define SMSM_V1_SIZE (sizeof(unsigned) * 8) | ||
| 65 | #define SMSM_V2_SIZE (sizeof(unsigned) * 4) | ||
| 66 | |||
| 67 | #ifdef CONFIG_MSM_SMD_PKG3 | ||
| 68 | struct smsm_interrupt_info { | ||
| 69 | uint32_t interrupt_mask; | ||
| 70 | uint32_t pending_interrupts; | ||
| 71 | uint32_t wakeup_reason; | ||
| 72 | }; | ||
| 73 | #else | ||
| 74 | #define DEM_MAX_PORT_NAME_LEN (20) | ||
| 75 | struct msm_dem_slave_data { | ||
| 76 | uint32_t sleep_time; | ||
| 77 | uint32_t interrupt_mask; | ||
| 78 | uint32_t resources_used; | ||
| 79 | uint32_t reserved1; | ||
| 80 | |||
| 81 | uint32_t wakeup_reason; | ||
| 82 | uint32_t pending_interrupts; | ||
| 83 | uint32_t rpc_prog; | ||
| 84 | uint32_t rpc_proc; | ||
| 85 | char smd_port_name[DEM_MAX_PORT_NAME_LEN]; | ||
| 86 | uint32_t reserved2; | ||
| 87 | }; | ||
| 88 | #endif | ||
| 89 | |||
| 90 | #define SZ_DIAG_ERR_MSG 0xC8 | ||
| 91 | #define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE | ||
| 92 | #define ID_SMD_CHANNELS SMEM_SMD_BASE_ID | ||
| 93 | #define ID_SHARED_STATE SMEM_SMSM_SHARED_STATE | ||
| 94 | #define ID_CH_ALLOC_TBL SMEM_CHANNEL_ALLOC_TBL | ||
| 95 | |||
| 96 | #define SMSM_INIT 0x00000001 | ||
| 97 | #define SMSM_SMDINIT 0x00000008 | ||
| 98 | #define SMSM_RPCINIT 0x00000020 | ||
| 99 | #define SMSM_RESET 0x00000040 | ||
| 100 | #define SMSM_RSA 0x00000080 | ||
| 101 | #define SMSM_RUN 0x00000100 | ||
| 102 | #define SMSM_PWRC 0x00000200 | ||
| 103 | #define SMSM_TIMEWAIT 0x00000400 | ||
| 104 | #define SMSM_TIMEINIT 0x00000800 | ||
| 105 | #define SMSM_PWRC_EARLY_EXIT 0x00001000 | ||
| 106 | #define SMSM_WFPI 0x00002000 | ||
| 107 | #define SMSM_SLEEP 0x00004000 | ||
| 108 | #define SMSM_SLEEPEXIT 0x00008000 | ||
| 109 | #define SMSM_APPS_REBOOT 0x00020000 | ||
| 110 | #define SMSM_SYSTEM_POWER_DOWN 0x00040000 | ||
| 111 | #define SMSM_SYSTEM_REBOOT 0x00080000 | ||
| 112 | #define SMSM_SYSTEM_DOWNLOAD 0x00100000 | ||
| 113 | #define SMSM_PWRC_SUSPEND 0x00200000 | ||
| 114 | #define SMSM_APPS_SHUTDOWN 0x00400000 | ||
| 115 | #define SMSM_SMD_LOOPBACK 0x00800000 | ||
| 116 | #define SMSM_RUN_QUIET 0x01000000 | ||
| 117 | #define SMSM_MODEM_WAIT 0x02000000 | ||
| 118 | #define SMSM_MODEM_BREAK 0x04000000 | ||
| 119 | #define SMSM_MODEM_CONTINUE 0x08000000 | ||
| 120 | #define SMSM_UNKNOWN 0x80000000 | ||
| 121 | |||
| 122 | #define SMSM_WKUP_REASON_RPC 0x00000001 | ||
| 123 | #define SMSM_WKUP_REASON_INT 0x00000002 | ||
| 124 | #define SMSM_WKUP_REASON_GPIO 0x00000004 | ||
| 125 | #define SMSM_WKUP_REASON_TIMER 0x00000008 | ||
| 126 | #define SMSM_WKUP_REASON_ALARM 0x00000010 | ||
| 127 | #define SMSM_WKUP_REASON_RESET 0x00000020 | ||
| 128 | |||
| 129 | #ifdef CONFIG_ARCH_MSM7X00A | ||
| 130 | enum smsm_state_item { | ||
| 131 | SMSM_STATE_APPS = 1, | ||
| 132 | SMSM_STATE_MODEM = 3, | ||
| 133 | SMSM_STATE_COUNT, | ||
| 134 | }; | ||
| 135 | #else | ||
| 136 | enum smsm_state_item { | ||
| 137 | SMSM_STATE_APPS, | ||
| 138 | SMSM_STATE_MODEM, | ||
| 139 | SMSM_STATE_HEXAGON, | ||
| 140 | SMSM_STATE_APPS_DEM, | ||
| 141 | SMSM_STATE_MODEM_DEM, | ||
| 142 | SMSM_STATE_QDSP6_DEM, | ||
| 143 | SMSM_STATE_POWER_MASTER_DEM, | ||
| 144 | SMSM_STATE_TIME_MASTER_DEM, | ||
| 145 | SMSM_STATE_COUNT, | ||
| 146 | }; | ||
| 147 | #endif | ||
| 148 | |||
| 149 | void *smem_alloc(unsigned id, unsigned size); | ||
| 150 | int smsm_change_state(enum smsm_state_item item, uint32_t clear_mask, uint32_t set_mask); | ||
| 151 | uint32_t smsm_get_state(enum smsm_state_item item); | ||
| 152 | int smsm_set_sleep_duration(uint32_t delay); | ||
| 153 | void smsm_print_sleep_info(void); | ||
| 154 | |||
| 155 | #define SMEM_NUM_SMD_CHANNELS 64 | ||
| 156 | |||
| 157 | typedef enum { | ||
| 158 | /* fixed items */ | ||
| 159 | SMEM_PROC_COMM = 0, | ||
| 160 | SMEM_HEAP_INFO, | ||
| 161 | SMEM_ALLOCATION_TABLE, | ||
| 162 | SMEM_VERSION_INFO, | ||
| 163 | SMEM_HW_RESET_DETECT, | ||
| 164 | SMEM_AARM_WARM_BOOT, | ||
| 165 | SMEM_DIAG_ERR_MESSAGE, | ||
| 166 | SMEM_SPINLOCK_ARRAY, | ||
| 167 | SMEM_MEMORY_BARRIER_LOCATION, | ||
| 168 | |||
| 169 | /* dynamic items */ | ||
| 170 | SMEM_AARM_PARTITION_TABLE, | ||
| 171 | SMEM_AARM_BAD_BLOCK_TABLE, | ||
| 172 | SMEM_RESERVE_BAD_BLOCKS, | ||
| 173 | SMEM_WM_UUID, | ||
| 174 | SMEM_CHANNEL_ALLOC_TBL, | ||
| 175 | SMEM_SMD_BASE_ID, | ||
| 176 | SMEM_SMEM_LOG_IDX = SMEM_SMD_BASE_ID + SMEM_NUM_SMD_CHANNELS, | ||
| 177 | SMEM_SMEM_LOG_EVENTS, | ||
| 178 | SMEM_SMEM_STATIC_LOG_IDX, | ||
| 179 | SMEM_SMEM_STATIC_LOG_EVENTS, | ||
| 180 | SMEM_SMEM_SLOW_CLOCK_SYNC, | ||
| 181 | SMEM_SMEM_SLOW_CLOCK_VALUE, | ||
| 182 | SMEM_BIO_LED_BUF, | ||
| 183 | SMEM_SMSM_SHARED_STATE, | ||
| 184 | SMEM_SMSM_INT_INFO, | ||
| 185 | SMEM_SMSM_SLEEP_DELAY, | ||
| 186 | SMEM_SMSM_LIMIT_SLEEP, | ||
| 187 | SMEM_SLEEP_POWER_COLLAPSE_DISABLED, | ||
| 188 | SMEM_KEYPAD_KEYS_PRESSED, | ||
| 189 | SMEM_KEYPAD_STATE_UPDATED, | ||
| 190 | SMEM_KEYPAD_STATE_IDX, | ||
| 191 | SMEM_GPIO_INT, | ||
| 192 | SMEM_MDDI_LCD_IDX, | ||
| 193 | SMEM_MDDI_HOST_DRIVER_STATE, | ||
| 194 | SMEM_MDDI_LCD_DISP_STATE, | ||
| 195 | SMEM_LCD_CUR_PANEL, | ||
| 196 | SMEM_MARM_BOOT_SEGMENT_INFO, | ||
| 197 | SMEM_AARM_BOOT_SEGMENT_INFO, | ||
| 198 | SMEM_SLEEP_STATIC, | ||
| 199 | SMEM_SCORPION_FREQUENCY, | ||
| 200 | SMEM_SMD_PROFILES, | ||
| 201 | SMEM_TSSC_BUSY, | ||
| 202 | SMEM_HS_SUSPEND_FILTER_INFO, | ||
| 203 | SMEM_BATT_INFO, | ||
| 204 | SMEM_APPS_BOOT_MODE, | ||
| 205 | SMEM_VERSION_FIRST, | ||
| 206 | SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24, | ||
| 207 | SMEM_OSS_RRCASN1_BUF1, | ||
| 208 | SMEM_OSS_RRCASN1_BUF2, | ||
| 209 | SMEM_ID_VENDOR0, | ||
| 210 | SMEM_ID_VENDOR1, | ||
| 211 | SMEM_ID_VENDOR2, | ||
| 212 | SMEM_HW_SW_BUILD_ID, | ||
| 213 | SMEM_SMD_BLOCK_PORT_BASE_ID, | ||
| 214 | SMEM_SMD_BLOCK_PORT_PROC0_HEAP = SMEM_SMD_BLOCK_PORT_BASE_ID + SMEM_NUM_SMD_CHANNELS, | ||
| 215 | SMEM_SMD_BLOCK_PORT_PROC1_HEAP = SMEM_SMD_BLOCK_PORT_PROC0_HEAP + SMEM_NUM_SMD_CHANNELS, | ||
| 216 | SMEM_I2C_MUTEX = SMEM_SMD_BLOCK_PORT_PROC1_HEAP + SMEM_NUM_SMD_CHANNELS, | ||
| 217 | SMEM_SCLK_CONVERSION, | ||
| 218 | SMEM_SMD_SMSM_INTR_MUX, | ||
| 219 | SMEM_SMSM_CPU_INTR_MASK, | ||
| 220 | SMEM_APPS_DEM_SLAVE_DATA, | ||
| 221 | SMEM_QDSP6_DEM_SLAVE_DATA, | ||
| 222 | SMEM_CLKREGIM_BSP, | ||
| 223 | SMEM_CLKREGIM_SOURCES, | ||
| 224 | SMEM_SMD_FIFO_BASE_ID, | ||
| 225 | SMEM_USABLE_RAM_PARTITION_TABLE = SMEM_SMD_FIFO_BASE_ID + SMEM_NUM_SMD_CHANNELS, | ||
| 226 | SMEM_POWER_ON_STATUS_INFO, | ||
| 227 | SMEM_DAL_AREA, | ||
| 228 | SMEM_SMEM_LOG_POWER_IDX, | ||
| 229 | SMEM_SMEM_LOG_POWER_WRAP, | ||
| 230 | SMEM_SMEM_LOG_POWER_EVENTS, | ||
| 231 | SMEM_ERR_CRASH_LOG, | ||
| 232 | SMEM_ERR_F3_TRACE_LOG, | ||
| 233 | SMEM_NUM_ITEMS, | ||
| 234 | } smem_mem_type; | ||
| 235 | |||
| 236 | |||
| 237 | #define SMD_SS_CLOSED 0x00000000 | ||
| 238 | #define SMD_SS_OPENING 0x00000001 | ||
| 239 | #define SMD_SS_OPENED 0x00000002 | ||
| 240 | #define SMD_SS_FLUSHING 0x00000003 | ||
| 241 | #define SMD_SS_CLOSING 0x00000004 | ||
| 242 | #define SMD_SS_RESET 0x00000005 | ||
| 243 | #define SMD_SS_RESET_OPENING 0x00000006 | ||
| 244 | |||
| 245 | #define SMD_BUF_SIZE 8192 | ||
| 246 | #define SMD_CHANNELS 64 | ||
| 247 | |||
| 248 | #define SMD_HEADER_SIZE 20 | ||
| 249 | |||
| 250 | struct smd_alloc_elm { | ||
| 251 | char name[20]; | ||
| 252 | uint32_t cid; | ||
| 253 | uint32_t ctype; | ||
| 254 | uint32_t ref_count; | ||
| 255 | }; | ||
| 256 | |||
| 257 | struct smd_half_channel { | ||
| 258 | unsigned state; | ||
| 259 | unsigned char fDSR; | ||
| 260 | unsigned char fCTS; | ||
| 261 | unsigned char fCD; | ||
| 262 | unsigned char fRI; | ||
| 263 | unsigned char fHEAD; | ||
| 264 | unsigned char fTAIL; | ||
| 265 | unsigned char fSTATE; | ||
| 266 | unsigned char fUNUSED; | ||
| 267 | unsigned tail; | ||
| 268 | unsigned head; | ||
| 269 | } __attribute__(( aligned(4), packed )); | ||
| 270 | |||
| 271 | /* Only used on SMD package v3 on msm7201a */ | ||
| 272 | struct smd_shared_v1 { | ||
| 273 | struct smd_half_channel ch0; | ||
| 274 | unsigned char data0[SMD_BUF_SIZE]; | ||
| 275 | struct smd_half_channel ch1; | ||
| 276 | unsigned char data1[SMD_BUF_SIZE]; | ||
| 277 | }; | ||
| 278 | |||
| 279 | /* Used on SMD package v4 */ | ||
| 280 | struct smd_shared_v2 { | ||
| 281 | struct smd_half_channel ch0; | ||
| 282 | struct smd_half_channel ch1; | ||
| 283 | }; | ||
| 284 | |||
| 285 | struct smd_channel { | ||
| 286 | volatile struct smd_half_channel *send; | ||
| 287 | volatile struct smd_half_channel *recv; | ||
| 288 | unsigned char *send_data; | ||
| 289 | unsigned char *recv_data; | ||
| 290 | |||
| 291 | unsigned fifo_mask; | ||
| 292 | unsigned fifo_size; | ||
| 293 | unsigned current_packet; | ||
| 294 | unsigned n; | ||
| 295 | |||
| 296 | struct list_head ch_list; | ||
| 297 | |||
| 298 | void *priv; | ||
| 299 | void (*notify)(void *priv, unsigned flags); | ||
| 300 | |||
| 301 | int (*read)(struct smd_channel *ch, void *data, int len); | ||
| 302 | int (*write)(struct smd_channel *ch, const void *data, int len); | ||
| 303 | int (*read_avail)(struct smd_channel *ch); | ||
| 304 | int (*write_avail)(struct smd_channel *ch); | ||
| 305 | |||
| 306 | void (*update_state)(struct smd_channel *ch); | ||
| 307 | unsigned last_state; | ||
| 308 | void (*notify_other_cpu)(void); | ||
| 309 | unsigned type; | ||
| 310 | |||
| 311 | char name[32]; | ||
| 312 | struct platform_device pdev; | ||
| 313 | }; | ||
| 314 | |||
| 315 | #define SMD_TYPE_MASK 0x0FF | ||
| 316 | #define SMD_TYPE_APPS_MODEM 0x000 | ||
| 317 | #define SMD_TYPE_APPS_DSP 0x001 | ||
| 318 | #define SMD_TYPE_MODEM_DSP 0x002 | ||
| 319 | |||
| 320 | #define SMD_KIND_MASK 0xF00 | ||
| 321 | #define SMD_KIND_UNKNOWN 0x000 | ||
| 322 | #define SMD_KIND_STREAM 0x100 | ||
| 323 | #define SMD_KIND_PACKET 0x200 | ||
| 324 | |||
| 325 | extern struct list_head smd_ch_closed_list; | ||
| 326 | extern struct list_head smd_ch_list_modem; | ||
| 327 | extern struct list_head smd_ch_list_dsp; | ||
| 328 | |||
| 329 | extern spinlock_t smd_lock; | ||
| 330 | extern spinlock_t smem_lock; | ||
| 331 | |||
| 332 | void *smem_find(unsigned id, unsigned size); | ||
| 333 | void *smem_item(unsigned id, unsigned *size); | ||
| 334 | uint32_t raw_smsm_get_state(enum smsm_state_item item); | ||
| 335 | |||
| 336 | extern void msm_init_last_radio_log(struct module *); | ||
| 337 | |||
| 338 | #ifdef CONFIG_MSM_SMD_PKG3 | ||
| 339 | /* | ||
| 340 | * This allocator assumes an SMD Package v3 which only exists on | ||
| 341 | * MSM7x00 SoC's. | ||
| 342 | */ | ||
| 343 | static inline int _smd_alloc_channel(struct smd_channel *ch) | ||
| 344 | { | ||
| 345 | struct smd_shared_v1 *shared1; | ||
| 346 | |||
| 347 | shared1 = smem_alloc(ID_SMD_CHANNELS + ch->n, sizeof(*shared1)); | ||
| 348 | if (!shared1) { | ||
| 349 | pr_err("smd_alloc_channel() cid %d does not exist\n", ch->n); | ||
| 350 | return -1; | ||
| 351 | } | ||
| 352 | ch->send = &shared1->ch0; | ||
| 353 | ch->recv = &shared1->ch1; | ||
| 354 | ch->send_data = shared1->data0; | ||
| 355 | ch->recv_data = shared1->data1; | ||
| 356 | ch->fifo_size = SMD_BUF_SIZE; | ||
| 357 | return 0; | ||
| 358 | } | ||
| 359 | #else | ||
| 360 | /* | ||
| 361 | * This allocator assumes an SMD Package v4, the most common | ||
| 362 | * and the default. | ||
| 363 | */ | ||
| 364 | static inline int _smd_alloc_channel(struct smd_channel *ch) | ||
| 365 | { | ||
| 366 | struct smd_shared_v2 *shared2; | ||
| 367 | void *buffer; | ||
| 368 | unsigned buffer_sz; | ||
| 369 | |||
| 370 | shared2 = smem_alloc(SMEM_SMD_BASE_ID + ch->n, sizeof(*shared2)); | ||
| 371 | buffer = smem_item(SMEM_SMD_FIFO_BASE_ID + ch->n, &buffer_sz); | ||
| 372 | |||
| 373 | if (!buffer) | ||
| 374 | return -1; | ||
| 375 | |||
| 376 | /* buffer must be a power-of-two size */ | ||
| 377 | if (buffer_sz & (buffer_sz - 1)) | ||
| 378 | return -1; | ||
| 379 | |||
| 380 | buffer_sz /= 2; | ||
| 381 | ch->send = &shared2->ch0; | ||
| 382 | ch->recv = &shared2->ch1; | ||
| 383 | ch->send_data = buffer; | ||
| 384 | ch->recv_data = buffer + buffer_sz; | ||
| 385 | ch->fifo_size = buffer_sz; | ||
| 386 | return 0; | ||
| 387 | } | ||
| 388 | #endif /* CONFIG_MSM_SMD_PKG3 */ | ||
| 389 | |||
| 390 | #if defined(CONFIG_ARCH_MSM7X30) | ||
| 391 | static inline void msm_a2m_int(uint32_t irq) | ||
| 392 | { | ||
| 393 | writel(1 << irq, MSM_GCC_BASE + 0x8); | ||
| 394 | } | ||
| 395 | #else | ||
| 396 | static inline void msm_a2m_int(uint32_t irq) | ||
| 397 | { | ||
| 398 | writel(1, MSM_CSR_BASE + 0x400 + (irq * 4)); | ||
| 399 | } | ||
| 400 | #endif /* CONFIG_ARCH_MSM7X30 */ | ||
| 401 | |||
| 402 | |||
| 403 | #endif | ||
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 4855b8ca5101..dec5ca622d7d 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c | |||
| @@ -25,7 +25,9 @@ | |||
| 25 | #include <asm/mach/time.h> | 25 | #include <asm/mach/time.h> |
| 26 | #include <mach/msm_iomap.h> | 26 | #include <mach/msm_iomap.h> |
| 27 | 27 | ||
| 28 | #ifndef MSM_DGT_BASE | ||
| 28 | #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10) | 29 | #define MSM_DGT_BASE (MSM_GPT_BASE + 0x10) |
| 30 | #endif | ||
| 29 | #define MSM_DGT_SHIFT (5) | 31 | #define MSM_DGT_SHIFT (5) |
| 30 | 32 | ||
| 31 | #define TIMER_MATCH_VAL 0x0000 | 33 | #define TIMER_MATCH_VAL 0x0000 |
diff --git a/arch/arm/mach-msm/vreg.c b/arch/arm/mach-msm/vreg.c index fcb0b9f25684..a9103bc6615f 100644 --- a/arch/arm/mach-msm/vreg.c +++ b/arch/arm/mach-msm/vreg.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* arch/arm/mach-msm/vreg.c | 1 | /* arch/arm/mach-msm/vreg.c |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2008 Google, Inc. | 3 | * Copyright (C) 2008 Google, Inc. |
| 4 | * Copyright (c) 2009, Code Aurora Forum. All rights reserved. | ||
| 4 | * Author: Brian Swetland <swetland@google.com> | 5 | * Author: Brian Swetland <swetland@google.com> |
| 5 | * | 6 | * |
| 6 | * This software is licensed under the terms of the GNU General Public | 7 | * This software is licensed under the terms of the GNU General Public |
| @@ -18,6 +19,7 @@ | |||
| 18 | #include <linux/device.h> | 19 | #include <linux/device.h> |
| 19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
| 20 | #include <linux/debugfs.h> | 21 | #include <linux/debugfs.h> |
| 22 | #include <linux/string.h> | ||
| 21 | #include <mach/vreg.h> | 23 | #include <mach/vreg.h> |
| 22 | 24 | ||
| 23 | #include "proc_comm.h" | 25 | #include "proc_comm.h" |
| @@ -25,42 +27,62 @@ | |||
| 25 | struct vreg { | 27 | struct vreg { |
| 26 | const char *name; | 28 | const char *name; |
| 27 | unsigned id; | 29 | unsigned id; |
| 30 | int status; | ||
| 31 | unsigned refcnt; | ||
| 28 | }; | 32 | }; |
| 29 | 33 | ||
| 30 | #define VREG(_name, _id) { .name = _name, .id = _id, } | 34 | #define VREG(_name, _id, _status, _refcnt) \ |
| 35 | { .name = _name, .id = _id, .status = _status, .refcnt = _refcnt } | ||
| 31 | 36 | ||
| 32 | static struct vreg vregs[] = { | 37 | static struct vreg vregs[] = { |
| 33 | VREG("msma", 0), | 38 | VREG("msma", 0, 0, 0), |
| 34 | VREG("msmp", 1), | 39 | VREG("msmp", 1, 0, 0), |
| 35 | VREG("msme1", 2), | 40 | VREG("msme1", 2, 0, 0), |
| 36 | VREG("msmc1", 3), | 41 | VREG("msmc1", 3, 0, 0), |
| 37 | VREG("msmc2", 4), | 42 | VREG("msmc2", 4, 0, 0), |
| 38 | VREG("gp3", 5), | 43 | VREG("gp3", 5, 0, 0), |
| 39 | VREG("msme2", 6), | 44 | VREG("msme2", 6, 0, 0), |
| 40 | VREG("gp4", 7), | 45 | VREG("gp4", 7, 0, 0), |
| 41 | VREG("gp1", 8), | 46 | VREG("gp1", 8, 0, 0), |
| 42 | VREG("tcxo", 9), | 47 | VREG("tcxo", 9, 0, 0), |
| 43 | VREG("pa", 10), | 48 | VREG("pa", 10, 0, 0), |
| 44 | VREG("rftx", 11), | 49 | VREG("rftx", 11, 0, 0), |
| 45 | VREG("rfrx1", 12), | 50 | VREG("rfrx1", 12, 0, 0), |
| 46 | VREG("rfrx2", 13), | 51 | VREG("rfrx2", 13, 0, 0), |
| 47 | VREG("synt", 14), | 52 | VREG("synt", 14, 0, 0), |
| 48 | VREG("wlan", 15), | 53 | VREG("wlan", 15, 0, 0), |
| 49 | VREG("usb", 16), | 54 | VREG("usb", 16, 0, 0), |
| 50 | VREG("boost", 17), | 55 | VREG("boost", 17, 0, 0), |
| 51 | VREG("mmc", 18), | 56 | VREG("mmc", 18, 0, 0), |
| 52 | VREG("ruim", 19), | 57 | VREG("ruim", 19, 0, 0), |
| 53 | VREG("msmc0", 20), | 58 | VREG("msmc0", 20, 0, 0), |
| 54 | VREG("gp2", 21), | 59 | VREG("gp2", 21, 0, 0), |
| 55 | VREG("gp5", 22), | 60 | VREG("gp5", 22, 0, 0), |
| 56 | VREG("gp6", 23), | 61 | VREG("gp6", 23, 0, 0), |
| 57 | VREG("rf", 24), | 62 | VREG("rf", 24, 0, 0), |
| 58 | VREG("rf_vco", 26), | 63 | VREG("rf_vco", 26, 0, 0), |
| 59 | VREG("mpll", 27), | 64 | VREG("mpll", 27, 0, 0), |
| 60 | VREG("s2", 28), | 65 | VREG("s2", 28, 0, 0), |
| 61 | VREG("s3", 29), | 66 | VREG("s3", 29, 0, 0), |
| 62 | VREG("rfubm", 30), | 67 | VREG("rfubm", 30, 0, 0), |
| 63 | VREG("ncp", 31), | 68 | VREG("ncp", 31, 0, 0), |
| 69 | VREG("gp7", 32, 0, 0), | ||
| 70 | VREG("gp8", 33, 0, 0), | ||
| 71 | VREG("gp9", 34, 0, 0), | ||
| 72 | VREG("gp10", 35, 0, 0), | ||
| 73 | VREG("gp11", 36, 0, 0), | ||
| 74 | VREG("gp12", 37, 0, 0), | ||
| 75 | VREG("gp13", 38, 0, 0), | ||
| 76 | VREG("gp14", 39, 0, 0), | ||
| 77 | VREG("gp15", 40, 0, 0), | ||
| 78 | VREG("gp16", 41, 0, 0), | ||
| 79 | VREG("gp17", 42, 0, 0), | ||
| 80 | VREG("s4", 43, 0, 0), | ||
| 81 | VREG("usb2", 44, 0, 0), | ||
| 82 | VREG("wlan2", 45, 0, 0), | ||
| 83 | VREG("xo_out", 46, 0, 0), | ||
| 84 | VREG("lvsw0", 47, 0, 0), | ||
| 85 | VREG("lvsw1", 48, 0, 0), | ||
| 64 | }; | 86 | }; |
| 65 | 87 | ||
| 66 | struct vreg *vreg_get(struct device *dev, const char *id) | 88 | struct vreg *vreg_get(struct device *dev, const char *id) |
| @@ -70,7 +92,7 @@ struct vreg *vreg_get(struct device *dev, const char *id) | |||
| 70 | if (!strcmp(vregs[n].name, id)) | 92 | if (!strcmp(vregs[n].name, id)) |
| 71 | return vregs + n; | 93 | return vregs + n; |
| 72 | } | 94 | } |
| 73 | return 0; | 95 | return ERR_PTR(-ENOENT); |
| 74 | } | 96 | } |
| 75 | 97 | ||
| 76 | void vreg_put(struct vreg *vreg) | 98 | void vreg_put(struct vreg *vreg) |
| @@ -81,20 +103,39 @@ int vreg_enable(struct vreg *vreg) | |||
| 81 | { | 103 | { |
| 82 | unsigned id = vreg->id; | 104 | unsigned id = vreg->id; |
| 83 | unsigned enable = 1; | 105 | unsigned enable = 1; |
| 84 | return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); | 106 | |
| 107 | if (vreg->refcnt == 0) | ||
| 108 | vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); | ||
| 109 | |||
| 110 | if ((vreg->refcnt < UINT_MAX) && (!vreg->status)) | ||
| 111 | vreg->refcnt++; | ||
| 112 | |||
| 113 | return vreg->status; | ||
| 85 | } | 114 | } |
| 86 | 115 | ||
| 87 | void vreg_disable(struct vreg *vreg) | 116 | int vreg_disable(struct vreg *vreg) |
| 88 | { | 117 | { |
| 89 | unsigned id = vreg->id; | 118 | unsigned id = vreg->id; |
| 90 | unsigned enable = 0; | 119 | unsigned enable = 0; |
| 91 | msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); | 120 | |
| 121 | if (!vreg->refcnt) | ||
| 122 | return 0; | ||
| 123 | |||
| 124 | if (vreg->refcnt == 1) | ||
| 125 | vreg->status = msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable); | ||
| 126 | |||
| 127 | if (!vreg->status) | ||
| 128 | vreg->refcnt--; | ||
| 129 | |||
| 130 | return vreg->status; | ||
| 92 | } | 131 | } |
| 93 | 132 | ||
| 94 | int vreg_set_level(struct vreg *vreg, unsigned mv) | 133 | int vreg_set_level(struct vreg *vreg, unsigned mv) |
| 95 | { | 134 | { |
| 96 | unsigned id = vreg->id; | 135 | unsigned id = vreg->id; |
| 97 | return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); | 136 | |
| 137 | vreg->status = msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv); | ||
| 138 | return vreg->status; | ||
| 98 | } | 139 | } |
| 99 | 140 | ||
| 100 | #if defined(CONFIG_DEBUG_FS) | 141 | #if defined(CONFIG_DEBUG_FS) |
| @@ -118,24 +159,59 @@ static int vreg_debug_set(void *data, u64 val) | |||
| 118 | 159 | ||
| 119 | static int vreg_debug_get(void *data, u64 *val) | 160 | static int vreg_debug_get(void *data, u64 *val) |
| 120 | { | 161 | { |
| 121 | return -ENOSYS; | 162 | struct vreg *vreg = data; |
| 163 | |||
| 164 | if (!vreg->status) | ||
| 165 | *val = 0; | ||
| 166 | else | ||
| 167 | *val = 1; | ||
| 168 | |||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 172 | static int vreg_debug_count_set(void *data, u64 val) | ||
| 173 | { | ||
| 174 | struct vreg *vreg = data; | ||
| 175 | if (val > UINT_MAX) | ||
| 176 | val = UINT_MAX; | ||
| 177 | vreg->refcnt = val; | ||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | static int vreg_debug_count_get(void *data, u64 *val) | ||
| 182 | { | ||
| 183 | struct vreg *vreg = data; | ||
| 184 | |||
| 185 | *val = vreg->refcnt; | ||
| 186 | |||
| 187 | return 0; | ||
| 122 | } | 188 | } |
| 123 | 189 | ||
| 124 | DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n"); | 190 | DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n"); |
| 191 | DEFINE_SIMPLE_ATTRIBUTE(vreg_count_fops, vreg_debug_count_get, | ||
| 192 | vreg_debug_count_set, "%llu\n"); | ||
| 125 | 193 | ||
| 126 | static int __init vreg_debug_init(void) | 194 | static int __init vreg_debug_init(void) |
| 127 | { | 195 | { |
| 128 | struct dentry *dent; | 196 | struct dentry *dent; |
| 129 | int n; | 197 | int n; |
| 198 | char name[32]; | ||
| 199 | const char *refcnt_name = "_refcnt"; | ||
| 130 | 200 | ||
| 131 | dent = debugfs_create_dir("vreg", 0); | 201 | dent = debugfs_create_dir("vreg", 0); |
| 132 | if (IS_ERR(dent)) | 202 | if (IS_ERR(dent)) |
| 133 | return 0; | 203 | return 0; |
| 134 | 204 | ||
| 135 | for (n = 0; n < ARRAY_SIZE(vregs); n++) | 205 | for (n = 0; n < ARRAY_SIZE(vregs); n++) { |
| 136 | (void) debugfs_create_file(vregs[n].name, 0644, | 206 | (void) debugfs_create_file(vregs[n].name, 0644, |
| 137 | dent, vregs + n, &vreg_fops); | 207 | dent, vregs + n, &vreg_fops); |
| 138 | 208 | ||
| 209 | strlcpy(name, vregs[n].name, sizeof(name)); | ||
| 210 | strlcat(name, refcnt_name, sizeof(name)); | ||
| 211 | (void) debugfs_create_file(name, 0644, | ||
| 212 | dent, vregs + n, &vreg_count_fops); | ||
| 213 | } | ||
| 214 | |||
| 139 | return 0; | 215 | return 0; |
| 140 | } | 216 | } |
| 141 | 217 | ||
