diff options
author | David Brown <davidb@codeaurora.org> | 2010-12-20 16:11:10 -0500 |
---|---|---|
committer | David Brown <davidb@codeaurora.org> | 2010-12-20 16:11:10 -0500 |
commit | ba119204ff6ff722dcec387b305d9c2d23380726 (patch) | |
tree | ae608ce52cf4d47a4278bb9d5df9a8616bb7200c | |
parent | cf7d7e5a1980d1116ee152d25dac382b112b9c17 (diff) | |
parent | 0c521ccbd0c9ad5623ff9b37b20b3ff9d4ad65a7 (diff) |
Merge branches 'msm-core' and 'msm-mmc' into for-next
* msm-core: (28 commits)
msm: initial framebuffer support
msm: add handling for clocks tagged as CLK_MINMAX
msm: trout: change name of pmdh_clk to mddi_clk
msm: add CLK_MINMAX to pmdh_clk
msm: trout: add gpio_to_irq
msm: iommu: Use the correct memory allocation flag
msm_serial: Remove redundant unlikely()
msm: iommu: Miscellaneous code cleanup
msm: iommu: Support cache-coherent memory access
msm: iommu: Definitions for extended memory attributes
msm: iommu: Kconfig dependency for the IOMMU API
msm: iommu: Check if device is already attached
msm: iommu: Kconfig item for cacheable page tables
msm: iommu: Don't flush page tables if no devices attached
msm: iommu: Mark functions with the right section names
msm: iommu: Support for the 2nd GFX core's IOMMU
msm: iommu: Revise GFX2D0 IOMMU contexts and M2V mappings
msm: iommu: Revise GFX3D IOMMU contexts and M2V mappings
msm: iommu: Use more consistent naming in platform data
msm: iomap: Addresses and IRQs for 2nd GFX core IOMMU
...
* msm-mmc: (33 commits)
mmc: msm_sdcc: Check for only DATA_END interrupt to end a request
mmc: msm_sdcc: Fix bug in PIO mode when data size is not word aligned
mmc: msm_sdcc: Reset SDCC in case of data transfer errors
mmc: msm_sdcc: Add prog done interrupt support
mmc: msm_sdcc: Fix possible circular locking dependency warning
msm: initial framebuffer support
msm: add handling for clocks tagged as CLK_MINMAX
msm: trout: change name of pmdh_clk to mddi_clk
msm: add CLK_MINMAX to pmdh_clk
msm: trout: add gpio_to_irq
msm: iommu: Use the correct memory allocation flag
msm_serial: Remove redundant unlikely()
msm: iommu: Miscellaneous code cleanup
msm: iommu: Support cache-coherent memory access
msm: iommu: Definitions for extended memory attributes
msm: iommu: Kconfig dependency for the IOMMU API
msm: iommu: Check if device is already attached
msm: iommu: Kconfig item for cacheable page tables
msm: iommu: Don't flush page tables if no devices attached
msm: iommu: Mark functions with the right section names
...
-rw-r--r-- | arch/arm/mach-msm/Kconfig | 8 | ||||
-rw-r--r-- | arch/arm/mach-msm/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-msm/board-trout-gpio.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-msm/board-trout-panel.c | 297 | ||||
-rw-r--r-- | arch/arm/mach-msm/clock.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices-msm7x00.c | 69 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices-msm8x60-iommu.c | 243 | ||||
-rw-r--r-- | arch/arm/mach-msm/devices.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-msm/gpio-v2.c | 426 | ||||
-rw-r--r-- | arch/arm/mach-msm/include/mach/iommu.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h | 22 | ||||
-rw-r--r-- | arch/arm/mach-msm/include/mach/irqs-8x60.h | 7 | ||||
-rw-r--r-- | arch/arm/mach-msm/include/mach/msm_iomap-8x60.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-msm/io.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-msm/iommu.c | 146 | ||||
-rw-r--r-- | arch/arm/mach-msm/iommu_dev.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-msm/sirc.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-msm/smd.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-msm/smd_debug.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/msm_sdcc.c | 139 | ||||
-rw-r--r-- | drivers/mmc/host/msm_sdcc.h | 8 | ||||
-rw-r--r-- | drivers/serial/msm_serial.c | 2 |
22 files changed, 1247 insertions, 197 deletions
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig index dbbcfeb919db..1a11f1ed216d 100644 --- a/arch/arm/mach-msm/Kconfig +++ b/arch/arm/mach-msm/Kconfig | |||
@@ -44,6 +44,7 @@ config ARCH_MSM8X60 | |||
44 | select CPU_V7 | 44 | select CPU_V7 |
45 | select MSM_V2_TLMM | 45 | select MSM_V2_TLMM |
46 | select MSM_GPIOMUX | 46 | select MSM_GPIOMUX |
47 | select IOMMU_API | ||
47 | 48 | ||
48 | endchoice | 49 | endchoice |
49 | 50 | ||
@@ -122,6 +123,10 @@ config MACH_MSM8X60_FFA | |||
122 | 123 | ||
123 | endmenu | 124 | endmenu |
124 | 125 | ||
126 | config IOMMU_PGTABLES_L2 | ||
127 | def_bool y | ||
128 | depends on ARCH_MSM8X60 && MMU && SMP && CPU_DCACHE_DISABLE=n | ||
129 | |||
125 | config MSM_DEBUG_UART | 130 | config MSM_DEBUG_UART |
126 | int | 131 | int |
127 | default 1 if MSM_DEBUG_UART1 | 132 | default 1 if MSM_DEBUG_UART1 |
@@ -162,4 +167,7 @@ config MSM_GPIOMUX | |||
162 | 167 | ||
163 | config MSM_V2_TLMM | 168 | config MSM_V2_TLMM |
164 | bool | 169 | bool |
170 | |||
171 | config IOMMU_API | ||
172 | bool | ||
165 | endif | 173 | endif |
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index b5a7b07a44f5..59646bbd6195 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o | |||
20 | obj-$(CONFIG_MSM_SMD) += last_radio_log.o | 20 | obj-$(CONFIG_MSM_SMD) += last_radio_log.o |
21 | 21 | ||
22 | obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o | 22 | obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o |
23 | obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o | ||
23 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o | 24 | obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o |
24 | obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o | 25 | obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o |
25 | obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o | 26 | obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o |
@@ -28,6 +29,8 @@ obj-$(CONFIG_ARCH_MSM8X60) += board-msm8x60.o | |||
28 | obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o | 29 | obj-$(CONFIG_ARCH_MSM7X30) += gpiomux-7x30.o gpiomux-v1.o gpiomux.o |
29 | obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o | 30 | obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o gpiomux-v1.o gpiomux.o |
30 | obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o | 31 | obj-$(CONFIG_ARCH_MSM8X60) += gpiomux-8x60.o gpiomux-v2.o gpiomux.o |
31 | ifndef CONFIG_MSM_V2_TLMM | 32 | ifdef CONFIG_MSM_V2_TLMM |
33 | obj-y += gpio-v2.o | ||
34 | else | ||
32 | obj-y += gpio.o | 35 | obj-y += gpio.o |
33 | endif | 36 | endif |
diff --git a/arch/arm/mach-msm/board-trout-gpio.c b/arch/arm/mach-msm/board-trout-gpio.c index c50f3afc3134..f8c09ef6666f 100644 --- a/arch/arm/mach-msm/board-trout-gpio.c +++ b/arch/arm/mach-msm/board-trout-gpio.c | |||
@@ -72,6 +72,13 @@ static int msm_gpiolib_direction_output(struct gpio_chip *chip, | |||
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | static int trout_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
76 | { | ||
77 | struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip); | ||
78 | |||
79 | return TROUT_GPIO_TO_INT(offset + chip->base); | ||
80 | } | ||
81 | |||
75 | #define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \ | 82 | #define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \ |
76 | { \ | 83 | { \ |
77 | .chip = { \ | 84 | .chip = { \ |
@@ -80,6 +87,7 @@ static int msm_gpiolib_direction_output(struct gpio_chip *chip, | |||
80 | .direction_output = msm_gpiolib_direction_output, \ | 87 | .direction_output = msm_gpiolib_direction_output, \ |
81 | .get = msm_gpiolib_get, \ | 88 | .get = msm_gpiolib_get, \ |
82 | .set = msm_gpiolib_set, \ | 89 | .set = msm_gpiolib_set, \ |
90 | .to_irq = trout_gpio_to_irq, \ | ||
83 | .base = base_gpio, \ | 91 | .base = base_gpio, \ |
84 | .ngpio = 8, \ | 92 | .ngpio = 8, \ |
85 | }, \ | 93 | }, \ |
diff --git a/arch/arm/mach-msm/board-trout-panel.c b/arch/arm/mach-msm/board-trout-panel.c new file mode 100644 index 000000000000..729bb49a44ca --- /dev/null +++ b/arch/arm/mach-msm/board-trout-panel.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* linux/arch/arm/mach-msm/board-trout-mddi.c | ||
2 | ** Author: Brian Swetland <swetland@google.com> | ||
3 | */ | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/init.h> | ||
7 | #include <linux/platform_device.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/leds.h> | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/err.h> | ||
12 | |||
13 | #include <asm/io.h> | ||
14 | #include <asm/gpio.h> | ||
15 | #include <asm/mach-types.h> | ||
16 | |||
17 | #include <mach/msm_fb.h> | ||
18 | #include <mach/vreg.h> | ||
19 | |||
20 | #include "board-trout.h" | ||
21 | #include "proc_comm.h" | ||
22 | #include "devices.h" | ||
23 | |||
24 | #define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 255 | ||
25 | |||
26 | #define MDDI_CLIENT_CORE_BASE 0x108000 | ||
27 | #define LCD_CONTROL_BLOCK_BASE 0x110000 | ||
28 | #define SPI_BLOCK_BASE 0x120000 | ||
29 | #define I2C_BLOCK_BASE 0x130000 | ||
30 | #define PWM_BLOCK_BASE 0x140000 | ||
31 | #define GPIO_BLOCK_BASE 0x150000 | ||
32 | #define SYSTEM_BLOCK1_BASE 0x160000 | ||
33 | #define SYSTEM_BLOCK2_BASE 0x170000 | ||
34 | |||
35 | |||
36 | #define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) | ||
37 | #define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C) | ||
38 | #define PWM0OFF (PWM_BLOCK_BASE|0x1C) | ||
39 | |||
40 | #define V_VDDE2E_VDD2_GPIO 0 | ||
41 | #define MDDI_RST_N 82 | ||
42 | |||
43 | #define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00) | ||
44 | #define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04) | ||
45 | #define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08) | ||
46 | #define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C) | ||
47 | #define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10) | ||
48 | #define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14) | ||
49 | #define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18) | ||
50 | #define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C) | ||
51 | #define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20) | ||
52 | #define DPSUS (MDDI_CLIENT_CORE_BASE|0x24) | ||
53 | #define DPRUN (MDDI_CLIENT_CORE_BASE|0x28) | ||
54 | #define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C) | ||
55 | #define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30) | ||
56 | #define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34) | ||
57 | #define INTMONI (MDDI_CLIENT_CORE_BASE|0x38) | ||
58 | #define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C) | ||
59 | #define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40) | ||
60 | #define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44) | ||
61 | #define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48) | ||
62 | #define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C) | ||
63 | #define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50) | ||
64 | #define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54) | ||
65 | |||
66 | #define SRST (LCD_CONTROL_BLOCK_BASE|0x00) | ||
67 | #define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04) | ||
68 | #define START (LCD_CONTROL_BLOCK_BASE|0x08) | ||
69 | #define PORT (LCD_CONTROL_BLOCK_BASE|0x0C) | ||
70 | #define CMN (LCD_CONTROL_BLOCK_BASE|0x10) | ||
71 | #define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14) | ||
72 | #define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18) | ||
73 | #define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C) | ||
74 | #define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20) | ||
75 | #define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24) | ||
76 | #define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28) | ||
77 | #define PXL (LCD_CONTROL_BLOCK_BASE|0x30) | ||
78 | #define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34) | ||
79 | #define HSW (LCD_CONTROL_BLOCK_BASE|0x38) | ||
80 | #define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C) | ||
81 | #define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40) | ||
82 | #define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44) | ||
83 | #define VSW (LCD_CONTROL_BLOCK_BASE|0x48) | ||
84 | #define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C) | ||
85 | #define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50) | ||
86 | #define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54) | ||
87 | #define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58) | ||
88 | #define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C) | ||
89 | #define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60) | ||
90 | #define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64) | ||
91 | #define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68) | ||
92 | #define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C) | ||
93 | #define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70) | ||
94 | #define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74) | ||
95 | #define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78) | ||
96 | #define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C) | ||
97 | #define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80) | ||
98 | #define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84) | ||
99 | #define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88) | ||
100 | #define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C) | ||
101 | |||
102 | #define SSICTL (SPI_BLOCK_BASE|0x00) | ||
103 | #define SSITIME (SPI_BLOCK_BASE|0x04) | ||
104 | #define SSITX (SPI_BLOCK_BASE|0x08) | ||
105 | #define SSIRX (SPI_BLOCK_BASE|0x0C) | ||
106 | #define SSIINTC (SPI_BLOCK_BASE|0x10) | ||
107 | #define SSIINTS (SPI_BLOCK_BASE|0x14) | ||
108 | #define SSIDBG1 (SPI_BLOCK_BASE|0x18) | ||
109 | #define SSIDBG2 (SPI_BLOCK_BASE|0x1C) | ||
110 | #define SSIID (SPI_BLOCK_BASE|0x20) | ||
111 | |||
112 | #define WKREQ (SYSTEM_BLOCK1_BASE|0x00) | ||
113 | #define CLKENB (SYSTEM_BLOCK1_BASE|0x04) | ||
114 | #define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08) | ||
115 | #define INTMASK (SYSTEM_BLOCK1_BASE|0x0C) | ||
116 | #define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00) | ||
117 | |||
118 | #define GPIODATA (GPIO_BLOCK_BASE|0x00) | ||
119 | #define GPIODIR (GPIO_BLOCK_BASE|0x04) | ||
120 | #define GPIOIS (GPIO_BLOCK_BASE|0x08) | ||
121 | #define GPIOIBE (GPIO_BLOCK_BASE|0x0C) | ||
122 | #define GPIOIEV (GPIO_BLOCK_BASE|0x10) | ||
123 | #define GPIOIE (GPIO_BLOCK_BASE|0x14) | ||
124 | #define GPIORIS (GPIO_BLOCK_BASE|0x18) | ||
125 | #define GPIOMIS (GPIO_BLOCK_BASE|0x1C) | ||
126 | #define GPIOIC (GPIO_BLOCK_BASE|0x20) | ||
127 | #define GPIOOMS (GPIO_BLOCK_BASE|0x24) | ||
128 | #define GPIOPC (GPIO_BLOCK_BASE|0x28) | ||
129 | #define GPIOID (GPIO_BLOCK_BASE|0x30) | ||
130 | |||
131 | #define SPI_WRITE(reg, val) \ | ||
132 | { SSITX, 0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \ | ||
133 | { 0, 5 }, | ||
134 | |||
135 | #define SPI_WRITE1(reg) \ | ||
136 | { SSITX, (reg) & 0xff }, \ | ||
137 | { 0, 5 }, | ||
138 | |||
139 | struct mddi_table { | ||
140 | uint32_t reg; | ||
141 | uint32_t value; | ||
142 | }; | ||
143 | static struct mddi_table mddi_toshiba_init_table[] = { | ||
144 | { DPSET0, 0x09e90046 }, | ||
145 | { DPSET1, 0x00000118 }, | ||
146 | { DPSUS, 0x00000000 }, | ||
147 | { DPRUN, 0x00000001 }, | ||
148 | { 1, 14 }, /* msleep 14 */ | ||
149 | { SYSCKENA, 0x00000001 }, | ||
150 | { CLKENB, 0x0000A1EF }, /* # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) */ | ||
151 | |||
152 | { GPIODATA, 0x02000200 }, /* # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */ | ||
153 | { GPIODIR, 0x000030D }, /* 24D # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) */ | ||
154 | { GPIOSEL, 0/*0x00000173*/}, /* # SYS.GPIOSEL # GPIO port multiplexing control */ | ||
155 | { GPIOPC, 0x03C300C0 }, /* # GPI .GPIOPC # GPIO2,3 PD cut */ | ||
156 | { WKREQ, 0x00000000 }, /* # SYS.WKREQ # Wake-up request event is VSYNC alignment */ | ||
157 | |||
158 | { GPIOIBE, 0x000003FF }, | ||
159 | { GPIOIS, 0x00000000 }, | ||
160 | { GPIOIC, 0x000003FF }, | ||
161 | { GPIOIE, 0x00000000 }, | ||
162 | |||
163 | { GPIODATA, 0x00040004 }, /* # GPI .GPIODATA # eDRAM VD supply */ | ||
164 | { 1, 1 }, /* msleep 1 */ | ||
165 | { GPIODATA, 0x02040004 }, /* # GPI .GPIODATA # eDRAM VD supply */ | ||
166 | { DRAMPWR, 0x00000001 }, /* eDRAM power */ | ||
167 | }; | ||
168 | |||
169 | #define GPIOSEL_VWAKEINT (1U << 0) | ||
170 | #define INTMASK_VWAKEOUT (1U << 0) | ||
171 | |||
172 | |||
173 | static struct clk *gp_clk; | ||
174 | static int trout_new_backlight = 1; | ||
175 | static struct vreg *vreg_mddi_1v5; | ||
176 | static struct vreg *vreg_lcm_2v85; | ||
177 | |||
178 | static void trout_process_mddi_table(struct msm_mddi_client_data *client_data, | ||
179 | struct mddi_table *table, size_t count) | ||
180 | { | ||
181 | int i; | ||
182 | for (i = 0; i < count; i++) { | ||
183 | uint32_t reg = table[i].reg; | ||
184 | uint32_t value = table[i].value; | ||
185 | |||
186 | if (reg == 0) | ||
187 | udelay(value); | ||
188 | else if (reg == 1) | ||
189 | msleep(value); | ||
190 | else | ||
191 | client_data->remote_write(client_data, value, reg); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static int trout_mddi_toshiba_client_init( | ||
196 | struct msm_mddi_bridge_platform_data *bridge_data, | ||
197 | struct msm_mddi_client_data *client_data) | ||
198 | { | ||
199 | int panel_id; | ||
200 | |||
201 | client_data->auto_hibernate(client_data, 0); | ||
202 | trout_process_mddi_table(client_data, mddi_toshiba_init_table, | ||
203 | ARRAY_SIZE(mddi_toshiba_init_table)); | ||
204 | client_data->auto_hibernate(client_data, 1); | ||
205 | panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3; | ||
206 | if (panel_id > 1) { | ||
207 | printk(KERN_WARNING "unknown panel id at mddi_enable\n"); | ||
208 | return -1; | ||
209 | } | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static int trout_mddi_toshiba_client_uninit( | ||
214 | struct msm_mddi_bridge_platform_data *bridge_data, | ||
215 | struct msm_mddi_client_data *client_data) | ||
216 | { | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static struct resource resources_msm_fb[] = { | ||
221 | { | ||
222 | .start = MSM_FB_BASE, | ||
223 | .end = MSM_FB_BASE + MSM_FB_SIZE, | ||
224 | .flags = IORESOURCE_MEM, | ||
225 | }, | ||
226 | }; | ||
227 | |||
228 | struct msm_mddi_bridge_platform_data toshiba_client_data = { | ||
229 | .init = trout_mddi_toshiba_client_init, | ||
230 | .uninit = trout_mddi_toshiba_client_uninit, | ||
231 | .fb_data = { | ||
232 | .xres = 320, | ||
233 | .yres = 480, | ||
234 | .width = 45, | ||
235 | .height = 67, | ||
236 | .output_format = 0, | ||
237 | }, | ||
238 | }; | ||
239 | |||
240 | static struct msm_mddi_platform_data mddi_pdata = { | ||
241 | .clk_rate = 122880000, | ||
242 | .fb_resource = resources_msm_fb, | ||
243 | .num_clients = 1, | ||
244 | .client_platform_data = { | ||
245 | { | ||
246 | .product_id = (0xd263 << 16 | 0), | ||
247 | .name = "mddi_c_d263_0000", | ||
248 | .id = 0, | ||
249 | .client_data = &toshiba_client_data, | ||
250 | .clk_rate = 0, | ||
251 | }, | ||
252 | }, | ||
253 | }; | ||
254 | |||
255 | int __init trout_init_panel(void) | ||
256 | { | ||
257 | int rc; | ||
258 | |||
259 | if (!machine_is_trout()) | ||
260 | return 0; | ||
261 | vreg_mddi_1v5 = vreg_get(0, "gp2"); | ||
262 | if (IS_ERR(vreg_mddi_1v5)) | ||
263 | return PTR_ERR(vreg_mddi_1v5); | ||
264 | vreg_lcm_2v85 = vreg_get(0, "gp4"); | ||
265 | if (IS_ERR(vreg_lcm_2v85)) | ||
266 | return PTR_ERR(vreg_lcm_2v85); | ||
267 | |||
268 | trout_new_backlight = system_rev >= 5; | ||
269 | if (trout_new_backlight) { | ||
270 | uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT, | ||
271 | GPIO_NO_PULL, GPIO_8MA); | ||
272 | msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0); | ||
273 | } else { | ||
274 | uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT, | ||
275 | GPIO_NO_PULL, GPIO_8MA); | ||
276 | msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0); | ||
277 | |||
278 | gp_clk = clk_get(NULL, "gp_clk"); | ||
279 | if (IS_ERR(gp_clk)) { | ||
280 | printk(KERN_ERR "trout_init_panel: could not get gp" | ||
281 | "clock\n"); | ||
282 | gp_clk = NULL; | ||
283 | } | ||
284 | rc = clk_set_rate(gp_clk, 19200000); | ||
285 | if (rc) | ||
286 | printk(KERN_ERR "trout_init_panel: set clock rate " | ||
287 | "failed\n"); | ||
288 | } | ||
289 | |||
290 | rc = platform_device_register(&msm_device_mdp); | ||
291 | if (rc) | ||
292 | return rc; | ||
293 | msm_device_mddi0.dev.platform_data = &mddi_pdata; | ||
294 | return platform_device_register(&msm_device_mddi0); | ||
295 | } | ||
296 | |||
297 | device_initcall(trout_init_panel); | ||
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index c57210f4f06a..2069bfaa3a26 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c | |||
@@ -120,6 +120,21 @@ EXPORT_SYMBOL(clk_get_rate); | |||
120 | 120 | ||
121 | int clk_set_rate(struct clk *clk, unsigned long rate) | 121 | int clk_set_rate(struct clk *clk, unsigned long rate) |
122 | { | 122 | { |
123 | int ret; | ||
124 | if (clk->flags & CLKFLAG_MAX) { | ||
125 | ret = clk->ops->set_max_rate(clk->id, rate); | ||
126 | if (ret) | ||
127 | return ret; | ||
128 | } | ||
129 | if (clk->flags & CLKFLAG_MIN) { | ||
130 | ret = clk->ops->set_min_rate(clk->id, rate); | ||
131 | if (ret) | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | if (clk->flags & CLKFLAG_MAX || clk->flags & CLKFLAG_MIN) | ||
136 | return ret; | ||
137 | |||
123 | return clk->ops->set_rate(clk->id, rate); | 138 | return clk->ops->set_rate(clk->id, rate); |
124 | } | 139 | } |
125 | EXPORT_SYMBOL(clk_set_rate); | 140 | EXPORT_SYMBOL(clk_set_rate); |
diff --git a/arch/arm/mach-msm/devices-msm7x00.c b/arch/arm/mach-msm/devices-msm7x00.c index 4e8c0bcdc92d..fb548a8a21db 100644 --- a/arch/arm/mach-msm/devices-msm7x00.c +++ b/arch/arm/mach-msm/devices-msm7x00.c | |||
@@ -347,6 +347,73 @@ int __init msm_add_sdcc(unsigned int controller, | |||
347 | return platform_device_register(pdev); | 347 | return platform_device_register(pdev); |
348 | } | 348 | } |
349 | 349 | ||
350 | static struct resource resources_mddi0[] = { | ||
351 | { | ||
352 | .start = MSM_PMDH_PHYS, | ||
353 | .end = MSM_PMDH_PHYS + MSM_PMDH_SIZE - 1, | ||
354 | .flags = IORESOURCE_MEM, | ||
355 | }, | ||
356 | { | ||
357 | .start = INT_MDDI_PRI, | ||
358 | .end = INT_MDDI_PRI, | ||
359 | .flags = IORESOURCE_IRQ, | ||
360 | }, | ||
361 | }; | ||
362 | |||
363 | static struct resource resources_mddi1[] = { | ||
364 | { | ||
365 | .start = MSM_EMDH_PHYS, | ||
366 | .end = MSM_EMDH_PHYS + MSM_EMDH_SIZE - 1, | ||
367 | .flags = IORESOURCE_MEM, | ||
368 | }, | ||
369 | { | ||
370 | .start = INT_MDDI_EXT, | ||
371 | .end = INT_MDDI_EXT, | ||
372 | .flags = IORESOURCE_IRQ, | ||
373 | }, | ||
374 | }; | ||
375 | |||
376 | struct platform_device msm_device_mddi0 = { | ||
377 | .name = "msm_mddi", | ||
378 | .id = 0, | ||
379 | .num_resources = ARRAY_SIZE(resources_mddi0), | ||
380 | .resource = resources_mddi0, | ||
381 | .dev = { | ||
382 | .coherent_dma_mask = 0xffffffff, | ||
383 | }, | ||
384 | }; | ||
385 | |||
386 | struct platform_device msm_device_mddi1 = { | ||
387 | .name = "msm_mddi", | ||
388 | .id = 1, | ||
389 | .num_resources = ARRAY_SIZE(resources_mddi1), | ||
390 | .resource = resources_mddi1, | ||
391 | .dev = { | ||
392 | .coherent_dma_mask = 0xffffffff, | ||
393 | }, | ||
394 | }; | ||
395 | |||
396 | static struct resource resources_mdp[] = { | ||
397 | { | ||
398 | .start = MSM_MDP_PHYS, | ||
399 | .end = MSM_MDP_PHYS + MSM_MDP_SIZE - 1, | ||
400 | .name = "mdp", | ||
401 | .flags = IORESOURCE_MEM | ||
402 | }, | ||
403 | { | ||
404 | .start = INT_MDP, | ||
405 | .end = INT_MDP, | ||
406 | .flags = IORESOURCE_IRQ, | ||
407 | }, | ||
408 | }; | ||
409 | |||
410 | struct platform_device msm_device_mdp = { | ||
411 | .name = "msm_mdp", | ||
412 | .id = 0, | ||
413 | .num_resources = ARRAY_SIZE(resources_mdp), | ||
414 | .resource = resources_mdp, | ||
415 | }; | ||
416 | |||
350 | struct clk msm_clocks_7x01a[] = { | 417 | struct clk msm_clocks_7x01a[] = { |
351 | CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), | 418 | CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), |
352 | CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), | 419 | CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), |
@@ -364,7 +431,7 @@ struct clk msm_clocks_7x01a[] = { | |||
364 | CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), | 431 | CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), |
365 | CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0), | 432 | CLK_PCOM("pbus_clk", PBUS_CLK, NULL, 0), |
366 | CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), | 433 | CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), |
367 | CLK_PCOM("pmdh_clk", PMDH_CLK, NULL, OFF ), | 434 | CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | CLK_MINMAX), |
368 | CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), | 435 | CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), |
369 | CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), | 436 | CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), |
370 | CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF), | 437 | CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF), |
diff --git a/arch/arm/mach-msm/devices-msm8x60-iommu.c b/arch/arm/mach-msm/devices-msm8x60-iommu.c index 89b9d4437e92..f9e7bd34ec59 100644 --- a/arch/arm/mach-msm/devices-msm8x60-iommu.c +++ b/arch/arm/mach-msm/devices-msm8x60-iommu.c | |||
@@ -254,60 +254,86 @@ static struct resource msm_iommu_gfx2d0_resources[] = { | |||
254 | }, | 254 | }, |
255 | }; | 255 | }; |
256 | 256 | ||
257 | static struct resource msm_iommu_gfx2d1_resources[] = { | ||
258 | { | ||
259 | .start = MSM_IOMMU_GFX2D1_PHYS, | ||
260 | .end = MSM_IOMMU_GFX2D1_PHYS + MSM_IOMMU_GFX2D1_SIZE - 1, | ||
261 | .name = "physbase", | ||
262 | .flags = IORESOURCE_MEM, | ||
263 | }, | ||
264 | { | ||
265 | .name = "nonsecure_irq", | ||
266 | .start = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ, | ||
267 | .end = SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ, | ||
268 | .flags = IORESOURCE_IRQ, | ||
269 | }, | ||
270 | { | ||
271 | .name = "secure_irq", | ||
272 | .start = SMMU_GFX2D1_CB_SC_SECURE_IRQ, | ||
273 | .end = SMMU_GFX2D1_CB_SC_SECURE_IRQ, | ||
274 | .flags = IORESOURCE_IRQ, | ||
275 | }, | ||
276 | }; | ||
277 | |||
257 | static struct platform_device msm_root_iommu_dev = { | 278 | static struct platform_device msm_root_iommu_dev = { |
258 | .name = "msm_iommu", | 279 | .name = "msm_iommu", |
259 | .id = -1, | 280 | .id = -1, |
260 | }; | 281 | }; |
261 | 282 | ||
262 | static struct msm_iommu_dev jpegd_smmu = { | 283 | static struct msm_iommu_dev jpegd_iommu = { |
263 | .name = "jpegd", | 284 | .name = "jpegd", |
264 | .clk_rate = -1 | 285 | .clk_rate = -1 |
265 | }; | 286 | }; |
266 | 287 | ||
267 | static struct msm_iommu_dev vpe_smmu = { | 288 | static struct msm_iommu_dev vpe_iommu = { |
268 | .name = "vpe" | 289 | .name = "vpe" |
269 | }; | 290 | }; |
270 | 291 | ||
271 | static struct msm_iommu_dev mdp0_smmu = { | 292 | static struct msm_iommu_dev mdp0_iommu = { |
272 | .name = "mdp0" | 293 | .name = "mdp0" |
273 | }; | 294 | }; |
274 | 295 | ||
275 | static struct msm_iommu_dev mdp1_smmu = { | 296 | static struct msm_iommu_dev mdp1_iommu = { |
276 | .name = "mdp1" | 297 | .name = "mdp1" |
277 | }; | 298 | }; |
278 | 299 | ||
279 | static struct msm_iommu_dev rot_smmu = { | 300 | static struct msm_iommu_dev rot_iommu = { |
280 | .name = "rot" | 301 | .name = "rot" |
281 | }; | 302 | }; |
282 | 303 | ||
283 | static struct msm_iommu_dev ijpeg_smmu = { | 304 | static struct msm_iommu_dev ijpeg_iommu = { |
284 | .name = "ijpeg" | 305 | .name = "ijpeg" |
285 | }; | 306 | }; |
286 | 307 | ||
287 | static struct msm_iommu_dev vfe_smmu = { | 308 | static struct msm_iommu_dev vfe_iommu = { |
288 | .name = "vfe", | 309 | .name = "vfe", |
289 | .clk_rate = -1 | 310 | .clk_rate = -1 |
290 | }; | 311 | }; |
291 | 312 | ||
292 | static struct msm_iommu_dev vcodec_a_smmu = { | 313 | static struct msm_iommu_dev vcodec_a_iommu = { |
293 | .name = "vcodec_a" | 314 | .name = "vcodec_a" |
294 | }; | 315 | }; |
295 | 316 | ||
296 | static struct msm_iommu_dev vcodec_b_smmu = { | 317 | static struct msm_iommu_dev vcodec_b_iommu = { |
297 | .name = "vcodec_b" | 318 | .name = "vcodec_b" |
298 | }; | 319 | }; |
299 | 320 | ||
300 | static struct msm_iommu_dev gfx3d_smmu = { | 321 | static struct msm_iommu_dev gfx3d_iommu = { |
301 | .name = "gfx3d", | 322 | .name = "gfx3d", |
302 | .clk_rate = 27000000 | 323 | .clk_rate = 27000000 |
303 | }; | 324 | }; |
304 | 325 | ||
305 | static struct msm_iommu_dev gfx2d0_smmu = { | 326 | static struct msm_iommu_dev gfx2d0_iommu = { |
306 | .name = "gfx2d0", | 327 | .name = "gfx2d0", |
307 | .clk_rate = 27000000 | 328 | .clk_rate = 27000000 |
308 | }; | 329 | }; |
309 | 330 | ||
310 | static struct platform_device msm_device_smmu_jpegd = { | 331 | static struct msm_iommu_dev gfx2d1_iommu = { |
332 | .name = "gfx2d1", | ||
333 | .clk_rate = 27000000 | ||
334 | }; | ||
335 | |||
336 | static struct platform_device msm_device_iommu_jpegd = { | ||
311 | .name = "msm_iommu", | 337 | .name = "msm_iommu", |
312 | .id = 0, | 338 | .id = 0, |
313 | .dev = { | 339 | .dev = { |
@@ -317,7 +343,7 @@ static struct platform_device msm_device_smmu_jpegd = { | |||
317 | .resource = msm_iommu_jpegd_resources, | 343 | .resource = msm_iommu_jpegd_resources, |
318 | }; | 344 | }; |
319 | 345 | ||
320 | static struct platform_device msm_device_smmu_vpe = { | 346 | static struct platform_device msm_device_iommu_vpe = { |
321 | .name = "msm_iommu", | 347 | .name = "msm_iommu", |
322 | .id = 1, | 348 | .id = 1, |
323 | .dev = { | 349 | .dev = { |
@@ -327,7 +353,7 @@ static struct platform_device msm_device_smmu_vpe = { | |||
327 | .resource = msm_iommu_vpe_resources, | 353 | .resource = msm_iommu_vpe_resources, |
328 | }; | 354 | }; |
329 | 355 | ||
330 | static struct platform_device msm_device_smmu_mdp0 = { | 356 | static struct platform_device msm_device_iommu_mdp0 = { |
331 | .name = "msm_iommu", | 357 | .name = "msm_iommu", |
332 | .id = 2, | 358 | .id = 2, |
333 | .dev = { | 359 | .dev = { |
@@ -337,7 +363,7 @@ static struct platform_device msm_device_smmu_mdp0 = { | |||
337 | .resource = msm_iommu_mdp0_resources, | 363 | .resource = msm_iommu_mdp0_resources, |
338 | }; | 364 | }; |
339 | 365 | ||
340 | static struct platform_device msm_device_smmu_mdp1 = { | 366 | static struct platform_device msm_device_iommu_mdp1 = { |
341 | .name = "msm_iommu", | 367 | .name = "msm_iommu", |
342 | .id = 3, | 368 | .id = 3, |
343 | .dev = { | 369 | .dev = { |
@@ -347,7 +373,7 @@ static struct platform_device msm_device_smmu_mdp1 = { | |||
347 | .resource = msm_iommu_mdp1_resources, | 373 | .resource = msm_iommu_mdp1_resources, |
348 | }; | 374 | }; |
349 | 375 | ||
350 | static struct platform_device msm_device_smmu_rot = { | 376 | static struct platform_device msm_device_iommu_rot = { |
351 | .name = "msm_iommu", | 377 | .name = "msm_iommu", |
352 | .id = 4, | 378 | .id = 4, |
353 | .dev = { | 379 | .dev = { |
@@ -357,7 +383,7 @@ static struct platform_device msm_device_smmu_rot = { | |||
357 | .resource = msm_iommu_rot_resources, | 383 | .resource = msm_iommu_rot_resources, |
358 | }; | 384 | }; |
359 | 385 | ||
360 | static struct platform_device msm_device_smmu_ijpeg = { | 386 | static struct platform_device msm_device_iommu_ijpeg = { |
361 | .name = "msm_iommu", | 387 | .name = "msm_iommu", |
362 | .id = 5, | 388 | .id = 5, |
363 | .dev = { | 389 | .dev = { |
@@ -367,7 +393,7 @@ static struct platform_device msm_device_smmu_ijpeg = { | |||
367 | .resource = msm_iommu_ijpeg_resources, | 393 | .resource = msm_iommu_ijpeg_resources, |
368 | }; | 394 | }; |
369 | 395 | ||
370 | static struct platform_device msm_device_smmu_vfe = { | 396 | static struct platform_device msm_device_iommu_vfe = { |
371 | .name = "msm_iommu", | 397 | .name = "msm_iommu", |
372 | .id = 6, | 398 | .id = 6, |
373 | .dev = { | 399 | .dev = { |
@@ -377,7 +403,7 @@ static struct platform_device msm_device_smmu_vfe = { | |||
377 | .resource = msm_iommu_vfe_resources, | 403 | .resource = msm_iommu_vfe_resources, |
378 | }; | 404 | }; |
379 | 405 | ||
380 | static struct platform_device msm_device_smmu_vcodec_a = { | 406 | static struct platform_device msm_device_iommu_vcodec_a = { |
381 | .name = "msm_iommu", | 407 | .name = "msm_iommu", |
382 | .id = 7, | 408 | .id = 7, |
383 | .dev = { | 409 | .dev = { |
@@ -387,7 +413,7 @@ static struct platform_device msm_device_smmu_vcodec_a = { | |||
387 | .resource = msm_iommu_vcodec_a_resources, | 413 | .resource = msm_iommu_vcodec_a_resources, |
388 | }; | 414 | }; |
389 | 415 | ||
390 | static struct platform_device msm_device_smmu_vcodec_b = { | 416 | static struct platform_device msm_device_iommu_vcodec_b = { |
391 | .name = "msm_iommu", | 417 | .name = "msm_iommu", |
392 | .id = 8, | 418 | .id = 8, |
393 | .dev = { | 419 | .dev = { |
@@ -397,7 +423,7 @@ static struct platform_device msm_device_smmu_vcodec_b = { | |||
397 | .resource = msm_iommu_vcodec_b_resources, | 423 | .resource = msm_iommu_vcodec_b_resources, |
398 | }; | 424 | }; |
399 | 425 | ||
400 | static struct platform_device msm_device_smmu_gfx3d = { | 426 | static struct platform_device msm_device_iommu_gfx3d = { |
401 | .name = "msm_iommu", | 427 | .name = "msm_iommu", |
402 | .id = 9, | 428 | .id = 9, |
403 | .dev = { | 429 | .dev = { |
@@ -407,7 +433,7 @@ static struct platform_device msm_device_smmu_gfx3d = { | |||
407 | .resource = msm_iommu_gfx3d_resources, | 433 | .resource = msm_iommu_gfx3d_resources, |
408 | }; | 434 | }; |
409 | 435 | ||
410 | static struct platform_device msm_device_smmu_gfx2d0 = { | 436 | static struct platform_device msm_device_iommu_gfx2d0 = { |
411 | .name = "msm_iommu", | 437 | .name = "msm_iommu", |
412 | .id = 10, | 438 | .id = 10, |
413 | .dev = { | 439 | .dev = { |
@@ -417,6 +443,16 @@ static struct platform_device msm_device_smmu_gfx2d0 = { | |||
417 | .resource = msm_iommu_gfx2d0_resources, | 443 | .resource = msm_iommu_gfx2d0_resources, |
418 | }; | 444 | }; |
419 | 445 | ||
446 | struct platform_device msm_device_iommu_gfx2d1 = { | ||
447 | .name = "msm_iommu", | ||
448 | .id = 11, | ||
449 | .dev = { | ||
450 | .parent = &msm_root_iommu_dev.dev, | ||
451 | }, | ||
452 | .num_resources = ARRAY_SIZE(msm_iommu_gfx2d1_resources), | ||
453 | .resource = msm_iommu_gfx2d1_resources, | ||
454 | }; | ||
455 | |||
420 | static struct msm_iommu_ctx_dev jpegd_src_ctx = { | 456 | static struct msm_iommu_ctx_dev jpegd_src_ctx = { |
421 | .name = "jpegd_src", | 457 | .name = "jpegd_src", |
422 | .num = 0, | 458 | .num = 0, |
@@ -519,41 +555,36 @@ static struct msm_iommu_ctx_dev vcodec_b_mm2_ctx = { | |||
519 | .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1} | 555 | .mids = {0, 1, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1} |
520 | }; | 556 | }; |
521 | 557 | ||
522 | static struct msm_iommu_ctx_dev gfx3d_rbpa_ctx = { | 558 | static struct msm_iommu_ctx_dev gfx3d_user_ctx = { |
523 | .name = "gfx3d_rbpa", | 559 | .name = "gfx3d_user", |
524 | .num = 0, | 560 | .num = 0, |
525 | .mids = {-1} | 561 | .mids = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1} |
526 | }; | 562 | }; |
527 | 563 | ||
528 | static struct msm_iommu_ctx_dev gfx3d_cpvgttc_ctx = { | 564 | static struct msm_iommu_ctx_dev gfx3d_priv_ctx = { |
529 | .name = "gfx3d_cpvgttc", | 565 | .name = "gfx3d_priv", |
530 | .num = 1, | 566 | .num = 1, |
531 | .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1} | 567 | .mids = {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, |
532 | }; | 568 | 31, -1} |
533 | |||
534 | static struct msm_iommu_ctx_dev gfx3d_smmu_ctx = { | ||
535 | .name = "gfx3d_smmu", | ||
536 | .num = 2, | ||
537 | .mids = {8, 9, 10, 11, 12, -1} | ||
538 | }; | 569 | }; |
539 | 570 | ||
540 | static struct msm_iommu_ctx_dev gfx2d0_pixv1_ctx = { | 571 | static struct msm_iommu_ctx_dev gfx2d0_2d0_ctx = { |
541 | .name = "gfx2d0_pixv1_smmu", | 572 | .name = "gfx2d0_2d0", |
542 | .num = 0, | 573 | .num = 0, |
543 | .mids = {0, 3, 4, -1} | 574 | .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1} |
544 | }; | 575 | }; |
545 | 576 | ||
546 | static struct msm_iommu_ctx_dev gfx2d0_texv3_ctx = { | 577 | static struct msm_iommu_ctx_dev gfx2d1_2d1_ctx = { |
547 | .name = "gfx2d0_texv3_smmu", | 578 | .name = "gfx2d1_2d1", |
548 | .num = 1, | 579 | .num = 0, |
549 | .mids = {1, 6, 7, -1} | 580 | .mids = {0, 1, 2, 3, 4, 5, 6, 7, -1} |
550 | }; | 581 | }; |
551 | 582 | ||
552 | static struct platform_device msm_device_jpegd_src_ctx = { | 583 | static struct platform_device msm_device_jpegd_src_ctx = { |
553 | .name = "msm_iommu_ctx", | 584 | .name = "msm_iommu_ctx", |
554 | .id = 0, | 585 | .id = 0, |
555 | .dev = { | 586 | .dev = { |
556 | .parent = &msm_device_smmu_jpegd.dev, | 587 | .parent = &msm_device_iommu_jpegd.dev, |
557 | }, | 588 | }, |
558 | }; | 589 | }; |
559 | 590 | ||
@@ -561,7 +592,7 @@ static struct platform_device msm_device_jpegd_dst_ctx = { | |||
561 | .name = "msm_iommu_ctx", | 592 | .name = "msm_iommu_ctx", |
562 | .id = 1, | 593 | .id = 1, |
563 | .dev = { | 594 | .dev = { |
564 | .parent = &msm_device_smmu_jpegd.dev, | 595 | .parent = &msm_device_iommu_jpegd.dev, |
565 | }, | 596 | }, |
566 | }; | 597 | }; |
567 | 598 | ||
@@ -569,7 +600,7 @@ static struct platform_device msm_device_vpe_src_ctx = { | |||
569 | .name = "msm_iommu_ctx", | 600 | .name = "msm_iommu_ctx", |
570 | .id = 2, | 601 | .id = 2, |
571 | .dev = { | 602 | .dev = { |
572 | .parent = &msm_device_smmu_vpe.dev, | 603 | .parent = &msm_device_iommu_vpe.dev, |
573 | }, | 604 | }, |
574 | }; | 605 | }; |
575 | 606 | ||
@@ -577,7 +608,7 @@ static struct platform_device msm_device_vpe_dst_ctx = { | |||
577 | .name = "msm_iommu_ctx", | 608 | .name = "msm_iommu_ctx", |
578 | .id = 3, | 609 | .id = 3, |
579 | .dev = { | 610 | .dev = { |
580 | .parent = &msm_device_smmu_vpe.dev, | 611 | .parent = &msm_device_iommu_vpe.dev, |
581 | }, | 612 | }, |
582 | }; | 613 | }; |
583 | 614 | ||
@@ -585,7 +616,7 @@ static struct platform_device msm_device_mdp_vg1_ctx = { | |||
585 | .name = "msm_iommu_ctx", | 616 | .name = "msm_iommu_ctx", |
586 | .id = 4, | 617 | .id = 4, |
587 | .dev = { | 618 | .dev = { |
588 | .parent = &msm_device_smmu_mdp0.dev, | 619 | .parent = &msm_device_iommu_mdp0.dev, |
589 | }, | 620 | }, |
590 | }; | 621 | }; |
591 | 622 | ||
@@ -593,7 +624,7 @@ static struct platform_device msm_device_mdp_rgb1_ctx = { | |||
593 | .name = "msm_iommu_ctx", | 624 | .name = "msm_iommu_ctx", |
594 | .id = 5, | 625 | .id = 5, |
595 | .dev = { | 626 | .dev = { |
596 | .parent = &msm_device_smmu_mdp0.dev, | 627 | .parent = &msm_device_iommu_mdp0.dev, |
597 | }, | 628 | }, |
598 | }; | 629 | }; |
599 | 630 | ||
@@ -601,7 +632,7 @@ static struct platform_device msm_device_mdp_vg2_ctx = { | |||
601 | .name = "msm_iommu_ctx", | 632 | .name = "msm_iommu_ctx", |
602 | .id = 6, | 633 | .id = 6, |
603 | .dev = { | 634 | .dev = { |
604 | .parent = &msm_device_smmu_mdp1.dev, | 635 | .parent = &msm_device_iommu_mdp1.dev, |
605 | }, | 636 | }, |
606 | }; | 637 | }; |
607 | 638 | ||
@@ -609,7 +640,7 @@ static struct platform_device msm_device_mdp_rgb2_ctx = { | |||
609 | .name = "msm_iommu_ctx", | 640 | .name = "msm_iommu_ctx", |
610 | .id = 7, | 641 | .id = 7, |
611 | .dev = { | 642 | .dev = { |
612 | .parent = &msm_device_smmu_mdp1.dev, | 643 | .parent = &msm_device_iommu_mdp1.dev, |
613 | }, | 644 | }, |
614 | }; | 645 | }; |
615 | 646 | ||
@@ -617,7 +648,7 @@ static struct platform_device msm_device_rot_src_ctx = { | |||
617 | .name = "msm_iommu_ctx", | 648 | .name = "msm_iommu_ctx", |
618 | .id = 8, | 649 | .id = 8, |
619 | .dev = { | 650 | .dev = { |
620 | .parent = &msm_device_smmu_rot.dev, | 651 | .parent = &msm_device_iommu_rot.dev, |
621 | }, | 652 | }, |
622 | }; | 653 | }; |
623 | 654 | ||
@@ -625,7 +656,7 @@ static struct platform_device msm_device_rot_dst_ctx = { | |||
625 | .name = "msm_iommu_ctx", | 656 | .name = "msm_iommu_ctx", |
626 | .id = 9, | 657 | .id = 9, |
627 | .dev = { | 658 | .dev = { |
628 | .parent = &msm_device_smmu_rot.dev, | 659 | .parent = &msm_device_iommu_rot.dev, |
629 | }, | 660 | }, |
630 | }; | 661 | }; |
631 | 662 | ||
@@ -633,7 +664,7 @@ static struct platform_device msm_device_ijpeg_src_ctx = { | |||
633 | .name = "msm_iommu_ctx", | 664 | .name = "msm_iommu_ctx", |
634 | .id = 10, | 665 | .id = 10, |
635 | .dev = { | 666 | .dev = { |
636 | .parent = &msm_device_smmu_ijpeg.dev, | 667 | .parent = &msm_device_iommu_ijpeg.dev, |
637 | }, | 668 | }, |
638 | }; | 669 | }; |
639 | 670 | ||
@@ -641,7 +672,7 @@ static struct platform_device msm_device_ijpeg_dst_ctx = { | |||
641 | .name = "msm_iommu_ctx", | 672 | .name = "msm_iommu_ctx", |
642 | .id = 11, | 673 | .id = 11, |
643 | .dev = { | 674 | .dev = { |
644 | .parent = &msm_device_smmu_ijpeg.dev, | 675 | .parent = &msm_device_iommu_ijpeg.dev, |
645 | }, | 676 | }, |
646 | }; | 677 | }; |
647 | 678 | ||
@@ -649,7 +680,7 @@ static struct platform_device msm_device_vfe_imgwr_ctx = { | |||
649 | .name = "msm_iommu_ctx", | 680 | .name = "msm_iommu_ctx", |
650 | .id = 12, | 681 | .id = 12, |
651 | .dev = { | 682 | .dev = { |
652 | .parent = &msm_device_smmu_vfe.dev, | 683 | .parent = &msm_device_iommu_vfe.dev, |
653 | }, | 684 | }, |
654 | }; | 685 | }; |
655 | 686 | ||
@@ -657,7 +688,7 @@ static struct platform_device msm_device_vfe_misc_ctx = { | |||
657 | .name = "msm_iommu_ctx", | 688 | .name = "msm_iommu_ctx", |
658 | .id = 13, | 689 | .id = 13, |
659 | .dev = { | 690 | .dev = { |
660 | .parent = &msm_device_smmu_vfe.dev, | 691 | .parent = &msm_device_iommu_vfe.dev, |
661 | }, | 692 | }, |
662 | }; | 693 | }; |
663 | 694 | ||
@@ -665,7 +696,7 @@ static struct platform_device msm_device_vcodec_a_stream_ctx = { | |||
665 | .name = "msm_iommu_ctx", | 696 | .name = "msm_iommu_ctx", |
666 | .id = 14, | 697 | .id = 14, |
667 | .dev = { | 698 | .dev = { |
668 | .parent = &msm_device_smmu_vcodec_a.dev, | 699 | .parent = &msm_device_iommu_vcodec_a.dev, |
669 | }, | 700 | }, |
670 | }; | 701 | }; |
671 | 702 | ||
@@ -673,7 +704,7 @@ static struct platform_device msm_device_vcodec_a_mm1_ctx = { | |||
673 | .name = "msm_iommu_ctx", | 704 | .name = "msm_iommu_ctx", |
674 | .id = 15, | 705 | .id = 15, |
675 | .dev = { | 706 | .dev = { |
676 | .parent = &msm_device_smmu_vcodec_a.dev, | 707 | .parent = &msm_device_iommu_vcodec_a.dev, |
677 | }, | 708 | }, |
678 | }; | 709 | }; |
679 | 710 | ||
@@ -681,76 +712,70 @@ static struct platform_device msm_device_vcodec_b_mm2_ctx = { | |||
681 | .name = "msm_iommu_ctx", | 712 | .name = "msm_iommu_ctx", |
682 | .id = 16, | 713 | .id = 16, |
683 | .dev = { | 714 | .dev = { |
684 | .parent = &msm_device_smmu_vcodec_b.dev, | 715 | .parent = &msm_device_iommu_vcodec_b.dev, |
685 | }, | 716 | }, |
686 | }; | 717 | }; |
687 | 718 | ||
688 | static struct platform_device msm_device_gfx3d_rbpa_ctx = { | 719 | static struct platform_device msm_device_gfx3d_user_ctx = { |
689 | .name = "msm_iommu_ctx", | 720 | .name = "msm_iommu_ctx", |
690 | .id = 17, | 721 | .id = 17, |
691 | .dev = { | 722 | .dev = { |
692 | .parent = &msm_device_smmu_gfx3d.dev, | 723 | .parent = &msm_device_iommu_gfx3d.dev, |
693 | }, | 724 | }, |
694 | }; | 725 | }; |
695 | 726 | ||
696 | static struct platform_device msm_device_gfx3d_cpvgttc_ctx = { | 727 | static struct platform_device msm_device_gfx3d_priv_ctx = { |
697 | .name = "msm_iommu_ctx", | 728 | .name = "msm_iommu_ctx", |
698 | .id = 18, | 729 | .id = 18, |
699 | .dev = { | 730 | .dev = { |
700 | .parent = &msm_device_smmu_gfx3d.dev, | 731 | .parent = &msm_device_iommu_gfx3d.dev, |
701 | }, | 732 | }, |
702 | }; | 733 | }; |
703 | 734 | ||
704 | static struct platform_device msm_device_gfx3d_smmu_ctx = { | 735 | static struct platform_device msm_device_gfx2d0_2d0_ctx = { |
705 | .name = "msm_iommu_ctx", | 736 | .name = "msm_iommu_ctx", |
706 | .id = 19, | 737 | .id = 19, |
707 | .dev = { | 738 | .dev = { |
708 | .parent = &msm_device_smmu_gfx3d.dev, | 739 | .parent = &msm_device_iommu_gfx2d0.dev, |
709 | }, | 740 | }, |
710 | }; | 741 | }; |
711 | 742 | ||
712 | static struct platform_device msm_device_gfx2d0_pixv1_ctx = { | 743 | static struct platform_device msm_device_gfx2d1_2d1_ctx = { |
713 | .name = "msm_iommu_ctx", | 744 | .name = "msm_iommu_ctx", |
714 | .id = 20, | 745 | .id = 20, |
715 | .dev = { | 746 | .dev = { |
716 | .parent = &msm_device_smmu_gfx2d0.dev, | 747 | .parent = &msm_device_iommu_gfx2d1.dev, |
717 | }, | ||
718 | }; | ||
719 | |||
720 | static struct platform_device msm_device_gfx2d0_texv3_ctx = { | ||
721 | .name = "msm_iommu_ctx", | ||
722 | .id = 21, | ||
723 | .dev = { | ||
724 | .parent = &msm_device_smmu_gfx2d0.dev, | ||
725 | }, | 748 | }, |
726 | }; | 749 | }; |
727 | 750 | ||
728 | static struct platform_device *msm_iommu_devs[] = { | 751 | static struct platform_device *msm_iommu_devs[] = { |
729 | &msm_device_smmu_jpegd, | 752 | &msm_device_iommu_jpegd, |
730 | &msm_device_smmu_vpe, | 753 | &msm_device_iommu_vpe, |
731 | &msm_device_smmu_mdp0, | 754 | &msm_device_iommu_mdp0, |
732 | &msm_device_smmu_mdp1, | 755 | &msm_device_iommu_mdp1, |
733 | &msm_device_smmu_rot, | 756 | &msm_device_iommu_rot, |
734 | &msm_device_smmu_ijpeg, | 757 | &msm_device_iommu_ijpeg, |
735 | &msm_device_smmu_vfe, | 758 | &msm_device_iommu_vfe, |
736 | &msm_device_smmu_vcodec_a, | 759 | &msm_device_iommu_vcodec_a, |
737 | &msm_device_smmu_vcodec_b, | 760 | &msm_device_iommu_vcodec_b, |
738 | &msm_device_smmu_gfx3d, | 761 | &msm_device_iommu_gfx3d, |
739 | &msm_device_smmu_gfx2d0, | 762 | &msm_device_iommu_gfx2d0, |
763 | &msm_device_iommu_gfx2d1, | ||
740 | }; | 764 | }; |
741 | 765 | ||
742 | static struct msm_iommu_dev *msm_iommu_data[] = { | 766 | static struct msm_iommu_dev *msm_iommu_data[] = { |
743 | &jpegd_smmu, | 767 | &jpegd_iommu, |
744 | &vpe_smmu, | 768 | &vpe_iommu, |
745 | &mdp0_smmu, | 769 | &mdp0_iommu, |
746 | &mdp1_smmu, | 770 | &mdp1_iommu, |
747 | &rot_smmu, | 771 | &rot_iommu, |
748 | &ijpeg_smmu, | 772 | &ijpeg_iommu, |
749 | &vfe_smmu, | 773 | &vfe_iommu, |
750 | &vcodec_a_smmu, | 774 | &vcodec_a_iommu, |
751 | &vcodec_b_smmu, | 775 | &vcodec_b_iommu, |
752 | &gfx3d_smmu, | 776 | &gfx3d_iommu, |
753 | &gfx2d0_smmu, | 777 | &gfx2d0_iommu, |
778 | &gfx2d1_iommu, | ||
754 | }; | 779 | }; |
755 | 780 | ||
756 | static struct platform_device *msm_iommu_ctx_devs[] = { | 781 | static struct platform_device *msm_iommu_ctx_devs[] = { |
@@ -771,11 +796,10 @@ static struct platform_device *msm_iommu_ctx_devs[] = { | |||
771 | &msm_device_vcodec_a_stream_ctx, | 796 | &msm_device_vcodec_a_stream_ctx, |
772 | &msm_device_vcodec_a_mm1_ctx, | 797 | &msm_device_vcodec_a_mm1_ctx, |
773 | &msm_device_vcodec_b_mm2_ctx, | 798 | &msm_device_vcodec_b_mm2_ctx, |
774 | &msm_device_gfx3d_rbpa_ctx, | 799 | &msm_device_gfx3d_user_ctx, |
775 | &msm_device_gfx3d_cpvgttc_ctx, | 800 | &msm_device_gfx3d_priv_ctx, |
776 | &msm_device_gfx3d_smmu_ctx, | 801 | &msm_device_gfx2d0_2d0_ctx, |
777 | &msm_device_gfx2d0_pixv1_ctx, | 802 | &msm_device_gfx2d1_2d1_ctx, |
778 | &msm_device_gfx2d0_texv3_ctx, | ||
779 | }; | 803 | }; |
780 | 804 | ||
781 | static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = { | 805 | static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = { |
@@ -796,14 +820,13 @@ static struct msm_iommu_ctx_dev *msm_iommu_ctx_data[] = { | |||
796 | &vcodec_a_stream_ctx, | 820 | &vcodec_a_stream_ctx, |
797 | &vcodec_a_mm1_ctx, | 821 | &vcodec_a_mm1_ctx, |
798 | &vcodec_b_mm2_ctx, | 822 | &vcodec_b_mm2_ctx, |
799 | &gfx3d_rbpa_ctx, | 823 | &gfx3d_user_ctx, |
800 | &gfx3d_cpvgttc_ctx, | 824 | &gfx3d_priv_ctx, |
801 | &gfx3d_smmu_ctx, | 825 | &gfx2d0_2d0_ctx, |
802 | &gfx2d0_pixv1_ctx, | 826 | &gfx2d1_2d1_ctx, |
803 | &gfx2d0_texv3_ctx, | ||
804 | }; | 827 | }; |
805 | 828 | ||
806 | static int msm8x60_iommu_init(void) | 829 | static int __init msm8x60_iommu_init(void) |
807 | { | 830 | { |
808 | int ret, i; | 831 | int ret, i; |
809 | 832 | ||
@@ -826,7 +849,7 @@ static int msm8x60_iommu_init(void) | |||
826 | ret = platform_device_register(msm_iommu_devs[i]); | 849 | ret = platform_device_register(msm_iommu_devs[i]); |
827 | 850 | ||
828 | if (ret != 0) { | 851 | if (ret != 0) { |
829 | pr_err("platform_device_register smmu failed, " | 852 | pr_err("platform_device_register iommu failed, " |
830 | "i = %d\n", i); | 853 | "i = %d\n", i); |
831 | goto failure_unwind; | 854 | goto failure_unwind; |
832 | } | 855 | } |
@@ -837,7 +860,7 @@ static int msm8x60_iommu_init(void) | |||
837 | msm_iommu_ctx_data[i], | 860 | msm_iommu_ctx_data[i], |
838 | sizeof(*msm_iommu_ctx_devs[i])); | 861 | sizeof(*msm_iommu_ctx_devs[i])); |
839 | if (ret != 0) { | 862 | if (ret != 0) { |
840 | pr_err("platform_device_add_data smmu failed, " | 863 | pr_err("platform_device_add_data iommu failed, " |
841 | "i = %d\n", i); | 864 | "i = %d\n", i); |
842 | goto failure_unwind2; | 865 | goto failure_unwind2; |
843 | } | 866 | } |
@@ -863,7 +886,7 @@ failure: | |||
863 | return ret; | 886 | return ret; |
864 | } | 887 | } |
865 | 888 | ||
866 | static void msm8x60_iommu_exit(void) | 889 | static void __exit msm8x60_iommu_exit(void) |
867 | { | 890 | { |
868 | int i; | 891 | int i; |
869 | 892 | ||
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h index 568443e76423..68b8075f8ca4 100644 --- a/arch/arm/mach-msm/devices.h +++ b/arch/arm/mach-msm/devices.h | |||
@@ -35,6 +35,10 @@ extern struct platform_device msm_device_smd; | |||
35 | 35 | ||
36 | extern struct platform_device msm_device_nand; | 36 | extern struct platform_device msm_device_nand; |
37 | 37 | ||
38 | extern struct platform_device msm_device_mddi0; | ||
39 | extern struct platform_device msm_device_mddi1; | ||
40 | extern struct platform_device msm_device_mdp; | ||
41 | |||
38 | extern struct clk msm_clocks_7x01a[]; | 42 | extern struct clk msm_clocks_7x01a[]; |
39 | extern unsigned msm_num_clocks_7x01a; | 43 | extern unsigned msm_num_clocks_7x01a; |
40 | 44 | ||
diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c new file mode 100644 index 000000000000..0de19ec74e34 --- /dev/null +++ b/arch/arm/mach-msm/gpio-v2.c | |||
@@ -0,0 +1,426 @@ | |||
1 | /* Copyright (c) 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 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
19 | |||
20 | #include <linux/bitmap.h> | ||
21 | #include <linux/bitops.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <mach/msm_iomap.h> | ||
31 | #include "gpiomux.h" | ||
32 | |||
33 | /* Bits of interest in the GPIO_IN_OUT register. | ||
34 | */ | ||
35 | enum { | ||
36 | GPIO_IN = 0, | ||
37 | GPIO_OUT = 1 | ||
38 | }; | ||
39 | |||
40 | /* Bits of interest in the GPIO_INTR_STATUS register. | ||
41 | */ | ||
42 | enum { | ||
43 | INTR_STATUS = 0, | ||
44 | }; | ||
45 | |||
46 | /* Bits of interest in the GPIO_CFG register. | ||
47 | */ | ||
48 | enum { | ||
49 | GPIO_OE = 9, | ||
50 | }; | ||
51 | |||
52 | /* Bits of interest in the GPIO_INTR_CFG register. | ||
53 | * When a GPIO triggers, two separate decisions are made, controlled | ||
54 | * by two separate flags. | ||
55 | * | ||
56 | * - First, INTR_RAW_STATUS_EN controls whether or not the GPIO_INTR_STATUS | ||
57 | * register for that GPIO will be updated to reflect the triggering of that | ||
58 | * gpio. If this bit is 0, this register will not be updated. | ||
59 | * - Second, INTR_ENABLE controls whether an interrupt is triggered. | ||
60 | * | ||
61 | * If INTR_ENABLE is set and INTR_RAW_STATUS_EN is NOT set, an interrupt | ||
62 | * can be triggered but the status register will not reflect it. | ||
63 | */ | ||
64 | enum { | ||
65 | INTR_ENABLE = 0, | ||
66 | INTR_POL_CTL = 1, | ||
67 | INTR_DECT_CTL = 2, | ||
68 | INTR_RAW_STATUS_EN = 3, | ||
69 | }; | ||
70 | |||
71 | /* Codes of interest in GPIO_INTR_CFG_SU. | ||
72 | */ | ||
73 | enum { | ||
74 | TARGET_PROC_SCORPION = 4, | ||
75 | TARGET_PROC_NONE = 7, | ||
76 | }; | ||
77 | |||
78 | |||
79 | #define GPIO_INTR_CFG_SU(gpio) (MSM_TLMM_BASE + 0x0400 + (0x04 * (gpio))) | ||
80 | #define GPIO_CONFIG(gpio) (MSM_TLMM_BASE + 0x1000 + (0x10 * (gpio))) | ||
81 | #define GPIO_IN_OUT(gpio) (MSM_TLMM_BASE + 0x1004 + (0x10 * (gpio))) | ||
82 | #define GPIO_INTR_CFG(gpio) (MSM_TLMM_BASE + 0x1008 + (0x10 * (gpio))) | ||
83 | #define GPIO_INTR_STATUS(gpio) (MSM_TLMM_BASE + 0x100c + (0x10 * (gpio))) | ||
84 | |||
85 | /** | ||
86 | * struct msm_gpio_dev: the MSM8660 SoC GPIO device structure | ||
87 | * | ||
88 | * @enabled_irqs: a bitmap used to optimize the summary-irq handler. By | ||
89 | * keeping track of which gpios are unmasked as irq sources, we avoid | ||
90 | * having to do readl calls on hundreds of iomapped registers each time | ||
91 | * the summary interrupt fires in order to locate the active interrupts. | ||
92 | * | ||
93 | * @wake_irqs: a bitmap for tracking which interrupt lines are enabled | ||
94 | * as wakeup sources. When the device is suspended, interrupts which are | ||
95 | * not wakeup sources are disabled. | ||
96 | * | ||
97 | * @dual_edge_irqs: a bitmap used to track which irqs are configured | ||
98 | * as dual-edge, as this is not supported by the hardware and requires | ||
99 | * some special handling in the driver. | ||
100 | */ | ||
101 | struct msm_gpio_dev { | ||
102 | struct gpio_chip gpio_chip; | ||
103 | DECLARE_BITMAP(enabled_irqs, NR_GPIO_IRQS); | ||
104 | DECLARE_BITMAP(wake_irqs, NR_GPIO_IRQS); | ||
105 | DECLARE_BITMAP(dual_edge_irqs, NR_GPIO_IRQS); | ||
106 | }; | ||
107 | |||
108 | static DEFINE_SPINLOCK(tlmm_lock); | ||
109 | |||
110 | static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip) | ||
111 | { | ||
112 | return container_of(chip, struct msm_gpio_dev, gpio_chip); | ||
113 | } | ||
114 | |||
115 | static inline void set_gpio_bits(unsigned n, void __iomem *reg) | ||
116 | { | ||
117 | writel(readl(reg) | n, reg); | ||
118 | } | ||
119 | |||
120 | static inline void clear_gpio_bits(unsigned n, void __iomem *reg) | ||
121 | { | ||
122 | writel(readl(reg) & ~n, reg); | ||
123 | } | ||
124 | |||
125 | static int msm_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
126 | { | ||
127 | return readl(GPIO_IN_OUT(offset)) & BIT(GPIO_IN); | ||
128 | } | ||
129 | |||
130 | static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | ||
131 | { | ||
132 | writel(val ? BIT(GPIO_OUT) : 0, GPIO_IN_OUT(offset)); | ||
133 | } | ||
134 | |||
135 | static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
136 | { | ||
137 | unsigned long irq_flags; | ||
138 | |||
139 | spin_lock_irqsave(&tlmm_lock, irq_flags); | ||
140 | clear_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset)); | ||
141 | spin_unlock_irqrestore(&tlmm_lock, irq_flags); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static int msm_gpio_direction_output(struct gpio_chip *chip, | ||
146 | unsigned offset, | ||
147 | int val) | ||
148 | { | ||
149 | unsigned long irq_flags; | ||
150 | |||
151 | spin_lock_irqsave(&tlmm_lock, irq_flags); | ||
152 | msm_gpio_set(chip, offset, val); | ||
153 | set_gpio_bits(BIT(GPIO_OE), GPIO_CONFIG(offset)); | ||
154 | spin_unlock_irqrestore(&tlmm_lock, irq_flags); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int msm_gpio_request(struct gpio_chip *chip, unsigned offset) | ||
159 | { | ||
160 | return msm_gpiomux_get(chip->base + offset); | ||
161 | } | ||
162 | |||
163 | static void msm_gpio_free(struct gpio_chip *chip, unsigned offset) | ||
164 | { | ||
165 | msm_gpiomux_put(chip->base + offset); | ||
166 | } | ||
167 | |||
168 | static int msm_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | ||
169 | { | ||
170 | return MSM_GPIO_TO_INT(chip->base + offset); | ||
171 | } | ||
172 | |||
173 | static inline int msm_irq_to_gpio(struct gpio_chip *chip, unsigned irq) | ||
174 | { | ||
175 | return irq - MSM_GPIO_TO_INT(chip->base); | ||
176 | } | ||
177 | |||
178 | static struct msm_gpio_dev msm_gpio = { | ||
179 | .gpio_chip = { | ||
180 | .base = 0, | ||
181 | .ngpio = NR_GPIO_IRQS, | ||
182 | .direction_input = msm_gpio_direction_input, | ||
183 | .direction_output = msm_gpio_direction_output, | ||
184 | .get = msm_gpio_get, | ||
185 | .set = msm_gpio_set, | ||
186 | .to_irq = msm_gpio_to_irq, | ||
187 | .request = msm_gpio_request, | ||
188 | .free = msm_gpio_free, | ||
189 | }, | ||
190 | }; | ||
191 | |||
192 | /* For dual-edge interrupts in software, since the hardware has no | ||
193 | * such support: | ||
194 | * | ||
195 | * At appropriate moments, this function may be called to flip the polarity | ||
196 | * settings of both-edge irq lines to try and catch the next edge. | ||
197 | * | ||
198 | * The attempt is considered successful if: | ||
199 | * - the status bit goes high, indicating that an edge was caught, or | ||
200 | * - the input value of the gpio doesn't change during the attempt. | ||
201 | * If the value changes twice during the process, that would cause the first | ||
202 | * test to fail but would force the second, as two opposite | ||
203 | * transitions would cause a detection no matter the polarity setting. | ||
204 | * | ||
205 | * The do-loop tries to sledge-hammer closed the timing hole between | ||
206 | * the initial value-read and the polarity-write - if the line value changes | ||
207 | * during that window, an interrupt is lost, the new polarity setting is | ||
208 | * incorrect, and the first success test will fail, causing a retry. | ||
209 | * | ||
210 | * Algorithm comes from Google's msmgpio driver, see mach-msm/gpio.c. | ||
211 | */ | ||
212 | static void msm_gpio_update_dual_edge_pos(unsigned gpio) | ||
213 | { | ||
214 | int loop_limit = 100; | ||
215 | unsigned val, val2, intstat; | ||
216 | |||
217 | do { | ||
218 | val = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN); | ||
219 | if (val) | ||
220 | clear_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio)); | ||
221 | else | ||
222 | set_gpio_bits(BIT(INTR_POL_CTL), GPIO_INTR_CFG(gpio)); | ||
223 | val2 = readl(GPIO_IN_OUT(gpio)) & BIT(GPIO_IN); | ||
224 | intstat = readl(GPIO_INTR_STATUS(gpio)) & BIT(INTR_STATUS); | ||
225 | if (intstat || val == val2) | ||
226 | return; | ||
227 | } while (loop_limit-- > 0); | ||
228 | pr_err("dual-edge irq failed to stabilize, " | ||
229 | "interrupts dropped. %#08x != %#08x\n", | ||
230 | val, val2); | ||
231 | } | ||
232 | |||
233 | static void msm_gpio_irq_ack(unsigned int irq) | ||
234 | { | ||
235 | int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); | ||
236 | |||
237 | writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio)); | ||
238 | if (test_bit(gpio, msm_gpio.dual_edge_irqs)) | ||
239 | msm_gpio_update_dual_edge_pos(gpio); | ||
240 | } | ||
241 | |||
242 | static void msm_gpio_irq_mask(unsigned int irq) | ||
243 | { | ||
244 | int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); | ||
245 | unsigned long irq_flags; | ||
246 | |||
247 | spin_lock_irqsave(&tlmm_lock, irq_flags); | ||
248 | writel(TARGET_PROC_NONE, GPIO_INTR_CFG_SU(gpio)); | ||
249 | clear_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio)); | ||
250 | __clear_bit(gpio, msm_gpio.enabled_irqs); | ||
251 | spin_unlock_irqrestore(&tlmm_lock, irq_flags); | ||
252 | } | ||
253 | |||
254 | static void msm_gpio_irq_unmask(unsigned int irq) | ||
255 | { | ||
256 | int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); | ||
257 | unsigned long irq_flags; | ||
258 | |||
259 | spin_lock_irqsave(&tlmm_lock, irq_flags); | ||
260 | __set_bit(gpio, msm_gpio.enabled_irqs); | ||
261 | set_gpio_bits(INTR_RAW_STATUS_EN | INTR_ENABLE, GPIO_INTR_CFG(gpio)); | ||
262 | writel(TARGET_PROC_SCORPION, GPIO_INTR_CFG_SU(gpio)); | ||
263 | spin_unlock_irqrestore(&tlmm_lock, irq_flags); | ||
264 | } | ||
265 | |||
266 | static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type) | ||
267 | { | ||
268 | int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); | ||
269 | unsigned long irq_flags; | ||
270 | uint32_t bits; | ||
271 | |||
272 | spin_lock_irqsave(&tlmm_lock, irq_flags); | ||
273 | |||
274 | bits = readl(GPIO_INTR_CFG(gpio)); | ||
275 | |||
276 | if (flow_type & IRQ_TYPE_EDGE_BOTH) { | ||
277 | bits |= BIT(INTR_DECT_CTL); | ||
278 | irq_desc[irq].handle_irq = handle_edge_irq; | ||
279 | if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) | ||
280 | __set_bit(gpio, msm_gpio.dual_edge_irqs); | ||
281 | else | ||
282 | __clear_bit(gpio, msm_gpio.dual_edge_irqs); | ||
283 | } else { | ||
284 | bits &= ~BIT(INTR_DECT_CTL); | ||
285 | irq_desc[irq].handle_irq = handle_level_irq; | ||
286 | __clear_bit(gpio, msm_gpio.dual_edge_irqs); | ||
287 | } | ||
288 | |||
289 | if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) | ||
290 | bits |= BIT(INTR_POL_CTL); | ||
291 | else | ||
292 | bits &= ~BIT(INTR_POL_CTL); | ||
293 | |||
294 | writel(bits, GPIO_INTR_CFG(gpio)); | ||
295 | |||
296 | if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) | ||
297 | msm_gpio_update_dual_edge_pos(gpio); | ||
298 | |||
299 | spin_unlock_irqrestore(&tlmm_lock, irq_flags); | ||
300 | |||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * When the summary IRQ is raised, any number of GPIO lines may be high. | ||
306 | * It is the job of the summary handler to find all those GPIO lines | ||
307 | * which have been set as summary IRQ lines and which are triggered, | ||
308 | * and to call their interrupt handlers. | ||
309 | */ | ||
310 | static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
311 | { | ||
312 | unsigned long i; | ||
313 | |||
314 | for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS); | ||
315 | i < NR_GPIO_IRQS; | ||
316 | i = find_next_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS, i + 1)) { | ||
317 | if (readl(GPIO_INTR_STATUS(i)) & BIT(INTR_STATUS)) | ||
318 | generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip, | ||
319 | i)); | ||
320 | } | ||
321 | desc->chip->ack(irq); | ||
322 | } | ||
323 | |||
324 | static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on) | ||
325 | { | ||
326 | int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq); | ||
327 | |||
328 | if (on) { | ||
329 | if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS)) | ||
330 | set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1); | ||
331 | set_bit(gpio, msm_gpio.wake_irqs); | ||
332 | } else { | ||
333 | clear_bit(gpio, msm_gpio.wake_irqs); | ||
334 | if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS)) | ||
335 | set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0); | ||
336 | } | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static struct irq_chip msm_gpio_irq_chip = { | ||
342 | .name = "msmgpio", | ||
343 | .mask = msm_gpio_irq_mask, | ||
344 | .unmask = msm_gpio_irq_unmask, | ||
345 | .ack = msm_gpio_irq_ack, | ||
346 | .set_type = msm_gpio_irq_set_type, | ||
347 | .set_wake = msm_gpio_irq_set_wake, | ||
348 | }; | ||
349 | |||
350 | static int __devinit msm_gpio_probe(struct platform_device *dev) | ||
351 | { | ||
352 | int i, irq, ret; | ||
353 | |||
354 | bitmap_zero(msm_gpio.enabled_irqs, NR_GPIO_IRQS); | ||
355 | bitmap_zero(msm_gpio.wake_irqs, NR_GPIO_IRQS); | ||
356 | bitmap_zero(msm_gpio.dual_edge_irqs, NR_GPIO_IRQS); | ||
357 | msm_gpio.gpio_chip.label = dev->name; | ||
358 | ret = gpiochip_add(&msm_gpio.gpio_chip); | ||
359 | if (ret < 0) | ||
360 | return ret; | ||
361 | |||
362 | for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) { | ||
363 | irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i); | ||
364 | set_irq_chip(irq, &msm_gpio_irq_chip); | ||
365 | set_irq_handler(irq, handle_level_irq); | ||
366 | set_irq_flags(irq, IRQF_VALID); | ||
367 | } | ||
368 | |||
369 | set_irq_chained_handler(TLMM_SCSS_SUMMARY_IRQ, | ||
370 | msm_summary_irq_handler); | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | static int __devexit msm_gpio_remove(struct platform_device *dev) | ||
375 | { | ||
376 | int ret = gpiochip_remove(&msm_gpio.gpio_chip); | ||
377 | |||
378 | if (ret < 0) | ||
379 | return ret; | ||
380 | |||
381 | set_irq_handler(TLMM_SCSS_SUMMARY_IRQ, NULL); | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | |||
386 | static struct platform_driver msm_gpio_driver = { | ||
387 | .probe = msm_gpio_probe, | ||
388 | .remove = __devexit_p(msm_gpio_remove), | ||
389 | .driver = { | ||
390 | .name = "msmgpio", | ||
391 | .owner = THIS_MODULE, | ||
392 | }, | ||
393 | }; | ||
394 | |||
395 | static struct platform_device msm_device_gpio = { | ||
396 | .name = "msmgpio", | ||
397 | .id = -1, | ||
398 | }; | ||
399 | |||
400 | static int __init msm_gpio_init(void) | ||
401 | { | ||
402 | int rc; | ||
403 | |||
404 | rc = platform_driver_register(&msm_gpio_driver); | ||
405 | if (!rc) { | ||
406 | rc = platform_device_register(&msm_device_gpio); | ||
407 | if (rc) | ||
408 | platform_driver_unregister(&msm_gpio_driver); | ||
409 | } | ||
410 | |||
411 | return rc; | ||
412 | } | ||
413 | |||
414 | static void __exit msm_gpio_exit(void) | ||
415 | { | ||
416 | platform_device_unregister(&msm_device_gpio); | ||
417 | platform_driver_unregister(&msm_gpio_driver); | ||
418 | } | ||
419 | |||
420 | postcore_initcall(msm_gpio_init); | ||
421 | module_exit(msm_gpio_exit); | ||
422 | |||
423 | MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>"); | ||
424 | MODULE_DESCRIPTION("Driver for Qualcomm MSM TLMMv2 SoC GPIOs"); | ||
425 | MODULE_LICENSE("GPL v2"); | ||
426 | MODULE_ALIAS("platform:msmgpio"); | ||
diff --git a/arch/arm/mach-msm/include/mach/iommu.h b/arch/arm/mach-msm/include/mach/iommu.h index 218ef5732a24..296c0f10f230 100644 --- a/arch/arm/mach-msm/include/mach/iommu.h +++ b/arch/arm/mach-msm/include/mach/iommu.h | |||
@@ -20,13 +20,26 @@ | |||
20 | 20 | ||
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | 22 | ||
23 | /* Sharability attributes of MSM IOMMU mappings */ | ||
24 | #define MSM_IOMMU_ATTR_NON_SH 0x0 | ||
25 | #define MSM_IOMMU_ATTR_SH 0x4 | ||
26 | |||
27 | /* Cacheability attributes of MSM IOMMU mappings */ | ||
28 | #define MSM_IOMMU_ATTR_NONCACHED 0x0 | ||
29 | #define MSM_IOMMU_ATTR_CACHED_WB_WA 0x1 | ||
30 | #define MSM_IOMMU_ATTR_CACHED_WB_NWA 0x2 | ||
31 | #define MSM_IOMMU_ATTR_CACHED_WT 0x3 | ||
32 | |||
33 | /* Mask for the cache policy attribute */ | ||
34 | #define MSM_IOMMU_CP_MASK 0x03 | ||
35 | |||
23 | /* Maximum number of Machine IDs that we are allowing to be mapped to the same | 36 | /* Maximum number of Machine IDs that we are allowing to be mapped to the same |
24 | * context bank. The number of MIDs mapped to the same CB does not affect | 37 | * context bank. The number of MIDs mapped to the same CB does not affect |
25 | * performance, but there is a practical limit on how many distinct MIDs may | 38 | * performance, but there is a practical limit on how many distinct MIDs may |
26 | * be present. These mappings are typically determined at design time and are | 39 | * be present. These mappings are typically determined at design time and are |
27 | * not expected to change at run time. | 40 | * not expected to change at run time. |
28 | */ | 41 | */ |
29 | #define MAX_NUM_MIDS 16 | 42 | #define MAX_NUM_MIDS 32 |
30 | 43 | ||
31 | /** | 44 | /** |
32 | * struct msm_iommu_dev - a single IOMMU hardware instance | 45 | * struct msm_iommu_dev - a single IOMMU hardware instance |
diff --git a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h index f9386d3a2f77..c2c3da9444f4 100644 --- a/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h +++ b/arch/arm/mach-msm/include/mach/iommu_hw-8xxx.h | |||
@@ -54,6 +54,7 @@ do { \ | |||
54 | 54 | ||
55 | #define NUM_FL_PTE 4096 | 55 | #define NUM_FL_PTE 4096 |
56 | #define NUM_SL_PTE 256 | 56 | #define NUM_SL_PTE 256 |
57 | #define NUM_TEX_CLASS 8 | ||
57 | 58 | ||
58 | /* First-level page table bits */ | 59 | /* First-level page table bits */ |
59 | #define FL_BASE_MASK 0xFFFFFC00 | 60 | #define FL_BASE_MASK 0xFFFFFC00 |
@@ -63,6 +64,9 @@ do { \ | |||
63 | #define FL_AP_WRITE (1 << 10) | 64 | #define FL_AP_WRITE (1 << 10) |
64 | #define FL_AP_READ (1 << 11) | 65 | #define FL_AP_READ (1 << 11) |
65 | #define FL_SHARED (1 << 16) | 66 | #define FL_SHARED (1 << 16) |
67 | #define FL_BUFFERABLE (1 << 2) | ||
68 | #define FL_CACHEABLE (1 << 3) | ||
69 | #define FL_TEX0 (1 << 12) | ||
66 | #define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20) | 70 | #define FL_OFFSET(va) (((va) & 0xFFF00000) >> 20) |
67 | 71 | ||
68 | /* Second-level page table bits */ | 72 | /* Second-level page table bits */ |
@@ -73,8 +77,20 @@ do { \ | |||
73 | #define SL_AP0 (1 << 4) | 77 | #define SL_AP0 (1 << 4) |
74 | #define SL_AP1 (2 << 4) | 78 | #define SL_AP1 (2 << 4) |
75 | #define SL_SHARED (1 << 10) | 79 | #define SL_SHARED (1 << 10) |
80 | #define SL_BUFFERABLE (1 << 2) | ||
81 | #define SL_CACHEABLE (1 << 3) | ||
82 | #define SL_TEX0 (1 << 6) | ||
76 | #define SL_OFFSET(va) (((va) & 0xFF000) >> 12) | 83 | #define SL_OFFSET(va) (((va) & 0xFF000) >> 12) |
77 | 84 | ||
85 | /* Memory type and cache policy attributes */ | ||
86 | #define MT_SO 0 | ||
87 | #define MT_DEV 1 | ||
88 | #define MT_NORMAL 2 | ||
89 | #define CP_NONCACHED 0 | ||
90 | #define CP_WB_WA 1 | ||
91 | #define CP_WT 2 | ||
92 | #define CP_WB_NWA 3 | ||
93 | |||
78 | /* Global register setters / getters */ | 94 | /* Global register setters / getters */ |
79 | #define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v)) | 95 | #define SET_M2VCBR_N(b, N, v) SET_GLOBAL_REG_N(M2VCBR_N, N, (b), (v)) |
80 | #define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v)) | 96 | #define SET_CBACR_N(b, N, v) SET_GLOBAL_REG_N(CBACR_N, N, (b), (v)) |
@@ -706,7 +722,9 @@ do { \ | |||
706 | #define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5) | 722 | #define GET_OCPC5(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC5) |
707 | #define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6) | 723 | #define GET_OCPC6(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC6) |
708 | #define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7) | 724 | #define GET_OCPC7(b, c) GET_CONTEXT_FIELD(b, c, NMRR, OCPC7) |
709 | 725 | #define NMRR_ICP(nmrr, n) (((nmrr) & (3 << ((n) * 2))) >> ((n) * 2)) | |
726 | #define NMRR_OCP(nmrr, n) (((nmrr) & (3 << ((n) * 2 + 16))) >> \ | ||
727 | ((n) * 2 + 16)) | ||
710 | 728 | ||
711 | /* PAR */ | 729 | /* PAR */ |
712 | #define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT) | 730 | #define GET_FAULT(b, c) GET_CONTEXT_FIELD(b, c, PAR, FAULT) |
@@ -750,6 +768,8 @@ do { \ | |||
750 | #define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5) | 768 | #define GET_NOS5(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS5) |
751 | #define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6) | 769 | #define GET_NOS6(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS6) |
752 | #define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7) | 770 | #define GET_NOS7(b, c) GET_CONTEXT_FIELD(b, c, PRRR, NOS7) |
771 | #define PRRR_NOS(prrr, n) ((prrr) & (1 << ((n) + 24)) ? 1 : 0) | ||
772 | #define PRRR_MT(prrr, n) ((((prrr) & (3 << ((n) * 2))) >> ((n) * 2))) | ||
753 | 773 | ||
754 | 774 | ||
755 | /* RESUME */ | 775 | /* RESUME */ |
diff --git a/arch/arm/mach-msm/include/mach/irqs-8x60.h b/arch/arm/mach-msm/include/mach/irqs-8x60.h index 36074cfc9ad2..f65841c74c0b 100644 --- a/arch/arm/mach-msm/include/mach/irqs-8x60.h +++ b/arch/arm/mach-msm/include/mach/irqs-8x60.h | |||
@@ -237,7 +237,12 @@ | |||
237 | #define GSBI11_QUP_IRQ (GIC_SPI_START + 194) | 237 | #define GSBI11_QUP_IRQ (GIC_SPI_START + 194) |
238 | #define INT_UART12DM_IRQ (GIC_SPI_START + 195) | 238 | #define INT_UART12DM_IRQ (GIC_SPI_START + 195) |
239 | #define GSBI12_QUP_IRQ (GIC_SPI_START + 196) | 239 | #define GSBI12_QUP_IRQ (GIC_SPI_START + 196) |
240 | /*SPI 197 to 216 arent used in 8x60*/ | 240 | |
241 | /*SPI 197 to 209 arent used in 8x60*/ | ||
242 | #define SMMU_GFX2D1_CB_SC_SECURE_IRQ (GIC_SPI_START + 210) | ||
243 | #define SMMU_GFX2D1_CB_SC_NON_SECURE_IRQ (GIC_SPI_START + 211) | ||
244 | |||
245 | /*SPI 212 to 216 arent used in 8x60*/ | ||
241 | #define SMPSS_SPARE_1 (GIC_SPI_START + 217) | 246 | #define SMPSS_SPARE_1 (GIC_SPI_START + 217) |
242 | #define SMPSS_SPARE_2 (GIC_SPI_START + 218) | 247 | #define SMPSS_SPARE_2 (GIC_SPI_START + 218) |
243 | #define SMPSS_SPARE_3 (GIC_SPI_START + 219) | 248 | #define SMPSS_SPARE_3 (GIC_SPI_START + 219) |
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h index 45bab50e3ee6..7c43a9bff1a9 100644 --- a/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h +++ b/arch/arm/mach-msm/include/mach/msm_iomap-8x60.h | |||
@@ -98,4 +98,7 @@ | |||
98 | #define MSM_IOMMU_GFX2D0_PHYS 0x07D00000 | 98 | #define MSM_IOMMU_GFX2D0_PHYS 0x07D00000 |
99 | #define MSM_IOMMU_GFX2D0_SIZE SZ_1M | 99 | #define MSM_IOMMU_GFX2D0_SIZE SZ_1M |
100 | 100 | ||
101 | #define MSM_IOMMU_GFX2D1_PHYS 0x07E00000 | ||
102 | #define MSM_IOMMU_GFX2D1_SIZE SZ_1M | ||
103 | |||
101 | #endif | 104 | #endif |
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index d36b61074146..f912d7bf1889 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c | |||
@@ -163,3 +163,4 @@ __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) | |||
163 | return __arm_ioremap_caller(phys_addr, size, mtype, | 163 | return __arm_ioremap_caller(phys_addr, size, mtype, |
164 | __builtin_return_address(0)); | 164 | __builtin_return_address(0)); |
165 | } | 165 | } |
166 | EXPORT_SYMBOL(__msm_ioremap); | ||
diff --git a/arch/arm/mach-msm/iommu.c b/arch/arm/mach-msm/iommu.c index f71747db3bee..e2d58e4cb0d7 100644 --- a/arch/arm/mach-msm/iommu.c +++ b/arch/arm/mach-msm/iommu.c | |||
@@ -33,6 +33,16 @@ | |||
33 | #include <mach/iommu_hw-8xxx.h> | 33 | #include <mach/iommu_hw-8xxx.h> |
34 | #include <mach/iommu.h> | 34 | #include <mach/iommu.h> |
35 | 35 | ||
36 | #define MRC(reg, processor, op1, crn, crm, op2) \ | ||
37 | __asm__ __volatile__ ( \ | ||
38 | " mrc " #processor "," #op1 ", %0," #crn "," #crm "," #op2 "\n" \ | ||
39 | : "=r" (reg)) | ||
40 | |||
41 | #define RCP15_PRRR(reg) MRC(reg, p15, 0, c10, c2, 0) | ||
42 | #define RCP15_NMRR(reg) MRC(reg, p15, 0, c10, c2, 1) | ||
43 | |||
44 | static int msm_iommu_tex_class[4]; | ||
45 | |||
36 | DEFINE_SPINLOCK(msm_iommu_lock); | 46 | DEFINE_SPINLOCK(msm_iommu_lock); |
37 | 47 | ||
38 | struct msm_priv { | 48 | struct msm_priv { |
@@ -40,23 +50,26 @@ struct msm_priv { | |||
40 | struct list_head list_attached; | 50 | struct list_head list_attached; |
41 | }; | 51 | }; |
42 | 52 | ||
43 | static void __flush_iotlb(struct iommu_domain *domain) | 53 | static int __flush_iotlb(struct iommu_domain *domain) |
44 | { | 54 | { |
45 | struct msm_priv *priv = domain->priv; | 55 | struct msm_priv *priv = domain->priv; |
46 | struct msm_iommu_drvdata *iommu_drvdata; | 56 | struct msm_iommu_drvdata *iommu_drvdata; |
47 | struct msm_iommu_ctx_drvdata *ctx_drvdata; | 57 | struct msm_iommu_ctx_drvdata *ctx_drvdata; |
48 | 58 | int ret = 0; | |
49 | #ifndef CONFIG_IOMMU_PGTABLES_L2 | 59 | #ifndef CONFIG_IOMMU_PGTABLES_L2 |
50 | unsigned long *fl_table = priv->pgtable; | 60 | unsigned long *fl_table = priv->pgtable; |
51 | int i; | 61 | int i; |
52 | 62 | ||
53 | dmac_flush_range(fl_table, fl_table + SZ_16K); | 63 | if (!list_empty(&priv->list_attached)) { |
64 | dmac_flush_range(fl_table, fl_table + SZ_16K); | ||
54 | 65 | ||
55 | for (i = 0; i < NUM_FL_PTE; i++) | 66 | for (i = 0; i < NUM_FL_PTE; i++) |
56 | if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) { | 67 | if ((fl_table[i] & 0x03) == FL_TYPE_TABLE) { |
57 | void *sl_table = __va(fl_table[i] & FL_BASE_MASK); | 68 | void *sl_table = __va(fl_table[i] & |
58 | dmac_flush_range(sl_table, sl_table + SZ_4K); | 69 | FL_BASE_MASK); |
59 | } | 70 | dmac_flush_range(sl_table, sl_table + SZ_4K); |
71 | } | ||
72 | } | ||
60 | #endif | 73 | #endif |
61 | 74 | ||
62 | list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) { | 75 | list_for_each_entry(ctx_drvdata, &priv->list_attached, attached_elm) { |
@@ -66,6 +79,8 @@ static void __flush_iotlb(struct iommu_domain *domain) | |||
66 | iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent); | 79 | iommu_drvdata = dev_get_drvdata(ctx_drvdata->pdev->dev.parent); |
67 | SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0); | 80 | SET_CTX_TLBIALL(iommu_drvdata->base, ctx_drvdata->num, 0); |
68 | } | 81 | } |
82 | |||
83 | return ret; | ||
69 | } | 84 | } |
70 | 85 | ||
71 | static void __reset_context(void __iomem *base, int ctx) | 86 | static void __reset_context(void __iomem *base, int ctx) |
@@ -95,6 +110,7 @@ static void __reset_context(void __iomem *base, int ctx) | |||
95 | 110 | ||
96 | static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable) | 111 | static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable) |
97 | { | 112 | { |
113 | unsigned int prrr, nmrr; | ||
98 | __reset_context(base, ctx); | 114 | __reset_context(base, ctx); |
99 | 115 | ||
100 | /* Set up HTW mode */ | 116 | /* Set up HTW mode */ |
@@ -127,11 +143,11 @@ static void __program_context(void __iomem *base, int ctx, phys_addr_t pgtable) | |||
127 | /* Turn on TEX Remap */ | 143 | /* Turn on TEX Remap */ |
128 | SET_TRE(base, ctx, 1); | 144 | SET_TRE(base, ctx, 1); |
129 | 145 | ||
130 | /* Do not configure PRRR / NMRR on the IOMMU for now. We will assume | 146 | /* Set TEX remap attributes */ |
131 | * TEX class 0 for everything until attributes are properly worked out | 147 | RCP15_PRRR(prrr); |
132 | */ | 148 | RCP15_NMRR(nmrr); |
133 | SET_PRRR(base, ctx, 0); | 149 | SET_PRRR(base, ctx, prrr); |
134 | SET_NMRR(base, ctx, 0); | 150 | SET_NMRR(base, ctx, nmrr); |
135 | 151 | ||
136 | /* Turn on BFB prefetch */ | 152 | /* Turn on BFB prefetch */ |
137 | SET_BFBDFE(base, ctx, 1); | 153 | SET_BFBDFE(base, ctx, 1); |
@@ -238,6 +254,11 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
238 | goto fail; | 254 | goto fail; |
239 | } | 255 | } |
240 | 256 | ||
257 | if (!list_empty(&ctx_drvdata->attached_elm)) { | ||
258 | ret = -EBUSY; | ||
259 | goto fail; | ||
260 | } | ||
261 | |||
241 | list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm) | 262 | list_for_each_entry(tmp_drvdata, &priv->list_attached, attached_elm) |
242 | if (tmp_drvdata == ctx_drvdata) { | 263 | if (tmp_drvdata == ctx_drvdata) { |
243 | ret = -EBUSY; | 264 | ret = -EBUSY; |
@@ -248,7 +269,7 @@ static int msm_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) | |||
248 | __pa(priv->pgtable)); | 269 | __pa(priv->pgtable)); |
249 | 270 | ||
250 | list_add(&(ctx_drvdata->attached_elm), &priv->list_attached); | 271 | list_add(&(ctx_drvdata->attached_elm), &priv->list_attached); |
251 | __flush_iotlb(domain); | 272 | ret = __flush_iotlb(domain); |
252 | 273 | ||
253 | fail: | 274 | fail: |
254 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | 275 | spin_unlock_irqrestore(&msm_iommu_lock, flags); |
@@ -263,6 +284,7 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain, | |||
263 | struct msm_iommu_drvdata *iommu_drvdata; | 284 | struct msm_iommu_drvdata *iommu_drvdata; |
264 | struct msm_iommu_ctx_drvdata *ctx_drvdata; | 285 | struct msm_iommu_ctx_drvdata *ctx_drvdata; |
265 | unsigned long flags; | 286 | unsigned long flags; |
287 | int ret; | ||
266 | 288 | ||
267 | spin_lock_irqsave(&msm_iommu_lock, flags); | 289 | spin_lock_irqsave(&msm_iommu_lock, flags); |
268 | priv = domain->priv; | 290 | priv = domain->priv; |
@@ -277,7 +299,10 @@ static void msm_iommu_detach_dev(struct iommu_domain *domain, | |||
277 | if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) | 299 | if (!iommu_drvdata || !ctx_drvdata || !ctx_dev) |
278 | goto fail; | 300 | goto fail; |
279 | 301 | ||
280 | __flush_iotlb(domain); | 302 | ret = __flush_iotlb(domain); |
303 | if (ret) | ||
304 | goto fail; | ||
305 | |||
281 | __reset_context(iommu_drvdata->base, ctx_dev->num); | 306 | __reset_context(iommu_drvdata->base, ctx_dev->num); |
282 | list_del_init(&ctx_drvdata->attached_elm); | 307 | list_del_init(&ctx_drvdata->attached_elm); |
283 | 308 | ||
@@ -296,12 +321,21 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, | |||
296 | unsigned long *sl_table; | 321 | unsigned long *sl_table; |
297 | unsigned long *sl_pte; | 322 | unsigned long *sl_pte; |
298 | unsigned long sl_offset; | 323 | unsigned long sl_offset; |
324 | unsigned int pgprot; | ||
299 | size_t len = 0x1000UL << order; | 325 | size_t len = 0x1000UL << order; |
300 | int ret = 0; | 326 | int ret = 0, tex, sh; |
301 | 327 | ||
302 | spin_lock_irqsave(&msm_iommu_lock, flags); | 328 | spin_lock_irqsave(&msm_iommu_lock, flags); |
303 | priv = domain->priv; | ||
304 | 329 | ||
330 | sh = (prot & MSM_IOMMU_ATTR_SH) ? 1 : 0; | ||
331 | tex = msm_iommu_tex_class[prot & MSM_IOMMU_CP_MASK]; | ||
332 | |||
333 | if (tex < 0 || tex > NUM_TEX_CLASS - 1) { | ||
334 | ret = -EINVAL; | ||
335 | goto fail; | ||
336 | } | ||
337 | |||
338 | priv = domain->priv; | ||
305 | if (!priv) { | 339 | if (!priv) { |
306 | ret = -EINVAL; | 340 | ret = -EINVAL; |
307 | goto fail; | 341 | goto fail; |
@@ -322,6 +356,18 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, | |||
322 | goto fail; | 356 | goto fail; |
323 | } | 357 | } |
324 | 358 | ||
359 | if (len == SZ_16M || len == SZ_1M) { | ||
360 | pgprot = sh ? FL_SHARED : 0; | ||
361 | pgprot |= tex & 0x01 ? FL_BUFFERABLE : 0; | ||
362 | pgprot |= tex & 0x02 ? FL_CACHEABLE : 0; | ||
363 | pgprot |= tex & 0x04 ? FL_TEX0 : 0; | ||
364 | } else { | ||
365 | pgprot = sh ? SL_SHARED : 0; | ||
366 | pgprot |= tex & 0x01 ? SL_BUFFERABLE : 0; | ||
367 | pgprot |= tex & 0x02 ? SL_CACHEABLE : 0; | ||
368 | pgprot |= tex & 0x04 ? SL_TEX0 : 0; | ||
369 | } | ||
370 | |||
325 | fl_offset = FL_OFFSET(va); /* Upper 12 bits */ | 371 | fl_offset = FL_OFFSET(va); /* Upper 12 bits */ |
326 | fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */ | 372 | fl_pte = fl_table + fl_offset; /* int pointers, 4 bytes */ |
327 | 373 | ||
@@ -330,17 +376,17 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, | |||
330 | for (i = 0; i < 16; i++) | 376 | for (i = 0; i < 16; i++) |
331 | *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION | | 377 | *(fl_pte+i) = (pa & 0xFF000000) | FL_SUPERSECTION | |
332 | FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT | | 378 | FL_AP_READ | FL_AP_WRITE | FL_TYPE_SECT | |
333 | FL_SHARED; | 379 | FL_SHARED | pgprot; |
334 | } | 380 | } |
335 | 381 | ||
336 | if (len == SZ_1M) | 382 | if (len == SZ_1M) |
337 | *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | | 383 | *fl_pte = (pa & 0xFFF00000) | FL_AP_READ | FL_AP_WRITE | |
338 | FL_TYPE_SECT | FL_SHARED; | 384 | FL_TYPE_SECT | FL_SHARED | pgprot; |
339 | 385 | ||
340 | /* Need a 2nd level table */ | 386 | /* Need a 2nd level table */ |
341 | if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) { | 387 | if ((len == SZ_4K || len == SZ_64K) && (*fl_pte) == 0) { |
342 | unsigned long *sl; | 388 | unsigned long *sl; |
343 | sl = (unsigned long *) __get_free_pages(GFP_KERNEL, | 389 | sl = (unsigned long *) __get_free_pages(GFP_ATOMIC, |
344 | get_order(SZ_4K)); | 390 | get_order(SZ_4K)); |
345 | 391 | ||
346 | if (!sl) { | 392 | if (!sl) { |
@@ -360,17 +406,17 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long va, | |||
360 | 406 | ||
361 | if (len == SZ_4K) | 407 | if (len == SZ_4K) |
362 | *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | | 408 | *sl_pte = (pa & SL_BASE_MASK_SMALL) | SL_AP0 | SL_AP1 | |
363 | SL_SHARED | SL_TYPE_SMALL; | 409 | SL_SHARED | SL_TYPE_SMALL | pgprot; |
364 | 410 | ||
365 | if (len == SZ_64K) { | 411 | if (len == SZ_64K) { |
366 | int i; | 412 | int i; |
367 | 413 | ||
368 | for (i = 0; i < 16; i++) | 414 | for (i = 0; i < 16; i++) |
369 | *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 | | 415 | *(sl_pte+i) = (pa & SL_BASE_MASK_LARGE) | SL_AP0 | |
370 | SL_AP1 | SL_SHARED | SL_TYPE_LARGE; | 416 | SL_AP1 | SL_SHARED | SL_TYPE_LARGE | pgprot; |
371 | } | 417 | } |
372 | 418 | ||
373 | __flush_iotlb(domain); | 419 | ret = __flush_iotlb(domain); |
374 | fail: | 420 | fail: |
375 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | 421 | spin_unlock_irqrestore(&msm_iommu_lock, flags); |
376 | return ret; | 422 | return ret; |
@@ -455,7 +501,7 @@ static int msm_iommu_unmap(struct iommu_domain *domain, unsigned long va, | |||
455 | } | 501 | } |
456 | } | 502 | } |
457 | 503 | ||
458 | __flush_iotlb(domain); | 504 | ret = __flush_iotlb(domain); |
459 | fail: | 505 | fail: |
460 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | 506 | spin_unlock_irqrestore(&msm_iommu_lock, flags); |
461 | return ret; | 507 | return ret; |
@@ -490,9 +536,6 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, | |||
490 | SET_CTX_TLBIALL(base, ctx, 0); | 536 | SET_CTX_TLBIALL(base, ctx, 0); |
491 | SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT); | 537 | SET_V2PPR_VA(base, ctx, va >> V2Pxx_VA_SHIFT); |
492 | 538 | ||
493 | if (GET_FAULT(base, ctx)) | ||
494 | goto fail; | ||
495 | |||
496 | par = GET_PAR(base, ctx); | 539 | par = GET_PAR(base, ctx); |
497 | 540 | ||
498 | /* We are dealing with a supersection */ | 541 | /* We are dealing with a supersection */ |
@@ -501,6 +544,9 @@ static phys_addr_t msm_iommu_iova_to_phys(struct iommu_domain *domain, | |||
501 | else /* Upper 20 bits from PAR, lower 12 from VA */ | 544 | else /* Upper 20 bits from PAR, lower 12 from VA */ |
502 | ret = (par & 0xFFFFF000) | (va & 0x00000FFF); | 545 | ret = (par & 0xFFFFF000) | (va & 0x00000FFF); |
503 | 546 | ||
547 | if (GET_FAULT(base, ctx)) | ||
548 | ret = 0; | ||
549 | |||
504 | fail: | 550 | fail: |
505 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | 551 | spin_unlock_irqrestore(&msm_iommu_lock, flags); |
506 | return ret; | 552 | return ret; |
@@ -543,8 +589,8 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) | |||
543 | { | 589 | { |
544 | struct msm_iommu_drvdata *drvdata = dev_id; | 590 | struct msm_iommu_drvdata *drvdata = dev_id; |
545 | void __iomem *base; | 591 | void __iomem *base; |
546 | unsigned int fsr = 0; | 592 | unsigned int fsr; |
547 | int ncb = 0, i = 0; | 593 | int ncb, i; |
548 | 594 | ||
549 | spin_lock(&msm_iommu_lock); | 595 | spin_lock(&msm_iommu_lock); |
550 | 596 | ||
@@ -555,7 +601,6 @@ irqreturn_t msm_iommu_fault_handler(int irq, void *dev_id) | |||
555 | 601 | ||
556 | base = drvdata->base; | 602 | base = drvdata->base; |
557 | 603 | ||
558 | pr_err("===== WOAH! =====\n"); | ||
559 | pr_err("Unexpected IOMMU page fault!\n"); | 604 | pr_err("Unexpected IOMMU page fault!\n"); |
560 | pr_err("base = %08x\n", (unsigned int) base); | 605 | pr_err("base = %08x\n", (unsigned int) base); |
561 | 606 | ||
@@ -585,8 +630,47 @@ static struct iommu_ops msm_iommu_ops = { | |||
585 | .domain_has_cap = msm_iommu_domain_has_cap | 630 | .domain_has_cap = msm_iommu_domain_has_cap |
586 | }; | 631 | }; |
587 | 632 | ||
588 | static int msm_iommu_init(void) | 633 | static int __init get_tex_class(int icp, int ocp, int mt, int nos) |
634 | { | ||
635 | int i = 0; | ||
636 | unsigned int prrr = 0; | ||
637 | unsigned int nmrr = 0; | ||
638 | int c_icp, c_ocp, c_mt, c_nos; | ||
639 | |||
640 | RCP15_PRRR(prrr); | ||
641 | RCP15_NMRR(nmrr); | ||
642 | |||
643 | for (i = 0; i < NUM_TEX_CLASS; i++) { | ||
644 | c_nos = PRRR_NOS(prrr, i); | ||
645 | c_mt = PRRR_MT(prrr, i); | ||
646 | c_icp = NMRR_ICP(nmrr, i); | ||
647 | c_ocp = NMRR_OCP(nmrr, i); | ||
648 | |||
649 | if (icp == c_icp && ocp == c_ocp && c_mt == mt && c_nos == nos) | ||
650 | return i; | ||
651 | } | ||
652 | |||
653 | return -ENODEV; | ||
654 | } | ||
655 | |||
656 | static void __init setup_iommu_tex_classes(void) | ||
657 | { | ||
658 | msm_iommu_tex_class[MSM_IOMMU_ATTR_NONCACHED] = | ||
659 | get_tex_class(CP_NONCACHED, CP_NONCACHED, MT_NORMAL, 1); | ||
660 | |||
661 | msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_WA] = | ||
662 | get_tex_class(CP_WB_WA, CP_WB_WA, MT_NORMAL, 1); | ||
663 | |||
664 | msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WB_NWA] = | ||
665 | get_tex_class(CP_WB_NWA, CP_WB_NWA, MT_NORMAL, 1); | ||
666 | |||
667 | msm_iommu_tex_class[MSM_IOMMU_ATTR_CACHED_WT] = | ||
668 | get_tex_class(CP_WT, CP_WT, MT_NORMAL, 1); | ||
669 | } | ||
670 | |||
671 | static int __init msm_iommu_init(void) | ||
589 | { | 672 | { |
673 | setup_iommu_tex_classes(); | ||
590 | register_iommu(&msm_iommu_ops); | 674 | register_iommu(&msm_iommu_ops); |
591 | return 0; | 675 | return 0; |
592 | } | 676 | } |
diff --git a/arch/arm/mach-msm/iommu_dev.c b/arch/arm/mach-msm/iommu_dev.c index 9019cee2907b..b83c73b41fd1 100644 --- a/arch/arm/mach-msm/iommu_dev.c +++ b/arch/arm/mach-msm/iommu_dev.c | |||
@@ -346,7 +346,7 @@ static struct platform_driver msm_iommu_ctx_driver = { | |||
346 | .remove = msm_iommu_ctx_remove, | 346 | .remove = msm_iommu_ctx_remove, |
347 | }; | 347 | }; |
348 | 348 | ||
349 | static int msm_iommu_driver_init(void) | 349 | static int __init msm_iommu_driver_init(void) |
350 | { | 350 | { |
351 | int ret; | 351 | int ret; |
352 | ret = platform_driver_register(&msm_iommu_driver); | 352 | ret = platform_driver_register(&msm_iommu_driver); |
@@ -365,7 +365,7 @@ error: | |||
365 | return ret; | 365 | return ret; |
366 | } | 366 | } |
367 | 367 | ||
368 | static void msm_iommu_driver_exit(void) | 368 | static void __exit msm_iommu_driver_exit(void) |
369 | { | 369 | { |
370 | platform_driver_unregister(&msm_iommu_ctx_driver); | 370 | platform_driver_unregister(&msm_iommu_ctx_driver); |
371 | platform_driver_unregister(&msm_iommu_driver); | 371 | platform_driver_unregister(&msm_iommu_driver); |
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c index b0794524ba6e..152eefda3ce6 100644 --- a/arch/arm/mach-msm/sirc.c +++ b/arch/arm/mach-msm/sirc.c | |||
@@ -40,9 +40,6 @@ static struct sirc_cascade_regs sirc_reg_table[] = { | |||
40 | } | 40 | } |
41 | }; | 41 | }; |
42 | 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 | 43 | /* 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. */ | 44 | the enable reg, so it can be restored after power collapse. */ |
48 | static void sirc_irq_mask(unsigned int irq) | 45 | static void sirc_irq_mask(unsigned int irq) |
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index f07dc7c738f0..657be73297db 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c | |||
@@ -14,6 +14,8 @@ | |||
14 | * | 14 | * |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
17 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
18 | #include <linux/module.h> | 20 | #include <linux/module.h> |
19 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
@@ -89,7 +91,7 @@ static void smd_diag(void) | |||
89 | x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); | 91 | x = smem_find(ID_DIAG_ERR_MSG, SZ_DIAG_ERR_MSG); |
90 | if (x != 0) { | 92 | if (x != 0) { |
91 | x[SZ_DIAG_ERR_MSG - 1] = 0; | 93 | x[SZ_DIAG_ERR_MSG - 1] = 0; |
92 | pr_info("smem: DIAG '%s'\n", x); | 94 | pr_debug("DIAG '%s'\n", x); |
93 | } | 95 | } |
94 | } | 96 | } |
95 | 97 | ||
@@ -312,7 +314,7 @@ static void smd_state_change(struct smd_channel *ch, | |||
312 | { | 314 | { |
313 | ch->last_state = next; | 315 | ch->last_state = next; |
314 | 316 | ||
315 | pr_info("SMD: ch %d %d -> %d\n", ch->n, last, next); | 317 | pr_debug("ch %d %d -> %d\n", ch->n, last, next); |
316 | 318 | ||
317 | switch (next) { | 319 | switch (next) { |
318 | case SMD_SS_OPENING: | 320 | case SMD_SS_OPENING: |
@@ -601,7 +603,7 @@ static int smd_alloc_channel(const char *name, uint32_t cid, uint32_t type) | |||
601 | ch->pdev.name = ch->name; | 603 | ch->pdev.name = ch->name; |
602 | ch->pdev.id = -1; | 604 | ch->pdev.id = -1; |
603 | 605 | ||
604 | pr_info("smd_alloc_channel() cid=%02d size=%05d '%s'\n", | 606 | pr_debug("smd_alloc_channel() cid=%02d size=%05d '%s'\n", |
605 | ch->n, ch->fifo_size, ch->name); | 607 | ch->n, ch->fifo_size, ch->name); |
606 | 608 | ||
607 | mutex_lock(&smd_creation_mutex); | 609 | mutex_lock(&smd_creation_mutex); |
@@ -621,7 +623,7 @@ static void smd_channel_probe_worker(struct work_struct *work) | |||
621 | 623 | ||
622 | shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); | 624 | shared = smem_find(ID_CH_ALLOC_TBL, sizeof(*shared) * 64); |
623 | if (!shared) { | 625 | if (!shared) { |
624 | pr_err("smd: cannot find allocation table\n"); | 626 | pr_err("cannot find allocation table\n"); |
625 | return; | 627 | return; |
626 | } | 628 | } |
627 | for (n = 0; n < 64; n++) { | 629 | for (n = 0; n < 64; n++) { |
@@ -725,8 +727,6 @@ int smd_close(smd_channel_t *ch) | |||
725 | { | 727 | { |
726 | unsigned long flags; | 728 | unsigned long flags; |
727 | 729 | ||
728 | pr_info("smd_close(%p)\n", ch); | ||
729 | |||
730 | if (ch == 0) | 730 | if (ch == 0) |
731 | return -1; | 731 | return -1; |
732 | 732 | ||
@@ -939,7 +939,6 @@ int smsm_set_sleep_duration(uint32_t delay) | |||
939 | int smd_core_init(void) | 939 | int smd_core_init(void) |
940 | { | 940 | { |
941 | int r; | 941 | int r; |
942 | pr_info("smd_core_init()\n"); | ||
943 | 942 | ||
944 | /* wait for essential items to be initialized */ | 943 | /* wait for essential items to be initialized */ |
945 | for (;;) { | 944 | for (;;) { |
@@ -992,15 +991,11 @@ int smd_core_init(void) | |||
992 | smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0); | 991 | smsm_change_state(SMSM_STATE_APPS_DEM, ~0, 0); |
993 | #endif | 992 | #endif |
994 | 993 | ||
995 | pr_info("smd_core_init() done\n"); | ||
996 | |||
997 | return 0; | 994 | return 0; |
998 | } | 995 | } |
999 | 996 | ||
1000 | static int __devinit msm_smd_probe(struct platform_device *pdev) | 997 | static int __devinit msm_smd_probe(struct platform_device *pdev) |
1001 | { | 998 | { |
1002 | pr_info("smd_init()\n"); | ||
1003 | |||
1004 | /* | 999 | /* |
1005 | * If we haven't waited for the ARM9 to boot up till now, | 1000 | * If we haven't waited for the ARM9 to boot up till now, |
1006 | * then we need to wait here. Otherwise this should just | 1001 | * then we need to wait here. Otherwise this should just |
diff --git a/arch/arm/mach-msm/smd_debug.c b/arch/arm/mach-msm/smd_debug.c index f91c3b7bc655..8736afff82f3 100644 --- a/arch/arm/mach-msm/smd_debug.c +++ b/arch/arm/mach-msm/smd_debug.c | |||
@@ -270,8 +270,10 @@ void smsm_print_sleep_info(void) | |||
270 | { | 270 | { |
271 | unsigned long flags; | 271 | unsigned long flags; |
272 | uint32_t *ptr; | 272 | uint32_t *ptr; |
273 | #ifndef CONFIG_ARCH_MSM_SCORPION | ||
273 | struct tramp_gpio_smem *gpio; | 274 | struct tramp_gpio_smem *gpio; |
274 | struct smsm_interrupt_info *int_info; | 275 | struct smsm_interrupt_info *int_info; |
276 | #endif | ||
275 | 277 | ||
276 | 278 | ||
277 | spin_lock_irqsave(&smem_lock, flags); | 279 | spin_lock_irqsave(&smem_lock, flags); |
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 1290d14c5839..5decfd0bd61d 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <mach/mmc.h> | 44 | #include <mach/mmc.h> |
45 | #include <mach/msm_iomap.h> | 45 | #include <mach/msm_iomap.h> |
46 | #include <mach/dma.h> | 46 | #include <mach/dma.h> |
47 | #include <mach/clk.h> | ||
47 | 48 | ||
48 | #include "msm_sdcc.h" | 49 | #include "msm_sdcc.h" |
49 | 50 | ||
@@ -126,6 +127,40 @@ static void | |||
126 | msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, | 127 | msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd, |
127 | u32 c); | 128 | u32 c); |
128 | 129 | ||
130 | static void msmsdcc_reset_and_restore(struct msmsdcc_host *host) | ||
131 | { | ||
132 | u32 mci_clk = 0; | ||
133 | u32 mci_mask0 = 0; | ||
134 | int ret = 0; | ||
135 | |||
136 | /* Save the controller state */ | ||
137 | mci_clk = readl(host->base + MMCICLOCK); | ||
138 | mci_mask0 = readl(host->base + MMCIMASK0); | ||
139 | |||
140 | /* Reset the controller */ | ||
141 | ret = clk_reset(host->clk, CLK_RESET_ASSERT); | ||
142 | if (ret) | ||
143 | pr_err("%s: Clock assert failed at %u Hz with err %d\n", | ||
144 | mmc_hostname(host->mmc), host->clk_rate, ret); | ||
145 | |||
146 | ret = clk_reset(host->clk, CLK_RESET_DEASSERT); | ||
147 | if (ret) | ||
148 | pr_err("%s: Clock deassert failed at %u Hz with err %d\n", | ||
149 | mmc_hostname(host->mmc), host->clk_rate, ret); | ||
150 | |||
151 | pr_info("%s: Controller has been re-initialiazed\n", | ||
152 | mmc_hostname(host->mmc)); | ||
153 | |||
154 | /* Restore the contoller state */ | ||
155 | writel(host->pwr, host->base + MMCIPOWER); | ||
156 | writel(mci_clk, host->base + MMCICLOCK); | ||
157 | writel(mci_mask0, host->base + MMCIMASK0); | ||
158 | ret = clk_set_rate(host->clk, host->clk_rate); | ||
159 | if (ret) | ||
160 | pr_err("%s: Failed to set clk rate %u Hz (%d)\n", | ||
161 | mmc_hostname(host->mmc), host->clk_rate, ret); | ||
162 | } | ||
163 | |||
129 | static void | 164 | static void |
130 | msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) | 165 | msmsdcc_request_end(struct msmsdcc_host *host, struct mmc_request *mrq) |
131 | { | 166 | { |
@@ -155,7 +190,7 @@ static void | |||
155 | msmsdcc_stop_data(struct msmsdcc_host *host) | 190 | msmsdcc_stop_data(struct msmsdcc_host *host) |
156 | { | 191 | { |
157 | host->curr.data = NULL; | 192 | host->curr.data = NULL; |
158 | host->curr.got_dataend = host->curr.got_datablkend = 0; | 193 | host->curr.got_dataend = 0; |
159 | } | 194 | } |
160 | 195 | ||
161 | uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) | 196 | uint32_t msmsdcc_fifo_addr(struct msmsdcc_host *host) |
@@ -189,42 +224,42 @@ msmsdcc_dma_exec_func(struct msm_dmov_cmd *cmd) | |||
189 | } | 224 | } |
190 | 225 | ||
191 | static void | 226 | static void |
192 | msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, | 227 | msmsdcc_dma_complete_tlet(unsigned long data) |
193 | unsigned int result, | ||
194 | struct msm_dmov_errdata *err) | ||
195 | { | 228 | { |
196 | struct msmsdcc_dma_data *dma_data = | 229 | struct msmsdcc_host *host = (struct msmsdcc_host *)data; |
197 | container_of(cmd, struct msmsdcc_dma_data, hdr); | ||
198 | struct msmsdcc_host *host = dma_data->host; | ||
199 | unsigned long flags; | 230 | unsigned long flags; |
200 | struct mmc_request *mrq; | 231 | struct mmc_request *mrq; |
232 | struct msm_dmov_errdata err; | ||
201 | 233 | ||
202 | spin_lock_irqsave(&host->lock, flags); | 234 | spin_lock_irqsave(&host->lock, flags); |
203 | host->dma.active = 0; | 235 | host->dma.active = 0; |
204 | 236 | ||
237 | err = host->dma.err; | ||
205 | mrq = host->curr.mrq; | 238 | mrq = host->curr.mrq; |
206 | BUG_ON(!mrq); | 239 | BUG_ON(!mrq); |
207 | WARN_ON(!mrq->data); | 240 | WARN_ON(!mrq->data); |
208 | 241 | ||
209 | if (!(result & DMOV_RSLT_VALID)) { | 242 | if (!(host->dma.result & DMOV_RSLT_VALID)) { |
210 | pr_err("msmsdcc: Invalid DataMover result\n"); | 243 | pr_err("msmsdcc: Invalid DataMover result\n"); |
211 | goto out; | 244 | goto out; |
212 | } | 245 | } |
213 | 246 | ||
214 | if (result & DMOV_RSLT_DONE) { | 247 | if (host->dma.result & DMOV_RSLT_DONE) { |
215 | host->curr.data_xfered = host->curr.xfer_size; | 248 | host->curr.data_xfered = host->curr.xfer_size; |
216 | } else { | 249 | } else { |
217 | /* Error or flush */ | 250 | /* Error or flush */ |
218 | if (result & DMOV_RSLT_ERROR) | 251 | if (host->dma.result & DMOV_RSLT_ERROR) |
219 | pr_err("%s: DMA error (0x%.8x)\n", | 252 | pr_err("%s: DMA error (0x%.8x)\n", |
220 | mmc_hostname(host->mmc), result); | 253 | mmc_hostname(host->mmc), host->dma.result); |
221 | if (result & DMOV_RSLT_FLUSH) | 254 | if (host->dma.result & DMOV_RSLT_FLUSH) |
222 | pr_err("%s: DMA channel flushed (0x%.8x)\n", | 255 | pr_err("%s: DMA channel flushed (0x%.8x)\n", |
223 | mmc_hostname(host->mmc), result); | 256 | mmc_hostname(host->mmc), host->dma.result); |
224 | if (err) | 257 | |
225 | pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", | 258 | pr_err("Flush data: %.8x %.8x %.8x %.8x %.8x %.8x\n", |
226 | err->flush[0], err->flush[1], err->flush[2], | 259 | err.flush[0], err.flush[1], err.flush[2], |
227 | err->flush[3], err->flush[4], err->flush[5]); | 260 | err.flush[3], err.flush[4], err.flush[5]); |
261 | |||
262 | msmsdcc_reset_and_restore(host); | ||
228 | if (!mrq->data->error) | 263 | if (!mrq->data->error) |
229 | mrq->data->error = -EIO; | 264 | mrq->data->error = -EIO; |
230 | } | 265 | } |
@@ -242,8 +277,7 @@ msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, | |||
242 | host->dma.sg = NULL; | 277 | host->dma.sg = NULL; |
243 | host->dma.busy = 0; | 278 | host->dma.busy = 0; |
244 | 279 | ||
245 | if ((host->curr.got_dataend && host->curr.got_datablkend) | 280 | if (host->curr.got_dataend || mrq->data->error) { |
246 | || mrq->data->error) { | ||
247 | 281 | ||
248 | /* | 282 | /* |
249 | * If we've already gotten our DATAEND / DATABLKEND | 283 | * If we've already gotten our DATAEND / DATABLKEND |
@@ -273,6 +307,22 @@ out: | |||
273 | return; | 307 | return; |
274 | } | 308 | } |
275 | 309 | ||
310 | static void | ||
311 | msmsdcc_dma_complete_func(struct msm_dmov_cmd *cmd, | ||
312 | unsigned int result, | ||
313 | struct msm_dmov_errdata *err) | ||
314 | { | ||
315 | struct msmsdcc_dma_data *dma_data = | ||
316 | container_of(cmd, struct msmsdcc_dma_data, hdr); | ||
317 | struct msmsdcc_host *host = dma_data->host; | ||
318 | |||
319 | dma_data->result = result; | ||
320 | if (err) | ||
321 | memcpy(&dma_data->err, err, sizeof(struct msm_dmov_errdata)); | ||
322 | |||
323 | tasklet_schedule(&host->dma_tlet); | ||
324 | } | ||
325 | |||
276 | static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) | 326 | static int validate_dma(struct msmsdcc_host *host, struct mmc_data *data) |
277 | { | 327 | { |
278 | if (host->dma.channel == -1) | 328 | if (host->dma.channel == -1) |
@@ -424,6 +474,11 @@ msmsdcc_start_command_deferred(struct msmsdcc_host *host, | |||
424 | (cmd->opcode == 53)) | 474 | (cmd->opcode == 53)) |
425 | *c |= MCI_CSPM_DATCMD; | 475 | *c |= MCI_CSPM_DATCMD; |
426 | 476 | ||
477 | if (host->prog_scan && (cmd->opcode == 12)) { | ||
478 | *c |= MCI_CPSM_PROGENA; | ||
479 | host->prog_enable = true; | ||
480 | } | ||
481 | |||
427 | if (cmd == cmd->mrq->stop) | 482 | if (cmd == cmd->mrq->stop) |
428 | *c |= MCI_CSPM_MCIABORT; | 483 | *c |= MCI_CSPM_MCIABORT; |
429 | 484 | ||
@@ -450,7 +505,6 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data, | |||
450 | host->curr.xfer_remain = host->curr.xfer_size; | 505 | host->curr.xfer_remain = host->curr.xfer_size; |
451 | host->curr.data_xfered = 0; | 506 | host->curr.data_xfered = 0; |
452 | host->curr.got_dataend = 0; | 507 | host->curr.got_dataend = 0; |
453 | host->curr.got_datablkend = 0; | ||
454 | 508 | ||
455 | memset(&host->pio, 0, sizeof(host->pio)); | 509 | memset(&host->pio, 0, sizeof(host->pio)); |
456 | 510 | ||
@@ -494,6 +548,8 @@ msmsdcc_start_data(struct msmsdcc_host *host, struct mmc_data *data, | |||
494 | host->cmd_c = c; | 548 | host->cmd_c = c; |
495 | } | 549 | } |
496 | msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); | 550 | msm_dmov_enqueue_cmd(host->dma.channel, &host->dma.hdr); |
551 | if (data->flags & MMC_DATA_WRITE) | ||
552 | host->prog_scan = true; | ||
497 | } else { | 553 | } else { |
498 | msmsdcc_writel(host, timeout, MMCIDATATIMER); | 554 | msmsdcc_writel(host, timeout, MMCIDATATIMER); |
499 | 555 | ||
@@ -555,6 +611,9 @@ msmsdcc_pio_read(struct msmsdcc_host *host, char *buffer, unsigned int remain) | |||
555 | uint32_t *ptr = (uint32_t *) buffer; | 611 | uint32_t *ptr = (uint32_t *) buffer; |
556 | int count = 0; | 612 | int count = 0; |
557 | 613 | ||
614 | if (remain % 4) | ||
615 | remain = ((remain >> 2) + 1) << 2; | ||
616 | |||
558 | while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) { | 617 | while (msmsdcc_readl(host, MMCISTATUS) & MCI_RXDATAAVLBL) { |
559 | *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE)); | 618 | *ptr = msmsdcc_readl(host, MMCIFIFO + (count % MCI_FIFOSIZE)); |
560 | ptr++; | 619 | ptr++; |
@@ -575,13 +634,14 @@ msmsdcc_pio_write(struct msmsdcc_host *host, char *buffer, | |||
575 | char *ptr = buffer; | 634 | char *ptr = buffer; |
576 | 635 | ||
577 | do { | 636 | do { |
578 | unsigned int count, maxcnt; | 637 | unsigned int count, maxcnt, sz; |
579 | 638 | ||
580 | maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : | 639 | maxcnt = status & MCI_TXFIFOEMPTY ? MCI_FIFOSIZE : |
581 | MCI_FIFOHALFSIZE; | 640 | MCI_FIFOHALFSIZE; |
582 | count = min(remain, maxcnt); | 641 | count = min(remain, maxcnt); |
583 | 642 | ||
584 | writesl(base + MMCIFIFO, ptr, count >> 2); | 643 | sz = count % 4 ? (count >> 2) + 1 : (count >> 2); |
644 | writesl(base + MMCIFIFO, ptr, sz); | ||
585 | ptr += count; | 645 | ptr += count; |
586 | remain -= count; | 646 | remain -= count; |
587 | 647 | ||
@@ -702,10 +762,26 @@ static void msmsdcc_do_cmdirq(struct msmsdcc_host *host, uint32_t status) | |||
702 | msm_dmov_stop_cmd(host->dma.channel, | 762 | msm_dmov_stop_cmd(host->dma.channel, |
703 | &host->dma.hdr, 0); | 763 | &host->dma.hdr, 0); |
704 | else if (host->curr.data) { /* Non DMA */ | 764 | else if (host->curr.data) { /* Non DMA */ |
765 | msmsdcc_reset_and_restore(host); | ||
705 | msmsdcc_stop_data(host); | 766 | msmsdcc_stop_data(host); |
706 | msmsdcc_request_end(host, cmd->mrq); | 767 | msmsdcc_request_end(host, cmd->mrq); |
707 | } else /* host->data == NULL */ | 768 | } else { /* host->data == NULL */ |
708 | msmsdcc_request_end(host, cmd->mrq); | 769 | if (!cmd->error && host->prog_enable) { |
770 | if (status & MCI_PROGDONE) { | ||
771 | host->prog_scan = false; | ||
772 | host->prog_enable = false; | ||
773 | msmsdcc_request_end(host, cmd->mrq); | ||
774 | } else { | ||
775 | host->curr.cmd = cmd; | ||
776 | } | ||
777 | } else { | ||
778 | if (host->prog_enable) { | ||
779 | host->prog_scan = false; | ||
780 | host->prog_enable = false; | ||
781 | } | ||
782 | msmsdcc_request_end(host, cmd->mrq); | ||
783 | } | ||
784 | } | ||
709 | } else if (cmd->data) | 785 | } else if (cmd->data) |
710 | if (!(cmd->data->flags & MMC_DATA_READ)) | 786 | if (!(cmd->data->flags & MMC_DATA_READ)) |
711 | msmsdcc_start_data(host, cmd->data, | 787 | msmsdcc_start_data(host, cmd->data, |
@@ -719,7 +795,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, | |||
719 | struct mmc_data *data = host->curr.data; | 795 | struct mmc_data *data = host->curr.data; |
720 | 796 | ||
721 | if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | | 797 | if (status & (MCI_CMDSENT | MCI_CMDRESPEND | MCI_CMDCRCFAIL | |
722 | MCI_CMDTIMEOUT) && host->curr.cmd) { | 798 | MCI_CMDTIMEOUT | MCI_PROGDONE) && host->curr.cmd) { |
723 | msmsdcc_do_cmdirq(host, status); | 799 | msmsdcc_do_cmdirq(host, status); |
724 | } | 800 | } |
725 | 801 | ||
@@ -735,6 +811,7 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, | |||
735 | msm_dmov_stop_cmd(host->dma.channel, | 811 | msm_dmov_stop_cmd(host->dma.channel, |
736 | &host->dma.hdr, 0); | 812 | &host->dma.hdr, 0); |
737 | else { | 813 | else { |
814 | msmsdcc_reset_and_restore(host); | ||
738 | if (host->curr.data) | 815 | if (host->curr.data) |
739 | msmsdcc_stop_data(host); | 816 | msmsdcc_stop_data(host); |
740 | if (!data->stop) | 817 | if (!data->stop) |
@@ -748,14 +825,10 @@ msmsdcc_handle_irq_data(struct msmsdcc_host *host, u32 status, | |||
748 | if (!host->curr.got_dataend && (status & MCI_DATAEND)) | 825 | if (!host->curr.got_dataend && (status & MCI_DATAEND)) |
749 | host->curr.got_dataend = 1; | 826 | host->curr.got_dataend = 1; |
750 | 827 | ||
751 | if (!host->curr.got_datablkend && (status & MCI_DATABLOCKEND)) | ||
752 | host->curr.got_datablkend = 1; | ||
753 | |||
754 | /* | 828 | /* |
755 | * If DMA is still in progress, we complete via the completion handler | 829 | * If DMA is still in progress, we complete via the completion handler |
756 | */ | 830 | */ |
757 | if (host->curr.got_dataend && host->curr.got_datablkend && | 831 | if (host->curr.got_dataend && !host->dma.busy) { |
758 | !host->dma.busy) { | ||
759 | /* | 832 | /* |
760 | * There appears to be an issue in the controller where | 833 | * There appears to be an issue in the controller where |
761 | * if you request a small block transfer (< fifo size), | 834 | * if you request a small block transfer (< fifo size), |
@@ -792,8 +865,7 @@ msmsdcc_irq(int irq, void *dev_id) | |||
792 | 865 | ||
793 | do { | 866 | do { |
794 | status = msmsdcc_readl(host, MMCISTATUS); | 867 | status = msmsdcc_readl(host, MMCISTATUS); |
795 | status &= (msmsdcc_readl(host, MMCIMASK0) | | 868 | status &= msmsdcc_readl(host, MMCIMASK0); |
796 | MCI_DATABLOCKENDMASK); | ||
797 | msmsdcc_writel(host, status, MMCICLEAR); | 869 | msmsdcc_writel(host, status, MMCICLEAR); |
798 | 870 | ||
799 | if (status & MCI_SDIOINTR) | 871 | if (status & MCI_SDIOINTR) |
@@ -1118,6 +1190,9 @@ msmsdcc_probe(struct platform_device *pdev) | |||
1118 | host->dmares = dmares; | 1190 | host->dmares = dmares; |
1119 | spin_lock_init(&host->lock); | 1191 | spin_lock_init(&host->lock); |
1120 | 1192 | ||
1193 | tasklet_init(&host->dma_tlet, msmsdcc_dma_complete_tlet, | ||
1194 | (unsigned long)host); | ||
1195 | |||
1121 | /* | 1196 | /* |
1122 | * Setup DMA | 1197 | * Setup DMA |
1123 | */ | 1198 | */ |
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h index ff2b0f74f6f4..939557af266d 100644 --- a/drivers/mmc/host/msm_sdcc.h +++ b/drivers/mmc/host/msm_sdcc.h | |||
@@ -138,7 +138,7 @@ | |||
138 | #define MCI_IRQENABLE \ | 138 | #define MCI_IRQENABLE \ |
139 | (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ | 139 | (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ |
140 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ | 140 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ |
141 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK) | 141 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK|MCI_PROGDONEMASK) |
142 | 142 | ||
143 | /* | 143 | /* |
144 | * The size of the FIFO in bytes. | 144 | * The size of the FIFO in bytes. |
@@ -172,6 +172,8 @@ struct msmsdcc_dma_data { | |||
172 | struct msmsdcc_host *host; | 172 | struct msmsdcc_host *host; |
173 | int busy; /* Set if DM is busy */ | 173 | int busy; /* Set if DM is busy */ |
174 | int active; | 174 | int active; |
175 | unsigned int result; | ||
176 | struct msm_dmov_errdata err; | ||
175 | }; | 177 | }; |
176 | 178 | ||
177 | struct msmsdcc_pio_data { | 179 | struct msmsdcc_pio_data { |
@@ -188,7 +190,6 @@ struct msmsdcc_curr_req { | |||
188 | unsigned int xfer_remain; /* Bytes remaining to send */ | 190 | unsigned int xfer_remain; /* Bytes remaining to send */ |
189 | unsigned int data_xfered; /* Bytes acked by BLKEND irq */ | 191 | unsigned int data_xfered; /* Bytes acked by BLKEND irq */ |
190 | int got_dataend; | 192 | int got_dataend; |
191 | int got_datablkend; | ||
192 | int user_pages; | 193 | int user_pages; |
193 | }; | 194 | }; |
194 | 195 | ||
@@ -235,6 +236,7 @@ struct msmsdcc_host { | |||
235 | int cmdpoll; | 236 | int cmdpoll; |
236 | struct msmsdcc_stats stats; | 237 | struct msmsdcc_stats stats; |
237 | 238 | ||
239 | struct tasklet_struct dma_tlet; | ||
238 | /* Command parameters */ | 240 | /* Command parameters */ |
239 | unsigned int cmd_timeout; | 241 | unsigned int cmd_timeout; |
240 | unsigned int cmd_pio_irqmask; | 242 | unsigned int cmd_pio_irqmask; |
@@ -242,6 +244,8 @@ struct msmsdcc_host { | |||
242 | struct mmc_command *cmd_cmd; | 244 | struct mmc_command *cmd_cmd; |
243 | u32 cmd_c; | 245 | u32 cmd_c; |
244 | 246 | ||
247 | bool prog_scan; | ||
248 | bool prog_enable; | ||
245 | }; | 249 | }; |
246 | 250 | ||
247 | #endif | 251 | #endif |
diff --git a/drivers/serial/msm_serial.c b/drivers/serial/msm_serial.c index f8c816e7725d..8e43a7b69e64 100644 --- a/drivers/serial/msm_serial.c +++ b/drivers/serial/msm_serial.c | |||
@@ -686,7 +686,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
686 | msm_port = UART_TO_MSM(port); | 686 | msm_port = UART_TO_MSM(port); |
687 | 687 | ||
688 | msm_port->clk = clk_get(&pdev->dev, "uart_clk"); | 688 | msm_port->clk = clk_get(&pdev->dev, "uart_clk"); |
689 | if (unlikely(IS_ERR(msm_port->clk))) | 689 | if (IS_ERR(msm_port->clk)) |
690 | return PTR_ERR(msm_port->clk); | 690 | return PTR_ERR(msm_port->clk); |
691 | port->uartclk = clk_get_rate(msm_port->clk); | 691 | port->uartclk = clk_get_rate(msm_port->clk); |
692 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); | 692 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); |