diff options
Diffstat (limited to 'drivers/video/omap2/dss/dsi.c')
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 2357 |
1 files changed, 1583 insertions, 774 deletions
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index cbd9ca48d6ec..345757cfcbee 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c | |||
@@ -33,8 +33,11 @@ | |||
33 | #include <linux/regulator/consumer.h> | 33 | #include <linux/regulator/consumer.h> |
34 | #include <linux/wait.h> | 34 | #include <linux/wait.h> |
35 | #include <linux/workqueue.h> | 35 | #include <linux/workqueue.h> |
36 | #include <linux/sched.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/debugfs.h> | ||
36 | 39 | ||
37 | #include <plat/display.h> | 40 | #include <video/omapdss.h> |
38 | #include <plat/clock.h> | 41 | #include <plat/clock.h> |
39 | 42 | ||
40 | #include "dss.h" | 43 | #include "dss.h" |
@@ -56,6 +59,7 @@ struct dsi_reg { u16 idx; }; | |||
56 | #define DSI_IRQSTATUS DSI_REG(0x0018) | 59 | #define DSI_IRQSTATUS DSI_REG(0x0018) |
57 | #define DSI_IRQENABLE DSI_REG(0x001C) | 60 | #define DSI_IRQENABLE DSI_REG(0x001C) |
58 | #define DSI_CTRL DSI_REG(0x0040) | 61 | #define DSI_CTRL DSI_REG(0x0040) |
62 | #define DSI_GNQ DSI_REG(0x0044) | ||
59 | #define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048) | 63 | #define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048) |
60 | #define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C) | 64 | #define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C) |
61 | #define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050) | 65 | #define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050) |
@@ -90,6 +94,7 @@ struct dsi_reg { u16 idx; }; | |||
90 | #define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004) | 94 | #define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004) |
91 | #define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008) | 95 | #define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008) |
92 | #define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014) | 96 | #define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014) |
97 | #define DSI_DSIPHY_CFG10 DSI_REG(0x200 + 0x0028) | ||
93 | 98 | ||
94 | /* DSI_PLL_CTRL_SCP */ | 99 | /* DSI_PLL_CTRL_SCP */ |
95 | 100 | ||
@@ -99,11 +104,11 @@ struct dsi_reg { u16 idx; }; | |||
99 | #define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C) | 104 | #define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C) |
100 | #define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010) | 105 | #define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010) |
101 | 106 | ||
102 | #define REG_GET(idx, start, end) \ | 107 | #define REG_GET(dsidev, idx, start, end) \ |
103 | FLD_GET(dsi_read_reg(idx), start, end) | 108 | FLD_GET(dsi_read_reg(dsidev, idx), start, end) |
104 | 109 | ||
105 | #define REG_FLD_MOD(idx, val, start, end) \ | 110 | #define REG_FLD_MOD(dsidev, idx, val, start, end) \ |
106 | dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end)) | 111 | dsi_write_reg(dsidev, idx, FLD_MOD(dsi_read_reg(dsidev, idx), val, start, end)) |
107 | 112 | ||
108 | /* Global interrupts */ | 113 | /* Global interrupts */ |
109 | #define DSI_IRQ_VC0 (1 << 0) | 114 | #define DSI_IRQ_VC0 (1 << 0) |
@@ -147,31 +152,50 @@ struct dsi_reg { u16 idx; }; | |||
147 | #define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0) | 152 | #define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0) |
148 | #define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1) | 153 | #define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1) |
149 | #define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2) | 154 | #define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2) |
155 | #define DSI_CIO_IRQ_ERRSYNCESC4 (1 << 3) | ||
156 | #define DSI_CIO_IRQ_ERRSYNCESC5 (1 << 4) | ||
150 | #define DSI_CIO_IRQ_ERRESC1 (1 << 5) | 157 | #define DSI_CIO_IRQ_ERRESC1 (1 << 5) |
151 | #define DSI_CIO_IRQ_ERRESC2 (1 << 6) | 158 | #define DSI_CIO_IRQ_ERRESC2 (1 << 6) |
152 | #define DSI_CIO_IRQ_ERRESC3 (1 << 7) | 159 | #define DSI_CIO_IRQ_ERRESC3 (1 << 7) |
160 | #define DSI_CIO_IRQ_ERRESC4 (1 << 8) | ||
161 | #define DSI_CIO_IRQ_ERRESC5 (1 << 9) | ||
153 | #define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10) | 162 | #define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10) |
154 | #define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11) | 163 | #define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11) |
155 | #define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12) | 164 | #define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12) |
165 | #define DSI_CIO_IRQ_ERRCONTROL4 (1 << 13) | ||
166 | #define DSI_CIO_IRQ_ERRCONTROL5 (1 << 14) | ||
156 | #define DSI_CIO_IRQ_STATEULPS1 (1 << 15) | 167 | #define DSI_CIO_IRQ_STATEULPS1 (1 << 15) |
157 | #define DSI_CIO_IRQ_STATEULPS2 (1 << 16) | 168 | #define DSI_CIO_IRQ_STATEULPS2 (1 << 16) |
158 | #define DSI_CIO_IRQ_STATEULPS3 (1 << 17) | 169 | #define DSI_CIO_IRQ_STATEULPS3 (1 << 17) |
170 | #define DSI_CIO_IRQ_STATEULPS4 (1 << 18) | ||
171 | #define DSI_CIO_IRQ_STATEULPS5 (1 << 19) | ||
159 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20) | 172 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20) |
160 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21) | 173 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21) |
161 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22) | 174 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22) |
162 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23) | 175 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23) |
163 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24) | 176 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24) |
164 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25) | 177 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25) |
178 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_4 (1 << 26) | ||
179 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_4 (1 << 27) | ||
180 | #define DSI_CIO_IRQ_ERRCONTENTIONLP0_5 (1 << 28) | ||
181 | #define DSI_CIO_IRQ_ERRCONTENTIONLP1_5 (1 << 29) | ||
165 | #define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30) | 182 | #define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30) |
166 | #define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31) | 183 | #define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31) |
167 | #define DSI_CIO_IRQ_ERROR_MASK \ | 184 | #define DSI_CIO_IRQ_ERROR_MASK \ |
168 | (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \ | 185 | (DSI_CIO_IRQ_ERRSYNCESC1 | DSI_CIO_IRQ_ERRSYNCESC2 | \ |
169 | DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \ | 186 | DSI_CIO_IRQ_ERRSYNCESC3 | DSI_CIO_IRQ_ERRSYNCESC4 | \ |
170 | DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRCONTROL1 | \ | 187 | DSI_CIO_IRQ_ERRSYNCESC5 | \ |
171 | DSI_CIO_IRQ_ERRCONTROL2 | DSI_CIO_IRQ_ERRCONTROL3 | \ | 188 | DSI_CIO_IRQ_ERRESC1 | DSI_CIO_IRQ_ERRESC2 | \ |
189 | DSI_CIO_IRQ_ERRESC3 | DSI_CIO_IRQ_ERRESC4 | \ | ||
190 | DSI_CIO_IRQ_ERRESC5 | \ | ||
191 | DSI_CIO_IRQ_ERRCONTROL1 | DSI_CIO_IRQ_ERRCONTROL2 | \ | ||
192 | DSI_CIO_IRQ_ERRCONTROL3 | DSI_CIO_IRQ_ERRCONTROL4 | \ | ||
193 | DSI_CIO_IRQ_ERRCONTROL5 | \ | ||
172 | DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \ | 194 | DSI_CIO_IRQ_ERRCONTENTIONLP0_1 | DSI_CIO_IRQ_ERRCONTENTIONLP1_1 | \ |
173 | DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \ | 195 | DSI_CIO_IRQ_ERRCONTENTIONLP0_2 | DSI_CIO_IRQ_ERRCONTENTIONLP1_2 | \ |
174 | DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3) | 196 | DSI_CIO_IRQ_ERRCONTENTIONLP0_3 | DSI_CIO_IRQ_ERRCONTENTIONLP1_3 | \ |
197 | DSI_CIO_IRQ_ERRCONTENTIONLP0_4 | DSI_CIO_IRQ_ERRCONTENTIONLP1_4 | \ | ||
198 | DSI_CIO_IRQ_ERRCONTENTIONLP0_5 | DSI_CIO_IRQ_ERRCONTENTIONLP1_5) | ||
175 | 199 | ||
176 | #define DSI_DT_DCS_SHORT_WRITE_0 0x05 | 200 | #define DSI_DT_DCS_SHORT_WRITE_0 0x05 |
177 | #define DSI_DT_DCS_SHORT_WRITE_1 0x15 | 201 | #define DSI_DT_DCS_SHORT_WRITE_1 0x15 |
@@ -208,6 +232,19 @@ enum dsi_vc_mode { | |||
208 | DSI_VC_MODE_VP, | 232 | DSI_VC_MODE_VP, |
209 | }; | 233 | }; |
210 | 234 | ||
235 | enum dsi_lane { | ||
236 | DSI_CLK_P = 1 << 0, | ||
237 | DSI_CLK_N = 1 << 1, | ||
238 | DSI_DATA1_P = 1 << 2, | ||
239 | DSI_DATA1_N = 1 << 3, | ||
240 | DSI_DATA2_P = 1 << 4, | ||
241 | DSI_DATA2_N = 1 << 5, | ||
242 | DSI_DATA3_P = 1 << 6, | ||
243 | DSI_DATA3_N = 1 << 7, | ||
244 | DSI_DATA4_P = 1 << 8, | ||
245 | DSI_DATA4_N = 1 << 9, | ||
246 | }; | ||
247 | |||
211 | struct dsi_update_region { | 248 | struct dsi_update_region { |
212 | u16 x, y, w, h; | 249 | u16 x, y, w, h; |
213 | struct omap_dss_device *device; | 250 | struct omap_dss_device *device; |
@@ -227,14 +264,16 @@ struct dsi_isr_tables { | |||
227 | struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS]; | 264 | struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS]; |
228 | }; | 265 | }; |
229 | 266 | ||
230 | static struct | 267 | struct dsi_data { |
231 | { | ||
232 | struct platform_device *pdev; | 268 | struct platform_device *pdev; |
233 | void __iomem *base; | 269 | void __iomem *base; |
234 | int irq; | 270 | int irq; |
235 | 271 | ||
272 | void (*dsi_mux_pads)(bool enable); | ||
273 | |||
236 | struct dsi_clock_info current_cinfo; | 274 | struct dsi_clock_info current_cinfo; |
237 | 275 | ||
276 | bool vdds_dsi_enabled; | ||
238 | struct regulator *vdds_dsi_reg; | 277 | struct regulator *vdds_dsi_reg; |
239 | 278 | ||
240 | struct { | 279 | struct { |
@@ -258,8 +297,7 @@ static struct | |||
258 | struct dsi_update_region update_region; | 297 | struct dsi_update_region update_region; |
259 | 298 | ||
260 | bool te_enabled; | 299 | bool te_enabled; |
261 | 300 | bool ulps_enabled; | |
262 | struct workqueue_struct *workqueue; | ||
263 | 301 | ||
264 | void (*framedone_callback)(int, void *); | 302 | void (*framedone_callback)(int, void *); |
265 | void *framedone_data; | 303 | void *framedone_data; |
@@ -292,21 +330,63 @@ static struct | |||
292 | unsigned long regm_dispc_max, regm_dsi_max; | 330 | unsigned long regm_dispc_max, regm_dsi_max; |
293 | unsigned long fint_min, fint_max; | 331 | unsigned long fint_min, fint_max; |
294 | unsigned long lpdiv_max; | 332 | unsigned long lpdiv_max; |
295 | } dsi; | 333 | |
334 | int num_data_lanes; | ||
335 | |||
336 | unsigned scp_clk_refcount; | ||
337 | }; | ||
338 | |||
339 | struct dsi_packet_sent_handler_data { | ||
340 | struct platform_device *dsidev; | ||
341 | struct completion *completion; | ||
342 | }; | ||
343 | |||
344 | static struct platform_device *dsi_pdev_map[MAX_NUM_DSI]; | ||
296 | 345 | ||
297 | #ifdef DEBUG | 346 | #ifdef DEBUG |
298 | static unsigned int dsi_perf; | 347 | static unsigned int dsi_perf; |
299 | module_param_named(dsi_perf, dsi_perf, bool, 0644); | 348 | module_param_named(dsi_perf, dsi_perf, bool, 0644); |
300 | #endif | 349 | #endif |
301 | 350 | ||
302 | static inline void dsi_write_reg(const struct dsi_reg idx, u32 val) | 351 | static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dsidev) |
303 | { | 352 | { |
304 | __raw_writel(val, dsi.base + idx.idx); | 353 | return dev_get_drvdata(&dsidev->dev); |
305 | } | 354 | } |
306 | 355 | ||
307 | static inline u32 dsi_read_reg(const struct dsi_reg idx) | 356 | static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) |
308 | { | 357 | { |
309 | return __raw_readl(dsi.base + idx.idx); | 358 | return dsi_pdev_map[dssdev->phy.dsi.module]; |
359 | } | ||
360 | |||
361 | struct platform_device *dsi_get_dsidev_from_id(int module) | ||
362 | { | ||
363 | return dsi_pdev_map[module]; | ||
364 | } | ||
365 | |||
366 | static int dsi_get_dsidev_id(struct platform_device *dsidev) | ||
367 | { | ||
368 | /* TEMP: Pass 0 as the dsi module index till the time the dsi platform | ||
369 | * device names aren't changed to the form "omapdss_dsi.0", | ||
370 | * "omapdss_dsi.1" and so on */ | ||
371 | BUG_ON(dsidev->id != -1); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | static inline void dsi_write_reg(struct platform_device *dsidev, | ||
377 | const struct dsi_reg idx, u32 val) | ||
378 | { | ||
379 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
380 | |||
381 | __raw_writel(val, dsi->base + idx.idx); | ||
382 | } | ||
383 | |||
384 | static inline u32 dsi_read_reg(struct platform_device *dsidev, | ||
385 | const struct dsi_reg idx) | ||
386 | { | ||
387 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
388 | |||
389 | return __raw_readl(dsi->base + idx.idx); | ||
310 | } | 390 | } |
311 | 391 | ||
312 | 392 | ||
@@ -318,21 +398,29 @@ void dsi_restore_context(void) | |||
318 | { | 398 | { |
319 | } | 399 | } |
320 | 400 | ||
321 | void dsi_bus_lock(void) | 401 | void dsi_bus_lock(struct omap_dss_device *dssdev) |
322 | { | 402 | { |
323 | down(&dsi.bus_lock); | 403 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
404 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
405 | |||
406 | down(&dsi->bus_lock); | ||
324 | } | 407 | } |
325 | EXPORT_SYMBOL(dsi_bus_lock); | 408 | EXPORT_SYMBOL(dsi_bus_lock); |
326 | 409 | ||
327 | void dsi_bus_unlock(void) | 410 | void dsi_bus_unlock(struct omap_dss_device *dssdev) |
328 | { | 411 | { |
329 | up(&dsi.bus_lock); | 412 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
413 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
414 | |||
415 | up(&dsi->bus_lock); | ||
330 | } | 416 | } |
331 | EXPORT_SYMBOL(dsi_bus_unlock); | 417 | EXPORT_SYMBOL(dsi_bus_unlock); |
332 | 418 | ||
333 | static bool dsi_bus_is_locked(void) | 419 | static bool dsi_bus_is_locked(struct platform_device *dsidev) |
334 | { | 420 | { |
335 | return dsi.bus_lock.count == 0; | 421 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
422 | |||
423 | return dsi->bus_lock.count == 0; | ||
336 | } | 424 | } |
337 | 425 | ||
338 | static void dsi_completion_handler(void *data, u32 mask) | 426 | static void dsi_completion_handler(void *data, u32 mask) |
@@ -340,12 +428,12 @@ static void dsi_completion_handler(void *data, u32 mask) | |||
340 | complete((struct completion *)data); | 428 | complete((struct completion *)data); |
341 | } | 429 | } |
342 | 430 | ||
343 | static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, | 431 | static inline int wait_for_bit_change(struct platform_device *dsidev, |
344 | int value) | 432 | const struct dsi_reg idx, int bitnum, int value) |
345 | { | 433 | { |
346 | int t = 100000; | 434 | int t = 100000; |
347 | 435 | ||
348 | while (REG_GET(idx, bitnum, bitnum) != value) { | 436 | while (REG_GET(dsidev, idx, bitnum, bitnum) != value) { |
349 | if (--t == 0) | 437 | if (--t == 0) |
350 | return !value; | 438 | return !value; |
351 | } | 439 | } |
@@ -354,18 +442,21 @@ static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, | |||
354 | } | 442 | } |
355 | 443 | ||
356 | #ifdef DEBUG | 444 | #ifdef DEBUG |
357 | static void dsi_perf_mark_setup(void) | 445 | static void dsi_perf_mark_setup(struct platform_device *dsidev) |
358 | { | 446 | { |
359 | dsi.perf_setup_time = ktime_get(); | 447 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
448 | dsi->perf_setup_time = ktime_get(); | ||
360 | } | 449 | } |
361 | 450 | ||
362 | static void dsi_perf_mark_start(void) | 451 | static void dsi_perf_mark_start(struct platform_device *dsidev) |
363 | { | 452 | { |
364 | dsi.perf_start_time = ktime_get(); | 453 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
454 | dsi->perf_start_time = ktime_get(); | ||
365 | } | 455 | } |
366 | 456 | ||
367 | static void dsi_perf_show(const char *name) | 457 | static void dsi_perf_show(struct platform_device *dsidev, const char *name) |
368 | { | 458 | { |
459 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
369 | ktime_t t, setup_time, trans_time; | 460 | ktime_t t, setup_time, trans_time; |
370 | u32 total_bytes; | 461 | u32 total_bytes; |
371 | u32 setup_us, trans_us, total_us; | 462 | u32 setup_us, trans_us, total_us; |
@@ -375,21 +466,21 @@ static void dsi_perf_show(const char *name) | |||
375 | 466 | ||
376 | t = ktime_get(); | 467 | t = ktime_get(); |
377 | 468 | ||
378 | setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); | 469 | setup_time = ktime_sub(dsi->perf_start_time, dsi->perf_setup_time); |
379 | setup_us = (u32)ktime_to_us(setup_time); | 470 | setup_us = (u32)ktime_to_us(setup_time); |
380 | if (setup_us == 0) | 471 | if (setup_us == 0) |
381 | setup_us = 1; | 472 | setup_us = 1; |
382 | 473 | ||
383 | trans_time = ktime_sub(t, dsi.perf_start_time); | 474 | trans_time = ktime_sub(t, dsi->perf_start_time); |
384 | trans_us = (u32)ktime_to_us(trans_time); | 475 | trans_us = (u32)ktime_to_us(trans_time); |
385 | if (trans_us == 0) | 476 | if (trans_us == 0) |
386 | trans_us = 1; | 477 | trans_us = 1; |
387 | 478 | ||
388 | total_us = setup_us + trans_us; | 479 | total_us = setup_us + trans_us; |
389 | 480 | ||
390 | total_bytes = dsi.update_region.w * | 481 | total_bytes = dsi->update_region.w * |
391 | dsi.update_region.h * | 482 | dsi->update_region.h * |
392 | dsi.update_region.device->ctrl.pixel_size / 8; | 483 | dsi->update_region.device->ctrl.pixel_size / 8; |
393 | 484 | ||
394 | printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " | 485 | printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " |
395 | "%u bytes, %u kbytes/sec\n", | 486 | "%u bytes, %u kbytes/sec\n", |
@@ -402,9 +493,9 @@ static void dsi_perf_show(const char *name) | |||
402 | total_bytes * 1000 / total_us); | 493 | total_bytes * 1000 / total_us); |
403 | } | 494 | } |
404 | #else | 495 | #else |
405 | #define dsi_perf_mark_setup() | 496 | #define dsi_perf_mark_setup(x) |
406 | #define dsi_perf_mark_start() | 497 | #define dsi_perf_mark_start(x) |
407 | #define dsi_perf_show(x) | 498 | #define dsi_perf_show(x, y) |
408 | #endif | 499 | #endif |
409 | 500 | ||
410 | static void print_irq_status(u32 status) | 501 | static void print_irq_status(u32 status) |
@@ -510,38 +601,42 @@ static void print_irq_status_cio(u32 status) | |||
510 | } | 601 | } |
511 | 602 | ||
512 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | 603 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
513 | static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus) | 604 | static void dsi_collect_irq_stats(struct platform_device *dsidev, u32 irqstatus, |
605 | u32 *vcstatus, u32 ciostatus) | ||
514 | { | 606 | { |
607 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
515 | int i; | 608 | int i; |
516 | 609 | ||
517 | spin_lock(&dsi.irq_stats_lock); | 610 | spin_lock(&dsi->irq_stats_lock); |
518 | 611 | ||
519 | dsi.irq_stats.irq_count++; | 612 | dsi->irq_stats.irq_count++; |
520 | dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); | 613 | dss_collect_irq_stats(irqstatus, dsi->irq_stats.dsi_irqs); |
521 | 614 | ||
522 | for (i = 0; i < 4; ++i) | 615 | for (i = 0; i < 4; ++i) |
523 | dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]); | 616 | dss_collect_irq_stats(vcstatus[i], dsi->irq_stats.vc_irqs[i]); |
524 | 617 | ||
525 | dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); | 618 | dss_collect_irq_stats(ciostatus, dsi->irq_stats.cio_irqs); |
526 | 619 | ||
527 | spin_unlock(&dsi.irq_stats_lock); | 620 | spin_unlock(&dsi->irq_stats_lock); |
528 | } | 621 | } |
529 | #else | 622 | #else |
530 | #define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus) | 623 | #define dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus) |
531 | #endif | 624 | #endif |
532 | 625 | ||
533 | static int debug_irq; | 626 | static int debug_irq; |
534 | 627 | ||
535 | static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus) | 628 | static void dsi_handle_irq_errors(struct platform_device *dsidev, u32 irqstatus, |
629 | u32 *vcstatus, u32 ciostatus) | ||
536 | { | 630 | { |
631 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
537 | int i; | 632 | int i; |
538 | 633 | ||
539 | if (irqstatus & DSI_IRQ_ERROR_MASK) { | 634 | if (irqstatus & DSI_IRQ_ERROR_MASK) { |
540 | DSSERR("DSI error, irqstatus %x\n", irqstatus); | 635 | DSSERR("DSI error, irqstatus %x\n", irqstatus); |
541 | print_irq_status(irqstatus); | 636 | print_irq_status(irqstatus); |
542 | spin_lock(&dsi.errors_lock); | 637 | spin_lock(&dsi->errors_lock); |
543 | dsi.errors |= irqstatus & DSI_IRQ_ERROR_MASK; | 638 | dsi->errors |= irqstatus & DSI_IRQ_ERROR_MASK; |
544 | spin_unlock(&dsi.errors_lock); | 639 | spin_unlock(&dsi->errors_lock); |
545 | } else if (debug_irq) { | 640 | } else if (debug_irq) { |
546 | print_irq_status(irqstatus); | 641 | print_irq_status(irqstatus); |
547 | } | 642 | } |
@@ -602,22 +697,27 @@ static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables, | |||
602 | 697 | ||
603 | static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) | 698 | static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) |
604 | { | 699 | { |
700 | struct platform_device *dsidev; | ||
701 | struct dsi_data *dsi; | ||
605 | u32 irqstatus, vcstatus[4], ciostatus; | 702 | u32 irqstatus, vcstatus[4], ciostatus; |
606 | int i; | 703 | int i; |
607 | 704 | ||
608 | spin_lock(&dsi.irq_lock); | 705 | dsidev = (struct platform_device *) arg; |
706 | dsi = dsi_get_dsidrv_data(dsidev); | ||
707 | |||
708 | spin_lock(&dsi->irq_lock); | ||
609 | 709 | ||
610 | irqstatus = dsi_read_reg(DSI_IRQSTATUS); | 710 | irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS); |
611 | 711 | ||
612 | /* IRQ is not for us */ | 712 | /* IRQ is not for us */ |
613 | if (!irqstatus) { | 713 | if (!irqstatus) { |
614 | spin_unlock(&dsi.irq_lock); | 714 | spin_unlock(&dsi->irq_lock); |
615 | return IRQ_NONE; | 715 | return IRQ_NONE; |
616 | } | 716 | } |
617 | 717 | ||
618 | dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); | 718 | dsi_write_reg(dsidev, DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); |
619 | /* flush posted write */ | 719 | /* flush posted write */ |
620 | dsi_read_reg(DSI_IRQSTATUS); | 720 | dsi_read_reg(dsidev, DSI_IRQSTATUS); |
621 | 721 | ||
622 | for (i = 0; i < 4; ++i) { | 722 | for (i = 0; i < 4; ++i) { |
623 | if ((irqstatus & (1 << i)) == 0) { | 723 | if ((irqstatus & (1 << i)) == 0) { |
@@ -625,45 +725,47 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) | |||
625 | continue; | 725 | continue; |
626 | } | 726 | } |
627 | 727 | ||
628 | vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i)); | 728 | vcstatus[i] = dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i)); |
629 | 729 | ||
630 | dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]); | 730 | dsi_write_reg(dsidev, DSI_VC_IRQSTATUS(i), vcstatus[i]); |
631 | /* flush posted write */ | 731 | /* flush posted write */ |
632 | dsi_read_reg(DSI_VC_IRQSTATUS(i)); | 732 | dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i)); |
633 | } | 733 | } |
634 | 734 | ||
635 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { | 735 | if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { |
636 | ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 736 | ciostatus = dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS); |
637 | 737 | ||
638 | dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); | 738 | dsi_write_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS, ciostatus); |
639 | /* flush posted write */ | 739 | /* flush posted write */ |
640 | dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); | 740 | dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS); |
641 | } else { | 741 | } else { |
642 | ciostatus = 0; | 742 | ciostatus = 0; |
643 | } | 743 | } |
644 | 744 | ||
645 | #ifdef DSI_CATCH_MISSING_TE | 745 | #ifdef DSI_CATCH_MISSING_TE |
646 | if (irqstatus & DSI_IRQ_TE_TRIGGER) | 746 | if (irqstatus & DSI_IRQ_TE_TRIGGER) |
647 | del_timer(&dsi.te_timer); | 747 | del_timer(&dsi->te_timer); |
648 | #endif | 748 | #endif |
649 | 749 | ||
650 | /* make a copy and unlock, so that isrs can unregister | 750 | /* make a copy and unlock, so that isrs can unregister |
651 | * themselves */ | 751 | * themselves */ |
652 | memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables)); | 752 | memcpy(&dsi->isr_tables_copy, &dsi->isr_tables, |
753 | sizeof(dsi->isr_tables)); | ||
653 | 754 | ||
654 | spin_unlock(&dsi.irq_lock); | 755 | spin_unlock(&dsi->irq_lock); |
655 | 756 | ||
656 | dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus); | 757 | dsi_handle_isrs(&dsi->isr_tables_copy, irqstatus, vcstatus, ciostatus); |
657 | 758 | ||
658 | dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus); | 759 | dsi_handle_irq_errors(dsidev, irqstatus, vcstatus, ciostatus); |
659 | 760 | ||
660 | dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus); | 761 | dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus); |
661 | 762 | ||
662 | return IRQ_HANDLED; | 763 | return IRQ_HANDLED; |
663 | } | 764 | } |
664 | 765 | ||
665 | /* dsi.irq_lock has to be locked by the caller */ | 766 | /* dsi->irq_lock has to be locked by the caller */ |
666 | static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array, | 767 | static void _omap_dsi_configure_irqs(struct platform_device *dsidev, |
768 | struct dsi_isr_data *isr_array, | ||
667 | unsigned isr_array_size, u32 default_mask, | 769 | unsigned isr_array_size, u32 default_mask, |
668 | const struct dsi_reg enable_reg, | 770 | const struct dsi_reg enable_reg, |
669 | const struct dsi_reg status_reg) | 771 | const struct dsi_reg status_reg) |
@@ -684,61 +786,67 @@ static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array, | |||
684 | mask |= isr_data->mask; | 786 | mask |= isr_data->mask; |
685 | } | 787 | } |
686 | 788 | ||
687 | old_mask = dsi_read_reg(enable_reg); | 789 | old_mask = dsi_read_reg(dsidev, enable_reg); |
688 | /* clear the irqstatus for newly enabled irqs */ | 790 | /* clear the irqstatus for newly enabled irqs */ |
689 | dsi_write_reg(status_reg, (mask ^ old_mask) & mask); | 791 | dsi_write_reg(dsidev, status_reg, (mask ^ old_mask) & mask); |
690 | dsi_write_reg(enable_reg, mask); | 792 | dsi_write_reg(dsidev, enable_reg, mask); |
691 | 793 | ||
692 | /* flush posted writes */ | 794 | /* flush posted writes */ |
693 | dsi_read_reg(enable_reg); | 795 | dsi_read_reg(dsidev, enable_reg); |
694 | dsi_read_reg(status_reg); | 796 | dsi_read_reg(dsidev, status_reg); |
695 | } | 797 | } |
696 | 798 | ||
697 | /* dsi.irq_lock has to be locked by the caller */ | 799 | /* dsi->irq_lock has to be locked by the caller */ |
698 | static void _omap_dsi_set_irqs(void) | 800 | static void _omap_dsi_set_irqs(struct platform_device *dsidev) |
699 | { | 801 | { |
802 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
700 | u32 mask = DSI_IRQ_ERROR_MASK; | 803 | u32 mask = DSI_IRQ_ERROR_MASK; |
701 | #ifdef DSI_CATCH_MISSING_TE | 804 | #ifdef DSI_CATCH_MISSING_TE |
702 | mask |= DSI_IRQ_TE_TRIGGER; | 805 | mask |= DSI_IRQ_TE_TRIGGER; |
703 | #endif | 806 | #endif |
704 | _omap_dsi_configure_irqs(dsi.isr_tables.isr_table, | 807 | _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table, |
705 | ARRAY_SIZE(dsi.isr_tables.isr_table), mask, | 808 | ARRAY_SIZE(dsi->isr_tables.isr_table), mask, |
706 | DSI_IRQENABLE, DSI_IRQSTATUS); | 809 | DSI_IRQENABLE, DSI_IRQSTATUS); |
707 | } | 810 | } |
708 | 811 | ||
709 | /* dsi.irq_lock has to be locked by the caller */ | 812 | /* dsi->irq_lock has to be locked by the caller */ |
710 | static void _omap_dsi_set_irqs_vc(int vc) | 813 | static void _omap_dsi_set_irqs_vc(struct platform_device *dsidev, int vc) |
711 | { | 814 | { |
712 | _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc], | 815 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
713 | ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]), | 816 | |
817 | _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_vc[vc], | ||
818 | ARRAY_SIZE(dsi->isr_tables.isr_table_vc[vc]), | ||
714 | DSI_VC_IRQ_ERROR_MASK, | 819 | DSI_VC_IRQ_ERROR_MASK, |
715 | DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc)); | 820 | DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc)); |
716 | } | 821 | } |
717 | 822 | ||
718 | /* dsi.irq_lock has to be locked by the caller */ | 823 | /* dsi->irq_lock has to be locked by the caller */ |
719 | static void _omap_dsi_set_irqs_cio(void) | 824 | static void _omap_dsi_set_irqs_cio(struct platform_device *dsidev) |
720 | { | 825 | { |
721 | _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio, | 826 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
722 | ARRAY_SIZE(dsi.isr_tables.isr_table_cio), | 827 | |
828 | _omap_dsi_configure_irqs(dsidev, dsi->isr_tables.isr_table_cio, | ||
829 | ARRAY_SIZE(dsi->isr_tables.isr_table_cio), | ||
723 | DSI_CIO_IRQ_ERROR_MASK, | 830 | DSI_CIO_IRQ_ERROR_MASK, |
724 | DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS); | 831 | DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS); |
725 | } | 832 | } |
726 | 833 | ||
727 | static void _dsi_initialize_irq(void) | 834 | static void _dsi_initialize_irq(struct platform_device *dsidev) |
728 | { | 835 | { |
836 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
729 | unsigned long flags; | 837 | unsigned long flags; |
730 | int vc; | 838 | int vc; |
731 | 839 | ||
732 | spin_lock_irqsave(&dsi.irq_lock, flags); | 840 | spin_lock_irqsave(&dsi->irq_lock, flags); |
733 | 841 | ||
734 | memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables)); | 842 | memset(&dsi->isr_tables, 0, sizeof(dsi->isr_tables)); |
735 | 843 | ||
736 | _omap_dsi_set_irqs(); | 844 | _omap_dsi_set_irqs(dsidev); |
737 | for (vc = 0; vc < 4; ++vc) | 845 | for (vc = 0; vc < 4; ++vc) |
738 | _omap_dsi_set_irqs_vc(vc); | 846 | _omap_dsi_set_irqs_vc(dsidev, vc); |
739 | _omap_dsi_set_irqs_cio(); | 847 | _omap_dsi_set_irqs_cio(dsidev); |
740 | 848 | ||
741 | spin_unlock_irqrestore(&dsi.irq_lock, flags); | 849 | spin_unlock_irqrestore(&dsi->irq_lock, flags); |
742 | } | 850 | } |
743 | 851 | ||
744 | static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask, | 852 | static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask, |
@@ -797,126 +905,137 @@ static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask, | |||
797 | return -EINVAL; | 905 | return -EINVAL; |
798 | } | 906 | } |
799 | 907 | ||
800 | static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask) | 908 | static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr, |
909 | void *arg, u32 mask) | ||
801 | { | 910 | { |
911 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
802 | unsigned long flags; | 912 | unsigned long flags; |
803 | int r; | 913 | int r; |
804 | 914 | ||
805 | spin_lock_irqsave(&dsi.irq_lock, flags); | 915 | spin_lock_irqsave(&dsi->irq_lock, flags); |
806 | 916 | ||
807 | r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table, | 917 | r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table, |
808 | ARRAY_SIZE(dsi.isr_tables.isr_table)); | 918 | ARRAY_SIZE(dsi->isr_tables.isr_table)); |
809 | 919 | ||
810 | if (r == 0) | 920 | if (r == 0) |
811 | _omap_dsi_set_irqs(); | 921 | _omap_dsi_set_irqs(dsidev); |
812 | 922 | ||
813 | spin_unlock_irqrestore(&dsi.irq_lock, flags); | 923 | spin_unlock_irqrestore(&dsi->irq_lock, flags); |
814 | 924 | ||
815 | return r; | 925 | return r; |
816 | } | 926 | } |
817 | 927 | ||
818 | static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask) | 928 | static int dsi_unregister_isr(struct platform_device *dsidev, |
929 | omap_dsi_isr_t isr, void *arg, u32 mask) | ||
819 | { | 930 | { |
931 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
820 | unsigned long flags; | 932 | unsigned long flags; |
821 | int r; | 933 | int r; |
822 | 934 | ||
823 | spin_lock_irqsave(&dsi.irq_lock, flags); | 935 | spin_lock_irqsave(&dsi->irq_lock, flags); |
824 | 936 | ||
825 | r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table, | 937 | r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table, |
826 | ARRAY_SIZE(dsi.isr_tables.isr_table)); | 938 | ARRAY_SIZE(dsi->isr_tables.isr_table)); |
827 | 939 | ||
828 | if (r == 0) | 940 | if (r == 0) |
829 | _omap_dsi_set_irqs(); | 941 | _omap_dsi_set_irqs(dsidev); |
830 | 942 | ||
831 | spin_unlock_irqrestore(&dsi.irq_lock, flags); | 943 | spin_unlock_irqrestore(&dsi->irq_lock, flags); |
832 | 944 | ||
833 | return r; | 945 | return r; |
834 | } | 946 | } |
835 | 947 | ||
836 | static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, | 948 | static int dsi_register_isr_vc(struct platform_device *dsidev, int channel, |
837 | u32 mask) | 949 | omap_dsi_isr_t isr, void *arg, u32 mask) |
838 | { | 950 | { |
951 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
839 | unsigned long flags; | 952 | unsigned long flags; |
840 | int r; | 953 | int r; |
841 | 954 | ||
842 | spin_lock_irqsave(&dsi.irq_lock, flags); | 955 | spin_lock_irqsave(&dsi->irq_lock, flags); |
843 | 956 | ||
844 | r = _dsi_register_isr(isr, arg, mask, | 957 | r = _dsi_register_isr(isr, arg, mask, |
845 | dsi.isr_tables.isr_table_vc[channel], | 958 | dsi->isr_tables.isr_table_vc[channel], |
846 | ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); | 959 | ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel])); |
847 | 960 | ||
848 | if (r == 0) | 961 | if (r == 0) |
849 | _omap_dsi_set_irqs_vc(channel); | 962 | _omap_dsi_set_irqs_vc(dsidev, channel); |
850 | 963 | ||
851 | spin_unlock_irqrestore(&dsi.irq_lock, flags); | 964 | spin_unlock_irqrestore(&dsi->irq_lock, flags); |
852 | 965 | ||
853 | return r; | 966 | return r; |
854 | } | 967 | } |
855 | 968 | ||
856 | static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, | 969 | static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel, |
857 | u32 mask) | 970 | omap_dsi_isr_t isr, void *arg, u32 mask) |
858 | { | 971 | { |
972 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
859 | unsigned long flags; | 973 | unsigned long flags; |
860 | int r; | 974 | int r; |
861 | 975 | ||
862 | spin_lock_irqsave(&dsi.irq_lock, flags); | 976 | spin_lock_irqsave(&dsi->irq_lock, flags); |
863 | 977 | ||
864 | r = _dsi_unregister_isr(isr, arg, mask, | 978 | r = _dsi_unregister_isr(isr, arg, mask, |
865 | dsi.isr_tables.isr_table_vc[channel], | 979 | dsi->isr_tables.isr_table_vc[channel], |
866 | ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); | 980 | ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel])); |
867 | 981 | ||
868 | if (r == 0) | 982 | if (r == 0) |
869 | _omap_dsi_set_irqs_vc(channel); | 983 | _omap_dsi_set_irqs_vc(dsidev, channel); |
870 | 984 | ||
871 | spin_unlock_irqrestore(&dsi.irq_lock, flags); | 985 | spin_unlock_irqrestore(&dsi->irq_lock, flags); |
872 | 986 | ||
873 | return r; | 987 | return r; |
874 | } | 988 | } |
875 | 989 | ||
876 | static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) | 990 | static int dsi_register_isr_cio(struct platform_device *dsidev, |
991 | omap_dsi_isr_t isr, void *arg, u32 mask) | ||
877 | { | 992 | { |
993 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
878 | unsigned long flags; | 994 | unsigned long flags; |
879 | int r; | 995 | int r; |
880 | 996 | ||
881 | spin_lock_irqsave(&dsi.irq_lock, flags); | 997 | spin_lock_irqsave(&dsi->irq_lock, flags); |
882 | 998 | ||
883 | r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio, | 999 | r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio, |
884 | ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); | 1000 | ARRAY_SIZE(dsi->isr_tables.isr_table_cio)); |
885 | 1001 | ||
886 | if (r == 0) | 1002 | if (r == 0) |
887 | _omap_dsi_set_irqs_cio(); | 1003 | _omap_dsi_set_irqs_cio(dsidev); |
888 | 1004 | ||
889 | spin_unlock_irqrestore(&dsi.irq_lock, flags); | 1005 | spin_unlock_irqrestore(&dsi->irq_lock, flags); |
890 | 1006 | ||
891 | return r; | 1007 | return r; |
892 | } | 1008 | } |
893 | 1009 | ||
894 | static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) | 1010 | static int dsi_unregister_isr_cio(struct platform_device *dsidev, |
1011 | omap_dsi_isr_t isr, void *arg, u32 mask) | ||
895 | { | 1012 | { |
1013 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
896 | unsigned long flags; | 1014 | unsigned long flags; |
897 | int r; | 1015 | int r; |
898 | 1016 | ||
899 | spin_lock_irqsave(&dsi.irq_lock, flags); | 1017 | spin_lock_irqsave(&dsi->irq_lock, flags); |
900 | 1018 | ||
901 | r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio, | 1019 | r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio, |
902 | ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); | 1020 | ARRAY_SIZE(dsi->isr_tables.isr_table_cio)); |
903 | 1021 | ||
904 | if (r == 0) | 1022 | if (r == 0) |
905 | _omap_dsi_set_irqs_cio(); | 1023 | _omap_dsi_set_irqs_cio(dsidev); |
906 | 1024 | ||
907 | spin_unlock_irqrestore(&dsi.irq_lock, flags); | 1025 | spin_unlock_irqrestore(&dsi->irq_lock, flags); |
908 | 1026 | ||
909 | return r; | 1027 | return r; |
910 | } | 1028 | } |
911 | 1029 | ||
912 | static u32 dsi_get_errors(void) | 1030 | static u32 dsi_get_errors(struct platform_device *dsidev) |
913 | { | 1031 | { |
1032 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
914 | unsigned long flags; | 1033 | unsigned long flags; |
915 | u32 e; | 1034 | u32 e; |
916 | spin_lock_irqsave(&dsi.errors_lock, flags); | 1035 | spin_lock_irqsave(&dsi->errors_lock, flags); |
917 | e = dsi.errors; | 1036 | e = dsi->errors; |
918 | dsi.errors = 0; | 1037 | dsi->errors = 0; |
919 | spin_unlock_irqrestore(&dsi.errors_lock, flags); | 1038 | spin_unlock_irqrestore(&dsi->errors_lock, flags); |
920 | return e; | 1039 | return e; |
921 | } | 1040 | } |
922 | 1041 | ||
@@ -930,23 +1049,27 @@ static inline void enable_clocks(bool enable) | |||
930 | } | 1049 | } |
931 | 1050 | ||
932 | /* source clock for DSI PLL. this could also be PCLKFREE */ | 1051 | /* source clock for DSI PLL. this could also be PCLKFREE */ |
933 | static inline void dsi_enable_pll_clock(bool enable) | 1052 | static inline void dsi_enable_pll_clock(struct platform_device *dsidev, |
1053 | bool enable) | ||
934 | { | 1054 | { |
1055 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1056 | |||
935 | if (enable) | 1057 | if (enable) |
936 | dss_clk_enable(DSS_CLK_SYSCK); | 1058 | dss_clk_enable(DSS_CLK_SYSCK); |
937 | else | 1059 | else |
938 | dss_clk_disable(DSS_CLK_SYSCK); | 1060 | dss_clk_disable(DSS_CLK_SYSCK); |
939 | 1061 | ||
940 | if (enable && dsi.pll_locked) { | 1062 | if (enable && dsi->pll_locked) { |
941 | if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) | 1063 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) |
942 | DSSERR("cannot lock PLL when enabling clocks\n"); | 1064 | DSSERR("cannot lock PLL when enabling clocks\n"); |
943 | } | 1065 | } |
944 | } | 1066 | } |
945 | 1067 | ||
946 | #ifdef DEBUG | 1068 | #ifdef DEBUG |
947 | static void _dsi_print_reset_status(void) | 1069 | static void _dsi_print_reset_status(struct platform_device *dsidev) |
948 | { | 1070 | { |
949 | u32 l; | 1071 | u32 l; |
1072 | int b0, b1, b2; | ||
950 | 1073 | ||
951 | if (!dss_debug) | 1074 | if (!dss_debug) |
952 | return; | 1075 | return; |
@@ -954,35 +1077,47 @@ static void _dsi_print_reset_status(void) | |||
954 | /* A dummy read using the SCP interface to any DSIPHY register is | 1077 | /* A dummy read using the SCP interface to any DSIPHY register is |
955 | * required after DSIPHY reset to complete the reset of the DSI complex | 1078 | * required after DSIPHY reset to complete the reset of the DSI complex |
956 | * I/O. */ | 1079 | * I/O. */ |
957 | l = dsi_read_reg(DSI_DSIPHY_CFG5); | 1080 | l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); |
958 | 1081 | ||
959 | printk(KERN_DEBUG "DSI resets: "); | 1082 | printk(KERN_DEBUG "DSI resets: "); |
960 | 1083 | ||
961 | l = dsi_read_reg(DSI_PLL_STATUS); | 1084 | l = dsi_read_reg(dsidev, DSI_PLL_STATUS); |
962 | printk("PLL (%d) ", FLD_GET(l, 0, 0)); | 1085 | printk("PLL (%d) ", FLD_GET(l, 0, 0)); |
963 | 1086 | ||
964 | l = dsi_read_reg(DSI_COMPLEXIO_CFG1); | 1087 | l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1); |
965 | printk("CIO (%d) ", FLD_GET(l, 29, 29)); | 1088 | printk("CIO (%d) ", FLD_GET(l, 29, 29)); |
966 | 1089 | ||
967 | l = dsi_read_reg(DSI_DSIPHY_CFG5); | 1090 | if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) { |
968 | printk("PHY (%x, %d, %d, %d)\n", | 1091 | b0 = 28; |
969 | FLD_GET(l, 28, 26), | 1092 | b1 = 27; |
1093 | b2 = 26; | ||
1094 | } else { | ||
1095 | b0 = 24; | ||
1096 | b1 = 25; | ||
1097 | b2 = 26; | ||
1098 | } | ||
1099 | |||
1100 | l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); | ||
1101 | printk("PHY (%x%x%x, %d, %d, %d)\n", | ||
1102 | FLD_GET(l, b0, b0), | ||
1103 | FLD_GET(l, b1, b1), | ||
1104 | FLD_GET(l, b2, b2), | ||
970 | FLD_GET(l, 29, 29), | 1105 | FLD_GET(l, 29, 29), |
971 | FLD_GET(l, 30, 30), | 1106 | FLD_GET(l, 30, 30), |
972 | FLD_GET(l, 31, 31)); | 1107 | FLD_GET(l, 31, 31)); |
973 | } | 1108 | } |
974 | #else | 1109 | #else |
975 | #define _dsi_print_reset_status() | 1110 | #define _dsi_print_reset_status(x) |
976 | #endif | 1111 | #endif |
977 | 1112 | ||
978 | static inline int dsi_if_enable(bool enable) | 1113 | static inline int dsi_if_enable(struct platform_device *dsidev, bool enable) |
979 | { | 1114 | { |
980 | DSSDBG("dsi_if_enable(%d)\n", enable); | 1115 | DSSDBG("dsi_if_enable(%d)\n", enable); |
981 | 1116 | ||
982 | enable = enable ? 1 : 0; | 1117 | enable = enable ? 1 : 0; |
983 | REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */ | 1118 | REG_FLD_MOD(dsidev, DSI_CTRL, enable, 0, 0); /* IF_EN */ |
984 | 1119 | ||
985 | if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) { | 1120 | if (wait_for_bit_change(dsidev, DSI_CTRL, 0, enable) != enable) { |
986 | DSSERR("Failed to set dsi_if_enable to %d\n", enable); | 1121 | DSSERR("Failed to set dsi_if_enable to %d\n", enable); |
987 | return -EIO; | 1122 | return -EIO; |
988 | } | 1123 | } |
@@ -990,31 +1125,38 @@ static inline int dsi_if_enable(bool enable) | |||
990 | return 0; | 1125 | return 0; |
991 | } | 1126 | } |
992 | 1127 | ||
993 | unsigned long dsi_get_pll_hsdiv_dispc_rate(void) | 1128 | unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) |
994 | { | 1129 | { |
995 | return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk; | 1130 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1131 | |||
1132 | return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk; | ||
996 | } | 1133 | } |
997 | 1134 | ||
998 | static unsigned long dsi_get_pll_hsdiv_dsi_rate(void) | 1135 | static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev) |
999 | { | 1136 | { |
1000 | return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk; | 1137 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1138 | |||
1139 | return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk; | ||
1001 | } | 1140 | } |
1002 | 1141 | ||
1003 | static unsigned long dsi_get_txbyteclkhs(void) | 1142 | static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev) |
1004 | { | 1143 | { |
1005 | return dsi.current_cinfo.clkin4ddr / 16; | 1144 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1145 | |||
1146 | return dsi->current_cinfo.clkin4ddr / 16; | ||
1006 | } | 1147 | } |
1007 | 1148 | ||
1008 | static unsigned long dsi_fclk_rate(void) | 1149 | static unsigned long dsi_fclk_rate(struct platform_device *dsidev) |
1009 | { | 1150 | { |
1010 | unsigned long r; | 1151 | unsigned long r; |
1152 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
1011 | 1153 | ||
1012 | if (dss_get_dsi_clk_source() == DSS_CLK_SRC_FCK) { | 1154 | if (dss_get_dsi_clk_source(dsi_module) == OMAP_DSS_CLK_SRC_FCK) { |
1013 | /* DSI FCLK source is DSS_CLK_FCK */ | 1155 | /* DSI FCLK source is DSS_CLK_FCK */ |
1014 | r = dss_clk_get_rate(DSS_CLK_FCK); | 1156 | r = dss_clk_get_rate(DSS_CLK_FCK); |
1015 | } else { | 1157 | } else { |
1016 | /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ | 1158 | /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ |
1017 | r = dsi_get_pll_hsdiv_dsi_rate(); | 1159 | r = dsi_get_pll_hsdiv_dsi_rate(dsidev); |
1018 | } | 1160 | } |
1019 | 1161 | ||
1020 | return r; | 1162 | return r; |
@@ -1022,31 +1164,50 @@ static unsigned long dsi_fclk_rate(void) | |||
1022 | 1164 | ||
1023 | static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) | 1165 | static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) |
1024 | { | 1166 | { |
1167 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
1168 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1025 | unsigned long dsi_fclk; | 1169 | unsigned long dsi_fclk; |
1026 | unsigned lp_clk_div; | 1170 | unsigned lp_clk_div; |
1027 | unsigned long lp_clk; | 1171 | unsigned long lp_clk; |
1028 | 1172 | ||
1029 | lp_clk_div = dssdev->phy.dsi.div.lp_clk_div; | 1173 | lp_clk_div = dssdev->clocks.dsi.lp_clk_div; |
1030 | 1174 | ||
1031 | if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max) | 1175 | if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max) |
1032 | return -EINVAL; | 1176 | return -EINVAL; |
1033 | 1177 | ||
1034 | dsi_fclk = dsi_fclk_rate(); | 1178 | dsi_fclk = dsi_fclk_rate(dsidev); |
1035 | 1179 | ||
1036 | lp_clk = dsi_fclk / 2 / lp_clk_div; | 1180 | lp_clk = dsi_fclk / 2 / lp_clk_div; |
1037 | 1181 | ||
1038 | DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); | 1182 | DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); |
1039 | dsi.current_cinfo.lp_clk = lp_clk; | 1183 | dsi->current_cinfo.lp_clk = lp_clk; |
1040 | dsi.current_cinfo.lp_clk_div = lp_clk_div; | 1184 | dsi->current_cinfo.lp_clk_div = lp_clk_div; |
1041 | 1185 | ||
1042 | REG_FLD_MOD(DSI_CLK_CTRL, lp_clk_div, 12, 0); /* LP_CLK_DIVISOR */ | 1186 | /* LP_CLK_DIVISOR */ |
1187 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0); | ||
1043 | 1188 | ||
1044 | REG_FLD_MOD(DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, | 1189 | /* LP_RX_SYNCHRO_ENABLE */ |
1045 | 21, 21); /* LP_RX_SYNCHRO_ENABLE */ | 1190 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, 21, 21); |
1046 | 1191 | ||
1047 | return 0; | 1192 | return 0; |
1048 | } | 1193 | } |
1049 | 1194 | ||
1195 | static void dsi_enable_scp_clk(struct platform_device *dsidev) | ||
1196 | { | ||
1197 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1198 | |||
1199 | if (dsi->scp_clk_refcount++ == 0) | ||
1200 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */ | ||
1201 | } | ||
1202 | |||
1203 | static void dsi_disable_scp_clk(struct platform_device *dsidev) | ||
1204 | { | ||
1205 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1206 | |||
1207 | WARN_ON(dsi->scp_clk_refcount == 0); | ||
1208 | if (--dsi->scp_clk_refcount == 0) | ||
1209 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */ | ||
1210 | } | ||
1050 | 1211 | ||
1051 | enum dsi_pll_power_state { | 1212 | enum dsi_pll_power_state { |
1052 | DSI_PLL_POWER_OFF = 0x0, | 1213 | DSI_PLL_POWER_OFF = 0x0, |
@@ -1055,7 +1216,8 @@ enum dsi_pll_power_state { | |||
1055 | DSI_PLL_POWER_ON_DIV = 0x3, | 1216 | DSI_PLL_POWER_ON_DIV = 0x3, |
1056 | }; | 1217 | }; |
1057 | 1218 | ||
1058 | static int dsi_pll_power(enum dsi_pll_power_state state) | 1219 | static int dsi_pll_power(struct platform_device *dsidev, |
1220 | enum dsi_pll_power_state state) | ||
1059 | { | 1221 | { |
1060 | int t = 0; | 1222 | int t = 0; |
1061 | 1223 | ||
@@ -1064,10 +1226,11 @@ static int dsi_pll_power(enum dsi_pll_power_state state) | |||
1064 | state == DSI_PLL_POWER_ON_DIV) | 1226 | state == DSI_PLL_POWER_ON_DIV) |
1065 | state = DSI_PLL_POWER_ON_ALL; | 1227 | state = DSI_PLL_POWER_ON_ALL; |
1066 | 1228 | ||
1067 | REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */ | 1229 | /* PLL_PWR_CMD */ |
1230 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, state, 31, 30); | ||
1068 | 1231 | ||
1069 | /* PLL_PWR_STATUS */ | 1232 | /* PLL_PWR_STATUS */ |
1070 | while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { | 1233 | while (FLD_GET(dsi_read_reg(dsidev, DSI_CLK_CTRL), 29, 28) != state) { |
1071 | if (++t > 1000) { | 1234 | if (++t > 1000) { |
1072 | DSSERR("Failed to set DSI PLL power mode to %d\n", | 1235 | DSSERR("Failed to set DSI PLL power mode to %d\n", |
1073 | state); | 1236 | state); |
@@ -1083,16 +1246,19 @@ static int dsi_pll_power(enum dsi_pll_power_state state) | |||
1083 | static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, | 1246 | static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, |
1084 | struct dsi_clock_info *cinfo) | 1247 | struct dsi_clock_info *cinfo) |
1085 | { | 1248 | { |
1086 | if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max) | 1249 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
1250 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1251 | |||
1252 | if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max) | ||
1087 | return -EINVAL; | 1253 | return -EINVAL; |
1088 | 1254 | ||
1089 | if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max) | 1255 | if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max) |
1090 | return -EINVAL; | 1256 | return -EINVAL; |
1091 | 1257 | ||
1092 | if (cinfo->regm_dispc > dsi.regm_dispc_max) | 1258 | if (cinfo->regm_dispc > dsi->regm_dispc_max) |
1093 | return -EINVAL; | 1259 | return -EINVAL; |
1094 | 1260 | ||
1095 | if (cinfo->regm_dsi > dsi.regm_dsi_max) | 1261 | if (cinfo->regm_dsi > dsi->regm_dsi_max) |
1096 | return -EINVAL; | 1262 | return -EINVAL; |
1097 | 1263 | ||
1098 | if (cinfo->use_sys_clk) { | 1264 | if (cinfo->use_sys_clk) { |
@@ -1111,7 +1277,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, | |||
1111 | 1277 | ||
1112 | cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); | 1278 | cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); |
1113 | 1279 | ||
1114 | if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min) | 1280 | if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min) |
1115 | return -EINVAL; | 1281 | return -EINVAL; |
1116 | 1282 | ||
1117 | cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; | 1283 | cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; |
@@ -1134,10 +1300,11 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, | |||
1134 | return 0; | 1300 | return 0; |
1135 | } | 1301 | } |
1136 | 1302 | ||
1137 | int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, | 1303 | int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, |
1138 | struct dsi_clock_info *dsi_cinfo, | 1304 | unsigned long req_pck, struct dsi_clock_info *dsi_cinfo, |
1139 | struct dispc_clock_info *dispc_cinfo) | 1305 | struct dispc_clock_info *dispc_cinfo) |
1140 | { | 1306 | { |
1307 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1141 | struct dsi_clock_info cur, best; | 1308 | struct dsi_clock_info cur, best; |
1142 | struct dispc_clock_info best_dispc; | 1309 | struct dispc_clock_info best_dispc; |
1143 | int min_fck_per_pck; | 1310 | int min_fck_per_pck; |
@@ -1148,10 +1315,10 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, | |||
1148 | 1315 | ||
1149 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); | 1316 | max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); |
1150 | 1317 | ||
1151 | if (req_pck == dsi.cache_req_pck && | 1318 | if (req_pck == dsi->cache_req_pck && |
1152 | dsi.cache_cinfo.clkin == dss_sys_clk) { | 1319 | dsi->cache_cinfo.clkin == dss_sys_clk) { |
1153 | DSSDBG("DSI clock info found from cache\n"); | 1320 | DSSDBG("DSI clock info found from cache\n"); |
1154 | *dsi_cinfo = dsi.cache_cinfo; | 1321 | *dsi_cinfo = dsi->cache_cinfo; |
1155 | dispc_find_clk_divs(is_tft, req_pck, | 1322 | dispc_find_clk_divs(is_tft, req_pck, |
1156 | dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); | 1323 | dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); |
1157 | return 0; | 1324 | return 0; |
@@ -1181,17 +1348,17 @@ retry: | |||
1181 | /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ | 1348 | /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ |
1182 | /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ | 1349 | /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ |
1183 | /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ | 1350 | /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ |
1184 | for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) { | 1351 | for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { |
1185 | if (cur.highfreq == 0) | 1352 | if (cur.highfreq == 0) |
1186 | cur.fint = cur.clkin / cur.regn; | 1353 | cur.fint = cur.clkin / cur.regn; |
1187 | else | 1354 | else |
1188 | cur.fint = cur.clkin / (2 * cur.regn); | 1355 | cur.fint = cur.clkin / (2 * cur.regn); |
1189 | 1356 | ||
1190 | if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min) | 1357 | if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) |
1191 | continue; | 1358 | continue; |
1192 | 1359 | ||
1193 | /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ | 1360 | /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ |
1194 | for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) { | 1361 | for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { |
1195 | unsigned long a, b; | 1362 | unsigned long a, b; |
1196 | 1363 | ||
1197 | a = 2 * cur.regm * (cur.clkin/1000); | 1364 | a = 2 * cur.regm * (cur.clkin/1000); |
@@ -1203,8 +1370,8 @@ retry: | |||
1203 | 1370 | ||
1204 | /* dsi_pll_hsdiv_dispc_clk(MHz) = | 1371 | /* dsi_pll_hsdiv_dispc_clk(MHz) = |
1205 | * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ | 1372 | * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ |
1206 | for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max; | 1373 | for (cur.regm_dispc = 1; cur.regm_dispc < |
1207 | ++cur.regm_dispc) { | 1374 | dsi->regm_dispc_max; ++cur.regm_dispc) { |
1208 | struct dispc_clock_info cur_dispc; | 1375 | struct dispc_clock_info cur_dispc; |
1209 | cur.dsi_pll_hsdiv_dispc_clk = | 1376 | cur.dsi_pll_hsdiv_dispc_clk = |
1210 | cur.clkin4ddr / cur.regm_dispc; | 1377 | cur.clkin4ddr / cur.regm_dispc; |
@@ -1264,37 +1431,39 @@ found: | |||
1264 | if (dispc_cinfo) | 1431 | if (dispc_cinfo) |
1265 | *dispc_cinfo = best_dispc; | 1432 | *dispc_cinfo = best_dispc; |
1266 | 1433 | ||
1267 | dsi.cache_req_pck = req_pck; | 1434 | dsi->cache_req_pck = req_pck; |
1268 | dsi.cache_clk_freq = 0; | 1435 | dsi->cache_clk_freq = 0; |
1269 | dsi.cache_cinfo = best; | 1436 | dsi->cache_cinfo = best; |
1270 | 1437 | ||
1271 | return 0; | 1438 | return 0; |
1272 | } | 1439 | } |
1273 | 1440 | ||
1274 | int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) | 1441 | int dsi_pll_set_clock_div(struct platform_device *dsidev, |
1442 | struct dsi_clock_info *cinfo) | ||
1275 | { | 1443 | { |
1444 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1276 | int r = 0; | 1445 | int r = 0; |
1277 | u32 l; | 1446 | u32 l; |
1278 | int f; | 1447 | int f = 0; |
1279 | u8 regn_start, regn_end, regm_start, regm_end; | 1448 | u8 regn_start, regn_end, regm_start, regm_end; |
1280 | u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end; | 1449 | u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end; |
1281 | 1450 | ||
1282 | DSSDBGF(); | 1451 | DSSDBGF(); |
1283 | 1452 | ||
1284 | dsi.current_cinfo.use_sys_clk = cinfo->use_sys_clk; | 1453 | dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk; |
1285 | dsi.current_cinfo.highfreq = cinfo->highfreq; | 1454 | dsi->current_cinfo.highfreq = cinfo->highfreq; |
1286 | 1455 | ||
1287 | dsi.current_cinfo.fint = cinfo->fint; | 1456 | dsi->current_cinfo.fint = cinfo->fint; |
1288 | dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; | 1457 | dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr; |
1289 | dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk = | 1458 | dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk = |
1290 | cinfo->dsi_pll_hsdiv_dispc_clk; | 1459 | cinfo->dsi_pll_hsdiv_dispc_clk; |
1291 | dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk = | 1460 | dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk = |
1292 | cinfo->dsi_pll_hsdiv_dsi_clk; | 1461 | cinfo->dsi_pll_hsdiv_dsi_clk; |
1293 | 1462 | ||
1294 | dsi.current_cinfo.regn = cinfo->regn; | 1463 | dsi->current_cinfo.regn = cinfo->regn; |
1295 | dsi.current_cinfo.regm = cinfo->regm; | 1464 | dsi->current_cinfo.regm = cinfo->regm; |
1296 | dsi.current_cinfo.regm_dispc = cinfo->regm_dispc; | 1465 | dsi->current_cinfo.regm_dispc = cinfo->regm_dispc; |
1297 | dsi.current_cinfo.regm_dsi = cinfo->regm_dsi; | 1466 | dsi->current_cinfo.regm_dsi = cinfo->regm_dsi; |
1298 | 1467 | ||
1299 | DSSDBG("DSI Fint %ld\n", cinfo->fint); | 1468 | DSSDBG("DSI Fint %ld\n", cinfo->fint); |
1300 | 1469 | ||
@@ -1317,12 +1486,12 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) | |||
1317 | DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); | 1486 | DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4); |
1318 | 1487 | ||
1319 | DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc, | 1488 | DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc, |
1320 | dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), | 1489 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), |
1321 | dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), | 1490 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), |
1322 | cinfo->dsi_pll_hsdiv_dispc_clk); | 1491 | cinfo->dsi_pll_hsdiv_dispc_clk); |
1323 | DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi, | 1492 | DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi, |
1324 | dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), | 1493 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), |
1325 | dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), | 1494 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), |
1326 | cinfo->dsi_pll_hsdiv_dsi_clk); | 1495 | cinfo->dsi_pll_hsdiv_dsi_clk); |
1327 | 1496 | ||
1328 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, ®n_start, ®n_end); | 1497 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, ®n_start, ®n_end); |
@@ -1332,9 +1501,10 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) | |||
1332 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, ®m_dsi_start, | 1501 | dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, ®m_dsi_start, |
1333 | ®m_dsi_end); | 1502 | ®m_dsi_end); |
1334 | 1503 | ||
1335 | REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ | 1504 | /* DSI_PLL_AUTOMODE = manual */ |
1505 | REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0); | ||
1336 | 1506 | ||
1337 | l = dsi_read_reg(DSI_PLL_CONFIGURATION1); | 1507 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1); |
1338 | l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ | 1508 | l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ |
1339 | /* DSI_PLL_REGN */ | 1509 | /* DSI_PLL_REGN */ |
1340 | l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end); | 1510 | l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end); |
@@ -1346,22 +1516,22 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) | |||
1346 | /* DSIPROTO_CLOCK_DIV */ | 1516 | /* DSIPROTO_CLOCK_DIV */ |
1347 | l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, | 1517 | l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, |
1348 | regm_dsi_start, regm_dsi_end); | 1518 | regm_dsi_start, regm_dsi_end); |
1349 | dsi_write_reg(DSI_PLL_CONFIGURATION1, l); | 1519 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l); |
1350 | 1520 | ||
1351 | BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max); | 1521 | BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); |
1352 | if (cinfo->fint < 1000000) | ||
1353 | f = 0x3; | ||
1354 | else if (cinfo->fint < 1250000) | ||
1355 | f = 0x4; | ||
1356 | else if (cinfo->fint < 1500000) | ||
1357 | f = 0x5; | ||
1358 | else if (cinfo->fint < 1750000) | ||
1359 | f = 0x6; | ||
1360 | else | ||
1361 | f = 0x7; | ||
1362 | 1522 | ||
1363 | l = dsi_read_reg(DSI_PLL_CONFIGURATION2); | 1523 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { |
1364 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ | 1524 | f = cinfo->fint < 1000000 ? 0x3 : |
1525 | cinfo->fint < 1250000 ? 0x4 : | ||
1526 | cinfo->fint < 1500000 ? 0x5 : | ||
1527 | cinfo->fint < 1750000 ? 0x6 : | ||
1528 | 0x7; | ||
1529 | } | ||
1530 | |||
1531 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); | ||
1532 | |||
1533 | if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) | ||
1534 | l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ | ||
1365 | l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, | 1535 | l = FLD_MOD(l, cinfo->use_sys_clk ? 0 : 1, |
1366 | 11, 11); /* DSI_PLL_CLKSEL */ | 1536 | 11, 11); /* DSI_PLL_CLKSEL */ |
1367 | l = FLD_MOD(l, cinfo->highfreq, | 1537 | l = FLD_MOD(l, cinfo->highfreq, |
@@ -1369,25 +1539,25 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) | |||
1369 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ | 1539 | l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ |
1370 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ | 1540 | l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ |
1371 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ | 1541 | l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ |
1372 | dsi_write_reg(DSI_PLL_CONFIGURATION2, l); | 1542 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); |
1373 | 1543 | ||
1374 | REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ | 1544 | REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ |
1375 | 1545 | ||
1376 | if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) { | 1546 | if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) { |
1377 | DSSERR("dsi pll go bit not going down.\n"); | 1547 | DSSERR("dsi pll go bit not going down.\n"); |
1378 | r = -EIO; | 1548 | r = -EIO; |
1379 | goto err; | 1549 | goto err; |
1380 | } | 1550 | } |
1381 | 1551 | ||
1382 | if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) { | 1552 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) { |
1383 | DSSERR("cannot lock PLL\n"); | 1553 | DSSERR("cannot lock PLL\n"); |
1384 | r = -EIO; | 1554 | r = -EIO; |
1385 | goto err; | 1555 | goto err; |
1386 | } | 1556 | } |
1387 | 1557 | ||
1388 | dsi.pll_locked = 1; | 1558 | dsi->pll_locked = 1; |
1389 | 1559 | ||
1390 | l = dsi_read_reg(DSI_PLL_CONFIGURATION2); | 1560 | l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); |
1391 | l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ | 1561 | l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ |
1392 | l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ | 1562 | l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ |
1393 | l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */ | 1563 | l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */ |
@@ -1402,52 +1572,53 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) | |||
1402 | l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */ | 1572 | l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */ |
1403 | l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */ | 1573 | l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */ |
1404 | l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */ | 1574 | l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */ |
1405 | dsi_write_reg(DSI_PLL_CONFIGURATION2, l); | 1575 | dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); |
1406 | 1576 | ||
1407 | DSSDBG("PLL config done\n"); | 1577 | DSSDBG("PLL config done\n"); |
1408 | err: | 1578 | err: |
1409 | return r; | 1579 | return r; |
1410 | } | 1580 | } |
1411 | 1581 | ||
1412 | int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, | 1582 | int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, |
1413 | bool enable_hsdiv) | 1583 | bool enable_hsdiv) |
1414 | { | 1584 | { |
1585 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1415 | int r = 0; | 1586 | int r = 0; |
1416 | enum dsi_pll_power_state pwstate; | 1587 | enum dsi_pll_power_state pwstate; |
1417 | 1588 | ||
1418 | DSSDBG("PLL init\n"); | 1589 | DSSDBG("PLL init\n"); |
1419 | 1590 | ||
1420 | #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL | 1591 | if (dsi->vdds_dsi_reg == NULL) { |
1421 | /* | ||
1422 | * HACK: this is just a quick hack to get the USE_DSI_PLL | ||
1423 | * option working. USE_DSI_PLL is itself a big hack, and | ||
1424 | * should be removed. | ||
1425 | */ | ||
1426 | if (dsi.vdds_dsi_reg == NULL) { | ||
1427 | struct regulator *vdds_dsi; | 1592 | struct regulator *vdds_dsi; |
1428 | 1593 | ||
1429 | vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); | 1594 | vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); |
1430 | 1595 | ||
1431 | if (IS_ERR(vdds_dsi)) { | 1596 | if (IS_ERR(vdds_dsi)) { |
1432 | DSSERR("can't get VDDS_DSI regulator\n"); | 1597 | DSSERR("can't get VDDS_DSI regulator\n"); |
1433 | return PTR_ERR(vdds_dsi); | 1598 | return PTR_ERR(vdds_dsi); |
1434 | } | 1599 | } |
1435 | 1600 | ||
1436 | dsi.vdds_dsi_reg = vdds_dsi; | 1601 | dsi->vdds_dsi_reg = vdds_dsi; |
1437 | } | 1602 | } |
1438 | #endif | ||
1439 | 1603 | ||
1440 | enable_clocks(1); | 1604 | enable_clocks(1); |
1441 | dsi_enable_pll_clock(1); | 1605 | dsi_enable_pll_clock(dsidev, 1); |
1606 | /* | ||
1607 | * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. | ||
1608 | */ | ||
1609 | dsi_enable_scp_clk(dsidev); | ||
1442 | 1610 | ||
1443 | r = regulator_enable(dsi.vdds_dsi_reg); | 1611 | if (!dsi->vdds_dsi_enabled) { |
1444 | if (r) | 1612 | r = regulator_enable(dsi->vdds_dsi_reg); |
1445 | goto err0; | 1613 | if (r) |
1614 | goto err0; | ||
1615 | dsi->vdds_dsi_enabled = true; | ||
1616 | } | ||
1446 | 1617 | ||
1447 | /* XXX PLL does not come out of reset without this... */ | 1618 | /* XXX PLL does not come out of reset without this... */ |
1448 | dispc_pck_free_enable(1); | 1619 | dispc_pck_free_enable(1); |
1449 | 1620 | ||
1450 | if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { | 1621 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 0, 1) != 1) { |
1451 | DSSERR("PLL not coming out of reset.\n"); | 1622 | DSSERR("PLL not coming out of reset.\n"); |
1452 | r = -ENODEV; | 1623 | r = -ENODEV; |
1453 | dispc_pck_free_enable(0); | 1624 | dispc_pck_free_enable(0); |
@@ -1467,7 +1638,7 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, | |||
1467 | else | 1638 | else |
1468 | pwstate = DSI_PLL_POWER_OFF; | 1639 | pwstate = DSI_PLL_POWER_OFF; |
1469 | 1640 | ||
1470 | r = dsi_pll_power(pwstate); | 1641 | r = dsi_pll_power(dsidev, pwstate); |
1471 | 1642 | ||
1472 | if (r) | 1643 | if (r) |
1473 | goto err1; | 1644 | goto err1; |
@@ -1476,35 +1647,50 @@ int dsi_pll_init(struct omap_dss_device *dssdev, bool enable_hsclk, | |||
1476 | 1647 | ||
1477 | return 0; | 1648 | return 0; |
1478 | err1: | 1649 | err1: |
1479 | regulator_disable(dsi.vdds_dsi_reg); | 1650 | if (dsi->vdds_dsi_enabled) { |
1651 | regulator_disable(dsi->vdds_dsi_reg); | ||
1652 | dsi->vdds_dsi_enabled = false; | ||
1653 | } | ||
1480 | err0: | 1654 | err0: |
1655 | dsi_disable_scp_clk(dsidev); | ||
1481 | enable_clocks(0); | 1656 | enable_clocks(0); |
1482 | dsi_enable_pll_clock(0); | 1657 | dsi_enable_pll_clock(dsidev, 0); |
1483 | return r; | 1658 | return r; |
1484 | } | 1659 | } |
1485 | 1660 | ||
1486 | void dsi_pll_uninit(void) | 1661 | void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) |
1487 | { | 1662 | { |
1663 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1664 | |||
1665 | dsi->pll_locked = 0; | ||
1666 | dsi_pll_power(dsidev, DSI_PLL_POWER_OFF); | ||
1667 | if (disconnect_lanes) { | ||
1668 | WARN_ON(!dsi->vdds_dsi_enabled); | ||
1669 | regulator_disable(dsi->vdds_dsi_reg); | ||
1670 | dsi->vdds_dsi_enabled = false; | ||
1671 | } | ||
1672 | |||
1673 | dsi_disable_scp_clk(dsidev); | ||
1488 | enable_clocks(0); | 1674 | enable_clocks(0); |
1489 | dsi_enable_pll_clock(0); | 1675 | dsi_enable_pll_clock(dsidev, 0); |
1490 | 1676 | ||
1491 | dsi.pll_locked = 0; | ||
1492 | dsi_pll_power(DSI_PLL_POWER_OFF); | ||
1493 | regulator_disable(dsi.vdds_dsi_reg); | ||
1494 | DSSDBG("PLL uninit done\n"); | 1677 | DSSDBG("PLL uninit done\n"); |
1495 | } | 1678 | } |
1496 | 1679 | ||
1497 | void dsi_dump_clocks(struct seq_file *s) | 1680 | static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, |
1681 | struct seq_file *s) | ||
1498 | { | 1682 | { |
1499 | struct dsi_clock_info *cinfo = &dsi.current_cinfo; | 1683 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
1500 | enum dss_clk_source dispc_clk_src, dsi_clk_src; | 1684 | struct dsi_clock_info *cinfo = &dsi->current_cinfo; |
1685 | enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; | ||
1686 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
1501 | 1687 | ||
1502 | dispc_clk_src = dss_get_dispc_clk_source(); | 1688 | dispc_clk_src = dss_get_dispc_clk_source(); |
1503 | dsi_clk_src = dss_get_dsi_clk_source(); | 1689 | dsi_clk_src = dss_get_dsi_clk_source(dsi_module); |
1504 | 1690 | ||
1505 | enable_clocks(1); | 1691 | enable_clocks(1); |
1506 | 1692 | ||
1507 | seq_printf(s, "- DSI PLL -\n"); | 1693 | seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); |
1508 | 1694 | ||
1509 | seq_printf(s, "dsi pll source = %s\n", | 1695 | seq_printf(s, "dsi pll source = %s\n", |
1510 | cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree"); | 1696 | cinfo->use_sys_clk ? "dss_sys_clk" : "pclkfree"); |
@@ -1519,7 +1705,7 @@ void dsi_dump_clocks(struct seq_file *s) | |||
1519 | dss_feat_get_clk_source_name(dispc_clk_src), | 1705 | dss_feat_get_clk_source_name(dispc_clk_src), |
1520 | cinfo->dsi_pll_hsdiv_dispc_clk, | 1706 | cinfo->dsi_pll_hsdiv_dispc_clk, |
1521 | cinfo->regm_dispc, | 1707 | cinfo->regm_dispc, |
1522 | dispc_clk_src == DSS_CLK_SRC_FCK ? | 1708 | dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ? |
1523 | "off" : "on"); | 1709 | "off" : "on"); |
1524 | 1710 | ||
1525 | seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n", | 1711 | seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n", |
@@ -1527,45 +1713,55 @@ void dsi_dump_clocks(struct seq_file *s) | |||
1527 | dss_feat_get_clk_source_name(dsi_clk_src), | 1713 | dss_feat_get_clk_source_name(dsi_clk_src), |
1528 | cinfo->dsi_pll_hsdiv_dsi_clk, | 1714 | cinfo->dsi_pll_hsdiv_dsi_clk, |
1529 | cinfo->regm_dsi, | 1715 | cinfo->regm_dsi, |
1530 | dsi_clk_src == DSS_CLK_SRC_FCK ? | 1716 | dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ? |
1531 | "off" : "on"); | 1717 | "off" : "on"); |
1532 | 1718 | ||
1533 | seq_printf(s, "- DSI -\n"); | 1719 | seq_printf(s, "- DSI%d -\n", dsi_module + 1); |
1534 | 1720 | ||
1535 | seq_printf(s, "dsi fclk source = %s (%s)\n", | 1721 | seq_printf(s, "dsi fclk source = %s (%s)\n", |
1536 | dss_get_generic_clk_source_name(dsi_clk_src), | 1722 | dss_get_generic_clk_source_name(dsi_clk_src), |
1537 | dss_feat_get_clk_source_name(dsi_clk_src)); | 1723 | dss_feat_get_clk_source_name(dsi_clk_src)); |
1538 | 1724 | ||
1539 | seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); | 1725 | seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); |
1540 | 1726 | ||
1541 | seq_printf(s, "DDR_CLK\t\t%lu\n", | 1727 | seq_printf(s, "DDR_CLK\t\t%lu\n", |
1542 | cinfo->clkin4ddr / 4); | 1728 | cinfo->clkin4ddr / 4); |
1543 | 1729 | ||
1544 | seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs()); | 1730 | seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev)); |
1545 | 1731 | ||
1546 | seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); | 1732 | seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); |
1547 | 1733 | ||
1548 | seq_printf(s, "VP_CLK\t\t%lu\n" | ||
1549 | "VP_PCLK\t\t%lu\n", | ||
1550 | dispc_lclk_rate(OMAP_DSS_CHANNEL_LCD), | ||
1551 | dispc_pclk_rate(OMAP_DSS_CHANNEL_LCD)); | ||
1552 | |||
1553 | enable_clocks(0); | 1734 | enable_clocks(0); |
1554 | } | 1735 | } |
1555 | 1736 | ||
1737 | void dsi_dump_clocks(struct seq_file *s) | ||
1738 | { | ||
1739 | struct platform_device *dsidev; | ||
1740 | int i; | ||
1741 | |||
1742 | for (i = 0; i < MAX_NUM_DSI; i++) { | ||
1743 | dsidev = dsi_get_dsidev_from_id(i); | ||
1744 | if (dsidev) | ||
1745 | dsi_dump_dsidev_clocks(dsidev, s); | ||
1746 | } | ||
1747 | } | ||
1748 | |||
1556 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | 1749 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
1557 | void dsi_dump_irqs(struct seq_file *s) | 1750 | static void dsi_dump_dsidev_irqs(struct platform_device *dsidev, |
1751 | struct seq_file *s) | ||
1558 | { | 1752 | { |
1753 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1559 | unsigned long flags; | 1754 | unsigned long flags; |
1560 | struct dsi_irq_stats stats; | 1755 | struct dsi_irq_stats stats; |
1756 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
1561 | 1757 | ||
1562 | spin_lock_irqsave(&dsi.irq_stats_lock, flags); | 1758 | spin_lock_irqsave(&dsi->irq_stats_lock, flags); |
1563 | 1759 | ||
1564 | stats = dsi.irq_stats; | 1760 | stats = dsi->irq_stats; |
1565 | memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats)); | 1761 | memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats)); |
1566 | dsi.irq_stats.last_reset = jiffies; | 1762 | dsi->irq_stats.last_reset = jiffies; |
1567 | 1763 | ||
1568 | spin_unlock_irqrestore(&dsi.irq_stats_lock, flags); | 1764 | spin_unlock_irqrestore(&dsi->irq_stats_lock, flags); |
1569 | 1765 | ||
1570 | seq_printf(s, "period %u ms\n", | 1766 | seq_printf(s, "period %u ms\n", |
1571 | jiffies_to_msecs(jiffies - stats.last_reset)); | 1767 | jiffies_to_msecs(jiffies - stats.last_reset)); |
@@ -1574,7 +1770,7 @@ void dsi_dump_irqs(struct seq_file *s) | |||
1574 | #define PIS(x) \ | 1770 | #define PIS(x) \ |
1575 | seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); | 1771 | seq_printf(s, "%-20s %10d\n", #x, stats.dsi_irqs[ffs(DSI_IRQ_##x)-1]); |
1576 | 1772 | ||
1577 | seq_printf(s, "-- DSI interrupts --\n"); | 1773 | seq_printf(s, "-- DSI%d interrupts --\n", dsi_module + 1); |
1578 | PIS(VC0); | 1774 | PIS(VC0); |
1579 | PIS(VC1); | 1775 | PIS(VC1); |
1580 | PIS(VC2); | 1776 | PIS(VC2); |
@@ -1640,13 +1836,45 @@ void dsi_dump_irqs(struct seq_file *s) | |||
1640 | PIS(ULPSACTIVENOT_ALL1); | 1836 | PIS(ULPSACTIVENOT_ALL1); |
1641 | #undef PIS | 1837 | #undef PIS |
1642 | } | 1838 | } |
1839 | |||
1840 | static void dsi1_dump_irqs(struct seq_file *s) | ||
1841 | { | ||
1842 | struct platform_device *dsidev = dsi_get_dsidev_from_id(0); | ||
1843 | |||
1844 | dsi_dump_dsidev_irqs(dsidev, s); | ||
1845 | } | ||
1846 | |||
1847 | static void dsi2_dump_irqs(struct seq_file *s) | ||
1848 | { | ||
1849 | struct platform_device *dsidev = dsi_get_dsidev_from_id(1); | ||
1850 | |||
1851 | dsi_dump_dsidev_irqs(dsidev, s); | ||
1852 | } | ||
1853 | |||
1854 | void dsi_create_debugfs_files_irq(struct dentry *debugfs_dir, | ||
1855 | const struct file_operations *debug_fops) | ||
1856 | { | ||
1857 | struct platform_device *dsidev; | ||
1858 | |||
1859 | dsidev = dsi_get_dsidev_from_id(0); | ||
1860 | if (dsidev) | ||
1861 | debugfs_create_file("dsi1_irqs", S_IRUGO, debugfs_dir, | ||
1862 | &dsi1_dump_irqs, debug_fops); | ||
1863 | |||
1864 | dsidev = dsi_get_dsidev_from_id(1); | ||
1865 | if (dsidev) | ||
1866 | debugfs_create_file("dsi2_irqs", S_IRUGO, debugfs_dir, | ||
1867 | &dsi2_dump_irqs, debug_fops); | ||
1868 | } | ||
1643 | #endif | 1869 | #endif |
1644 | 1870 | ||
1645 | void dsi_dump_regs(struct seq_file *s) | 1871 | static void dsi_dump_dsidev_regs(struct platform_device *dsidev, |
1872 | struct seq_file *s) | ||
1646 | { | 1873 | { |
1647 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) | 1874 | #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r)) |
1648 | 1875 | ||
1649 | dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); | 1876 | dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); |
1877 | dsi_enable_scp_clk(dsidev); | ||
1650 | 1878 | ||
1651 | DUMPREG(DSI_REVISION); | 1879 | DUMPREG(DSI_REVISION); |
1652 | DUMPREG(DSI_SYSCONFIG); | 1880 | DUMPREG(DSI_SYSCONFIG); |
@@ -1718,25 +1946,57 @@ void dsi_dump_regs(struct seq_file *s) | |||
1718 | DUMPREG(DSI_PLL_CONFIGURATION1); | 1946 | DUMPREG(DSI_PLL_CONFIGURATION1); |
1719 | DUMPREG(DSI_PLL_CONFIGURATION2); | 1947 | DUMPREG(DSI_PLL_CONFIGURATION2); |
1720 | 1948 | ||
1949 | dsi_disable_scp_clk(dsidev); | ||
1721 | dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); | 1950 | dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); |
1722 | #undef DUMPREG | 1951 | #undef DUMPREG |
1723 | } | 1952 | } |
1724 | 1953 | ||
1725 | enum dsi_complexio_power_state { | 1954 | static void dsi1_dump_regs(struct seq_file *s) |
1955 | { | ||
1956 | struct platform_device *dsidev = dsi_get_dsidev_from_id(0); | ||
1957 | |||
1958 | dsi_dump_dsidev_regs(dsidev, s); | ||
1959 | } | ||
1960 | |||
1961 | static void dsi2_dump_regs(struct seq_file *s) | ||
1962 | { | ||
1963 | struct platform_device *dsidev = dsi_get_dsidev_from_id(1); | ||
1964 | |||
1965 | dsi_dump_dsidev_regs(dsidev, s); | ||
1966 | } | ||
1967 | |||
1968 | void dsi_create_debugfs_files_reg(struct dentry *debugfs_dir, | ||
1969 | const struct file_operations *debug_fops) | ||
1970 | { | ||
1971 | struct platform_device *dsidev; | ||
1972 | |||
1973 | dsidev = dsi_get_dsidev_from_id(0); | ||
1974 | if (dsidev) | ||
1975 | debugfs_create_file("dsi1_regs", S_IRUGO, debugfs_dir, | ||
1976 | &dsi1_dump_regs, debug_fops); | ||
1977 | |||
1978 | dsidev = dsi_get_dsidev_from_id(1); | ||
1979 | if (dsidev) | ||
1980 | debugfs_create_file("dsi2_regs", S_IRUGO, debugfs_dir, | ||
1981 | &dsi2_dump_regs, debug_fops); | ||
1982 | } | ||
1983 | enum dsi_cio_power_state { | ||
1726 | DSI_COMPLEXIO_POWER_OFF = 0x0, | 1984 | DSI_COMPLEXIO_POWER_OFF = 0x0, |
1727 | DSI_COMPLEXIO_POWER_ON = 0x1, | 1985 | DSI_COMPLEXIO_POWER_ON = 0x1, |
1728 | DSI_COMPLEXIO_POWER_ULPS = 0x2, | 1986 | DSI_COMPLEXIO_POWER_ULPS = 0x2, |
1729 | }; | 1987 | }; |
1730 | 1988 | ||
1731 | static int dsi_complexio_power(enum dsi_complexio_power_state state) | 1989 | static int dsi_cio_power(struct platform_device *dsidev, |
1990 | enum dsi_cio_power_state state) | ||
1732 | { | 1991 | { |
1733 | int t = 0; | 1992 | int t = 0; |
1734 | 1993 | ||
1735 | /* PWR_CMD */ | 1994 | /* PWR_CMD */ |
1736 | REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27); | 1995 | REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG1, state, 28, 27); |
1737 | 1996 | ||
1738 | /* PWR_STATUS */ | 1997 | /* PWR_STATUS */ |
1739 | while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { | 1998 | while (FLD_GET(dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1), |
1999 | 26, 25) != state) { | ||
1740 | if (++t > 1000) { | 2000 | if (++t > 1000) { |
1741 | DSSERR("failed to set complexio power state to " | 2001 | DSSERR("failed to set complexio power state to " |
1742 | "%d\n", state); | 2002 | "%d\n", state); |
@@ -1748,9 +2008,70 @@ static int dsi_complexio_power(enum dsi_complexio_power_state state) | |||
1748 | return 0; | 2008 | return 0; |
1749 | } | 2009 | } |
1750 | 2010 | ||
1751 | static void dsi_complexio_config(struct omap_dss_device *dssdev) | 2011 | /* Number of data lanes present on DSI interface */ |
2012 | static inline int dsi_get_num_data_lanes(struct platform_device *dsidev) | ||
2013 | { | ||
2014 | /* DSI on OMAP3 doesn't have register DSI_GNQ, set number | ||
2015 | * of data lanes as 2 by default */ | ||
2016 | if (dss_has_feature(FEAT_DSI_GNQ)) | ||
2017 | return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */ | ||
2018 | else | ||
2019 | return 2; | ||
2020 | } | ||
2021 | |||
2022 | /* Number of data lanes used by the dss device */ | ||
2023 | static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev) | ||
2024 | { | ||
2025 | int num_data_lanes = 0; | ||
2026 | |||
2027 | if (dssdev->phy.dsi.data1_lane != 0) | ||
2028 | num_data_lanes++; | ||
2029 | if (dssdev->phy.dsi.data2_lane != 0) | ||
2030 | num_data_lanes++; | ||
2031 | if (dssdev->phy.dsi.data3_lane != 0) | ||
2032 | num_data_lanes++; | ||
2033 | if (dssdev->phy.dsi.data4_lane != 0) | ||
2034 | num_data_lanes++; | ||
2035 | |||
2036 | return num_data_lanes; | ||
2037 | } | ||
2038 | |||
2039 | static unsigned dsi_get_line_buf_size(struct platform_device *dsidev) | ||
2040 | { | ||
2041 | int val; | ||
2042 | |||
2043 | /* line buffer on OMAP3 is 1024 x 24bits */ | ||
2044 | /* XXX: for some reason using full buffer size causes | ||
2045 | * considerable TX slowdown with update sizes that fill the | ||
2046 | * whole buffer */ | ||
2047 | if (!dss_has_feature(FEAT_DSI_GNQ)) | ||
2048 | return 1023 * 3; | ||
2049 | |||
2050 | val = REG_GET(dsidev, DSI_GNQ, 14, 12); /* VP1_LINE_BUFFER_SIZE */ | ||
2051 | |||
2052 | switch (val) { | ||
2053 | case 1: | ||
2054 | return 512 * 3; /* 512x24 bits */ | ||
2055 | case 2: | ||
2056 | return 682 * 3; /* 682x24 bits */ | ||
2057 | case 3: | ||
2058 | return 853 * 3; /* 853x24 bits */ | ||
2059 | case 4: | ||
2060 | return 1024 * 3; /* 1024x24 bits */ | ||
2061 | case 5: | ||
2062 | return 1194 * 3; /* 1194x24 bits */ | ||
2063 | case 6: | ||
2064 | return 1365 * 3; /* 1365x24 bits */ | ||
2065 | default: | ||
2066 | BUG(); | ||
2067 | } | ||
2068 | } | ||
2069 | |||
2070 | static void dsi_set_lane_config(struct omap_dss_device *dssdev) | ||
1752 | { | 2071 | { |
2072 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
1753 | u32 r; | 2073 | u32 r; |
2074 | int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev); | ||
1754 | 2075 | ||
1755 | int clk_lane = dssdev->phy.dsi.clk_lane; | 2076 | int clk_lane = dssdev->phy.dsi.clk_lane; |
1756 | int data1_lane = dssdev->phy.dsi.data1_lane; | 2077 | int data1_lane = dssdev->phy.dsi.data1_lane; |
@@ -1759,14 +2080,28 @@ static void dsi_complexio_config(struct omap_dss_device *dssdev) | |||
1759 | int data1_pol = dssdev->phy.dsi.data1_pol; | 2080 | int data1_pol = dssdev->phy.dsi.data1_pol; |
1760 | int data2_pol = dssdev->phy.dsi.data2_pol; | 2081 | int data2_pol = dssdev->phy.dsi.data2_pol; |
1761 | 2082 | ||
1762 | r = dsi_read_reg(DSI_COMPLEXIO_CFG1); | 2083 | r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1); |
1763 | r = FLD_MOD(r, clk_lane, 2, 0); | 2084 | r = FLD_MOD(r, clk_lane, 2, 0); |
1764 | r = FLD_MOD(r, clk_pol, 3, 3); | 2085 | r = FLD_MOD(r, clk_pol, 3, 3); |
1765 | r = FLD_MOD(r, data1_lane, 6, 4); | 2086 | r = FLD_MOD(r, data1_lane, 6, 4); |
1766 | r = FLD_MOD(r, data1_pol, 7, 7); | 2087 | r = FLD_MOD(r, data1_pol, 7, 7); |
1767 | r = FLD_MOD(r, data2_lane, 10, 8); | 2088 | r = FLD_MOD(r, data2_lane, 10, 8); |
1768 | r = FLD_MOD(r, data2_pol, 11, 11); | 2089 | r = FLD_MOD(r, data2_pol, 11, 11); |
1769 | dsi_write_reg(DSI_COMPLEXIO_CFG1, r); | 2090 | if (num_data_lanes_dssdev > 2) { |
2091 | int data3_lane = dssdev->phy.dsi.data3_lane; | ||
2092 | int data3_pol = dssdev->phy.dsi.data3_pol; | ||
2093 | |||
2094 | r = FLD_MOD(r, data3_lane, 14, 12); | ||
2095 | r = FLD_MOD(r, data3_pol, 15, 15); | ||
2096 | } | ||
2097 | if (num_data_lanes_dssdev > 3) { | ||
2098 | int data4_lane = dssdev->phy.dsi.data4_lane; | ||
2099 | int data4_pol = dssdev->phy.dsi.data4_pol; | ||
2100 | |||
2101 | r = FLD_MOD(r, data4_lane, 18, 16); | ||
2102 | r = FLD_MOD(r, data4_pol, 19, 19); | ||
2103 | } | ||
2104 | dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r); | ||
1770 | 2105 | ||
1771 | /* The configuration of the DSI complex I/O (number of data lanes, | 2106 | /* The configuration of the DSI complex I/O (number of data lanes, |
1772 | position, differential order) should not be changed while | 2107 | position, differential order) should not be changed while |
@@ -1780,27 +2115,31 @@ static void dsi_complexio_config(struct omap_dss_device *dssdev) | |||
1780 | DSI complex I/O configuration is unknown. */ | 2115 | DSI complex I/O configuration is unknown. */ |
1781 | 2116 | ||
1782 | /* | 2117 | /* |
1783 | REG_FLD_MOD(DSI_CTRL, 1, 0, 0); | 2118 | REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0); |
1784 | REG_FLD_MOD(DSI_CTRL, 0, 0, 0); | 2119 | REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0); |
1785 | REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); | 2120 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); |
1786 | REG_FLD_MOD(DSI_CTRL, 1, 0, 0); | 2121 | REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0); |
1787 | */ | 2122 | */ |
1788 | } | 2123 | } |
1789 | 2124 | ||
1790 | static inline unsigned ns2ddr(unsigned ns) | 2125 | static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns) |
1791 | { | 2126 | { |
2127 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2128 | |||
1792 | /* convert time in ns to ddr ticks, rounding up */ | 2129 | /* convert time in ns to ddr ticks, rounding up */ |
1793 | unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; | 2130 | unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; |
1794 | return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; | 2131 | return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; |
1795 | } | 2132 | } |
1796 | 2133 | ||
1797 | static inline unsigned ddr2ns(unsigned ddr) | 2134 | static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr) |
1798 | { | 2135 | { |
1799 | unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; | 2136 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2137 | |||
2138 | unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; | ||
1800 | return ddr * 1000 * 1000 / (ddr_clk / 1000); | 2139 | return ddr * 1000 * 1000 / (ddr_clk / 1000); |
1801 | } | 2140 | } |
1802 | 2141 | ||
1803 | static void dsi_complexio_timings(void) | 2142 | static void dsi_cio_timings(struct platform_device *dsidev) |
1804 | { | 2143 | { |
1805 | u32 r; | 2144 | u32 r; |
1806 | u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit; | 2145 | u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit; |
@@ -1812,139 +2151,323 @@ static void dsi_complexio_timings(void) | |||
1812 | /* 1 * DDR_CLK = 2 * UI */ | 2151 | /* 1 * DDR_CLK = 2 * UI */ |
1813 | 2152 | ||
1814 | /* min 40ns + 4*UI max 85ns + 6*UI */ | 2153 | /* min 40ns + 4*UI max 85ns + 6*UI */ |
1815 | ths_prepare = ns2ddr(70) + 2; | 2154 | ths_prepare = ns2ddr(dsidev, 70) + 2; |
1816 | 2155 | ||
1817 | /* min 145ns + 10*UI */ | 2156 | /* min 145ns + 10*UI */ |
1818 | ths_prepare_ths_zero = ns2ddr(175) + 2; | 2157 | ths_prepare_ths_zero = ns2ddr(dsidev, 175) + 2; |
1819 | 2158 | ||
1820 | /* min max(8*UI, 60ns+4*UI) */ | 2159 | /* min max(8*UI, 60ns+4*UI) */ |
1821 | ths_trail = ns2ddr(60) + 5; | 2160 | ths_trail = ns2ddr(dsidev, 60) + 5; |
1822 | 2161 | ||
1823 | /* min 100ns */ | 2162 | /* min 100ns */ |
1824 | ths_exit = ns2ddr(145); | 2163 | ths_exit = ns2ddr(dsidev, 145); |
1825 | 2164 | ||
1826 | /* tlpx min 50n */ | 2165 | /* tlpx min 50n */ |
1827 | tlpx_half = ns2ddr(25); | 2166 | tlpx_half = ns2ddr(dsidev, 25); |
1828 | 2167 | ||
1829 | /* min 60ns */ | 2168 | /* min 60ns */ |
1830 | tclk_trail = ns2ddr(60) + 2; | 2169 | tclk_trail = ns2ddr(dsidev, 60) + 2; |
1831 | 2170 | ||
1832 | /* min 38ns, max 95ns */ | 2171 | /* min 38ns, max 95ns */ |
1833 | tclk_prepare = ns2ddr(65); | 2172 | tclk_prepare = ns2ddr(dsidev, 65); |
1834 | 2173 | ||
1835 | /* min tclk-prepare + tclk-zero = 300ns */ | 2174 | /* min tclk-prepare + tclk-zero = 300ns */ |
1836 | tclk_zero = ns2ddr(260); | 2175 | tclk_zero = ns2ddr(dsidev, 260); |
1837 | 2176 | ||
1838 | DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n", | 2177 | DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n", |
1839 | ths_prepare, ddr2ns(ths_prepare), | 2178 | ths_prepare, ddr2ns(dsidev, ths_prepare), |
1840 | ths_prepare_ths_zero, ddr2ns(ths_prepare_ths_zero)); | 2179 | ths_prepare_ths_zero, ddr2ns(dsidev, ths_prepare_ths_zero)); |
1841 | DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n", | 2180 | DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n", |
1842 | ths_trail, ddr2ns(ths_trail), | 2181 | ths_trail, ddr2ns(dsidev, ths_trail), |
1843 | ths_exit, ddr2ns(ths_exit)); | 2182 | ths_exit, ddr2ns(dsidev, ths_exit)); |
1844 | 2183 | ||
1845 | DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), " | 2184 | DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), " |
1846 | "tclk_zero %u (%uns)\n", | 2185 | "tclk_zero %u (%uns)\n", |
1847 | tlpx_half, ddr2ns(tlpx_half), | 2186 | tlpx_half, ddr2ns(dsidev, tlpx_half), |
1848 | tclk_trail, ddr2ns(tclk_trail), | 2187 | tclk_trail, ddr2ns(dsidev, tclk_trail), |
1849 | tclk_zero, ddr2ns(tclk_zero)); | 2188 | tclk_zero, ddr2ns(dsidev, tclk_zero)); |
1850 | DSSDBG("tclk_prepare %u (%uns)\n", | 2189 | DSSDBG("tclk_prepare %u (%uns)\n", |
1851 | tclk_prepare, ddr2ns(tclk_prepare)); | 2190 | tclk_prepare, ddr2ns(dsidev, tclk_prepare)); |
1852 | 2191 | ||
1853 | /* program timings */ | 2192 | /* program timings */ |
1854 | 2193 | ||
1855 | r = dsi_read_reg(DSI_DSIPHY_CFG0); | 2194 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0); |
1856 | r = FLD_MOD(r, ths_prepare, 31, 24); | 2195 | r = FLD_MOD(r, ths_prepare, 31, 24); |
1857 | r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16); | 2196 | r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16); |
1858 | r = FLD_MOD(r, ths_trail, 15, 8); | 2197 | r = FLD_MOD(r, ths_trail, 15, 8); |
1859 | r = FLD_MOD(r, ths_exit, 7, 0); | 2198 | r = FLD_MOD(r, ths_exit, 7, 0); |
1860 | dsi_write_reg(DSI_DSIPHY_CFG0, r); | 2199 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r); |
1861 | 2200 | ||
1862 | r = dsi_read_reg(DSI_DSIPHY_CFG1); | 2201 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); |
1863 | r = FLD_MOD(r, tlpx_half, 22, 16); | 2202 | r = FLD_MOD(r, tlpx_half, 22, 16); |
1864 | r = FLD_MOD(r, tclk_trail, 15, 8); | 2203 | r = FLD_MOD(r, tclk_trail, 15, 8); |
1865 | r = FLD_MOD(r, tclk_zero, 7, 0); | 2204 | r = FLD_MOD(r, tclk_zero, 7, 0); |
1866 | dsi_write_reg(DSI_DSIPHY_CFG1, r); | 2205 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r); |
1867 | 2206 | ||
1868 | r = dsi_read_reg(DSI_DSIPHY_CFG2); | 2207 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); |
1869 | r = FLD_MOD(r, tclk_prepare, 7, 0); | 2208 | r = FLD_MOD(r, tclk_prepare, 7, 0); |
1870 | dsi_write_reg(DSI_DSIPHY_CFG2, r); | 2209 | dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r); |
2210 | } | ||
2211 | |||
2212 | static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev, | ||
2213 | enum dsi_lane lanes) | ||
2214 | { | ||
2215 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2216 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2217 | int clk_lane = dssdev->phy.dsi.clk_lane; | ||
2218 | int data1_lane = dssdev->phy.dsi.data1_lane; | ||
2219 | int data2_lane = dssdev->phy.dsi.data2_lane; | ||
2220 | int data3_lane = dssdev->phy.dsi.data3_lane; | ||
2221 | int data4_lane = dssdev->phy.dsi.data4_lane; | ||
2222 | int clk_pol = dssdev->phy.dsi.clk_pol; | ||
2223 | int data1_pol = dssdev->phy.dsi.data1_pol; | ||
2224 | int data2_pol = dssdev->phy.dsi.data2_pol; | ||
2225 | int data3_pol = dssdev->phy.dsi.data3_pol; | ||
2226 | int data4_pol = dssdev->phy.dsi.data4_pol; | ||
2227 | |||
2228 | u32 l = 0; | ||
2229 | u8 lptxscp_start = dsi->num_data_lanes == 2 ? 22 : 26; | ||
2230 | |||
2231 | if (lanes & DSI_CLK_P) | ||
2232 | l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1)); | ||
2233 | if (lanes & DSI_CLK_N) | ||
2234 | l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 1 : 0)); | ||
2235 | |||
2236 | if (lanes & DSI_DATA1_P) | ||
2237 | l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 0 : 1)); | ||
2238 | if (lanes & DSI_DATA1_N) | ||
2239 | l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 1 : 0)); | ||
2240 | |||
2241 | if (lanes & DSI_DATA2_P) | ||
2242 | l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 0 : 1)); | ||
2243 | if (lanes & DSI_DATA2_N) | ||
2244 | l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0)); | ||
2245 | |||
2246 | if (lanes & DSI_DATA3_P) | ||
2247 | l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1)); | ||
2248 | if (lanes & DSI_DATA3_N) | ||
2249 | l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0)); | ||
2250 | |||
2251 | if (lanes & DSI_DATA4_P) | ||
2252 | l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1)); | ||
2253 | if (lanes & DSI_DATA4_N) | ||
2254 | l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0)); | ||
2255 | /* | ||
2256 | * Bits in REGLPTXSCPDAT4TO0DXDY: | ||
2257 | * 17: DY0 18: DX0 | ||
2258 | * 19: DY1 20: DX1 | ||
2259 | * 21: DY2 22: DX2 | ||
2260 | * 23: DY3 24: DX3 | ||
2261 | * 25: DY4 26: DX4 | ||
2262 | */ | ||
2263 | |||
2264 | /* Set the lane override configuration */ | ||
2265 | |||
2266 | /* REGLPTXSCPDAT4TO0DXDY */ | ||
2267 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, l, lptxscp_start, 17); | ||
2268 | |||
2269 | /* Enable lane override */ | ||
2270 | |||
2271 | /* ENLPTXSCPDAT */ | ||
2272 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 1, 27, 27); | ||
1871 | } | 2273 | } |
1872 | 2274 | ||
2275 | static void dsi_cio_disable_lane_override(struct platform_device *dsidev) | ||
2276 | { | ||
2277 | /* Disable lane override */ | ||
2278 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 27, 27); /* ENLPTXSCPDAT */ | ||
2279 | /* Reset the lane override configuration */ | ||
2280 | /* REGLPTXSCPDAT4TO0DXDY */ | ||
2281 | REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17); | ||
2282 | } | ||
1873 | 2283 | ||
1874 | static int dsi_complexio_init(struct omap_dss_device *dssdev) | 2284 | static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) |
1875 | { | 2285 | { |
1876 | int r = 0; | 2286 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
2287 | int t; | ||
2288 | int bits[3]; | ||
2289 | bool in_use[3]; | ||
2290 | |||
2291 | if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) { | ||
2292 | bits[0] = 28; | ||
2293 | bits[1] = 27; | ||
2294 | bits[2] = 26; | ||
2295 | } else { | ||
2296 | bits[0] = 24; | ||
2297 | bits[1] = 25; | ||
2298 | bits[2] = 26; | ||
2299 | } | ||
2300 | |||
2301 | in_use[0] = false; | ||
2302 | in_use[1] = false; | ||
2303 | in_use[2] = false; | ||
2304 | |||
2305 | if (dssdev->phy.dsi.clk_lane != 0) | ||
2306 | in_use[dssdev->phy.dsi.clk_lane - 1] = true; | ||
2307 | if (dssdev->phy.dsi.data1_lane != 0) | ||
2308 | in_use[dssdev->phy.dsi.data1_lane - 1] = true; | ||
2309 | if (dssdev->phy.dsi.data2_lane != 0) | ||
2310 | in_use[dssdev->phy.dsi.data2_lane - 1] = true; | ||
2311 | |||
2312 | t = 100000; | ||
2313 | while (true) { | ||
2314 | u32 l; | ||
2315 | int i; | ||
2316 | int ok; | ||
2317 | |||
2318 | l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); | ||
2319 | |||
2320 | ok = 0; | ||
2321 | for (i = 0; i < 3; ++i) { | ||
2322 | if (!in_use[i] || (l & (1 << bits[i]))) | ||
2323 | ok++; | ||
2324 | } | ||
2325 | |||
2326 | if (ok == 3) | ||
2327 | break; | ||
2328 | |||
2329 | if (--t == 0) { | ||
2330 | for (i = 0; i < 3; ++i) { | ||
2331 | if (!in_use[i] || (l & (1 << bits[i]))) | ||
2332 | continue; | ||
2333 | |||
2334 | DSSERR("CIO TXCLKESC%d domain not coming " \ | ||
2335 | "out of reset\n", i); | ||
2336 | } | ||
2337 | return -EIO; | ||
2338 | } | ||
2339 | } | ||
2340 | |||
2341 | return 0; | ||
2342 | } | ||
2343 | |||
2344 | static int dsi_cio_init(struct omap_dss_device *dssdev) | ||
2345 | { | ||
2346 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2347 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2348 | int r; | ||
2349 | int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev); | ||
2350 | u32 l; | ||
1877 | 2351 | ||
1878 | DSSDBG("dsi_complexio_init\n"); | 2352 | DSSDBGF(); |
2353 | |||
2354 | if (dsi->dsi_mux_pads) | ||
2355 | dsi->dsi_mux_pads(true); | ||
1879 | 2356 | ||
1880 | /* CIO_CLK_ICG, enable L3 clk to CIO */ | 2357 | dsi_enable_scp_clk(dsidev); |
1881 | REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); | ||
1882 | 2358 | ||
1883 | /* A dummy read using the SCP interface to any DSIPHY register is | 2359 | /* A dummy read using the SCP interface to any DSIPHY register is |
1884 | * required after DSIPHY reset to complete the reset of the DSI complex | 2360 | * required after DSIPHY reset to complete the reset of the DSI complex |
1885 | * I/O. */ | 2361 | * I/O. */ |
1886 | dsi_read_reg(DSI_DSIPHY_CFG5); | 2362 | dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); |
1887 | 2363 | ||
1888 | if (wait_for_bit_change(DSI_DSIPHY_CFG5, 30, 1) != 1) { | 2364 | if (wait_for_bit_change(dsidev, DSI_DSIPHY_CFG5, 30, 1) != 1) { |
1889 | DSSERR("ComplexIO PHY not coming out of reset.\n"); | 2365 | DSSERR("CIO SCP Clock domain not coming out of reset.\n"); |
1890 | r = -ENODEV; | 2366 | r = -EIO; |
1891 | goto err; | 2367 | goto err_scp_clk_dom; |
1892 | } | 2368 | } |
1893 | 2369 | ||
1894 | dsi_complexio_config(dssdev); | 2370 | dsi_set_lane_config(dssdev); |
2371 | |||
2372 | /* set TX STOP MODE timer to maximum for this operation */ | ||
2373 | l = dsi_read_reg(dsidev, DSI_TIMING1); | ||
2374 | l = FLD_MOD(l, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ | ||
2375 | l = FLD_MOD(l, 1, 14, 14); /* STOP_STATE_X16_IO */ | ||
2376 | l = FLD_MOD(l, 1, 13, 13); /* STOP_STATE_X4_IO */ | ||
2377 | l = FLD_MOD(l, 0x1fff, 12, 0); /* STOP_STATE_COUNTER_IO */ | ||
2378 | dsi_write_reg(dsidev, DSI_TIMING1, l); | ||
2379 | |||
2380 | if (dsi->ulps_enabled) { | ||
2381 | u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P; | ||
2382 | |||
2383 | DSSDBG("manual ulps exit\n"); | ||
1895 | 2384 | ||
1896 | r = dsi_complexio_power(DSI_COMPLEXIO_POWER_ON); | 2385 | /* ULPS is exited by Mark-1 state for 1ms, followed by |
2386 | * stop state. DSS HW cannot do this via the normal | ||
2387 | * ULPS exit sequence, as after reset the DSS HW thinks | ||
2388 | * that we are not in ULPS mode, and refuses to send the | ||
2389 | * sequence. So we need to send the ULPS exit sequence | ||
2390 | * manually. | ||
2391 | */ | ||
1897 | 2392 | ||
2393 | if (num_data_lanes_dssdev > 2) | ||
2394 | lane_mask |= DSI_DATA3_P; | ||
2395 | |||
2396 | if (num_data_lanes_dssdev > 3) | ||
2397 | lane_mask |= DSI_DATA4_P; | ||
2398 | |||
2399 | dsi_cio_enable_lane_override(dssdev, lane_mask); | ||
2400 | } | ||
2401 | |||
2402 | r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON); | ||
1898 | if (r) | 2403 | if (r) |
1899 | goto err; | 2404 | goto err_cio_pwr; |
1900 | 2405 | ||
1901 | if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 29, 1) != 1) { | 2406 | if (wait_for_bit_change(dsidev, DSI_COMPLEXIO_CFG1, 29, 1) != 1) { |
1902 | DSSERR("ComplexIO not coming out of reset.\n"); | 2407 | DSSERR("CIO PWR clock domain not coming out of reset.\n"); |
1903 | r = -ENODEV; | 2408 | r = -ENODEV; |
1904 | goto err; | 2409 | goto err_cio_pwr_dom; |
1905 | } | 2410 | } |
1906 | 2411 | ||
1907 | if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) { | 2412 | dsi_if_enable(dsidev, true); |
1908 | DSSERR("ComplexIO LDO power down.\n"); | 2413 | dsi_if_enable(dsidev, false); |
1909 | r = -ENODEV; | 2414 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ |
1910 | goto err; | 2415 | |
2416 | r = dsi_cio_wait_tx_clk_esc_reset(dssdev); | ||
2417 | if (r) | ||
2418 | goto err_tx_clk_esc_rst; | ||
2419 | |||
2420 | if (dsi->ulps_enabled) { | ||
2421 | /* Keep Mark-1 state for 1ms (as per DSI spec) */ | ||
2422 | ktime_t wait = ns_to_ktime(1000 * 1000); | ||
2423 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2424 | schedule_hrtimeout(&wait, HRTIMER_MODE_REL); | ||
2425 | |||
2426 | /* Disable the override. The lanes should be set to Mark-11 | ||
2427 | * state by the HW */ | ||
2428 | dsi_cio_disable_lane_override(dsidev); | ||
1911 | } | 2429 | } |
1912 | 2430 | ||
1913 | dsi_complexio_timings(); | 2431 | /* FORCE_TX_STOP_MODE_IO */ |
2432 | REG_FLD_MOD(dsidev, DSI_TIMING1, 0, 15, 15); | ||
1914 | 2433 | ||
1915 | /* | 2434 | dsi_cio_timings(dsidev); |
1916 | The configuration of the DSI complex I/O (number of data lanes, | 2435 | |
1917 | position, differential order) should not be changed while | 2436 | dsi->ulps_enabled = false; |
1918 | DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. For the | ||
1919 | hardware to recognize a new configuration of the complex I/O (done | ||
1920 | in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to follow | ||
1921 | this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, next | ||
1922 | reset the DSS.DSI_CTRL[0] IF_EN to 0, then set DSS.DSI_CLK_CTRL[20] | ||
1923 | LP_CLK_ENABLE to 1, and finally, set again the DSS.DSI_CTRL[0] IF_EN | ||
1924 | bit to 1. If the sequence is not followed, the DSi complex I/O | ||
1925 | configuration is undetermined. | ||
1926 | */ | ||
1927 | dsi_if_enable(1); | ||
1928 | dsi_if_enable(0); | ||
1929 | REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */ | ||
1930 | dsi_if_enable(1); | ||
1931 | dsi_if_enable(0); | ||
1932 | 2437 | ||
1933 | DSSDBG("CIO init done\n"); | 2438 | DSSDBG("CIO init done\n"); |
1934 | err: | 2439 | |
2440 | return 0; | ||
2441 | |||
2442 | err_tx_clk_esc_rst: | ||
2443 | REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 20, 20); /* LP_CLK_ENABLE */ | ||
2444 | err_cio_pwr_dom: | ||
2445 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); | ||
2446 | err_cio_pwr: | ||
2447 | if (dsi->ulps_enabled) | ||
2448 | dsi_cio_disable_lane_override(dsidev); | ||
2449 | err_scp_clk_dom: | ||
2450 | dsi_disable_scp_clk(dsidev); | ||
2451 | if (dsi->dsi_mux_pads) | ||
2452 | dsi->dsi_mux_pads(false); | ||
1935 | return r; | 2453 | return r; |
1936 | } | 2454 | } |
1937 | 2455 | ||
1938 | static void dsi_complexio_uninit(void) | 2456 | static void dsi_cio_uninit(struct platform_device *dsidev) |
1939 | { | 2457 | { |
1940 | dsi_complexio_power(DSI_COMPLEXIO_POWER_OFF); | 2458 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2459 | |||
2460 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); | ||
2461 | dsi_disable_scp_clk(dsidev); | ||
2462 | if (dsi->dsi_mux_pads) | ||
2463 | dsi->dsi_mux_pads(false); | ||
1941 | } | 2464 | } |
1942 | 2465 | ||
1943 | static int _dsi_wait_reset(void) | 2466 | static int _dsi_wait_reset(struct platform_device *dsidev) |
1944 | { | 2467 | { |
1945 | int t = 0; | 2468 | int t = 0; |
1946 | 2469 | ||
1947 | while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) { | 2470 | while (REG_GET(dsidev, DSI_SYSSTATUS, 0, 0) == 0) { |
1948 | if (++t > 5) { | 2471 | if (++t > 5) { |
1949 | DSSERR("soft reset failed\n"); | 2472 | DSSERR("soft reset failed\n"); |
1950 | return -ENODEV; | 2473 | return -ENODEV; |
@@ -1955,28 +2478,30 @@ static int _dsi_wait_reset(void) | |||
1955 | return 0; | 2478 | return 0; |
1956 | } | 2479 | } |
1957 | 2480 | ||
1958 | static int _dsi_reset(void) | 2481 | static int _dsi_reset(struct platform_device *dsidev) |
1959 | { | 2482 | { |
1960 | /* Soft reset */ | 2483 | /* Soft reset */ |
1961 | REG_FLD_MOD(DSI_SYSCONFIG, 1, 1, 1); | 2484 | REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 1, 1); |
1962 | return _dsi_wait_reset(); | 2485 | return _dsi_wait_reset(dsidev); |
1963 | } | 2486 | } |
1964 | 2487 | ||
1965 | static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, | 2488 | static void dsi_config_tx_fifo(struct platform_device *dsidev, |
2489 | enum fifo_size size1, enum fifo_size size2, | ||
1966 | enum fifo_size size3, enum fifo_size size4) | 2490 | enum fifo_size size3, enum fifo_size size4) |
1967 | { | 2491 | { |
2492 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1968 | u32 r = 0; | 2493 | u32 r = 0; |
1969 | int add = 0; | 2494 | int add = 0; |
1970 | int i; | 2495 | int i; |
1971 | 2496 | ||
1972 | dsi.vc[0].fifo_size = size1; | 2497 | dsi->vc[0].fifo_size = size1; |
1973 | dsi.vc[1].fifo_size = size2; | 2498 | dsi->vc[1].fifo_size = size2; |
1974 | dsi.vc[2].fifo_size = size3; | 2499 | dsi->vc[2].fifo_size = size3; |
1975 | dsi.vc[3].fifo_size = size4; | 2500 | dsi->vc[3].fifo_size = size4; |
1976 | 2501 | ||
1977 | for (i = 0; i < 4; i++) { | 2502 | for (i = 0; i < 4; i++) { |
1978 | u8 v; | 2503 | u8 v; |
1979 | int size = dsi.vc[i].fifo_size; | 2504 | int size = dsi->vc[i].fifo_size; |
1980 | 2505 | ||
1981 | if (add + size > 4) { | 2506 | if (add + size > 4) { |
1982 | DSSERR("Illegal FIFO configuration\n"); | 2507 | DSSERR("Illegal FIFO configuration\n"); |
@@ -1989,24 +2514,26 @@ static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2, | |||
1989 | add += size; | 2514 | add += size; |
1990 | } | 2515 | } |
1991 | 2516 | ||
1992 | dsi_write_reg(DSI_TX_FIFO_VC_SIZE, r); | 2517 | dsi_write_reg(dsidev, DSI_TX_FIFO_VC_SIZE, r); |
1993 | } | 2518 | } |
1994 | 2519 | ||
1995 | static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2, | 2520 | static void dsi_config_rx_fifo(struct platform_device *dsidev, |
2521 | enum fifo_size size1, enum fifo_size size2, | ||
1996 | enum fifo_size size3, enum fifo_size size4) | 2522 | enum fifo_size size3, enum fifo_size size4) |
1997 | { | 2523 | { |
2524 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
1998 | u32 r = 0; | 2525 | u32 r = 0; |
1999 | int add = 0; | 2526 | int add = 0; |
2000 | int i; | 2527 | int i; |
2001 | 2528 | ||
2002 | dsi.vc[0].fifo_size = size1; | 2529 | dsi->vc[0].fifo_size = size1; |
2003 | dsi.vc[1].fifo_size = size2; | 2530 | dsi->vc[1].fifo_size = size2; |
2004 | dsi.vc[2].fifo_size = size3; | 2531 | dsi->vc[2].fifo_size = size3; |
2005 | dsi.vc[3].fifo_size = size4; | 2532 | dsi->vc[3].fifo_size = size4; |
2006 | 2533 | ||
2007 | for (i = 0; i < 4; i++) { | 2534 | for (i = 0; i < 4; i++) { |
2008 | u8 v; | 2535 | u8 v; |
2009 | int size = dsi.vc[i].fifo_size; | 2536 | int size = dsi->vc[i].fifo_size; |
2010 | 2537 | ||
2011 | if (add + size > 4) { | 2538 | if (add + size > 4) { |
2012 | DSSERR("Illegal FIFO configuration\n"); | 2539 | DSSERR("Illegal FIFO configuration\n"); |
@@ -2019,18 +2546,18 @@ static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2, | |||
2019 | add += size; | 2546 | add += size; |
2020 | } | 2547 | } |
2021 | 2548 | ||
2022 | dsi_write_reg(DSI_RX_FIFO_VC_SIZE, r); | 2549 | dsi_write_reg(dsidev, DSI_RX_FIFO_VC_SIZE, r); |
2023 | } | 2550 | } |
2024 | 2551 | ||
2025 | static int dsi_force_tx_stop_mode_io(void) | 2552 | static int dsi_force_tx_stop_mode_io(struct platform_device *dsidev) |
2026 | { | 2553 | { |
2027 | u32 r; | 2554 | u32 r; |
2028 | 2555 | ||
2029 | r = dsi_read_reg(DSI_TIMING1); | 2556 | r = dsi_read_reg(dsidev, DSI_TIMING1); |
2030 | r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ | 2557 | r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ |
2031 | dsi_write_reg(DSI_TIMING1, r); | 2558 | dsi_write_reg(dsidev, DSI_TIMING1, r); |
2032 | 2559 | ||
2033 | if (wait_for_bit_change(DSI_TIMING1, 15, 0) != 0) { | 2560 | if (wait_for_bit_change(dsidev, DSI_TIMING1, 15, 0) != 0) { |
2034 | DSSERR("TX_STOP bit not going down\n"); | 2561 | DSSERR("TX_STOP bit not going down\n"); |
2035 | return -EIO; | 2562 | return -EIO; |
2036 | } | 2563 | } |
@@ -2038,16 +2565,135 @@ static int dsi_force_tx_stop_mode_io(void) | |||
2038 | return 0; | 2565 | return 0; |
2039 | } | 2566 | } |
2040 | 2567 | ||
2041 | static int dsi_vc_enable(int channel, bool enable) | 2568 | static bool dsi_vc_is_enabled(struct platform_device *dsidev, int channel) |
2569 | { | ||
2570 | return REG_GET(dsidev, DSI_VC_CTRL(channel), 0, 0); | ||
2571 | } | ||
2572 | |||
2573 | static void dsi_packet_sent_handler_vp(void *data, u32 mask) | ||
2574 | { | ||
2575 | struct dsi_packet_sent_handler_data *vp_data = | ||
2576 | (struct dsi_packet_sent_handler_data *) data; | ||
2577 | struct dsi_data *dsi = dsi_get_dsidrv_data(vp_data->dsidev); | ||
2578 | const int channel = dsi->update_channel; | ||
2579 | u8 bit = dsi->te_enabled ? 30 : 31; | ||
2580 | |||
2581 | if (REG_GET(vp_data->dsidev, DSI_VC_TE(channel), bit, bit) == 0) | ||
2582 | complete(vp_data->completion); | ||
2583 | } | ||
2584 | |||
2585 | static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel) | ||
2586 | { | ||
2587 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2588 | DECLARE_COMPLETION_ONSTACK(completion); | ||
2589 | struct dsi_packet_sent_handler_data vp_data = { dsidev, &completion }; | ||
2590 | int r = 0; | ||
2591 | u8 bit; | ||
2592 | |||
2593 | bit = dsi->te_enabled ? 30 : 31; | ||
2594 | |||
2595 | r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp, | ||
2596 | &vp_data, DSI_VC_IRQ_PACKET_SENT); | ||
2597 | if (r) | ||
2598 | goto err0; | ||
2599 | |||
2600 | /* Wait for completion only if TE_EN/TE_START is still set */ | ||
2601 | if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit)) { | ||
2602 | if (wait_for_completion_timeout(&completion, | ||
2603 | msecs_to_jiffies(10)) == 0) { | ||
2604 | DSSERR("Failed to complete previous frame transfer\n"); | ||
2605 | r = -EIO; | ||
2606 | goto err1; | ||
2607 | } | ||
2608 | } | ||
2609 | |||
2610 | dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp, | ||
2611 | &vp_data, DSI_VC_IRQ_PACKET_SENT); | ||
2612 | |||
2613 | return 0; | ||
2614 | err1: | ||
2615 | dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp, | ||
2616 | &vp_data, DSI_VC_IRQ_PACKET_SENT); | ||
2617 | err0: | ||
2618 | return r; | ||
2619 | } | ||
2620 | |||
2621 | static void dsi_packet_sent_handler_l4(void *data, u32 mask) | ||
2622 | { | ||
2623 | struct dsi_packet_sent_handler_data *l4_data = | ||
2624 | (struct dsi_packet_sent_handler_data *) data; | ||
2625 | struct dsi_data *dsi = dsi_get_dsidrv_data(l4_data->dsidev); | ||
2626 | const int channel = dsi->update_channel; | ||
2627 | |||
2628 | if (REG_GET(l4_data->dsidev, DSI_VC_CTRL(channel), 5, 5) == 0) | ||
2629 | complete(l4_data->completion); | ||
2630 | } | ||
2631 | |||
2632 | static int dsi_sync_vc_l4(struct platform_device *dsidev, int channel) | ||
2633 | { | ||
2634 | DECLARE_COMPLETION_ONSTACK(completion); | ||
2635 | struct dsi_packet_sent_handler_data l4_data = { dsidev, &completion }; | ||
2636 | int r = 0; | ||
2637 | |||
2638 | r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4, | ||
2639 | &l4_data, DSI_VC_IRQ_PACKET_SENT); | ||
2640 | if (r) | ||
2641 | goto err0; | ||
2642 | |||
2643 | /* Wait for completion only if TX_FIFO_NOT_EMPTY is still set */ | ||
2644 | if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5)) { | ||
2645 | if (wait_for_completion_timeout(&completion, | ||
2646 | msecs_to_jiffies(10)) == 0) { | ||
2647 | DSSERR("Failed to complete previous l4 transfer\n"); | ||
2648 | r = -EIO; | ||
2649 | goto err1; | ||
2650 | } | ||
2651 | } | ||
2652 | |||
2653 | dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4, | ||
2654 | &l4_data, DSI_VC_IRQ_PACKET_SENT); | ||
2655 | |||
2656 | return 0; | ||
2657 | err1: | ||
2658 | dsi_unregister_isr_vc(dsidev, channel, dsi_packet_sent_handler_l4, | ||
2659 | &l4_data, DSI_VC_IRQ_PACKET_SENT); | ||
2660 | err0: | ||
2661 | return r; | ||
2662 | } | ||
2663 | |||
2664 | static int dsi_sync_vc(struct platform_device *dsidev, int channel) | ||
2665 | { | ||
2666 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2667 | |||
2668 | WARN_ON(!dsi_bus_is_locked(dsidev)); | ||
2669 | |||
2670 | WARN_ON(in_interrupt()); | ||
2671 | |||
2672 | if (!dsi_vc_is_enabled(dsidev, channel)) | ||
2673 | return 0; | ||
2674 | |||
2675 | switch (dsi->vc[channel].mode) { | ||
2676 | case DSI_VC_MODE_VP: | ||
2677 | return dsi_sync_vc_vp(dsidev, channel); | ||
2678 | case DSI_VC_MODE_L4: | ||
2679 | return dsi_sync_vc_l4(dsidev, channel); | ||
2680 | default: | ||
2681 | BUG(); | ||
2682 | } | ||
2683 | } | ||
2684 | |||
2685 | static int dsi_vc_enable(struct platform_device *dsidev, int channel, | ||
2686 | bool enable) | ||
2042 | { | 2687 | { |
2043 | DSSDBG("dsi_vc_enable channel %d, enable %d\n", | 2688 | DSSDBG("dsi_vc_enable channel %d, enable %d\n", |
2044 | channel, enable); | 2689 | channel, enable); |
2045 | 2690 | ||
2046 | enable = enable ? 1 : 0; | 2691 | enable = enable ? 1 : 0; |
2047 | 2692 | ||
2048 | REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 0, 0); | 2693 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 0, 0); |
2049 | 2694 | ||
2050 | if (wait_for_bit_change(DSI_VC_CTRL(channel), 0, enable) != enable) { | 2695 | if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), |
2696 | 0, enable) != enable) { | ||
2051 | DSSERR("Failed to set dsi_vc_enable to %d\n", enable); | 2697 | DSSERR("Failed to set dsi_vc_enable to %d\n", enable); |
2052 | return -EIO; | 2698 | return -EIO; |
2053 | } | 2699 | } |
@@ -2055,13 +2701,13 @@ static int dsi_vc_enable(int channel, bool enable) | |||
2055 | return 0; | 2701 | return 0; |
2056 | } | 2702 | } |
2057 | 2703 | ||
2058 | static void dsi_vc_initial_config(int channel) | 2704 | static void dsi_vc_initial_config(struct platform_device *dsidev, int channel) |
2059 | { | 2705 | { |
2060 | u32 r; | 2706 | u32 r; |
2061 | 2707 | ||
2062 | DSSDBGF("%d", channel); | 2708 | DSSDBGF("%d", channel); |
2063 | 2709 | ||
2064 | r = dsi_read_reg(DSI_VC_CTRL(channel)); | 2710 | r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel)); |
2065 | 2711 | ||
2066 | if (FLD_GET(r, 15, 15)) /* VC_BUSY */ | 2712 | if (FLD_GET(r, 15, 15)) /* VC_BUSY */ |
2067 | DSSERR("VC(%d) busy when trying to configure it!\n", | 2713 | DSSERR("VC(%d) busy when trying to configure it!\n", |
@@ -2074,85 +2720,107 @@ static void dsi_vc_initial_config(int channel) | |||
2074 | r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */ | 2720 | r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */ |
2075 | r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */ | 2721 | r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */ |
2076 | r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */ | 2722 | r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */ |
2723 | if (dss_has_feature(FEAT_DSI_VC_OCP_WIDTH)) | ||
2724 | r = FLD_MOD(r, 3, 11, 10); /* OCP_WIDTH = 32 bit */ | ||
2077 | 2725 | ||
2078 | r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */ | 2726 | r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */ |
2079 | r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ | 2727 | r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ |
2080 | 2728 | ||
2081 | dsi_write_reg(DSI_VC_CTRL(channel), r); | 2729 | dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r); |
2082 | } | 2730 | } |
2083 | 2731 | ||
2084 | static int dsi_vc_config_l4(int channel) | 2732 | static int dsi_vc_config_l4(struct platform_device *dsidev, int channel) |
2085 | { | 2733 | { |
2086 | if (dsi.vc[channel].mode == DSI_VC_MODE_L4) | 2734 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2735 | |||
2736 | if (dsi->vc[channel].mode == DSI_VC_MODE_L4) | ||
2087 | return 0; | 2737 | return 0; |
2088 | 2738 | ||
2089 | DSSDBGF("%d", channel); | 2739 | DSSDBGF("%d", channel); |
2090 | 2740 | ||
2091 | dsi_vc_enable(channel, 0); | 2741 | dsi_sync_vc(dsidev, channel); |
2742 | |||
2743 | dsi_vc_enable(dsidev, channel, 0); | ||
2092 | 2744 | ||
2093 | /* VC_BUSY */ | 2745 | /* VC_BUSY */ |
2094 | if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) { | 2746 | if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) { |
2095 | DSSERR("vc(%d) busy when trying to config for L4\n", channel); | 2747 | DSSERR("vc(%d) busy when trying to config for L4\n", channel); |
2096 | return -EIO; | 2748 | return -EIO; |
2097 | } | 2749 | } |
2098 | 2750 | ||
2099 | REG_FLD_MOD(DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */ | 2751 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 1, 1); /* SOURCE, 0 = L4 */ |
2100 | 2752 | ||
2101 | dsi_vc_enable(channel, 1); | 2753 | /* DCS_CMD_ENABLE */ |
2754 | if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) | ||
2755 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 30, 30); | ||
2102 | 2756 | ||
2103 | dsi.vc[channel].mode = DSI_VC_MODE_L4; | 2757 | dsi_vc_enable(dsidev, channel, 1); |
2758 | |||
2759 | dsi->vc[channel].mode = DSI_VC_MODE_L4; | ||
2104 | 2760 | ||
2105 | return 0; | 2761 | return 0; |
2106 | } | 2762 | } |
2107 | 2763 | ||
2108 | static int dsi_vc_config_vp(int channel) | 2764 | static int dsi_vc_config_vp(struct platform_device *dsidev, int channel) |
2109 | { | 2765 | { |
2110 | if (dsi.vc[channel].mode == DSI_VC_MODE_VP) | 2766 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2767 | |||
2768 | if (dsi->vc[channel].mode == DSI_VC_MODE_VP) | ||
2111 | return 0; | 2769 | return 0; |
2112 | 2770 | ||
2113 | DSSDBGF("%d", channel); | 2771 | DSSDBGF("%d", channel); |
2114 | 2772 | ||
2115 | dsi_vc_enable(channel, 0); | 2773 | dsi_sync_vc(dsidev, channel); |
2774 | |||
2775 | dsi_vc_enable(dsidev, channel, 0); | ||
2116 | 2776 | ||
2117 | /* VC_BUSY */ | 2777 | /* VC_BUSY */ |
2118 | if (wait_for_bit_change(DSI_VC_CTRL(channel), 15, 0) != 0) { | 2778 | if (wait_for_bit_change(dsidev, DSI_VC_CTRL(channel), 15, 0) != 0) { |
2119 | DSSERR("vc(%d) busy when trying to config for VP\n", channel); | 2779 | DSSERR("vc(%d) busy when trying to config for VP\n", channel); |
2120 | return -EIO; | 2780 | return -EIO; |
2121 | } | 2781 | } |
2122 | 2782 | ||
2123 | REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 1, 1); /* SOURCE, 1 = video port */ | 2783 | /* SOURCE, 1 = video port */ |
2784 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 1, 1); | ||
2124 | 2785 | ||
2125 | dsi_vc_enable(channel, 1); | 2786 | /* DCS_CMD_ENABLE */ |
2787 | if (dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) | ||
2788 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 30, 30); | ||
2126 | 2789 | ||
2127 | dsi.vc[channel].mode = DSI_VC_MODE_VP; | 2790 | dsi_vc_enable(dsidev, channel, 1); |
2791 | |||
2792 | dsi->vc[channel].mode = DSI_VC_MODE_VP; | ||
2128 | 2793 | ||
2129 | return 0; | 2794 | return 0; |
2130 | } | 2795 | } |
2131 | 2796 | ||
2132 | 2797 | ||
2133 | void omapdss_dsi_vc_enable_hs(int channel, bool enable) | 2798 | void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel, |
2799 | bool enable) | ||
2134 | { | 2800 | { |
2801 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2802 | |||
2135 | DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); | 2803 | DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); |
2136 | 2804 | ||
2137 | WARN_ON(!dsi_bus_is_locked()); | 2805 | WARN_ON(!dsi_bus_is_locked(dsidev)); |
2138 | 2806 | ||
2139 | dsi_vc_enable(channel, 0); | 2807 | dsi_vc_enable(dsidev, channel, 0); |
2140 | dsi_if_enable(0); | 2808 | dsi_if_enable(dsidev, 0); |
2141 | 2809 | ||
2142 | REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 9, 9); | 2810 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), enable, 9, 9); |
2143 | 2811 | ||
2144 | dsi_vc_enable(channel, 1); | 2812 | dsi_vc_enable(dsidev, channel, 1); |
2145 | dsi_if_enable(1); | 2813 | dsi_if_enable(dsidev, 1); |
2146 | 2814 | ||
2147 | dsi_force_tx_stop_mode_io(); | 2815 | dsi_force_tx_stop_mode_io(dsidev); |
2148 | } | 2816 | } |
2149 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); | 2817 | EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); |
2150 | 2818 | ||
2151 | static void dsi_vc_flush_long_data(int channel) | 2819 | static void dsi_vc_flush_long_data(struct platform_device *dsidev, int channel) |
2152 | { | 2820 | { |
2153 | while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { | 2821 | while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) { |
2154 | u32 val; | 2822 | u32 val; |
2155 | val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); | 2823 | val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel)); |
2156 | DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n", | 2824 | DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n", |
2157 | (val >> 0) & 0xff, | 2825 | (val >> 0) & 0xff, |
2158 | (val >> 8) & 0xff, | 2826 | (val >> 8) & 0xff, |
@@ -2198,13 +2866,14 @@ static void dsi_show_rx_ack_with_err(u16 err) | |||
2198 | DSSERR("\t\tDSI Protocol Violation\n"); | 2866 | DSSERR("\t\tDSI Protocol Violation\n"); |
2199 | } | 2867 | } |
2200 | 2868 | ||
2201 | static u16 dsi_vc_flush_receive_data(int channel) | 2869 | static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev, |
2870 | int channel) | ||
2202 | { | 2871 | { |
2203 | /* RX_FIFO_NOT_EMPTY */ | 2872 | /* RX_FIFO_NOT_EMPTY */ |
2204 | while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { | 2873 | while (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) { |
2205 | u32 val; | 2874 | u32 val; |
2206 | u8 dt; | 2875 | u8 dt; |
2207 | val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); | 2876 | val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel)); |
2208 | DSSERR("\trawval %#08x\n", val); | 2877 | DSSERR("\trawval %#08x\n", val); |
2209 | dt = FLD_GET(val, 5, 0); | 2878 | dt = FLD_GET(val, 5, 0); |
2210 | if (dt == DSI_DT_RX_ACK_WITH_ERR) { | 2879 | if (dt == DSI_DT_RX_ACK_WITH_ERR) { |
@@ -2219,7 +2888,7 @@ static u16 dsi_vc_flush_receive_data(int channel) | |||
2219 | } else if (dt == DSI_DT_RX_DCS_LONG_READ) { | 2888 | } else if (dt == DSI_DT_RX_DCS_LONG_READ) { |
2220 | DSSERR("\tDCS long response, len %d\n", | 2889 | DSSERR("\tDCS long response, len %d\n", |
2221 | FLD_GET(val, 23, 8)); | 2890 | FLD_GET(val, 23, 8)); |
2222 | dsi_vc_flush_long_data(channel); | 2891 | dsi_vc_flush_long_data(dsidev, channel); |
2223 | } else { | 2892 | } else { |
2224 | DSSERR("\tunknown datatype 0x%02x\n", dt); | 2893 | DSSERR("\tunknown datatype 0x%02x\n", dt); |
2225 | } | 2894 | } |
@@ -2227,40 +2896,44 @@ static u16 dsi_vc_flush_receive_data(int channel) | |||
2227 | return 0; | 2896 | return 0; |
2228 | } | 2897 | } |
2229 | 2898 | ||
2230 | static int dsi_vc_send_bta(int channel) | 2899 | static int dsi_vc_send_bta(struct platform_device *dsidev, int channel) |
2231 | { | 2900 | { |
2232 | if (dsi.debug_write || dsi.debug_read) | 2901 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
2902 | |||
2903 | if (dsi->debug_write || dsi->debug_read) | ||
2233 | DSSDBG("dsi_vc_send_bta %d\n", channel); | 2904 | DSSDBG("dsi_vc_send_bta %d\n", channel); |
2234 | 2905 | ||
2235 | WARN_ON(!dsi_bus_is_locked()); | 2906 | WARN_ON(!dsi_bus_is_locked(dsidev)); |
2236 | 2907 | ||
2237 | if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ | 2908 | /* RX_FIFO_NOT_EMPTY */ |
2909 | if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) { | ||
2238 | DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); | 2910 | DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); |
2239 | dsi_vc_flush_receive_data(channel); | 2911 | dsi_vc_flush_receive_data(dsidev, channel); |
2240 | } | 2912 | } |
2241 | 2913 | ||
2242 | REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */ | 2914 | REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */ |
2243 | 2915 | ||
2244 | return 0; | 2916 | return 0; |
2245 | } | 2917 | } |
2246 | 2918 | ||
2247 | int dsi_vc_send_bta_sync(int channel) | 2919 | int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel) |
2248 | { | 2920 | { |
2921 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2249 | DECLARE_COMPLETION_ONSTACK(completion); | 2922 | DECLARE_COMPLETION_ONSTACK(completion); |
2250 | int r = 0; | 2923 | int r = 0; |
2251 | u32 err; | 2924 | u32 err; |
2252 | 2925 | ||
2253 | r = dsi_register_isr_vc(channel, dsi_completion_handler, | 2926 | r = dsi_register_isr_vc(dsidev, channel, dsi_completion_handler, |
2254 | &completion, DSI_VC_IRQ_BTA); | 2927 | &completion, DSI_VC_IRQ_BTA); |
2255 | if (r) | 2928 | if (r) |
2256 | goto err0; | 2929 | goto err0; |
2257 | 2930 | ||
2258 | r = dsi_register_isr(dsi_completion_handler, &completion, | 2931 | r = dsi_register_isr(dsidev, dsi_completion_handler, &completion, |
2259 | DSI_IRQ_ERROR_MASK); | 2932 | DSI_IRQ_ERROR_MASK); |
2260 | if (r) | 2933 | if (r) |
2261 | goto err1; | 2934 | goto err1; |
2262 | 2935 | ||
2263 | r = dsi_vc_send_bta(channel); | 2936 | r = dsi_vc_send_bta(dsidev, channel); |
2264 | if (r) | 2937 | if (r) |
2265 | goto err2; | 2938 | goto err2; |
2266 | 2939 | ||
@@ -2271,41 +2944,42 @@ int dsi_vc_send_bta_sync(int channel) | |||
2271 | goto err2; | 2944 | goto err2; |
2272 | } | 2945 | } |
2273 | 2946 | ||
2274 | err = dsi_get_errors(); | 2947 | err = dsi_get_errors(dsidev); |
2275 | if (err) { | 2948 | if (err) { |
2276 | DSSERR("Error while sending BTA: %x\n", err); | 2949 | DSSERR("Error while sending BTA: %x\n", err); |
2277 | r = -EIO; | 2950 | r = -EIO; |
2278 | goto err2; | 2951 | goto err2; |
2279 | } | 2952 | } |
2280 | err2: | 2953 | err2: |
2281 | dsi_unregister_isr(dsi_completion_handler, &completion, | 2954 | dsi_unregister_isr(dsidev, dsi_completion_handler, &completion, |
2282 | DSI_IRQ_ERROR_MASK); | 2955 | DSI_IRQ_ERROR_MASK); |
2283 | err1: | 2956 | err1: |
2284 | dsi_unregister_isr_vc(channel, dsi_completion_handler, | 2957 | dsi_unregister_isr_vc(dsidev, channel, dsi_completion_handler, |
2285 | &completion, DSI_VC_IRQ_BTA); | 2958 | &completion, DSI_VC_IRQ_BTA); |
2286 | err0: | 2959 | err0: |
2287 | return r; | 2960 | return r; |
2288 | } | 2961 | } |
2289 | EXPORT_SYMBOL(dsi_vc_send_bta_sync); | 2962 | EXPORT_SYMBOL(dsi_vc_send_bta_sync); |
2290 | 2963 | ||
2291 | static inline void dsi_vc_write_long_header(int channel, u8 data_type, | 2964 | static inline void dsi_vc_write_long_header(struct platform_device *dsidev, |
2292 | u16 len, u8 ecc) | 2965 | int channel, u8 data_type, u16 len, u8 ecc) |
2293 | { | 2966 | { |
2967 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2294 | u32 val; | 2968 | u32 val; |
2295 | u8 data_id; | 2969 | u8 data_id; |
2296 | 2970 | ||
2297 | WARN_ON(!dsi_bus_is_locked()); | 2971 | WARN_ON(!dsi_bus_is_locked(dsidev)); |
2298 | 2972 | ||
2299 | data_id = data_type | dsi.vc[channel].vc_id << 6; | 2973 | data_id = data_type | dsi->vc[channel].vc_id << 6; |
2300 | 2974 | ||
2301 | val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | | 2975 | val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | |
2302 | FLD_VAL(ecc, 31, 24); | 2976 | FLD_VAL(ecc, 31, 24); |
2303 | 2977 | ||
2304 | dsi_write_reg(DSI_VC_LONG_PACKET_HEADER(channel), val); | 2978 | dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_HEADER(channel), val); |
2305 | } | 2979 | } |
2306 | 2980 | ||
2307 | static inline void dsi_vc_write_long_payload(int channel, | 2981 | static inline void dsi_vc_write_long_payload(struct platform_device *dsidev, |
2308 | u8 b1, u8 b2, u8 b3, u8 b4) | 2982 | int channel, u8 b1, u8 b2, u8 b3, u8 b4) |
2309 | { | 2983 | { |
2310 | u32 val; | 2984 | u32 val; |
2311 | 2985 | ||
@@ -2314,34 +2988,35 @@ static inline void dsi_vc_write_long_payload(int channel, | |||
2314 | /* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n", | 2988 | /* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n", |
2315 | b1, b2, b3, b4, val); */ | 2989 | b1, b2, b3, b4, val); */ |
2316 | 2990 | ||
2317 | dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(channel), val); | 2991 | dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(channel), val); |
2318 | } | 2992 | } |
2319 | 2993 | ||
2320 | static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, | 2994 | static int dsi_vc_send_long(struct platform_device *dsidev, int channel, |
2321 | u8 ecc) | 2995 | u8 data_type, u8 *data, u16 len, u8 ecc) |
2322 | { | 2996 | { |
2323 | /*u32 val; */ | 2997 | /*u32 val; */ |
2998 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2324 | int i; | 2999 | int i; |
2325 | u8 *p; | 3000 | u8 *p; |
2326 | int r = 0; | 3001 | int r = 0; |
2327 | u8 b1, b2, b3, b4; | 3002 | u8 b1, b2, b3, b4; |
2328 | 3003 | ||
2329 | if (dsi.debug_write) | 3004 | if (dsi->debug_write) |
2330 | DSSDBG("dsi_vc_send_long, %d bytes\n", len); | 3005 | DSSDBG("dsi_vc_send_long, %d bytes\n", len); |
2331 | 3006 | ||
2332 | /* len + header */ | 3007 | /* len + header */ |
2333 | if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) { | 3008 | if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) { |
2334 | DSSERR("unable to send long packet: packet too long.\n"); | 3009 | DSSERR("unable to send long packet: packet too long.\n"); |
2335 | return -EINVAL; | 3010 | return -EINVAL; |
2336 | } | 3011 | } |
2337 | 3012 | ||
2338 | dsi_vc_config_l4(channel); | 3013 | dsi_vc_config_l4(dsidev, channel); |
2339 | 3014 | ||
2340 | dsi_vc_write_long_header(channel, data_type, len, ecc); | 3015 | dsi_vc_write_long_header(dsidev, channel, data_type, len, ecc); |
2341 | 3016 | ||
2342 | p = data; | 3017 | p = data; |
2343 | for (i = 0; i < len >> 2; i++) { | 3018 | for (i = 0; i < len >> 2; i++) { |
2344 | if (dsi.debug_write) | 3019 | if (dsi->debug_write) |
2345 | DSSDBG("\tsending full packet %d\n", i); | 3020 | DSSDBG("\tsending full packet %d\n", i); |
2346 | 3021 | ||
2347 | b1 = *p++; | 3022 | b1 = *p++; |
@@ -2349,14 +3024,14 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, | |||
2349 | b3 = *p++; | 3024 | b3 = *p++; |
2350 | b4 = *p++; | 3025 | b4 = *p++; |
2351 | 3026 | ||
2352 | dsi_vc_write_long_payload(channel, b1, b2, b3, b4); | 3027 | dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, b4); |
2353 | } | 3028 | } |
2354 | 3029 | ||
2355 | i = len % 4; | 3030 | i = len % 4; |
2356 | if (i) { | 3031 | if (i) { |
2357 | b1 = 0; b2 = 0; b3 = 0; | 3032 | b1 = 0; b2 = 0; b3 = 0; |
2358 | 3033 | ||
2359 | if (dsi.debug_write) | 3034 | if (dsi->debug_write) |
2360 | DSSDBG("\tsending remainder bytes %d\n", i); | 3035 | DSSDBG("\tsending remainder bytes %d\n", i); |
2361 | 3036 | ||
2362 | switch (i) { | 3037 | switch (i) { |
@@ -2374,62 +3049,69 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, | |||
2374 | break; | 3049 | break; |
2375 | } | 3050 | } |
2376 | 3051 | ||
2377 | dsi_vc_write_long_payload(channel, b1, b2, b3, 0); | 3052 | dsi_vc_write_long_payload(dsidev, channel, b1, b2, b3, 0); |
2378 | } | 3053 | } |
2379 | 3054 | ||
2380 | return r; | 3055 | return r; |
2381 | } | 3056 | } |
2382 | 3057 | ||
2383 | static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) | 3058 | static int dsi_vc_send_short(struct platform_device *dsidev, int channel, |
3059 | u8 data_type, u16 data, u8 ecc) | ||
2384 | { | 3060 | { |
3061 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2385 | u32 r; | 3062 | u32 r; |
2386 | u8 data_id; | 3063 | u8 data_id; |
2387 | 3064 | ||
2388 | WARN_ON(!dsi_bus_is_locked()); | 3065 | WARN_ON(!dsi_bus_is_locked(dsidev)); |
2389 | 3066 | ||
2390 | if (dsi.debug_write) | 3067 | if (dsi->debug_write) |
2391 | DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", | 3068 | DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", |
2392 | channel, | 3069 | channel, |
2393 | data_type, data & 0xff, (data >> 8) & 0xff); | 3070 | data_type, data & 0xff, (data >> 8) & 0xff); |
2394 | 3071 | ||
2395 | dsi_vc_config_l4(channel); | 3072 | dsi_vc_config_l4(dsidev, channel); |
2396 | 3073 | ||
2397 | if (FLD_GET(dsi_read_reg(DSI_VC_CTRL(channel)), 16, 16)) { | 3074 | if (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(channel)), 16, 16)) { |
2398 | DSSERR("ERROR FIFO FULL, aborting transfer\n"); | 3075 | DSSERR("ERROR FIFO FULL, aborting transfer\n"); |
2399 | return -EINVAL; | 3076 | return -EINVAL; |
2400 | } | 3077 | } |
2401 | 3078 | ||
2402 | data_id = data_type | dsi.vc[channel].vc_id << 6; | 3079 | data_id = data_type | dsi->vc[channel].vc_id << 6; |
2403 | 3080 | ||
2404 | r = (data_id << 0) | (data << 8) | (ecc << 24); | 3081 | r = (data_id << 0) | (data << 8) | (ecc << 24); |
2405 | 3082 | ||
2406 | dsi_write_reg(DSI_VC_SHORT_PACKET_HEADER(channel), r); | 3083 | dsi_write_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel), r); |
2407 | 3084 | ||
2408 | return 0; | 3085 | return 0; |
2409 | } | 3086 | } |
2410 | 3087 | ||
2411 | int dsi_vc_send_null(int channel) | 3088 | int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel) |
2412 | { | 3089 | { |
3090 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2413 | u8 nullpkg[] = {0, 0, 0, 0}; | 3091 | u8 nullpkg[] = {0, 0, 0, 0}; |
2414 | return dsi_vc_send_long(channel, DSI_DT_NULL_PACKET, nullpkg, 4, 0); | 3092 | |
3093 | return dsi_vc_send_long(dsidev, channel, DSI_DT_NULL_PACKET, nullpkg, | ||
3094 | 4, 0); | ||
2415 | } | 3095 | } |
2416 | EXPORT_SYMBOL(dsi_vc_send_null); | 3096 | EXPORT_SYMBOL(dsi_vc_send_null); |
2417 | 3097 | ||
2418 | int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len) | 3098 | int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel, |
3099 | u8 *data, int len) | ||
2419 | { | 3100 | { |
3101 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2420 | int r; | 3102 | int r; |
2421 | 3103 | ||
2422 | BUG_ON(len == 0); | 3104 | BUG_ON(len == 0); |
2423 | 3105 | ||
2424 | if (len == 1) { | 3106 | if (len == 1) { |
2425 | r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_0, | 3107 | r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_0, |
2426 | data[0], 0); | 3108 | data[0], 0); |
2427 | } else if (len == 2) { | 3109 | } else if (len == 2) { |
2428 | r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_1, | 3110 | r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_SHORT_WRITE_1, |
2429 | data[0] | (data[1] << 8), 0); | 3111 | data[0] | (data[1] << 8), 0); |
2430 | } else { | 3112 | } else { |
2431 | /* 0x39 = DCS Long Write */ | 3113 | /* 0x39 = DCS Long Write */ |
2432 | r = dsi_vc_send_long(channel, DSI_DT_DCS_LONG_WRITE, | 3114 | r = dsi_vc_send_long(dsidev, channel, DSI_DT_DCS_LONG_WRITE, |
2433 | data, len, 0); | 3115 | data, len, 0); |
2434 | } | 3116 | } |
2435 | 3117 | ||
@@ -2437,21 +3119,24 @@ int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len) | |||
2437 | } | 3119 | } |
2438 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); | 3120 | EXPORT_SYMBOL(dsi_vc_dcs_write_nosync); |
2439 | 3121 | ||
2440 | int dsi_vc_dcs_write(int channel, u8 *data, int len) | 3122 | int dsi_vc_dcs_write(struct omap_dss_device *dssdev, int channel, u8 *data, |
3123 | int len) | ||
2441 | { | 3124 | { |
3125 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2442 | int r; | 3126 | int r; |
2443 | 3127 | ||
2444 | r = dsi_vc_dcs_write_nosync(channel, data, len); | 3128 | r = dsi_vc_dcs_write_nosync(dssdev, channel, data, len); |
2445 | if (r) | 3129 | if (r) |
2446 | goto err; | 3130 | goto err; |
2447 | 3131 | ||
2448 | r = dsi_vc_send_bta_sync(channel); | 3132 | r = dsi_vc_send_bta_sync(dssdev, channel); |
2449 | if (r) | 3133 | if (r) |
2450 | goto err; | 3134 | goto err; |
2451 | 3135 | ||
2452 | if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ | 3136 | /* RX_FIFO_NOT_EMPTY */ |
3137 | if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20)) { | ||
2453 | DSSERR("rx fifo not empty after write, dumping data:\n"); | 3138 | DSSERR("rx fifo not empty after write, dumping data:\n"); |
2454 | dsi_vc_flush_receive_data(channel); | 3139 | dsi_vc_flush_receive_data(dsidev, channel); |
2455 | r = -EIO; | 3140 | r = -EIO; |
2456 | goto err; | 3141 | goto err; |
2457 | } | 3142 | } |
@@ -2464,47 +3149,51 @@ err: | |||
2464 | } | 3149 | } |
2465 | EXPORT_SYMBOL(dsi_vc_dcs_write); | 3150 | EXPORT_SYMBOL(dsi_vc_dcs_write); |
2466 | 3151 | ||
2467 | int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd) | 3152 | int dsi_vc_dcs_write_0(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd) |
2468 | { | 3153 | { |
2469 | return dsi_vc_dcs_write(channel, &dcs_cmd, 1); | 3154 | return dsi_vc_dcs_write(dssdev, channel, &dcs_cmd, 1); |
2470 | } | 3155 | } |
2471 | EXPORT_SYMBOL(dsi_vc_dcs_write_0); | 3156 | EXPORT_SYMBOL(dsi_vc_dcs_write_0); |
2472 | 3157 | ||
2473 | int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param) | 3158 | int dsi_vc_dcs_write_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, |
3159 | u8 param) | ||
2474 | { | 3160 | { |
2475 | u8 buf[2]; | 3161 | u8 buf[2]; |
2476 | buf[0] = dcs_cmd; | 3162 | buf[0] = dcs_cmd; |
2477 | buf[1] = param; | 3163 | buf[1] = param; |
2478 | return dsi_vc_dcs_write(channel, buf, 2); | 3164 | return dsi_vc_dcs_write(dssdev, channel, buf, 2); |
2479 | } | 3165 | } |
2480 | EXPORT_SYMBOL(dsi_vc_dcs_write_1); | 3166 | EXPORT_SYMBOL(dsi_vc_dcs_write_1); |
2481 | 3167 | ||
2482 | int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) | 3168 | int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, |
3169 | u8 *buf, int buflen) | ||
2483 | { | 3170 | { |
3171 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3172 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2484 | u32 val; | 3173 | u32 val; |
2485 | u8 dt; | 3174 | u8 dt; |
2486 | int r; | 3175 | int r; |
2487 | 3176 | ||
2488 | if (dsi.debug_read) | 3177 | if (dsi->debug_read) |
2489 | DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); | 3178 | DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); |
2490 | 3179 | ||
2491 | r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0); | 3180 | r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0); |
2492 | if (r) | 3181 | if (r) |
2493 | goto err; | 3182 | goto err; |
2494 | 3183 | ||
2495 | r = dsi_vc_send_bta_sync(channel); | 3184 | r = dsi_vc_send_bta_sync(dssdev, channel); |
2496 | if (r) | 3185 | if (r) |
2497 | goto err; | 3186 | goto err; |
2498 | 3187 | ||
2499 | /* RX_FIFO_NOT_EMPTY */ | 3188 | /* RX_FIFO_NOT_EMPTY */ |
2500 | if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { | 3189 | if (REG_GET(dsidev, DSI_VC_CTRL(channel), 20, 20) == 0) { |
2501 | DSSERR("RX fifo empty when trying to read.\n"); | 3190 | DSSERR("RX fifo empty when trying to read.\n"); |
2502 | r = -EIO; | 3191 | r = -EIO; |
2503 | goto err; | 3192 | goto err; |
2504 | } | 3193 | } |
2505 | 3194 | ||
2506 | val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); | 3195 | val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel)); |
2507 | if (dsi.debug_read) | 3196 | if (dsi->debug_read) |
2508 | DSSDBG("\theader: %08x\n", val); | 3197 | DSSDBG("\theader: %08x\n", val); |
2509 | dt = FLD_GET(val, 5, 0); | 3198 | dt = FLD_GET(val, 5, 0); |
2510 | if (dt == DSI_DT_RX_ACK_WITH_ERR) { | 3199 | if (dt == DSI_DT_RX_ACK_WITH_ERR) { |
@@ -2515,7 +3204,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) | |||
2515 | 3204 | ||
2516 | } else if (dt == DSI_DT_RX_SHORT_READ_1) { | 3205 | } else if (dt == DSI_DT_RX_SHORT_READ_1) { |
2517 | u8 data = FLD_GET(val, 15, 8); | 3206 | u8 data = FLD_GET(val, 15, 8); |
2518 | if (dsi.debug_read) | 3207 | if (dsi->debug_read) |
2519 | DSSDBG("\tDCS short response, 1 byte: %02x\n", data); | 3208 | DSSDBG("\tDCS short response, 1 byte: %02x\n", data); |
2520 | 3209 | ||
2521 | if (buflen < 1) { | 3210 | if (buflen < 1) { |
@@ -2528,7 +3217,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) | |||
2528 | return 1; | 3217 | return 1; |
2529 | } else if (dt == DSI_DT_RX_SHORT_READ_2) { | 3218 | } else if (dt == DSI_DT_RX_SHORT_READ_2) { |
2530 | u16 data = FLD_GET(val, 23, 8); | 3219 | u16 data = FLD_GET(val, 23, 8); |
2531 | if (dsi.debug_read) | 3220 | if (dsi->debug_read) |
2532 | DSSDBG("\tDCS short response, 2 byte: %04x\n", data); | 3221 | DSSDBG("\tDCS short response, 2 byte: %04x\n", data); |
2533 | 3222 | ||
2534 | if (buflen < 2) { | 3223 | if (buflen < 2) { |
@@ -2543,7 +3232,7 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) | |||
2543 | } else if (dt == DSI_DT_RX_DCS_LONG_READ) { | 3232 | } else if (dt == DSI_DT_RX_DCS_LONG_READ) { |
2544 | int w; | 3233 | int w; |
2545 | int len = FLD_GET(val, 23, 8); | 3234 | int len = FLD_GET(val, 23, 8); |
2546 | if (dsi.debug_read) | 3235 | if (dsi->debug_read) |
2547 | DSSDBG("\tDCS long response, len %d\n", len); | 3236 | DSSDBG("\tDCS long response, len %d\n", len); |
2548 | 3237 | ||
2549 | if (len > buflen) { | 3238 | if (len > buflen) { |
@@ -2554,8 +3243,9 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) | |||
2554 | /* two byte checksum ends the packet, not included in len */ | 3243 | /* two byte checksum ends the packet, not included in len */ |
2555 | for (w = 0; w < len + 2;) { | 3244 | for (w = 0; w < len + 2;) { |
2556 | int b; | 3245 | int b; |
2557 | val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel)); | 3246 | val = dsi_read_reg(dsidev, |
2558 | if (dsi.debug_read) | 3247 | DSI_VC_SHORT_PACKET_HEADER(channel)); |
3248 | if (dsi->debug_read) | ||
2559 | DSSDBG("\t\t%02x %02x %02x %02x\n", | 3249 | DSSDBG("\t\t%02x %02x %02x %02x\n", |
2560 | (val >> 0) & 0xff, | 3250 | (val >> 0) & 0xff, |
2561 | (val >> 8) & 0xff, | 3251 | (val >> 8) & 0xff, |
@@ -2586,11 +3276,12 @@ err: | |||
2586 | } | 3276 | } |
2587 | EXPORT_SYMBOL(dsi_vc_dcs_read); | 3277 | EXPORT_SYMBOL(dsi_vc_dcs_read); |
2588 | 3278 | ||
2589 | int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data) | 3279 | int dsi_vc_dcs_read_1(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, |
3280 | u8 *data) | ||
2590 | { | 3281 | { |
2591 | int r; | 3282 | int r; |
2592 | 3283 | ||
2593 | r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1); | 3284 | r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, data, 1); |
2594 | 3285 | ||
2595 | if (r < 0) | 3286 | if (r < 0) |
2596 | return r; | 3287 | return r; |
@@ -2602,12 +3293,13 @@ int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data) | |||
2602 | } | 3293 | } |
2603 | EXPORT_SYMBOL(dsi_vc_dcs_read_1); | 3294 | EXPORT_SYMBOL(dsi_vc_dcs_read_1); |
2604 | 3295 | ||
2605 | int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2) | 3296 | int dsi_vc_dcs_read_2(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, |
3297 | u8 *data1, u8 *data2) | ||
2606 | { | 3298 | { |
2607 | u8 buf[2]; | 3299 | u8 buf[2]; |
2608 | int r; | 3300 | int r; |
2609 | 3301 | ||
2610 | r = dsi_vc_dcs_read(channel, dcs_cmd, buf, 2); | 3302 | r = dsi_vc_dcs_read(dssdev, channel, dcs_cmd, buf, 2); |
2611 | 3303 | ||
2612 | if (r < 0) | 3304 | if (r < 0) |
2613 | return r; | 3305 | return r; |
@@ -2622,14 +3314,94 @@ int dsi_vc_dcs_read_2(int channel, u8 dcs_cmd, u8 *data1, u8 *data2) | |||
2622 | } | 3314 | } |
2623 | EXPORT_SYMBOL(dsi_vc_dcs_read_2); | 3315 | EXPORT_SYMBOL(dsi_vc_dcs_read_2); |
2624 | 3316 | ||
2625 | int dsi_vc_set_max_rx_packet_size(int channel, u16 len) | 3317 | int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel, |
3318 | u16 len) | ||
2626 | { | 3319 | { |
2627 | return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE, | 3320 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3321 | |||
3322 | return dsi_vc_send_short(dsidev, channel, DSI_DT_SET_MAX_RET_PKG_SIZE, | ||
2628 | len, 0); | 3323 | len, 0); |
2629 | } | 3324 | } |
2630 | EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); | 3325 | EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); |
2631 | 3326 | ||
2632 | static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16) | 3327 | static int dsi_enter_ulps(struct platform_device *dsidev) |
3328 | { | ||
3329 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3330 | DECLARE_COMPLETION_ONSTACK(completion); | ||
3331 | int r; | ||
3332 | |||
3333 | DSSDBGF(); | ||
3334 | |||
3335 | WARN_ON(!dsi_bus_is_locked(dsidev)); | ||
3336 | |||
3337 | WARN_ON(dsi->ulps_enabled); | ||
3338 | |||
3339 | if (dsi->ulps_enabled) | ||
3340 | return 0; | ||
3341 | |||
3342 | if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) { | ||
3343 | DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n"); | ||
3344 | return -EIO; | ||
3345 | } | ||
3346 | |||
3347 | dsi_sync_vc(dsidev, 0); | ||
3348 | dsi_sync_vc(dsidev, 1); | ||
3349 | dsi_sync_vc(dsidev, 2); | ||
3350 | dsi_sync_vc(dsidev, 3); | ||
3351 | |||
3352 | dsi_force_tx_stop_mode_io(dsidev); | ||
3353 | |||
3354 | dsi_vc_enable(dsidev, 0, false); | ||
3355 | dsi_vc_enable(dsidev, 1, false); | ||
3356 | dsi_vc_enable(dsidev, 2, false); | ||
3357 | dsi_vc_enable(dsidev, 3, false); | ||
3358 | |||
3359 | if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 16, 16)) { /* HS_BUSY */ | ||
3360 | DSSERR("HS busy when enabling ULPS\n"); | ||
3361 | return -EIO; | ||
3362 | } | ||
3363 | |||
3364 | if (REG_GET(dsidev, DSI_COMPLEXIO_CFG2, 17, 17)) { /* LP_BUSY */ | ||
3365 | DSSERR("LP busy when enabling ULPS\n"); | ||
3366 | return -EIO; | ||
3367 | } | ||
3368 | |||
3369 | r = dsi_register_isr_cio(dsidev, dsi_completion_handler, &completion, | ||
3370 | DSI_CIO_IRQ_ULPSACTIVENOT_ALL0); | ||
3371 | if (r) | ||
3372 | return r; | ||
3373 | |||
3374 | /* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */ | ||
3375 | /* LANEx_ULPS_SIG2 */ | ||
3376 | REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2), | ||
3377 | 7, 5); | ||
3378 | |||
3379 | if (wait_for_completion_timeout(&completion, | ||
3380 | msecs_to_jiffies(1000)) == 0) { | ||
3381 | DSSERR("ULPS enable timeout\n"); | ||
3382 | r = -EIO; | ||
3383 | goto err; | ||
3384 | } | ||
3385 | |||
3386 | dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion, | ||
3387 | DSI_CIO_IRQ_ULPSACTIVENOT_ALL0); | ||
3388 | |||
3389 | dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS); | ||
3390 | |||
3391 | dsi_if_enable(dsidev, false); | ||
3392 | |||
3393 | dsi->ulps_enabled = true; | ||
3394 | |||
3395 | return 0; | ||
3396 | |||
3397 | err: | ||
3398 | dsi_unregister_isr_cio(dsidev, dsi_completion_handler, &completion, | ||
3399 | DSI_CIO_IRQ_ULPSACTIVENOT_ALL0); | ||
3400 | return r; | ||
3401 | } | ||
3402 | |||
3403 | static void dsi_set_lp_rx_timeout(struct platform_device *dsidev, | ||
3404 | unsigned ticks, bool x4, bool x16) | ||
2633 | { | 3405 | { |
2634 | unsigned long fck; | 3406 | unsigned long fck; |
2635 | unsigned long total_ticks; | 3407 | unsigned long total_ticks; |
@@ -2638,14 +3410,14 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16) | |||
2638 | BUG_ON(ticks > 0x1fff); | 3410 | BUG_ON(ticks > 0x1fff); |
2639 | 3411 | ||
2640 | /* ticks in DSI_FCK */ | 3412 | /* ticks in DSI_FCK */ |
2641 | fck = dsi_fclk_rate(); | 3413 | fck = dsi_fclk_rate(dsidev); |
2642 | 3414 | ||
2643 | r = dsi_read_reg(DSI_TIMING2); | 3415 | r = dsi_read_reg(dsidev, DSI_TIMING2); |
2644 | r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */ | 3416 | r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */ |
2645 | r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */ | 3417 | r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* LP_RX_TO_X16 */ |
2646 | r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */ | 3418 | r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* LP_RX_TO_X4 */ |
2647 | r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */ | 3419 | r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */ |
2648 | dsi_write_reg(DSI_TIMING2, r); | 3420 | dsi_write_reg(dsidev, DSI_TIMING2, r); |
2649 | 3421 | ||
2650 | total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); | 3422 | total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); |
2651 | 3423 | ||
@@ -2655,7 +3427,8 @@ static void dsi_set_lp_rx_timeout(unsigned ticks, bool x4, bool x16) | |||
2655 | (total_ticks * 1000) / (fck / 1000 / 1000)); | 3427 | (total_ticks * 1000) / (fck / 1000 / 1000)); |
2656 | } | 3428 | } |
2657 | 3429 | ||
2658 | static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16) | 3430 | static void dsi_set_ta_timeout(struct platform_device *dsidev, unsigned ticks, |
3431 | bool x8, bool x16) | ||
2659 | { | 3432 | { |
2660 | unsigned long fck; | 3433 | unsigned long fck; |
2661 | unsigned long total_ticks; | 3434 | unsigned long total_ticks; |
@@ -2664,14 +3437,14 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16) | |||
2664 | BUG_ON(ticks > 0x1fff); | 3437 | BUG_ON(ticks > 0x1fff); |
2665 | 3438 | ||
2666 | /* ticks in DSI_FCK */ | 3439 | /* ticks in DSI_FCK */ |
2667 | fck = dsi_fclk_rate(); | 3440 | fck = dsi_fclk_rate(dsidev); |
2668 | 3441 | ||
2669 | r = dsi_read_reg(DSI_TIMING1); | 3442 | r = dsi_read_reg(dsidev, DSI_TIMING1); |
2670 | r = FLD_MOD(r, 1, 31, 31); /* TA_TO */ | 3443 | r = FLD_MOD(r, 1, 31, 31); /* TA_TO */ |
2671 | r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */ | 3444 | r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* TA_TO_X16 */ |
2672 | r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */ | 3445 | r = FLD_MOD(r, x8 ? 1 : 0, 29, 29); /* TA_TO_X8 */ |
2673 | r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */ | 3446 | r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */ |
2674 | dsi_write_reg(DSI_TIMING1, r); | 3447 | dsi_write_reg(dsidev, DSI_TIMING1, r); |
2675 | 3448 | ||
2676 | total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1); | 3449 | total_ticks = ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1); |
2677 | 3450 | ||
@@ -2681,7 +3454,8 @@ static void dsi_set_ta_timeout(unsigned ticks, bool x8, bool x16) | |||
2681 | (total_ticks * 1000) / (fck / 1000 / 1000)); | 3454 | (total_ticks * 1000) / (fck / 1000 / 1000)); |
2682 | } | 3455 | } |
2683 | 3456 | ||
2684 | static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16) | 3457 | static void dsi_set_stop_state_counter(struct platform_device *dsidev, |
3458 | unsigned ticks, bool x4, bool x16) | ||
2685 | { | 3459 | { |
2686 | unsigned long fck; | 3460 | unsigned long fck; |
2687 | unsigned long total_ticks; | 3461 | unsigned long total_ticks; |
@@ -2690,14 +3464,14 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16) | |||
2690 | BUG_ON(ticks > 0x1fff); | 3464 | BUG_ON(ticks > 0x1fff); |
2691 | 3465 | ||
2692 | /* ticks in DSI_FCK */ | 3466 | /* ticks in DSI_FCK */ |
2693 | fck = dsi_fclk_rate(); | 3467 | fck = dsi_fclk_rate(dsidev); |
2694 | 3468 | ||
2695 | r = dsi_read_reg(DSI_TIMING1); | 3469 | r = dsi_read_reg(dsidev, DSI_TIMING1); |
2696 | r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ | 3470 | r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */ |
2697 | r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */ | 3471 | r = FLD_MOD(r, x16 ? 1 : 0, 14, 14); /* STOP_STATE_X16_IO */ |
2698 | r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */ | 3472 | r = FLD_MOD(r, x4 ? 1 : 0, 13, 13); /* STOP_STATE_X4_IO */ |
2699 | r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */ | 3473 | r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */ |
2700 | dsi_write_reg(DSI_TIMING1, r); | 3474 | dsi_write_reg(dsidev, DSI_TIMING1, r); |
2701 | 3475 | ||
2702 | total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); | 3476 | total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); |
2703 | 3477 | ||
@@ -2707,7 +3481,8 @@ static void dsi_set_stop_state_counter(unsigned ticks, bool x4, bool x16) | |||
2707 | (total_ticks * 1000) / (fck / 1000 / 1000)); | 3481 | (total_ticks * 1000) / (fck / 1000 / 1000)); |
2708 | } | 3482 | } |
2709 | 3483 | ||
2710 | static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16) | 3484 | static void dsi_set_hs_tx_timeout(struct platform_device *dsidev, |
3485 | unsigned ticks, bool x4, bool x16) | ||
2711 | { | 3486 | { |
2712 | unsigned long fck; | 3487 | unsigned long fck; |
2713 | unsigned long total_ticks; | 3488 | unsigned long total_ticks; |
@@ -2716,14 +3491,14 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16) | |||
2716 | BUG_ON(ticks > 0x1fff); | 3491 | BUG_ON(ticks > 0x1fff); |
2717 | 3492 | ||
2718 | /* ticks in TxByteClkHS */ | 3493 | /* ticks in TxByteClkHS */ |
2719 | fck = dsi_get_txbyteclkhs(); | 3494 | fck = dsi_get_txbyteclkhs(dsidev); |
2720 | 3495 | ||
2721 | r = dsi_read_reg(DSI_TIMING2); | 3496 | r = dsi_read_reg(dsidev, DSI_TIMING2); |
2722 | r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */ | 3497 | r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */ |
2723 | r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */ | 3498 | r = FLD_MOD(r, x16 ? 1 : 0, 30, 30); /* HS_TX_TO_X16 */ |
2724 | r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */ | 3499 | r = FLD_MOD(r, x4 ? 1 : 0, 29, 29); /* HS_TX_TO_X8 (4 really) */ |
2725 | r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */ | 3500 | r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */ |
2726 | dsi_write_reg(DSI_TIMING2, r); | 3501 | dsi_write_reg(dsidev, DSI_TIMING2, r); |
2727 | 3502 | ||
2728 | total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); | 3503 | total_ticks = ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1); |
2729 | 3504 | ||
@@ -2734,24 +3509,25 @@ static void dsi_set_hs_tx_timeout(unsigned ticks, bool x4, bool x16) | |||
2734 | } | 3509 | } |
2735 | static int dsi_proto_config(struct omap_dss_device *dssdev) | 3510 | static int dsi_proto_config(struct omap_dss_device *dssdev) |
2736 | { | 3511 | { |
3512 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2737 | u32 r; | 3513 | u32 r; |
2738 | int buswidth = 0; | 3514 | int buswidth = 0; |
2739 | 3515 | ||
2740 | dsi_config_tx_fifo(DSI_FIFO_SIZE_32, | 3516 | dsi_config_tx_fifo(dsidev, DSI_FIFO_SIZE_32, |
2741 | DSI_FIFO_SIZE_32, | 3517 | DSI_FIFO_SIZE_32, |
2742 | DSI_FIFO_SIZE_32, | 3518 | DSI_FIFO_SIZE_32, |
2743 | DSI_FIFO_SIZE_32); | 3519 | DSI_FIFO_SIZE_32); |
2744 | 3520 | ||
2745 | dsi_config_rx_fifo(DSI_FIFO_SIZE_32, | 3521 | dsi_config_rx_fifo(dsidev, DSI_FIFO_SIZE_32, |
2746 | DSI_FIFO_SIZE_32, | 3522 | DSI_FIFO_SIZE_32, |
2747 | DSI_FIFO_SIZE_32, | 3523 | DSI_FIFO_SIZE_32, |
2748 | DSI_FIFO_SIZE_32); | 3524 | DSI_FIFO_SIZE_32); |
2749 | 3525 | ||
2750 | /* XXX what values for the timeouts? */ | 3526 | /* XXX what values for the timeouts? */ |
2751 | dsi_set_stop_state_counter(0x1000, false, false); | 3527 | dsi_set_stop_state_counter(dsidev, 0x1000, false, false); |
2752 | dsi_set_ta_timeout(0x1fff, true, true); | 3528 | dsi_set_ta_timeout(dsidev, 0x1fff, true, true); |
2753 | dsi_set_lp_rx_timeout(0x1fff, true, true); | 3529 | dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true); |
2754 | dsi_set_hs_tx_timeout(0x1fff, true, true); | 3530 | dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true); |
2755 | 3531 | ||
2756 | switch (dssdev->ctrl.pixel_size) { | 3532 | switch (dssdev->ctrl.pixel_size) { |
2757 | case 16: | 3533 | case 16: |
@@ -2767,7 +3543,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
2767 | BUG(); | 3543 | BUG(); |
2768 | } | 3544 | } |
2769 | 3545 | ||
2770 | r = dsi_read_reg(DSI_CTRL); | 3546 | r = dsi_read_reg(dsidev, DSI_CTRL); |
2771 | r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */ | 3547 | r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */ |
2772 | r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */ | 3548 | r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */ |
2773 | r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */ | 3549 | r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */ |
@@ -2777,21 +3553,25 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) | |||
2777 | r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */ | 3553 | r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */ |
2778 | r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */ | 3554 | r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */ |
2779 | r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */ | 3555 | r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */ |
2780 | r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */ | 3556 | if (!dss_has_feature(FEAT_DSI_DCS_CMD_CONFIG_VC)) { |
2781 | r = FLD_MOD(r, 0, 25, 25); /* DCS_CMD_CODE, 1=start, 0=continue */ | 3557 | r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */ |
3558 | /* DCS_CMD_CODE, 1=start, 0=continue */ | ||
3559 | r = FLD_MOD(r, 0, 25, 25); | ||
3560 | } | ||
2782 | 3561 | ||
2783 | dsi_write_reg(DSI_CTRL, r); | 3562 | dsi_write_reg(dsidev, DSI_CTRL, r); |
2784 | 3563 | ||
2785 | dsi_vc_initial_config(0); | 3564 | dsi_vc_initial_config(dsidev, 0); |
2786 | dsi_vc_initial_config(1); | 3565 | dsi_vc_initial_config(dsidev, 1); |
2787 | dsi_vc_initial_config(2); | 3566 | dsi_vc_initial_config(dsidev, 2); |
2788 | dsi_vc_initial_config(3); | 3567 | dsi_vc_initial_config(dsidev, 3); |
2789 | 3568 | ||
2790 | return 0; | 3569 | return 0; |
2791 | } | 3570 | } |
2792 | 3571 | ||
2793 | static void dsi_proto_timings(struct omap_dss_device *dssdev) | 3572 | static void dsi_proto_timings(struct omap_dss_device *dssdev) |
2794 | { | 3573 | { |
3574 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
2795 | unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; | 3575 | unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail; |
2796 | unsigned tclk_pre, tclk_post; | 3576 | unsigned tclk_pre, tclk_post; |
2797 | unsigned ths_prepare, ths_prepare_ths_zero, ths_zero; | 3577 | unsigned ths_prepare, ths_prepare_ths_zero, ths_zero; |
@@ -2801,32 +3581,27 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
2801 | unsigned ths_eot; | 3581 | unsigned ths_eot; |
2802 | u32 r; | 3582 | u32 r; |
2803 | 3583 | ||
2804 | r = dsi_read_reg(DSI_DSIPHY_CFG0); | 3584 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0); |
2805 | ths_prepare = FLD_GET(r, 31, 24); | 3585 | ths_prepare = FLD_GET(r, 31, 24); |
2806 | ths_prepare_ths_zero = FLD_GET(r, 23, 16); | 3586 | ths_prepare_ths_zero = FLD_GET(r, 23, 16); |
2807 | ths_zero = ths_prepare_ths_zero - ths_prepare; | 3587 | ths_zero = ths_prepare_ths_zero - ths_prepare; |
2808 | ths_trail = FLD_GET(r, 15, 8); | 3588 | ths_trail = FLD_GET(r, 15, 8); |
2809 | ths_exit = FLD_GET(r, 7, 0); | 3589 | ths_exit = FLD_GET(r, 7, 0); |
2810 | 3590 | ||
2811 | r = dsi_read_reg(DSI_DSIPHY_CFG1); | 3591 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1); |
2812 | tlpx = FLD_GET(r, 22, 16) * 2; | 3592 | tlpx = FLD_GET(r, 22, 16) * 2; |
2813 | tclk_trail = FLD_GET(r, 15, 8); | 3593 | tclk_trail = FLD_GET(r, 15, 8); |
2814 | tclk_zero = FLD_GET(r, 7, 0); | 3594 | tclk_zero = FLD_GET(r, 7, 0); |
2815 | 3595 | ||
2816 | r = dsi_read_reg(DSI_DSIPHY_CFG2); | 3596 | r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2); |
2817 | tclk_prepare = FLD_GET(r, 7, 0); | 3597 | tclk_prepare = FLD_GET(r, 7, 0); |
2818 | 3598 | ||
2819 | /* min 8*UI */ | 3599 | /* min 8*UI */ |
2820 | tclk_pre = 20; | 3600 | tclk_pre = 20; |
2821 | /* min 60ns + 52*UI */ | 3601 | /* min 60ns + 52*UI */ |
2822 | tclk_post = ns2ddr(60) + 26; | 3602 | tclk_post = ns2ddr(dsidev, 60) + 26; |
2823 | 3603 | ||
2824 | /* ths_eot is 2 for 2 datalanes and 4 for 1 datalane */ | 3604 | ths_eot = DIV_ROUND_UP(4, dsi_get_num_data_lanes_dssdev(dssdev)); |
2825 | if (dssdev->phy.dsi.data1_lane != 0 && | ||
2826 | dssdev->phy.dsi.data2_lane != 0) | ||
2827 | ths_eot = 2; | ||
2828 | else | ||
2829 | ths_eot = 4; | ||
2830 | 3605 | ||
2831 | ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare, | 3606 | ddr_clk_pre = DIV_ROUND_UP(tclk_pre + tlpx + tclk_zero + tclk_prepare, |
2832 | 4); | 3607 | 4); |
@@ -2835,10 +3610,10 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
2835 | BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255); | 3610 | BUG_ON(ddr_clk_pre == 0 || ddr_clk_pre > 255); |
2836 | BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255); | 3611 | BUG_ON(ddr_clk_post == 0 || ddr_clk_post > 255); |
2837 | 3612 | ||
2838 | r = dsi_read_reg(DSI_CLK_TIMING); | 3613 | r = dsi_read_reg(dsidev, DSI_CLK_TIMING); |
2839 | r = FLD_MOD(r, ddr_clk_pre, 15, 8); | 3614 | r = FLD_MOD(r, ddr_clk_pre, 15, 8); |
2840 | r = FLD_MOD(r, ddr_clk_post, 7, 0); | 3615 | r = FLD_MOD(r, ddr_clk_post, 7, 0); |
2841 | dsi_write_reg(DSI_CLK_TIMING, r); | 3616 | dsi_write_reg(dsidev, DSI_CLK_TIMING, r); |
2842 | 3617 | ||
2843 | DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n", | 3618 | DSSDBG("ddr_clk_pre %u, ddr_clk_post %u\n", |
2844 | ddr_clk_pre, | 3619 | ddr_clk_pre, |
@@ -2852,7 +3627,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
2852 | 3627 | ||
2853 | r = FLD_VAL(enter_hs_mode_lat, 31, 16) | | 3628 | r = FLD_VAL(enter_hs_mode_lat, 31, 16) | |
2854 | FLD_VAL(exit_hs_mode_lat, 15, 0); | 3629 | FLD_VAL(exit_hs_mode_lat, 15, 0); |
2855 | dsi_write_reg(DSI_VM_TIMING7, r); | 3630 | dsi_write_reg(dsidev, DSI_VM_TIMING7, r); |
2856 | 3631 | ||
2857 | DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", | 3632 | DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n", |
2858 | enter_hs_mode_lat, exit_hs_mode_lat); | 3633 | enter_hs_mode_lat, exit_hs_mode_lat); |
@@ -2862,25 +3637,27 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev) | |||
2862 | #define DSI_DECL_VARS \ | 3637 | #define DSI_DECL_VARS \ |
2863 | int __dsi_cb = 0; u32 __dsi_cv = 0; | 3638 | int __dsi_cb = 0; u32 __dsi_cv = 0; |
2864 | 3639 | ||
2865 | #define DSI_FLUSH(ch) \ | 3640 | #define DSI_FLUSH(dsidev, ch) \ |
2866 | if (__dsi_cb > 0) { \ | 3641 | if (__dsi_cb > 0) { \ |
2867 | /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \ | 3642 | /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \ |
2868 | dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \ | 3643 | dsi_write_reg(dsidev, DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \ |
2869 | __dsi_cb = __dsi_cv = 0; \ | 3644 | __dsi_cb = __dsi_cv = 0; \ |
2870 | } | 3645 | } |
2871 | 3646 | ||
2872 | #define DSI_PUSH(ch, data) \ | 3647 | #define DSI_PUSH(dsidev, ch, data) \ |
2873 | do { \ | 3648 | do { \ |
2874 | __dsi_cv |= (data) << (__dsi_cb * 8); \ | 3649 | __dsi_cv |= (data) << (__dsi_cb * 8); \ |
2875 | /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \ | 3650 | /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \ |
2876 | if (++__dsi_cb > 3) \ | 3651 | if (++__dsi_cb > 3) \ |
2877 | DSI_FLUSH(ch); \ | 3652 | DSI_FLUSH(dsidev, ch); \ |
2878 | } while (0) | 3653 | } while (0) |
2879 | 3654 | ||
2880 | static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | 3655 | static int dsi_update_screen_l4(struct omap_dss_device *dssdev, |
2881 | int x, int y, int w, int h) | 3656 | int x, int y, int w, int h) |
2882 | { | 3657 | { |
2883 | /* Note: supports only 24bit colors in 32bit container */ | 3658 | /* Note: supports only 24bit colors in 32bit container */ |
3659 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3660 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
2884 | int first = 1; | 3661 | int first = 1; |
2885 | int fifo_stalls = 0; | 3662 | int fifo_stalls = 0; |
2886 | int max_dsi_packet_size; | 3663 | int max_dsi_packet_size; |
@@ -2919,7 +3696,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
2919 | * in fifo */ | 3696 | * in fifo */ |
2920 | 3697 | ||
2921 | /* When using CPU, max long packet size is TX buffer size */ | 3698 | /* When using CPU, max long packet size is TX buffer size */ |
2922 | max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4; | 3699 | max_dsi_packet_size = dsi->vc[0].fifo_size * 32 * 4; |
2923 | 3700 | ||
2924 | /* we seem to get better perf if we divide the tx fifo to half, | 3701 | /* we seem to get better perf if we divide the tx fifo to half, |
2925 | and while the other half is being sent, we fill the other half | 3702 | and while the other half is being sent, we fill the other half |
@@ -2948,35 +3725,36 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
2948 | #if 1 | 3725 | #if 1 |
2949 | /* using fifo not empty */ | 3726 | /* using fifo not empty */ |
2950 | /* TX_FIFO_NOT_EMPTY */ | 3727 | /* TX_FIFO_NOT_EMPTY */ |
2951 | while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) { | 3728 | while (FLD_GET(dsi_read_reg(dsidev, DSI_VC_CTRL(0)), 5, 5)) { |
2952 | fifo_stalls++; | 3729 | fifo_stalls++; |
2953 | if (fifo_stalls > 0xfffff) { | 3730 | if (fifo_stalls > 0xfffff) { |
2954 | DSSERR("fifo stalls overflow, pixels left %d\n", | 3731 | DSSERR("fifo stalls overflow, pixels left %d\n", |
2955 | pixels_left); | 3732 | pixels_left); |
2956 | dsi_if_enable(0); | 3733 | dsi_if_enable(dsidev, 0); |
2957 | return -EIO; | 3734 | return -EIO; |
2958 | } | 3735 | } |
2959 | udelay(1); | 3736 | udelay(1); |
2960 | } | 3737 | } |
2961 | #elif 1 | 3738 | #elif 1 |
2962 | /* using fifo emptiness */ | 3739 | /* using fifo emptiness */ |
2963 | while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 < | 3740 | while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 < |
2964 | max_dsi_packet_size) { | 3741 | max_dsi_packet_size) { |
2965 | fifo_stalls++; | 3742 | fifo_stalls++; |
2966 | if (fifo_stalls > 0xfffff) { | 3743 | if (fifo_stalls > 0xfffff) { |
2967 | DSSERR("fifo stalls overflow, pixels left %d\n", | 3744 | DSSERR("fifo stalls overflow, pixels left %d\n", |
2968 | pixels_left); | 3745 | pixels_left); |
2969 | dsi_if_enable(0); | 3746 | dsi_if_enable(dsidev, 0); |
2970 | return -EIO; | 3747 | return -EIO; |
2971 | } | 3748 | } |
2972 | } | 3749 | } |
2973 | #else | 3750 | #else |
2974 | while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) { | 3751 | while ((REG_GET(dsidev, DSI_TX_FIFO_VC_EMPTINESS, |
3752 | 7, 0) + 1) * 4 == 0) { | ||
2975 | fifo_stalls++; | 3753 | fifo_stalls++; |
2976 | if (fifo_stalls > 0xfffff) { | 3754 | if (fifo_stalls > 0xfffff) { |
2977 | DSSERR("fifo stalls overflow, pixels left %d\n", | 3755 | DSSERR("fifo stalls overflow, pixels left %d\n", |
2978 | pixels_left); | 3756 | pixels_left); |
2979 | dsi_if_enable(0); | 3757 | dsi_if_enable(dsidev, 0); |
2980 | return -EIO; | 3758 | return -EIO; |
2981 | } | 3759 | } |
2982 | } | 3760 | } |
@@ -2985,17 +3763,17 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
2985 | 3763 | ||
2986 | pixels_left -= pixels; | 3764 | pixels_left -= pixels; |
2987 | 3765 | ||
2988 | dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE, | 3766 | dsi_vc_write_long_header(dsidev, 0, DSI_DT_DCS_LONG_WRITE, |
2989 | 1 + pixels * bytespp, 0); | 3767 | 1 + pixels * bytespp, 0); |
2990 | 3768 | ||
2991 | DSI_PUSH(0, dcs_cmd); | 3769 | DSI_PUSH(dsidev, 0, dcs_cmd); |
2992 | 3770 | ||
2993 | while (pixels-- > 0) { | 3771 | while (pixels-- > 0) { |
2994 | u32 pix = __raw_readl(data++); | 3772 | u32 pix = __raw_readl(data++); |
2995 | 3773 | ||
2996 | DSI_PUSH(0, (pix >> 16) & 0xff); | 3774 | DSI_PUSH(dsidev, 0, (pix >> 16) & 0xff); |
2997 | DSI_PUSH(0, (pix >> 8) & 0xff); | 3775 | DSI_PUSH(dsidev, 0, (pix >> 8) & 0xff); |
2998 | DSI_PUSH(0, (pix >> 0) & 0xff); | 3776 | DSI_PUSH(dsidev, 0, (pix >> 0) & 0xff); |
2999 | 3777 | ||
3000 | current_x++; | 3778 | current_x++; |
3001 | if (current_x == x+w) { | 3779 | if (current_x == x+w) { |
@@ -3004,7 +3782,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
3004 | } | 3782 | } |
3005 | } | 3783 | } |
3006 | 3784 | ||
3007 | DSI_FLUSH(0); | 3785 | DSI_FLUSH(dsidev, 0); |
3008 | } | 3786 | } |
3009 | 3787 | ||
3010 | return 0; | 3788 | return 0; |
@@ -3013,6 +3791,8 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, | |||
3013 | static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | 3791 | static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, |
3014 | u16 x, u16 y, u16 w, u16 h) | 3792 | u16 x, u16 y, u16 w, u16 h) |
3015 | { | 3793 | { |
3794 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3795 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3016 | unsigned bytespp; | 3796 | unsigned bytespp; |
3017 | unsigned bytespl; | 3797 | unsigned bytespl; |
3018 | unsigned bytespf; | 3798 | unsigned bytespf; |
@@ -3021,16 +3801,13 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | |||
3021 | unsigned packet_len; | 3801 | unsigned packet_len; |
3022 | u32 l; | 3802 | u32 l; |
3023 | int r; | 3803 | int r; |
3024 | const unsigned channel = dsi.update_channel; | 3804 | const unsigned channel = dsi->update_channel; |
3025 | /* line buffer is 1024 x 24bits */ | 3805 | const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); |
3026 | /* XXX: for some reason using full buffer size causes considerable TX | ||
3027 | * slowdown with update sizes that fill the whole buffer */ | ||
3028 | const unsigned line_buf_size = 1023 * 3; | ||
3029 | 3806 | ||
3030 | DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", | 3807 | DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n", |
3031 | x, y, w, h); | 3808 | x, y, w, h); |
3032 | 3809 | ||
3033 | dsi_vc_config_vp(channel); | 3810 | dsi_vc_config_vp(dsidev, channel); |
3034 | 3811 | ||
3035 | bytespp = dssdev->ctrl.pixel_size / 8; | 3812 | bytespp = dssdev->ctrl.pixel_size / 8; |
3036 | bytespl = w * bytespp; | 3813 | bytespl = w * bytespp; |
@@ -3051,15 +3828,16 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | |||
3051 | total_len += (bytespf % packet_payload) + 1; | 3828 | total_len += (bytespf % packet_payload) + 1; |
3052 | 3829 | ||
3053 | l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ | 3830 | l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ |
3054 | dsi_write_reg(DSI_VC_TE(channel), l); | 3831 | dsi_write_reg(dsidev, DSI_VC_TE(channel), l); |
3055 | 3832 | ||
3056 | dsi_vc_write_long_header(channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); | 3833 | dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE, |
3834 | packet_len, 0); | ||
3057 | 3835 | ||
3058 | if (dsi.te_enabled) | 3836 | if (dsi->te_enabled) |
3059 | l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ | 3837 | l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ |
3060 | else | 3838 | else |
3061 | l = FLD_MOD(l, 1, 31, 31); /* TE_START */ | 3839 | l = FLD_MOD(l, 1, 31, 31); /* TE_START */ |
3062 | dsi_write_reg(DSI_VC_TE(channel), l); | 3840 | dsi_write_reg(dsidev, DSI_VC_TE(channel), l); |
3063 | 3841 | ||
3064 | /* We put SIDLEMODE to no-idle for the duration of the transfer, | 3842 | /* We put SIDLEMODE to no-idle for the duration of the transfer, |
3065 | * because DSS interrupts are not capable of waking up the CPU and the | 3843 | * because DSS interrupts are not capable of waking up the CPU and the |
@@ -3069,23 +3847,23 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, | |||
3069 | */ | 3847 | */ |
3070 | dispc_disable_sidle(); | 3848 | dispc_disable_sidle(); |
3071 | 3849 | ||
3072 | dsi_perf_mark_start(); | 3850 | dsi_perf_mark_start(dsidev); |
3073 | 3851 | ||
3074 | r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work, | 3852 | r = schedule_delayed_work(&dsi->framedone_timeout_work, |
3075 | msecs_to_jiffies(250)); | 3853 | msecs_to_jiffies(250)); |
3076 | BUG_ON(r == 0); | 3854 | BUG_ON(r == 0); |
3077 | 3855 | ||
3078 | dss_start_update(dssdev); | 3856 | dss_start_update(dssdev); |
3079 | 3857 | ||
3080 | if (dsi.te_enabled) { | 3858 | if (dsi->te_enabled) { |
3081 | /* disable LP_RX_TO, so that we can receive TE. Time to wait | 3859 | /* disable LP_RX_TO, so that we can receive TE. Time to wait |
3082 | * for TE is longer than the timer allows */ | 3860 | * for TE is longer than the timer allows */ |
3083 | REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ | 3861 | REG_FLD_MOD(dsidev, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ |
3084 | 3862 | ||
3085 | dsi_vc_send_bta(channel); | 3863 | dsi_vc_send_bta(dsidev, channel); |
3086 | 3864 | ||
3087 | #ifdef DSI_CATCH_MISSING_TE | 3865 | #ifdef DSI_CATCH_MISSING_TE |
3088 | mod_timer(&dsi.te_timer, jiffies + msecs_to_jiffies(250)); | 3866 | mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250)); |
3089 | #endif | 3867 | #endif |
3090 | } | 3868 | } |
3091 | } | 3869 | } |
@@ -3097,41 +3875,28 @@ static void dsi_te_timeout(unsigned long arg) | |||
3097 | } | 3875 | } |
3098 | #endif | 3876 | #endif |
3099 | 3877 | ||
3100 | static void dsi_framedone_bta_callback(void *data, u32 mask); | 3878 | static void dsi_handle_framedone(struct platform_device *dsidev, int error) |
3101 | |||
3102 | static void dsi_handle_framedone(int error) | ||
3103 | { | 3879 | { |
3104 | const int channel = dsi.update_channel; | 3880 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3105 | |||
3106 | dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback, | ||
3107 | NULL, DSI_VC_IRQ_BTA); | ||
3108 | |||
3109 | cancel_delayed_work(&dsi.framedone_timeout_work); | ||
3110 | 3881 | ||
3111 | /* SIDLEMODE back to smart-idle */ | 3882 | /* SIDLEMODE back to smart-idle */ |
3112 | dispc_enable_sidle(); | 3883 | dispc_enable_sidle(); |
3113 | 3884 | ||
3114 | if (dsi.te_enabled) { | 3885 | if (dsi->te_enabled) { |
3115 | /* enable LP_RX_TO again after the TE */ | 3886 | /* enable LP_RX_TO again after the TE */ |
3116 | REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ | 3887 | REG_FLD_MOD(dsidev, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ |
3117 | } | 3888 | } |
3118 | 3889 | ||
3119 | /* RX_FIFO_NOT_EMPTY */ | 3890 | dsi->framedone_callback(error, dsi->framedone_data); |
3120 | if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { | ||
3121 | DSSERR("Received error during frame transfer:\n"); | ||
3122 | dsi_vc_flush_receive_data(channel); | ||
3123 | if (!error) | ||
3124 | error = -EIO; | ||
3125 | } | ||
3126 | |||
3127 | dsi.framedone_callback(error, dsi.framedone_data); | ||
3128 | 3891 | ||
3129 | if (!error) | 3892 | if (!error) |
3130 | dsi_perf_show("DISPC"); | 3893 | dsi_perf_show(dsidev, "DISPC"); |
3131 | } | 3894 | } |
3132 | 3895 | ||
3133 | static void dsi_framedone_timeout_work_callback(struct work_struct *work) | 3896 | static void dsi_framedone_timeout_work_callback(struct work_struct *work) |
3134 | { | 3897 | { |
3898 | struct dsi_data *dsi = container_of(work, struct dsi_data, | ||
3899 | framedone_timeout_work.work); | ||
3135 | /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after | 3900 | /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after |
3136 | * 250ms which would conflict with this timeout work. What should be | 3901 | * 250ms which would conflict with this timeout work. What should be |
3137 | * done is first cancel the transfer on the HW, and then cancel the | 3902 | * done is first cancel the transfer on the HW, and then cancel the |
@@ -3141,70 +3906,34 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) | |||
3141 | 3906 | ||
3142 | DSSERR("Framedone not received for 250ms!\n"); | 3907 | DSSERR("Framedone not received for 250ms!\n"); |
3143 | 3908 | ||
3144 | dsi_handle_framedone(-ETIMEDOUT); | 3909 | dsi_handle_framedone(dsi->pdev, -ETIMEDOUT); |
3145 | } | ||
3146 | |||
3147 | static void dsi_framedone_bta_callback(void *data, u32 mask) | ||
3148 | { | ||
3149 | dsi_handle_framedone(0); | ||
3150 | |||
3151 | #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC | ||
3152 | dispc_fake_vsync_irq(); | ||
3153 | #endif | ||
3154 | } | 3910 | } |
3155 | 3911 | ||
3156 | static void dsi_framedone_irq_callback(void *data, u32 mask) | 3912 | static void dsi_framedone_irq_callback(void *data, u32 mask) |
3157 | { | 3913 | { |
3158 | const int channel = dsi.update_channel; | 3914 | struct omap_dss_device *dssdev = (struct omap_dss_device *) data; |
3159 | int r; | 3915 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3916 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3160 | 3917 | ||
3161 | /* Note: We get FRAMEDONE when DISPC has finished sending pixels and | 3918 | /* Note: We get FRAMEDONE when DISPC has finished sending pixels and |
3162 | * turns itself off. However, DSI still has the pixels in its buffers, | 3919 | * turns itself off. However, DSI still has the pixels in its buffers, |
3163 | * and is sending the data. | 3920 | * and is sending the data. |
3164 | */ | 3921 | */ |
3165 | 3922 | ||
3166 | if (dsi.te_enabled) { | 3923 | __cancel_delayed_work(&dsi->framedone_timeout_work); |
3167 | /* enable LP_RX_TO again after the TE */ | ||
3168 | REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ | ||
3169 | } | ||
3170 | |||
3171 | /* Send BTA after the frame. We need this for the TE to work, as TE | ||
3172 | * trigger is only sent for BTAs without preceding packet. Thus we need | ||
3173 | * to BTA after the pixel packets so that next BTA will cause TE | ||
3174 | * trigger. | ||
3175 | * | ||
3176 | * This is not needed when TE is not in use, but we do it anyway to | ||
3177 | * make sure that the transfer has been completed. It would be more | ||
3178 | * optimal, but more complex, to wait only just before starting next | ||
3179 | * transfer. | ||
3180 | * | ||
3181 | * Also, as there's no interrupt telling when the transfer has been | ||
3182 | * done and the channel could be reconfigured, the only way is to | ||
3183 | * busyloop until TE_SIZE is zero. With BTA we can do this | ||
3184 | * asynchronously. | ||
3185 | * */ | ||
3186 | |||
3187 | r = dsi_register_isr_vc(channel, dsi_framedone_bta_callback, | ||
3188 | NULL, DSI_VC_IRQ_BTA); | ||
3189 | if (r) { | ||
3190 | DSSERR("Failed to register BTA ISR\n"); | ||
3191 | dsi_handle_framedone(-EIO); | ||
3192 | return; | ||
3193 | } | ||
3194 | 3924 | ||
3195 | r = dsi_vc_send_bta(channel); | 3925 | dsi_handle_framedone(dsidev, 0); |
3196 | if (r) { | 3926 | |
3197 | DSSERR("BTA after framedone failed\n"); | 3927 | #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC |
3198 | dsi_unregister_isr_vc(channel, dsi_framedone_bta_callback, | 3928 | dispc_fake_vsync_irq(); |
3199 | NULL, DSI_VC_IRQ_BTA); | 3929 | #endif |
3200 | dsi_handle_framedone(-EIO); | ||
3201 | } | ||
3202 | } | 3930 | } |
3203 | 3931 | ||
3204 | int omap_dsi_prepare_update(struct omap_dss_device *dssdev, | 3932 | int omap_dsi_prepare_update(struct omap_dss_device *dssdev, |
3205 | u16 *x, u16 *y, u16 *w, u16 *h, | 3933 | u16 *x, u16 *y, u16 *w, u16 *h, |
3206 | bool enlarge_update_area) | 3934 | bool enlarge_update_area) |
3207 | { | 3935 | { |
3936 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3208 | u16 dw, dh; | 3937 | u16 dw, dh; |
3209 | 3938 | ||
3210 | dssdev->driver->get_resolution(dssdev, &dw, &dh); | 3939 | dssdev->driver->get_resolution(dssdev, &dw, &dh); |
@@ -3224,7 +3953,7 @@ int omap_dsi_prepare_update(struct omap_dss_device *dssdev, | |||
3224 | if (*w == 0 || *h == 0) | 3953 | if (*w == 0 || *h == 0) |
3225 | return -EINVAL; | 3954 | return -EINVAL; |
3226 | 3955 | ||
3227 | dsi_perf_mark_setup(); | 3956 | dsi_perf_mark_setup(dsidev); |
3228 | 3957 | ||
3229 | if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { | 3958 | if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { |
3230 | dss_setup_partial_planes(dssdev, x, y, w, h, | 3959 | dss_setup_partial_planes(dssdev, x, y, w, h, |
@@ -3241,7 +3970,10 @@ int omap_dsi_update(struct omap_dss_device *dssdev, | |||
3241 | u16 x, u16 y, u16 w, u16 h, | 3970 | u16 x, u16 y, u16 w, u16 h, |
3242 | void (*callback)(int, void *), void *data) | 3971 | void (*callback)(int, void *), void *data) |
3243 | { | 3972 | { |
3244 | dsi.update_channel = channel; | 3973 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3974 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3975 | |||
3976 | dsi->update_channel = channel; | ||
3245 | 3977 | ||
3246 | /* OMAP DSS cannot send updates of odd widths. | 3978 | /* OMAP DSS cannot send updates of odd widths. |
3247 | * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON | 3979 | * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON |
@@ -3250,14 +3982,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev, | |||
3250 | BUG_ON(x % 2 == 1); | 3982 | BUG_ON(x % 2 == 1); |
3251 | 3983 | ||
3252 | if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { | 3984 | if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { |
3253 | dsi.framedone_callback = callback; | 3985 | dsi->framedone_callback = callback; |
3254 | dsi.framedone_data = data; | 3986 | dsi->framedone_data = data; |
3255 | 3987 | ||
3256 | dsi.update_region.x = x; | 3988 | dsi->update_region.x = x; |
3257 | dsi.update_region.y = y; | 3989 | dsi->update_region.y = y; |
3258 | dsi.update_region.w = w; | 3990 | dsi->update_region.w = w; |
3259 | dsi.update_region.h = h; | 3991 | dsi->update_region.h = h; |
3260 | dsi.update_region.device = dssdev; | 3992 | dsi->update_region.device = dssdev; |
3261 | 3993 | ||
3262 | dsi_update_screen_dispc(dssdev, x, y, w, h); | 3994 | dsi_update_screen_dispc(dssdev, x, y, w, h); |
3263 | } else { | 3995 | } else { |
@@ -3267,7 +3999,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev, | |||
3267 | if (r) | 3999 | if (r) |
3268 | return r; | 4000 | return r; |
3269 | 4001 | ||
3270 | dsi_perf_show("L4"); | 4002 | dsi_perf_show(dsidev, "L4"); |
3271 | callback(0, data); | 4003 | callback(0, data); |
3272 | } | 4004 | } |
3273 | 4005 | ||
@@ -3280,9 +4012,13 @@ EXPORT_SYMBOL(omap_dsi_update); | |||
3280 | static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | 4012 | static int dsi_display_init_dispc(struct omap_dss_device *dssdev) |
3281 | { | 4013 | { |
3282 | int r; | 4014 | int r; |
4015 | u32 irq; | ||
4016 | |||
4017 | irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? | ||
4018 | DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2; | ||
3283 | 4019 | ||
3284 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, NULL, | 4020 | r = omap_dispc_register_isr(dsi_framedone_irq_callback, (void *) dssdev, |
3285 | DISPC_IRQ_FRAMEDONE); | 4021 | irq); |
3286 | if (r) { | 4022 | if (r) { |
3287 | DSSERR("can't get FRAMEDONE irq\n"); | 4023 | DSSERR("can't get FRAMEDONE irq\n"); |
3288 | return r; | 4024 | return r; |
@@ -3315,28 +4051,34 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev) | |||
3315 | 4051 | ||
3316 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) | 4052 | static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) |
3317 | { | 4053 | { |
3318 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, NULL, | 4054 | u32 irq; |
3319 | DISPC_IRQ_FRAMEDONE); | 4055 | |
4056 | irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ? | ||
4057 | DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2; | ||
4058 | |||
4059 | omap_dispc_unregister_isr(dsi_framedone_irq_callback, (void *) dssdev, | ||
4060 | irq); | ||
3320 | } | 4061 | } |
3321 | 4062 | ||
3322 | static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) | 4063 | static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) |
3323 | { | 4064 | { |
4065 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3324 | struct dsi_clock_info cinfo; | 4066 | struct dsi_clock_info cinfo; |
3325 | int r; | 4067 | int r; |
3326 | 4068 | ||
3327 | /* we always use DSS_CLK_SYSCK as input clock */ | 4069 | /* we always use DSS_CLK_SYSCK as input clock */ |
3328 | cinfo.use_sys_clk = true; | 4070 | cinfo.use_sys_clk = true; |
3329 | cinfo.regn = dssdev->phy.dsi.div.regn; | 4071 | cinfo.regn = dssdev->clocks.dsi.regn; |
3330 | cinfo.regm = dssdev->phy.dsi.div.regm; | 4072 | cinfo.regm = dssdev->clocks.dsi.regm; |
3331 | cinfo.regm_dispc = dssdev->phy.dsi.div.regm_dispc; | 4073 | cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc; |
3332 | cinfo.regm_dsi = dssdev->phy.dsi.div.regm_dsi; | 4074 | cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi; |
3333 | r = dsi_calc_clock_rates(dssdev, &cinfo); | 4075 | r = dsi_calc_clock_rates(dssdev, &cinfo); |
3334 | if (r) { | 4076 | if (r) { |
3335 | DSSERR("Failed to calc dsi clocks\n"); | 4077 | DSSERR("Failed to calc dsi clocks\n"); |
3336 | return r; | 4078 | return r; |
3337 | } | 4079 | } |
3338 | 4080 | ||
3339 | r = dsi_pll_set_clock_div(&cinfo); | 4081 | r = dsi_pll_set_clock_div(dsidev, &cinfo); |
3340 | if (r) { | 4082 | if (r) { |
3341 | DSSERR("Failed to set dsi clocks\n"); | 4083 | DSSERR("Failed to set dsi clocks\n"); |
3342 | return r; | 4084 | return r; |
@@ -3347,14 +4089,15 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) | |||
3347 | 4089 | ||
3348 | static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) | 4090 | static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) |
3349 | { | 4091 | { |
4092 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
3350 | struct dispc_clock_info dispc_cinfo; | 4093 | struct dispc_clock_info dispc_cinfo; |
3351 | int r; | 4094 | int r; |
3352 | unsigned long long fck; | 4095 | unsigned long long fck; |
3353 | 4096 | ||
3354 | fck = dsi_get_pll_hsdiv_dispc_rate(); | 4097 | fck = dsi_get_pll_hsdiv_dispc_rate(dsidev); |
3355 | 4098 | ||
3356 | dispc_cinfo.lck_div = dssdev->phy.dsi.div.lck_div; | 4099 | dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div; |
3357 | dispc_cinfo.pck_div = dssdev->phy.dsi.div.pck_div; | 4100 | dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div; |
3358 | 4101 | ||
3359 | r = dispc_calc_clock_rates(fck, &dispc_cinfo); | 4102 | r = dispc_calc_clock_rates(fck, &dispc_cinfo); |
3360 | if (r) { | 4103 | if (r) { |
@@ -3373,11 +4116,11 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) | |||
3373 | 4116 | ||
3374 | static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | 4117 | static int dsi_display_init_dsi(struct omap_dss_device *dssdev) |
3375 | { | 4118 | { |
4119 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4120 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
3376 | int r; | 4121 | int r; |
3377 | 4122 | ||
3378 | _dsi_print_reset_status(); | 4123 | r = dsi_pll_init(dsidev, true, true); |
3379 | |||
3380 | r = dsi_pll_init(dssdev, true, true); | ||
3381 | if (r) | 4124 | if (r) |
3382 | goto err0; | 4125 | goto err0; |
3383 | 4126 | ||
@@ -3385,8 +4128,10 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
3385 | if (r) | 4128 | if (r) |
3386 | goto err1; | 4129 | goto err1; |
3387 | 4130 | ||
3388 | dss_select_dispc_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC); | 4131 | dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); |
3389 | dss_select_dsi_clk_source(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI); | 4132 | dss_select_dsi_clk_source(dsi_module, dssdev->clocks.dsi.dsi_fclk_src); |
4133 | dss_select_lcd_clk_source(dssdev->manager->id, | ||
4134 | dssdev->clocks.dispc.channel.lcd_clk_src); | ||
3390 | 4135 | ||
3391 | DSSDBG("PLL OK\n"); | 4136 | DSSDBG("PLL OK\n"); |
3392 | 4137 | ||
@@ -3394,82 +4139,92 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) | |||
3394 | if (r) | 4139 | if (r) |
3395 | goto err2; | 4140 | goto err2; |
3396 | 4141 | ||
3397 | r = dsi_complexio_init(dssdev); | 4142 | r = dsi_cio_init(dssdev); |
3398 | if (r) | 4143 | if (r) |
3399 | goto err2; | 4144 | goto err2; |
3400 | 4145 | ||
3401 | _dsi_print_reset_status(); | 4146 | _dsi_print_reset_status(dsidev); |
3402 | 4147 | ||
3403 | dsi_proto_timings(dssdev); | 4148 | dsi_proto_timings(dssdev); |
3404 | dsi_set_lp_clk_divisor(dssdev); | 4149 | dsi_set_lp_clk_divisor(dssdev); |
3405 | 4150 | ||
3406 | if (1) | 4151 | if (1) |
3407 | _dsi_print_reset_status(); | 4152 | _dsi_print_reset_status(dsidev); |
3408 | 4153 | ||
3409 | r = dsi_proto_config(dssdev); | 4154 | r = dsi_proto_config(dssdev); |
3410 | if (r) | 4155 | if (r) |
3411 | goto err3; | 4156 | goto err3; |
3412 | 4157 | ||
3413 | /* enable interface */ | 4158 | /* enable interface */ |
3414 | dsi_vc_enable(0, 1); | 4159 | dsi_vc_enable(dsidev, 0, 1); |
3415 | dsi_vc_enable(1, 1); | 4160 | dsi_vc_enable(dsidev, 1, 1); |
3416 | dsi_vc_enable(2, 1); | 4161 | dsi_vc_enable(dsidev, 2, 1); |
3417 | dsi_vc_enable(3, 1); | 4162 | dsi_vc_enable(dsidev, 3, 1); |
3418 | dsi_if_enable(1); | 4163 | dsi_if_enable(dsidev, 1); |
3419 | dsi_force_tx_stop_mode_io(); | 4164 | dsi_force_tx_stop_mode_io(dsidev); |
3420 | 4165 | ||
3421 | return 0; | 4166 | return 0; |
3422 | err3: | 4167 | err3: |
3423 | dsi_complexio_uninit(); | 4168 | dsi_cio_uninit(dsidev); |
3424 | err2: | 4169 | err2: |
3425 | dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); | 4170 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); |
3426 | dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); | 4171 | dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); |
3427 | err1: | 4172 | err1: |
3428 | dsi_pll_uninit(); | 4173 | dsi_pll_uninit(dsidev, true); |
3429 | err0: | 4174 | err0: |
3430 | return r; | 4175 | return r; |
3431 | } | 4176 | } |
3432 | 4177 | ||
3433 | static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) | 4178 | static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, |
4179 | bool disconnect_lanes, bool enter_ulps) | ||
3434 | { | 4180 | { |
3435 | /* disable interface */ | 4181 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
3436 | dsi_if_enable(0); | 4182 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3437 | dsi_vc_enable(0, 0); | 4183 | int dsi_module = dsi_get_dsidev_id(dsidev); |
3438 | dsi_vc_enable(1, 0); | ||
3439 | dsi_vc_enable(2, 0); | ||
3440 | dsi_vc_enable(3, 0); | ||
3441 | 4184 | ||
3442 | dss_select_dispc_clk_source(DSS_CLK_SRC_FCK); | 4185 | if (enter_ulps && !dsi->ulps_enabled) |
3443 | dss_select_dsi_clk_source(DSS_CLK_SRC_FCK); | 4186 | dsi_enter_ulps(dsidev); |
3444 | dsi_complexio_uninit(); | 4187 | |
3445 | dsi_pll_uninit(); | 4188 | /* disable interface */ |
4189 | dsi_if_enable(dsidev, 0); | ||
4190 | dsi_vc_enable(dsidev, 0, 0); | ||
4191 | dsi_vc_enable(dsidev, 1, 0); | ||
4192 | dsi_vc_enable(dsidev, 2, 0); | ||
4193 | dsi_vc_enable(dsidev, 3, 0); | ||
4194 | |||
4195 | dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); | ||
4196 | dss_select_dsi_clk_source(dsi_module, OMAP_DSS_CLK_SRC_FCK); | ||
4197 | dsi_cio_uninit(dsidev); | ||
4198 | dsi_pll_uninit(dsidev, disconnect_lanes); | ||
3446 | } | 4199 | } |
3447 | 4200 | ||
3448 | static int dsi_core_init(void) | 4201 | static int dsi_core_init(struct platform_device *dsidev) |
3449 | { | 4202 | { |
3450 | /* Autoidle */ | 4203 | /* Autoidle */ |
3451 | REG_FLD_MOD(DSI_SYSCONFIG, 1, 0, 0); | 4204 | REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 0, 0); |
3452 | 4205 | ||
3453 | /* ENWAKEUP */ | 4206 | /* ENWAKEUP */ |
3454 | REG_FLD_MOD(DSI_SYSCONFIG, 1, 2, 2); | 4207 | REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 1, 2, 2); |
3455 | 4208 | ||
3456 | /* SIDLEMODE smart-idle */ | 4209 | /* SIDLEMODE smart-idle */ |
3457 | REG_FLD_MOD(DSI_SYSCONFIG, 2, 4, 3); | 4210 | REG_FLD_MOD(dsidev, DSI_SYSCONFIG, 2, 4, 3); |
3458 | 4211 | ||
3459 | _dsi_initialize_irq(); | 4212 | _dsi_initialize_irq(dsidev); |
3460 | 4213 | ||
3461 | return 0; | 4214 | return 0; |
3462 | } | 4215 | } |
3463 | 4216 | ||
3464 | int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | 4217 | int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) |
3465 | { | 4218 | { |
4219 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4220 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3466 | int r = 0; | 4221 | int r = 0; |
3467 | 4222 | ||
3468 | DSSDBG("dsi_display_enable\n"); | 4223 | DSSDBG("dsi_display_enable\n"); |
3469 | 4224 | ||
3470 | WARN_ON(!dsi_bus_is_locked()); | 4225 | WARN_ON(!dsi_bus_is_locked(dsidev)); |
3471 | 4226 | ||
3472 | mutex_lock(&dsi.lock); | 4227 | mutex_lock(&dsi->lock); |
3473 | 4228 | ||
3474 | r = omap_dss_start_device(dssdev); | 4229 | r = omap_dss_start_device(dssdev); |
3475 | if (r) { | 4230 | if (r) { |
@@ -3478,13 +4233,13 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | |||
3478 | } | 4233 | } |
3479 | 4234 | ||
3480 | enable_clocks(1); | 4235 | enable_clocks(1); |
3481 | dsi_enable_pll_clock(1); | 4236 | dsi_enable_pll_clock(dsidev, 1); |
3482 | 4237 | ||
3483 | r = _dsi_reset(); | 4238 | r = _dsi_reset(dsidev); |
3484 | if (r) | 4239 | if (r) |
3485 | goto err1; | 4240 | goto err1; |
3486 | 4241 | ||
3487 | dsi_core_init(); | 4242 | dsi_core_init(dsidev); |
3488 | 4243 | ||
3489 | r = dsi_display_init_dispc(dssdev); | 4244 | r = dsi_display_init_dispc(dssdev); |
3490 | if (r) | 4245 | if (r) |
@@ -3494,7 +4249,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) | |||
3494 | if (r) | 4249 | if (r) |
3495 | goto err2; | 4250 | goto err2; |
3496 | 4251 | ||
3497 | mutex_unlock(&dsi.lock); | 4252 | mutex_unlock(&dsi->lock); |
3498 | 4253 | ||
3499 | return 0; | 4254 | return 0; |
3500 | 4255 | ||
@@ -3502,39 +4257,46 @@ err2: | |||
3502 | dsi_display_uninit_dispc(dssdev); | 4257 | dsi_display_uninit_dispc(dssdev); |
3503 | err1: | 4258 | err1: |
3504 | enable_clocks(0); | 4259 | enable_clocks(0); |
3505 | dsi_enable_pll_clock(0); | 4260 | dsi_enable_pll_clock(dsidev, 0); |
3506 | omap_dss_stop_device(dssdev); | 4261 | omap_dss_stop_device(dssdev); |
3507 | err0: | 4262 | err0: |
3508 | mutex_unlock(&dsi.lock); | 4263 | mutex_unlock(&dsi->lock); |
3509 | DSSDBG("dsi_display_enable FAILED\n"); | 4264 | DSSDBG("dsi_display_enable FAILED\n"); |
3510 | return r; | 4265 | return r; |
3511 | } | 4266 | } |
3512 | EXPORT_SYMBOL(omapdss_dsi_display_enable); | 4267 | EXPORT_SYMBOL(omapdss_dsi_display_enable); |
3513 | 4268 | ||
3514 | void omapdss_dsi_display_disable(struct omap_dss_device *dssdev) | 4269 | void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, |
4270 | bool disconnect_lanes, bool enter_ulps) | ||
3515 | { | 4271 | { |
4272 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4273 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4274 | |||
3516 | DSSDBG("dsi_display_disable\n"); | 4275 | DSSDBG("dsi_display_disable\n"); |
3517 | 4276 | ||
3518 | WARN_ON(!dsi_bus_is_locked()); | 4277 | WARN_ON(!dsi_bus_is_locked(dsidev)); |
3519 | 4278 | ||
3520 | mutex_lock(&dsi.lock); | 4279 | mutex_lock(&dsi->lock); |
3521 | 4280 | ||
3522 | dsi_display_uninit_dispc(dssdev); | 4281 | dsi_display_uninit_dispc(dssdev); |
3523 | 4282 | ||
3524 | dsi_display_uninit_dsi(dssdev); | 4283 | dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps); |
3525 | 4284 | ||
3526 | enable_clocks(0); | 4285 | enable_clocks(0); |
3527 | dsi_enable_pll_clock(0); | 4286 | dsi_enable_pll_clock(dsidev, 0); |
3528 | 4287 | ||
3529 | omap_dss_stop_device(dssdev); | 4288 | omap_dss_stop_device(dssdev); |
3530 | 4289 | ||
3531 | mutex_unlock(&dsi.lock); | 4290 | mutex_unlock(&dsi->lock); |
3532 | } | 4291 | } |
3533 | EXPORT_SYMBOL(omapdss_dsi_display_disable); | 4292 | EXPORT_SYMBOL(omapdss_dsi_display_disable); |
3534 | 4293 | ||
3535 | int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) | 4294 | int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) |
3536 | { | 4295 | { |
3537 | dsi.te_enabled = enable; | 4296 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); |
4297 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4298 | |||
4299 | dsi->te_enabled = enable; | ||
3538 | return 0; | 4300 | return 0; |
3539 | } | 4301 | } |
3540 | EXPORT_SYMBOL(omapdss_dsi_enable_te); | 4302 | EXPORT_SYMBOL(omapdss_dsi_enable_te); |
@@ -3554,23 +4316,33 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, | |||
3554 | 4316 | ||
3555 | int dsi_init_display(struct omap_dss_device *dssdev) | 4317 | int dsi_init_display(struct omap_dss_device *dssdev) |
3556 | { | 4318 | { |
4319 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4320 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4321 | int dsi_module = dsi_get_dsidev_id(dsidev); | ||
4322 | |||
3557 | DSSDBG("DSI init\n"); | 4323 | DSSDBG("DSI init\n"); |
3558 | 4324 | ||
3559 | /* XXX these should be figured out dynamically */ | 4325 | /* XXX these should be figured out dynamically */ |
3560 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | | 4326 | dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | |
3561 | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; | 4327 | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; |
3562 | 4328 | ||
3563 | if (dsi.vdds_dsi_reg == NULL) { | 4329 | if (dsi->vdds_dsi_reg == NULL) { |
3564 | struct regulator *vdds_dsi; | 4330 | struct regulator *vdds_dsi; |
3565 | 4331 | ||
3566 | vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); | 4332 | vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); |
3567 | 4333 | ||
3568 | if (IS_ERR(vdds_dsi)) { | 4334 | if (IS_ERR(vdds_dsi)) { |
3569 | DSSERR("can't get VDDS_DSI regulator\n"); | 4335 | DSSERR("can't get VDDS_DSI regulator\n"); |
3570 | return PTR_ERR(vdds_dsi); | 4336 | return PTR_ERR(vdds_dsi); |
3571 | } | 4337 | } |
3572 | 4338 | ||
3573 | dsi.vdds_dsi_reg = vdds_dsi; | 4339 | dsi->vdds_dsi_reg = vdds_dsi; |
4340 | } | ||
4341 | |||
4342 | if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) { | ||
4343 | DSSERR("DSI%d can't support more than %d data lanes\n", | ||
4344 | dsi_module + 1, dsi->num_data_lanes); | ||
4345 | return -EINVAL; | ||
3574 | } | 4346 | } |
3575 | 4347 | ||
3576 | return 0; | 4348 | return 0; |
@@ -3578,11 +4350,13 @@ int dsi_init_display(struct omap_dss_device *dssdev) | |||
3578 | 4350 | ||
3579 | int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) | 4351 | int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) |
3580 | { | 4352 | { |
4353 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4354 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
3581 | int i; | 4355 | int i; |
3582 | 4356 | ||
3583 | for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { | 4357 | for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) { |
3584 | if (!dsi.vc[i].dssdev) { | 4358 | if (!dsi->vc[i].dssdev) { |
3585 | dsi.vc[i].dssdev = dssdev; | 4359 | dsi->vc[i].dssdev = dssdev; |
3586 | *channel = i; | 4360 | *channel = i; |
3587 | return 0; | 4361 | return 0; |
3588 | } | 4362 | } |
@@ -3595,6 +4369,9 @@ EXPORT_SYMBOL(omap_dsi_request_vc); | |||
3595 | 4369 | ||
3596 | int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) | 4370 | int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) |
3597 | { | 4371 | { |
4372 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4373 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4374 | |||
3598 | if (vc_id < 0 || vc_id > 3) { | 4375 | if (vc_id < 0 || vc_id > 3) { |
3599 | DSSERR("VC ID out of range\n"); | 4376 | DSSERR("VC ID out of range\n"); |
3600 | return -EINVAL; | 4377 | return -EINVAL; |
@@ -3605,13 +4382,13 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) | |||
3605 | return -EINVAL; | 4382 | return -EINVAL; |
3606 | } | 4383 | } |
3607 | 4384 | ||
3608 | if (dsi.vc[channel].dssdev != dssdev) { | 4385 | if (dsi->vc[channel].dssdev != dssdev) { |
3609 | DSSERR("Virtual Channel not allocated to display %s\n", | 4386 | DSSERR("Virtual Channel not allocated to display %s\n", |
3610 | dssdev->name); | 4387 | dssdev->name); |
3611 | return -EINVAL; | 4388 | return -EINVAL; |
3612 | } | 4389 | } |
3613 | 4390 | ||
3614 | dsi.vc[channel].vc_id = vc_id; | 4391 | dsi->vc[channel].vc_id = vc_id; |
3615 | 4392 | ||
3616 | return 0; | 4393 | return 0; |
3617 | } | 4394 | } |
@@ -3619,143 +4396,172 @@ EXPORT_SYMBOL(omap_dsi_set_vc_id); | |||
3619 | 4396 | ||
3620 | void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) | 4397 | void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) |
3621 | { | 4398 | { |
4399 | struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); | ||
4400 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); | ||
4401 | |||
3622 | if ((channel >= 0 && channel <= 3) && | 4402 | if ((channel >= 0 && channel <= 3) && |
3623 | dsi.vc[channel].dssdev == dssdev) { | 4403 | dsi->vc[channel].dssdev == dssdev) { |
3624 | dsi.vc[channel].dssdev = NULL; | 4404 | dsi->vc[channel].dssdev = NULL; |
3625 | dsi.vc[channel].vc_id = 0; | 4405 | dsi->vc[channel].vc_id = 0; |
3626 | } | 4406 | } |
3627 | } | 4407 | } |
3628 | EXPORT_SYMBOL(omap_dsi_release_vc); | 4408 | EXPORT_SYMBOL(omap_dsi_release_vc); |
3629 | 4409 | ||
3630 | void dsi_wait_pll_hsdiv_dispc_active(void) | 4410 | void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev) |
3631 | { | 4411 | { |
3632 | if (wait_for_bit_change(DSI_PLL_STATUS, 7, 1) != 1) | 4412 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 7, 1) != 1) |
3633 | DSSERR("%s (%s) not active\n", | 4413 | DSSERR("%s (%s) not active\n", |
3634 | dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), | 4414 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC), |
3635 | dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)); | 4415 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC)); |
3636 | } | 4416 | } |
3637 | 4417 | ||
3638 | void dsi_wait_pll_hsdiv_dsi_active(void) | 4418 | void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev) |
3639 | { | 4419 | { |
3640 | if (wait_for_bit_change(DSI_PLL_STATUS, 8, 1) != 1) | 4420 | if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 8, 1) != 1) |
3641 | DSSERR("%s (%s) not active\n", | 4421 | DSSERR("%s (%s) not active\n", |
3642 | dss_get_generic_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), | 4422 | dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI), |
3643 | dss_feat_get_clk_source_name(DSS_CLK_SRC_DSI_PLL_HSDIV_DSI)); | 4423 | dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI)); |
3644 | } | 4424 | } |
3645 | 4425 | ||
3646 | static void dsi_calc_clock_param_ranges(void) | 4426 | static void dsi_calc_clock_param_ranges(struct platform_device *dsidev) |
3647 | { | 4427 | { |
3648 | dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN); | 4428 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3649 | dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM); | 4429 | |
3650 | dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC); | 4430 | dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN); |
3651 | dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI); | 4431 | dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM); |
3652 | dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT); | 4432 | dsi->regm_dispc_max = |
3653 | dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT); | 4433 | dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC); |
3654 | dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); | 4434 | dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI); |
4435 | dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT); | ||
4436 | dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT); | ||
4437 | dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); | ||
3655 | } | 4438 | } |
3656 | 4439 | ||
3657 | static int dsi_init(struct platform_device *pdev) | 4440 | static int dsi_init(struct platform_device *dsidev) |
3658 | { | 4441 | { |
4442 | struct omap_display_platform_data *dss_plat_data; | ||
4443 | struct omap_dss_board_info *board_info; | ||
3659 | u32 rev; | 4444 | u32 rev; |
3660 | int r, i; | 4445 | int r, i, dsi_module = dsi_get_dsidev_id(dsidev); |
3661 | struct resource *dsi_mem; | 4446 | struct resource *dsi_mem; |
4447 | struct dsi_data *dsi; | ||
4448 | |||
4449 | dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); | ||
4450 | if (!dsi) { | ||
4451 | r = -ENOMEM; | ||
4452 | goto err0; | ||
4453 | } | ||
4454 | |||
4455 | dsi->pdev = dsidev; | ||
4456 | dsi_pdev_map[dsi_module] = dsidev; | ||
4457 | dev_set_drvdata(&dsidev->dev, dsi); | ||
4458 | |||
4459 | dss_plat_data = dsidev->dev.platform_data; | ||
4460 | board_info = dss_plat_data->board_data; | ||
4461 | dsi->dsi_mux_pads = board_info->dsi_mux_pads; | ||
3662 | 4462 | ||
3663 | spin_lock_init(&dsi.irq_lock); | 4463 | spin_lock_init(&dsi->irq_lock); |
3664 | spin_lock_init(&dsi.errors_lock); | 4464 | spin_lock_init(&dsi->errors_lock); |
3665 | dsi.errors = 0; | 4465 | dsi->errors = 0; |
3666 | 4466 | ||
3667 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS | 4467 | #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS |
3668 | spin_lock_init(&dsi.irq_stats_lock); | 4468 | spin_lock_init(&dsi->irq_stats_lock); |
3669 | dsi.irq_stats.last_reset = jiffies; | 4469 | dsi->irq_stats.last_reset = jiffies; |
3670 | #endif | 4470 | #endif |
3671 | 4471 | ||
3672 | mutex_init(&dsi.lock); | 4472 | mutex_init(&dsi->lock); |
3673 | sema_init(&dsi.bus_lock, 1); | 4473 | sema_init(&dsi->bus_lock, 1); |
3674 | 4474 | ||
3675 | dsi.workqueue = create_singlethread_workqueue("dsi"); | 4475 | INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work, |
3676 | if (dsi.workqueue == NULL) | ||
3677 | return -ENOMEM; | ||
3678 | |||
3679 | INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work, | ||
3680 | dsi_framedone_timeout_work_callback); | 4476 | dsi_framedone_timeout_work_callback); |
3681 | 4477 | ||
3682 | #ifdef DSI_CATCH_MISSING_TE | 4478 | #ifdef DSI_CATCH_MISSING_TE |
3683 | init_timer(&dsi.te_timer); | 4479 | init_timer(&dsi->te_timer); |
3684 | dsi.te_timer.function = dsi_te_timeout; | 4480 | dsi->te_timer.function = dsi_te_timeout; |
3685 | dsi.te_timer.data = 0; | 4481 | dsi->te_timer.data = 0; |
3686 | #endif | 4482 | #endif |
3687 | dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0); | 4483 | dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0); |
3688 | if (!dsi_mem) { | 4484 | if (!dsi_mem) { |
3689 | DSSERR("can't get IORESOURCE_MEM DSI\n"); | 4485 | DSSERR("can't get IORESOURCE_MEM DSI\n"); |
3690 | r = -EINVAL; | 4486 | r = -EINVAL; |
3691 | goto err1; | 4487 | goto err1; |
3692 | } | 4488 | } |
3693 | dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem)); | 4489 | dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); |
3694 | if (!dsi.base) { | 4490 | if (!dsi->base) { |
3695 | DSSERR("can't ioremap DSI\n"); | 4491 | DSSERR("can't ioremap DSI\n"); |
3696 | r = -ENOMEM; | 4492 | r = -ENOMEM; |
3697 | goto err1; | 4493 | goto err1; |
3698 | } | 4494 | } |
3699 | dsi.irq = platform_get_irq(dsi.pdev, 0); | 4495 | dsi->irq = platform_get_irq(dsi->pdev, 0); |
3700 | if (dsi.irq < 0) { | 4496 | if (dsi->irq < 0) { |
3701 | DSSERR("platform_get_irq failed\n"); | 4497 | DSSERR("platform_get_irq failed\n"); |
3702 | r = -ENODEV; | 4498 | r = -ENODEV; |
3703 | goto err2; | 4499 | goto err2; |
3704 | } | 4500 | } |
3705 | 4501 | ||
3706 | r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED, | 4502 | r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, |
3707 | "OMAP DSI1", dsi.pdev); | 4503 | dev_name(&dsidev->dev), dsi->pdev); |
3708 | if (r < 0) { | 4504 | if (r < 0) { |
3709 | DSSERR("request_irq failed\n"); | 4505 | DSSERR("request_irq failed\n"); |
3710 | goto err2; | 4506 | goto err2; |
3711 | } | 4507 | } |
3712 | 4508 | ||
3713 | /* DSI VCs initialization */ | 4509 | /* DSI VCs initialization */ |
3714 | for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { | 4510 | for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) { |
3715 | dsi.vc[i].mode = DSI_VC_MODE_L4; | 4511 | dsi->vc[i].mode = DSI_VC_MODE_L4; |
3716 | dsi.vc[i].dssdev = NULL; | 4512 | dsi->vc[i].dssdev = NULL; |
3717 | dsi.vc[i].vc_id = 0; | 4513 | dsi->vc[i].vc_id = 0; |
3718 | } | 4514 | } |
3719 | 4515 | ||
3720 | dsi_calc_clock_param_ranges(); | 4516 | dsi_calc_clock_param_ranges(dsidev); |
3721 | 4517 | ||
3722 | enable_clocks(1); | 4518 | enable_clocks(1); |
3723 | 4519 | ||
3724 | rev = dsi_read_reg(DSI_REVISION); | 4520 | rev = dsi_read_reg(dsidev, DSI_REVISION); |
3725 | dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n", | 4521 | dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", |
3726 | FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); | 4522 | FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); |
3727 | 4523 | ||
4524 | dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev); | ||
4525 | |||
3728 | enable_clocks(0); | 4526 | enable_clocks(0); |
3729 | 4527 | ||
3730 | return 0; | 4528 | return 0; |
3731 | err2: | 4529 | err2: |
3732 | iounmap(dsi.base); | 4530 | iounmap(dsi->base); |
3733 | err1: | 4531 | err1: |
3734 | destroy_workqueue(dsi.workqueue); | 4532 | kfree(dsi); |
4533 | err0: | ||
3735 | return r; | 4534 | return r; |
3736 | } | 4535 | } |
3737 | 4536 | ||
3738 | static void dsi_exit(void) | 4537 | static void dsi_exit(struct platform_device *dsidev) |
3739 | { | 4538 | { |
3740 | if (dsi.vdds_dsi_reg != NULL) { | 4539 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
3741 | regulator_put(dsi.vdds_dsi_reg); | 4540 | |
3742 | dsi.vdds_dsi_reg = NULL; | 4541 | if (dsi->vdds_dsi_reg != NULL) { |
4542 | if (dsi->vdds_dsi_enabled) { | ||
4543 | regulator_disable(dsi->vdds_dsi_reg); | ||
4544 | dsi->vdds_dsi_enabled = false; | ||
4545 | } | ||
4546 | |||
4547 | regulator_put(dsi->vdds_dsi_reg); | ||
4548 | dsi->vdds_dsi_reg = NULL; | ||
3743 | } | 4549 | } |
3744 | 4550 | ||
3745 | free_irq(dsi.irq, dsi.pdev); | 4551 | free_irq(dsi->irq, dsi->pdev); |
3746 | iounmap(dsi.base); | 4552 | iounmap(dsi->base); |
3747 | 4553 | ||
3748 | destroy_workqueue(dsi.workqueue); | 4554 | kfree(dsi); |
3749 | 4555 | ||
3750 | DSSDBG("omap_dsi_exit\n"); | 4556 | DSSDBG("omap_dsi_exit\n"); |
3751 | } | 4557 | } |
3752 | 4558 | ||
3753 | /* DSI1 HW IP initialisation */ | 4559 | /* DSI1 HW IP initialisation */ |
3754 | static int omap_dsi1hw_probe(struct platform_device *pdev) | 4560 | static int omap_dsi1hw_probe(struct platform_device *dsidev) |
3755 | { | 4561 | { |
3756 | int r; | 4562 | int r; |
3757 | dsi.pdev = pdev; | 4563 | |
3758 | r = dsi_init(pdev); | 4564 | r = dsi_init(dsidev); |
3759 | if (r) { | 4565 | if (r) { |
3760 | DSSERR("Failed to initialize DSI\n"); | 4566 | DSSERR("Failed to initialize DSI\n"); |
3761 | goto err_dsi; | 4567 | goto err_dsi; |
@@ -3764,9 +4570,12 @@ err_dsi: | |||
3764 | return r; | 4570 | return r; |
3765 | } | 4571 | } |
3766 | 4572 | ||
3767 | static int omap_dsi1hw_remove(struct platform_device *pdev) | 4573 | static int omap_dsi1hw_remove(struct platform_device *dsidev) |
3768 | { | 4574 | { |
3769 | dsi_exit(); | 4575 | struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); |
4576 | |||
4577 | dsi_exit(dsidev); | ||
4578 | WARN_ON(dsi->scp_clk_refcount > 0); | ||
3770 | return 0; | 4579 | return 0; |
3771 | } | 4580 | } |
3772 | 4581 | ||