diff options
author | Archit Taneja <archit@ti.com> | 2011-05-12 17:26:26 +0530 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2011-05-12 19:30:26 +0300 |
commit | a72b64b99918ee801a3a6abf5391e356752bcad0 (patch) | |
tree | 7e3c19fe6b77bf6187b503b5dec2b0e1e80e99d9 | |
parent | 41e03d15977978cdf8a5936f30ceb6088dda157a (diff) |
OMAP: DSS2: Pass platform_device as an argument in dsi functions
The DSI interface is represented as a platform device, using the DSI platform
driver(dsi.c). The current DSI driver design is capable of running only one
instance of a DSI device. On OMAP4, there are 2 very similar DSI modules which
can be represented as instances of "omapdss_dsi" platform device.
Add member "module" in "dssdev.phy.dsi" that tells us which DSI module's lanes
the panel is connected to. Modify dsi.c functions to take the device's
platform_device struct pointer, provide functions dsi_get_dsidev_from_dssdev()
and dsi_get_dsidev_from_id() take the panel's omap_dss_device and module number
respectively, and return the platform_device pointer. Currently, the dsi struct
is declared globally and is accessed when dsi data is needed. The new pdev
argument will be used later to provide the platform device's dsi related data.
Signed-off-by: Archit Taneja <archit@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
-rw-r--r-- | drivers/video/omap2/dss/dispc.c | 8 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dpi.c | 30 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dsi.c | 938 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.c | 12 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss.h | 31 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.h | 1 | ||||
-rw-r--r-- | include/video/omapdss.h | 2 |
7 files changed, 577 insertions, 445 deletions
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 10e9e8c16db..df8c9921763 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2239,6 +2239,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div, unsigned long dispc_fclk_rate(void) { + struct platform_device *dsidev; unsigned long r = 0; switch (dss_get_dispc_clk_source()) { @@ -2246,7 +2247,8 @@ unsigned long dispc_fclk_rate(void) r = dss_clk_get_rate(DSS_CLK_FCK); break; case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: - r = dsi_get_pll_hsdiv_dispc_rate(); + dsidev = dsi_get_dsidev_from_id(0); + r = dsi_get_pll_hsdiv_dispc_rate(dsidev); break; default: BUG(); @@ -2257,6 +2259,7 @@ unsigned long dispc_fclk_rate(void) unsigned long dispc_lclk_rate(enum omap_channel channel) { + struct platform_device *dsidev; int lcd; unsigned long r; u32 l; @@ -2270,7 +2273,8 @@ unsigned long dispc_lclk_rate(enum omap_channel channel) r = dss_clk_get_rate(DSS_CLK_FCK); break; case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: - r = dsi_get_pll_hsdiv_dispc_rate(); + dsidev = dsi_get_dsidev_from_id(0); + r = dsi_get_pll_hsdiv_dispc_rate(dsidev); break; default: BUG(); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 3c988b65ca1..4d661a949b8 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -37,8 +37,18 @@ static struct { struct regulator *vdds_dsi_reg; + struct platform_device *dsidev; } dpi; +static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) +{ + int dsi_module; + + dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1; + + return dsi_get_dsidev_from_id(dsi_module); +} + static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev) { if (dssdev->clocks.dispc.dispc_fclk_src == @@ -58,12 +68,12 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, bool is_tft, struct dispc_clock_info dispc_cinfo; int r; - r = dsi_pll_calc_clock_div_pck(is_tft, pck_req, &dsi_cinfo, - &dispc_cinfo); + r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, pck_req, + &dsi_cinfo, &dispc_cinfo); if (r) return r; - r = dsi_pll_set_clock_div(&dsi_cinfo); + r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo); if (r) return r; @@ -189,7 +199,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) if (dpi_use_dsi_pll(dssdev)) { dss_clk_enable(DSS_CLK_SYSCK); - r = dsi_pll_init(0, 1); + r = dsi_pll_init(dpi.dsidev, 0, 1); if (r) goto err3; } @@ -206,7 +216,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) err4: if (dpi_use_dsi_pll(dssdev)) - dsi_pll_uninit(true); + dsi_pll_uninit(dpi.dsidev, true); err3: if (dpi_use_dsi_pll(dssdev)) dss_clk_disable(DSS_CLK_SYSCK); @@ -227,7 +237,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) if (dpi_use_dsi_pll(dssdev)) { dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); - dsi_pll_uninit(true); + dsi_pll_uninit(dpi.dsidev, true); dss_clk_disable(DSS_CLK_SYSCK); } @@ -272,7 +282,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev, if (dpi_use_dsi_pll(dssdev)) { struct dsi_clock_info dsi_cinfo; - r = dsi_pll_calc_clock_div_pck(is_tft, + r = dsi_pll_calc_clock_div_pck(dpi.dsidev, is_tft, timings->pixel_clock * 1000, &dsi_cinfo, &dispc_cinfo); @@ -319,6 +329,12 @@ int dpi_init_display(struct omap_dss_device *dssdev) dpi.vdds_dsi_reg = vdds_dsi; } + if (dpi_use_dsi_pll(dssdev)) { + enum omap_dss_clk_source dispc_fclk_src = + dssdev->clocks.dispc.dispc_fclk_src; + dpi.dsidev = dpi_get_dsidev(dispc_fclk_src); + } + return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index b2945fed7ba..8d03eb6adcf 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -101,11 +101,11 @@ struct dsi_reg { u16 idx; }; #define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C) #define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010) -#define REG_GET(idx, start, end) \ - FLD_GET(dsi_read_reg(idx), start, end) +#define REG_GET(dsidev, idx, start, end) \ + FLD_GET(dsi_read_reg(dsidev, idx), start, end) -#define REG_FLD_MOD(idx, val, start, end) \ - dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end)) +#define REG_FLD_MOD(dsidev, idx, val, start, end) \ + dsi_write_reg(dsidev, idx, FLD_MOD(dsi_read_reg(dsidev, idx), val, start, end)) /* Global interrupts */ #define DSI_IRQ_VC0 (1 << 0) @@ -257,8 +257,7 @@ struct dsi_isr_tables { struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS]; }; -static struct -{ +static struct dsi_data { struct platform_device *pdev; void __iomem *base; int irq; @@ -330,17 +329,31 @@ static struct unsigned scp_clk_refcount; } dsi; +static struct platform_device *dsi_pdev_map[MAX_NUM_DSI]; + #ifdef DEBUG static unsigned int dsi_perf; module_param_named(dsi_perf, dsi_perf, bool, 0644); #endif -static inline void dsi_write_reg(const struct dsi_reg idx, u32 val) +static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev) +{ + return dsi_pdev_map[dssdev->phy.dsi.module]; +} + +struct platform_device *dsi_get_dsidev_from_id(int module) +{ + return dsi_pdev_map[module]; +} + +static inline void dsi_write_reg(struct platform_device *dsidev, + const struct dsi_reg idx, u32 val) { __raw_writel(val, dsi.base + idx.idx); } -static inline u32 dsi_read_reg(const struct dsi_reg idx) +static inline u32 dsi_read_reg(struct platform_device *dsidev, + const struct dsi_reg idx) { return __raw_readl(dsi.base + idx.idx); } @@ -366,7 +379,7 @@ void dsi_bus_unlock(struct omap_dss_device *dssdev) } EXPORT_SYMBOL(dsi_bus_unlock); -static bool dsi_bus_is_locked(void) +static bool dsi_bus_is_locked(struct platform_device *dsidev) { return dsi.bus_lock.count == 0; } @@ -376,12 +389,12 @@ static void dsi_completion_handler(void *data, u32 mask) complete((struct completion *)data); } -static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, - int value) +static inline int wait_for_bit_change(struct platform_device *dsidev, + const struct dsi_reg idx, int bitnum, int value) { int t = 100000; - while (REG_GET(idx, bitnum, bitnum) != value) { + while (REG_GET(dsidev, idx, bitnum, bitnum) != value) { if (--t == 0) return !value; } @@ -390,17 +403,17 @@ static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, } #ifdef DEBUG -static void dsi_perf_mark_setup(void) +static void dsi_perf_mark_setup(struct platform_device *dsidev) { dsi.perf_setup_time = ktime_get(); } -static void dsi_perf_mark_start(void) +static void dsi_perf_mark_start(struct platform_device *dsidev) { dsi.perf_start_time = ktime_get(); } -static void dsi_perf_show(const char *name) +static void dsi_perf_show(struct platform_device *dsidev, const char *name) { ktime_t t, setup_time, trans_time; u32 total_bytes; @@ -438,9 +451,9 @@ static void dsi_perf_show(const char *name) total_bytes * 1000 / total_us); } #else -#define dsi_perf_mark_setup() -#define dsi_perf_mark_start() -#define dsi_perf_show(x) +#define dsi_perf_mark_setup(x) +#define dsi_perf_mark_start(x) +#define dsi_perf_show(x, y) #endif static void print_irq_status(u32 status) @@ -546,7 +559,8 @@ static void print_irq_status_cio(u32 status) } #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS -static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus) +static void dsi_collect_irq_stats(struct platform_device *dsidev, u32 irqstatus, + u32 *vcstatus, u32 ciostatus) { int i; @@ -563,12 +577,13 @@ static void dsi_collect_irq_stats(u32 irqstatus, u32 *vcstatus, u32 ciostatus) spin_unlock(&dsi.irq_stats_lock); } #else -#define dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus) +#define dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus) #endif static int debug_irq; -static void dsi_handle_irq_errors(u32 irqstatus, u32 *vcstatus, u32 ciostatus) +static void dsi_handle_irq_errors(struct platform_device *dsidev, u32 irqstatus, + u32 *vcstatus, u32 ciostatus) { int i; @@ -638,12 +653,15 @@ static void dsi_handle_isrs(struct dsi_isr_tables *isr_tables, static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) { + struct platform_device *dsidev; u32 irqstatus, vcstatus[4], ciostatus; int i; + dsidev = (struct platform_device *) arg; + spin_lock(&dsi.irq_lock); - irqstatus = dsi_read_reg(DSI_IRQSTATUS); + irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS); /* IRQ is not for us */ if (!irqstatus) { @@ -651,9 +669,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) return IRQ_NONE; } - dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); + dsi_write_reg(dsidev, DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK); /* flush posted write */ - dsi_read_reg(DSI_IRQSTATUS); + dsi_read_reg(dsidev, DSI_IRQSTATUS); for (i = 0; i < 4; ++i) { if ((irqstatus & (1 << i)) == 0) { @@ -661,19 +679,19 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) continue; } - vcstatus[i] = dsi_read_reg(DSI_VC_IRQSTATUS(i)); + vcstatus[i] = dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i)); - dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus[i]); + dsi_write_reg(dsidev, DSI_VC_IRQSTATUS(i), vcstatus[i]); /* flush posted write */ - dsi_read_reg(DSI_VC_IRQSTATUS(i)); + dsi_read_reg(dsidev, DSI_VC_IRQSTATUS(i)); } if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) { - ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); + ciostatus = dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS); - dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus); + dsi_write_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS, ciostatus); /* flush posted write */ - dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS); + dsi_read_reg(dsidev, DSI_COMPLEXIO_IRQ_STATUS); } else { ciostatus = 0; } @@ -691,15 +709,16 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus); - dsi_handle_irq_errors(irqstatus, vcstatus, ciostatus); + dsi_handle_irq_errors(dsidev, irqstatus, vcstatus, ciostatus); - dsi_collect_irq_stats(irqstatus, vcstatus, ciostatus); + dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus); return IRQ_HANDLED; } /* dsi.irq_lock has to be locked by the caller */ -static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array, +static void _omap_dsi_configure_irqs(struct platform_device *dsidev, + struct dsi_isr_data *isr_array, unsigned isr_array_size, u32 default_mask, const struct dsi_reg enable_reg, const struct dsi_reg status_reg) @@ -720,47 +739,47 @@ static void _omap_dsi_configure_irqs(struct dsi_isr_data *isr_array, mask |= isr_data->mask; } - old_mask = dsi_read_reg(enable_reg); + old_mask = dsi_read_reg(dsidev, enable_reg); /* clear the irqstatus for newly enabled irqs */ - dsi_write_reg(status_reg, (mask ^ old_mask) & mask); - dsi_write_reg(enable_reg, mask); + dsi_write_reg(dsidev, status_reg, (mask ^ old_mask) & mask); + dsi_write_reg(dsidev, enable_reg, mask); /* flush posted writes */ - dsi_read_reg(enable_reg); - dsi_read_reg(status_reg); + dsi_read_reg(dsidev, enable_reg); + dsi_read_reg(dsidev, status_reg); } /* dsi.irq_lock has to be locked by the caller */ -static void _omap_dsi_set_irqs(void) +static void _omap_dsi_set_irqs(struct platform_device *dsidev) { u32 mask = DSI_IRQ_ERROR_MASK; #ifdef DSI_CATCH_MISSING_TE mask |= DSI_IRQ_TE_TRIGGER; #endif - _omap_dsi_configure_irqs(dsi.isr_tables.isr_table, + _omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table, ARRAY_SIZE(dsi.isr_tables.isr_table), mask, DSI_IRQENABLE, DSI_IRQSTATUS); } /* dsi.irq_lock has to be locked by the caller */ -static void _omap_dsi_set_irqs_vc(int vc) +static void _omap_dsi_set_irqs_vc(struct platform_device *dsidev, int vc) { - _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_vc[vc], + _omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_vc[vc], ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]), DSI_VC_IRQ_ERROR_MASK, DSI_VC_IRQENABLE(vc), DSI_VC_IRQSTATUS(vc)); } /* dsi.irq_lock has to be locked by the caller */ -static void _omap_dsi_set_irqs_cio(void) +static void _omap_dsi_set_irqs_cio(struct platform_device *dsidev) { - _omap_dsi_configure_irqs(dsi.isr_tables.isr_table_cio, + _omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_cio, ARRAY_SIZE(dsi.isr_tables.isr_table_cio), DSI_CIO_IRQ_ERROR_MASK, DSI_COMPLEXIO_IRQ_ENABLE, DSI_COMPLEXIO_IRQ_STATUS); } -static void _dsi_initialize_irq(void) +static void _dsi_initialize_irq(struct platform_device *dsidev) { unsigned long flags; int vc; @@ -769,10 +788,10 @@ static void _dsi_initialize_irq(void) memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables)); - _omap_dsi_set_irqs(); + _omap_dsi_set_irqs(dsidev); for (vc = 0; vc < 4; ++vc) - _omap_dsi_set_irqs_vc(vc); - _omap_dsi_set_irqs_cio(); + _omap_dsi_set_irqs_vc(dsidev, vc); + _omap_dsi_set_irqs_cio(dsidev); spin_unlock_irqrestore(&dsi.irq_lock, flags); } @@ -833,7 +852,8 @@ static int _dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask, return -EINVAL; } -static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask) +static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr, + void *arg, u32 mask) { unsigned long flags; int r; @@ -844,14 +864,15 @@ static int dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask) ARRAY_SIZE(dsi.isr_tables.isr_table)); if (r == 0) - _omap_dsi_set_irqs(); + _omap_dsi_set_irqs(dsidev); spin_unlock_irqrestore(&dsi.irq_lock, flags); return r; } -static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask) +static int dsi_unregister_isr(struct platform_device *dsidev, + omap_dsi_isr_t isr, void *arg, u32 mask) { unsigned long flags; int r; @@ -862,15 +883,15 @@ static int dsi_unregister_isr(omap_dsi_isr_t isr, void *arg, u32 mask) ARRAY_SIZE(dsi.isr_tables.isr_table)); if (r == 0) - _omap_dsi_set_irqs(); + _omap_dsi_set_irqs(dsidev); spin_unlock_irqrestore(&dsi.irq_lock, flags); return r; } -static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, - u32 mask) +static int dsi_register_isr_vc(struct platform_device *dsidev, int channel, + omap_dsi_isr_t isr, void *arg, u32 mask) { unsigned long flags; int r; @@ -882,15 +903,15 @@ static int dsi_register_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); if (r == 0) - _omap_dsi_set_irqs_vc(channel); + _omap_dsi_set_irqs_vc(dsidev, channel); spin_unlock_irqrestore(&dsi.irq_lock, flags); return r; } -static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, - u32 mask) +static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel, + omap_dsi_isr_t isr, void *arg, u32 mask) { unsigned long flags; int r; @@ -902,14 +923,15 @@ static int dsi_unregister_isr_vc(int channel, omap_dsi_isr_t isr, void *arg, ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); if (r == 0) - _omap_dsi_set_irqs_vc(channel); + _omap_dsi_set_irqs_vc(dsidev, channel); spin_unlock_irqrestore(&dsi.irq_lock, flags); return r; } -static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) +static int dsi_register_isr_cio(struct platform_device *dsidev, + omap_dsi_isr_t isr, void *arg, u32 mask) { unsigned long flags; int r; @@ -920,14 +942,15 @@ static int dsi_register_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); if (r == 0) - _omap_dsi_set_irqs_cio(); + _omap_dsi_set_irqs_cio(dsidev); spin_unlock_irqrestore(&dsi.irq_lock, flags); return r; } -static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) +static int dsi_unregister_isr_cio(struct platform_device *dsidev, + omap_dsi_isr_t isr, void *arg, u32 mask) { unsigned long flags; int r; @@ -938,14 +961,14 @@ static int dsi_unregister_isr_cio(omap_dsi_isr_t isr, void *arg, u32 mask) ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); if (r == 0) - _omap_dsi_set_irqs_cio(); + _omap_dsi_set_irqs_cio(dsidev); spin_unlock_irqrestore(&dsi.irq_lock, flags); return r; } -static u32 dsi_get_errors(void) +static u32 dsi_get_errors(struct platform_device *dsidev) { unsigned long flags; u32 e; @@ -966,7 +989,8 @@ static inline void enable_clocks(bool enable) } /* source clock for DSI PLL. this could also be PCLKFREE */ -static inline void dsi_enable_pll_clock(bool enable) +static inline void dsi_enable_pll_clock(struct platform_device *dsidev, + bool enable) { if (enable) dss_clk_enable(DSS_CLK_SYSCK); @@ -974,13 +998,13 @@ static inline void dsi_enable_pll_clock(bool enable) dss_clk_disable(DSS_CLK_SYSCK); if (enable && dsi.pll_locked) { - if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) + if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) DSSERR("cannot lock PLL when enabling clocks\n"); } } #ifdef DEBUG -static void _dsi_print_reset_status(void) +static void _dsi_print_reset_status(struct platform_device *dsidev) { u32 l; int b0, b1, b2; @@ -991,14 +1015,14 @@ static void _dsi_print_reset_status(void) /* A dummy read using the SCP interface to any DSIPHY register is * required after DSIPHY reset to complete the reset of the DSI complex * I/O. */ - l = dsi_read_reg(DSI_DSIPHY_CFG5); + l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); printk(KERN_DEBUG "DSI resets: "); - l = dsi_read_reg(DSI_PLL_STATUS); + l = dsi_read_reg(dsidev, DSI_PLL_STATUS); printk("PLL (%d) ", FLD_GET(l, 0, 0)); - l = dsi_read_reg(DSI_COMPLEXIO_CFG1); + l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1); printk("CIO (%d) ", FLD_GET(l, 29, 29)); if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) { @@ -1011,7 +1035,7 @@ static void _dsi_print_reset_status(void) b2 = 26; } - l = dsi_read_reg(DSI_DSIPHY_CFG5); + l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5); printk("PHY (%x%x%x, %d, %d, %d)\n", FLD_GET(l, b0, b0), FLD_GET(l, b1, b1), @@ -1021,17 +1045,17 @@ static void _dsi_print_reset_status(void) FLD_GET(l, 31, 31)); } #else -#define _dsi_print_reset_status() +#define _dsi_print_reset_status(x) #endif -static inline int dsi_if_enable(bool enable) +static inline int dsi_if_enable(struct platform_device *dsidev, bool enable) { DSSDBG("dsi_if_enable(%d)\n", enable); enable = enable ? 1 : 0; - REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */ + REG_FLD_MOD(dsidev, DSI_CTRL, enable, 0, 0); /* IF_EN */ - if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) { + if (wait_for_bit_change(dsidev, DSI_CTRL, 0, enable) != enable) { DSSERR("Failed to set dsi_if_enable to %d\n", enable); return -EIO; } @@ -1039,22 +1063,22 @@ static inline int dsi_if_enable(bool enable) return 0; } -unsigned long dsi_get_pll_hsdiv_dispc_rate(void) +unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) { return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk; } -static unsigned long dsi_get_pll_hsdiv_dsi_rate(void) +static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev) { return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk; } -static unsigned long dsi_get_txbyteclkhs(void) +static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev) { return dsi.current_cinfo.clkin4ddr / 16; } -static unsigned long dsi_fclk_rate(void) +static unsigned long dsi_fclk_rate(struct platform_device *dsidev) { unsigned long r; @@ -1063,7 +1087,7 @@ static unsigned long dsi_fclk_rate(void) r = dss_clk_get_rate(DSS_CLK_FCK); } else { /* DSI FCLK source is dsi_pll_hsdiv_dsi_clk */ - r = dsi_get_pll_hsdiv_dsi_rate(); + r = dsi_get_pll_hsdiv_dsi_rate(dsidev); } return r; @@ -1071,6 +1095,7 @@ static unsigned long dsi_fclk_rate(void) static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) { + struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); unsigned long dsi_fclk; unsigned lp_clk_div; unsigned long lp_clk; @@ -1080,7 +1105,7 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max) return -EINVAL; - dsi_fclk = dsi_fclk_rate(); + dsi_fclk = dsi_fclk_rate(dsidev); lp_clk = dsi_fclk / 2 / lp_clk_div; @@ -1088,25 +1113,26 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) dsi.current_cinfo.lp_clk = lp_clk; dsi.current_cinfo.lp_clk_div = lp_clk_div; - REG_FLD_MOD(DSI_CLK_CTRL, lp_clk_div, 12, 0); /* LP_CLK_DIVISOR */ + /* LP_CLK_DIVISOR */ + REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0); - REG_FLD_MOD(DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, - 21, 21); /* LP_RX_SYNCHRO_ENABLE */ + /* LP_RX_SYNCHRO_ENABLE */ + REG_FLD_MOD(dsidev, DSI_CLK_CTRL, dsi_fclk > 30000000 ? 1 : 0, 21, 21); return 0; } -static void dsi_enable_scp_clk(void) +static void dsi_enable_scp_clk(struct platform_device *dsidev) { if (dsi.scp_clk_refcount++ == 0) - REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */ + REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */ } -static void dsi_disable_scp_clk(void) +static void dsi_disable_scp_clk(struct platform_device *dsidev) { WARN_ON(dsi.scp_clk_refcount == 0); if (--dsi.scp_clk_refcount == 0) - REG_FLD_MOD(DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */ + REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */ } enum dsi_pll_power_state { @@ -1116,7 +1142,8 @@ enum dsi_pll_power_state { DSI_PLL_POWER_ON_DIV = 0x3, }; -static int dsi_pll_power(enum dsi_pll_power_state state) +static int dsi_pll_power(struct platform_device *dsidev, + enum dsi_pll_power_state state) { int t = 0; @@ -1125,10 +1152,11 @@ static int dsi_pll_power(enum dsi_pll_power_state state) state == DSI_PLL_POWER_ON_DIV) state = DSI_PLL_POWER_ON_ALL; - REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */ + /* PLL_PWR_CMD */ + REG_FLD_MOD(dsidev, DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_STATUS */ - while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) { + while (FLD_GET(dsi_read_reg(dsidev, DSI_CLK_CTRL), 29, 28) != state) { if (++t > 1000) { DSSERR("Failed to set DSI PLL power mode to %d\n", state); @@ -1195,8 +1223,8 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, return 0; } -int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck, - struct dsi_clock_info *dsi_cinfo, +int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, + unsigned long req_pck, struct dsi_clock_info *dsi_cinfo, struct dispc_clock_info *dispc_cinfo) { struct dsi_clock_info cur, best; @@ -1332,7 +1360,8 @@ found: return 0; } -int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) +int dsi_pll_set_clock_div(struct platform_device *dsidev, + struct dsi_clock_info *cinfo) { int r = 0; u32 l; @@ -1393,9 +1422,10 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, ®m_dsi_start, ®m_dsi_end); - REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */ + /* DSI_PLL_AUTOMODE = manual */ + REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0); - l = dsi_read_reg(DSI_PLL_CONFIGURATION1); + l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1); l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */ /* DSI_PLL_REGN */ l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end); @@ -1407,7 +1437,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) /* DSIPROTO_CLOCK_DIV */ l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0, regm_dsi_start, regm_dsi_end); - dsi_write_reg(DSI_PLL_CONFIGURATION1, l); + dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l); BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max); @@ -1419,7 +1449,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) 0x7; } - l = dsi_read_reg(DSI_PLL_CONFIGURATION2); + l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */ @@ -1430,17 +1460,17 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */ l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */ l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */ - dsi_write_reg(DSI_PLL_CONFIGURATION2, l); + dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); - REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ + REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */ - if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) { + if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) { DSSERR("dsi pll go bit not going down.\n"); r = -EIO; goto err; } - if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) { + if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) { DSSERR("cannot lock PLL\n"); r = -EIO; goto err; @@ -1448,7 +1478,7 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) dsi.pll_locked = 1; - l = dsi_read_reg(DSI_PLL_CONFIGURATION2); + l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */ l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */ @@ -1463,14 +1493,15 @@ int dsi_pll_set_clock_div(struct dsi_clock_info *cinfo) l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */ l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */ l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */ - dsi_write_reg(DSI_PLL_CONFIGURATION2, l); + dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l); DSSDBG("PLL config done\n"); err: return r; } -int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv) +int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, + bool enable_hsdiv) { int r = 0; enum dsi_pll_power_state pwstate; @@ -1491,11 +1522,11 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv) } enable_clocks(1); - dsi_enable_pll_clock(1); + dsi_enable_pll_clock(dsidev, 1); /* * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. */ - dsi_enable_scp_clk(); + dsi_enable_scp_clk(dsidev); if (!dsi.vdds_dsi_enabled) { r = regulator_enable(dsi.vdds_dsi_reg); @@ -1507,7 +1538,7 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv) /* XXX PLL does not come out of reset without this... */ dispc_pck_free_enable(1); - if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) { + if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 0, 1) != 1) { DSSERR("PLL not coming out of reset.\n"); r = -ENODEV; dispc_pck_free_enable(0); @@ -1527,7 +1558,7 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv) else pwstate = DSI_PLL_POWER_OFF; - r = dsi_pll_power(pwstate); + r = dsi_pll_power(dsidev, pwstate); if (r) goto err1; @@ -1541,31 +1572,32 @@ err1: dsi.vdds_dsi_enabled = false; } err0: - dsi_disable_scp_clk(); + dsi_disable_scp_clk(dsidev); enable_clocks(0); - dsi_enable_pll_clock(0); + dsi_enable_pll_clock(dsidev, 0); return r; } -void dsi_pll_uninit(bool disconnect_lanes) +void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) { dsi.pll_locked = 0; - dsi_pll_power(DSI_PLL_POWER_OFF); + dsi_pll_power(dsidev, DSI_PLL_POWER_OFF); if (disconnect_lanes) { WARN_ON(!dsi.vdds_dsi_enabled); regulator_disable(dsi.vdds_dsi_reg); dsi.vdds_dsi_enabled = false; } - dsi_disable_scp_clk(); + dsi_disable_scp_clk(dsidev); enable_clocks(0); - dsi_enable_pll_clock(0); + dsi_enable_pll_clock(dsidev, 0); DSSDBG("PLL uninit done\n"); } void dsi_dump_clocks(struct seq_file *s) { + struct platform_device *dsidev = dsi_get_dsidev_from_id(0); struct dsi_clock_info *cinfo = &dsi.current_cinfo; enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; @@ -1606,12 +1638,12 @@ void dsi_dump_clocks(struct seq_file *s) dss_get_generic_clk_source_name(dsi_clk_src), dss_feat_get_clk_source_name(dsi_clk_src)); - seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate()); + seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); seq_printf(s, "DDR_CLK\t\t%lu\n", cinfo->clkin4ddr / 4); - seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs()); + seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev)); seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); @@ -1714,10 +1746,12 @@ void dsi_dump_irqs(struct seq_file *s) void dsi_dump_regs(struct seq_file *s) { -#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r)) + struct platform_device *dsidev = dsi_get_dsidev_from_id(0); + +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(dsidev, r)) dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK); - dsi_enable_scp_clk(); + dsi_enable_scp_clk(dsidev); DUMPREG(DSI_REVISION); DUMPREG(DSI_SYSCONFIG); @@ -1789,7 +1823,7 @@ void dsi_dump_regs(struct seq_file *s) DUMPREG(DSI_PLL_CONFIGURATION1); DUMPREG(DSI_PLL_CONFIGURATION2); - dsi_disable_scp_clk(); + dsi_disable_scp_clk(dsidev); dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK); #undef DUMPREG } @@ -1800,15 +1834,17 @@ enum dsi_cio_power_state { DSI_COMPLEXIO_POWER_ULPS = 0x2, }; -static int dsi_cio_power(enum dsi_cio_power_state state) +static int dsi_cio_power(struct platform_device *dsidev, + enum dsi_cio_power_state state) { int t = 0; /* PWR_CMD */ - REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27); + REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG1, state, 28, 27); /* PWR_STATUS */ - while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) { + while (FLD_GET(dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1), + 26, 25) != state) { if (++t > 1000) { DSSERR("failed to set complexio power state to " "%d\n", state); @@ -1822,6 +1858,7 @@ static int dsi_cio_power(enum dsi_cio_power_state state) static void dsi_set_lane_config(struct omap_dss_device *dssdev) { + struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); u32 r; int clk_lane = dssdev->phy.dsi.clk_lane; @@ -1831,14 +1868,14 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev) int data1_pol = dssdev->phy.dsi.data1_pol; int data2_pol = dssdev->phy.dsi.data2_pol; - r = dsi_read_reg(DSI_COMPLEXIO_CFG1); + r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1); r = FLD_MOD(r, clk_lane, 2, 0); r = FLD_MOD(r, clk_pol, 3, 3); r = FLD_MOD(r, data1_lane, 6, 4); r = FLD_MOD(r, data1_pol, 7, 7); r = FLD_MOD(r, data2_lane, 10, 8); r = FLD_MOD(r, data2_pol, 11, 11); - dsi_write_reg(DSI_COMPLEXIO_CFG1, r); + dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r); /* The configuration of the DSI complex I/O (number of data lanes, position, differential order) should not be changed while @@ -1852,27 +1889,27 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev) DSI complex I/O configuration is unknown. */ /* - REG_FLD_MOD(DSI_CTRL, 1, 0, 0); - REG_FLD_MOD(DSI_CTRL, 0, 0, 0); - REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); - REG_FLD_MOD(DSI_CTRL, 1, 0, 0); + REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0); + REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0); + REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); + REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0); */ } -static inline unsigned ns2ddr(unsigned ns) +static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns) { /* convert time in ns to ddr ticks, rounding up */ unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; } -static inline unsigned ddr2ns(unsigned ddr) +static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr) { unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; return ddr * 1000 * 1000 / (ddr_clk / 1000); } -static void dsi_cio_timings(void) +static void dsi_cio_timings(struct platform_device *dsidev) { u32 r; u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit; @@ -1884,67 +1921,68 @@ static void dsi_cio_timings(void) /* 1 * DDR_CLK = 2 * UI */ /* min 40ns + 4*UI max 85ns + 6*UI */ - ths_prepare = ns2ddr(70) + 2; + ths_prepare = ns2ddr(dsidev, 70) + 2; /* min 145ns + 10*UI */ - ths_prepare_ths_zero = ns2ddr(175) + 2; + ths_prepare_ths_zero = ns2ddr(dsidev, 175) + 2; /* min max(8*UI, 60ns+4*UI) */ - ths_trail = ns2ddr(60) + 5; + ths_trail = ns2ddr(dsidev, 60) + 5; |