The dsi related data structure currently creates one global instance of itself which is accessed by dsi functions. Remove this global structure instance and declare the struct as dsi_data. Modify dsi_init() to allocate a "dsi_data" structure for each platform device instance. Link this data with the device's platform_device pointer. Create the function dsi_get_dsi_data() which takes the pdev and return a pointer to the device's dsi_data. Signed-off-by: Archit Taneja <archit@xxxxxx> --- drivers/video/omap2/dss/dsi.c | 655 +++++++++++++++++++++++++---------------- 1 files changed, 395 insertions(+), 260 deletions(-) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index c0e272b..627869e 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -34,6 +34,7 @@ #include <linux/wait.h> #include <linux/workqueue.h> #include <linux/sched.h> +#include <linux/slab.h> #include <plat/display.h> #include <plat/clock.h> @@ -257,7 +258,7 @@ struct dsi_isr_tables { struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS]; }; -static struct dsi_data { +struct dsi_data { struct platform_device *pdev; void __iomem *base; int irq; @@ -327,7 +328,7 @@ static struct dsi_data { unsigned long lpdiv_max; unsigned scp_clk_refcount; -} dsi; +}; static struct platform_device *dsi_pdev_map[MAX_NUM_DSI]; @@ -336,6 +337,11 @@ static unsigned int dsi_perf; module_param_named(dsi_perf, dsi_perf, bool, 0644); #endif +static inline struct dsi_data *dsi_get_dsi_data(struct platform_device *dsidev) +{ + return dev_get_drvdata(&dsidev->dev); +} + static inline struct platform_device *dsi_get_dsi_device(struct omap_dss_device *dssdev) { return dsi_pdev_map[dssdev->phy.dsi.module]; @@ -349,13 +355,17 @@ struct platform_device *dsi_get_dsi_device_module(int 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); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + __raw_writel(val, dsi->base + idx.idx); } static inline u32 dsi_read_reg(struct platform_device *dsidev, const struct dsi_reg idx) { - return __raw_readl(dsi.base + idx.idx); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + return __raw_readl(dsi->base + idx.idx); } @@ -369,19 +379,27 @@ void dsi_restore_context(void) void dsi_bus_lock(struct omap_dss_device *dssdev) { - down(&dsi.bus_lock); + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + down(&dsi->bus_lock); } EXPORT_SYMBOL(dsi_bus_lock); void dsi_bus_unlock(struct omap_dss_device *dssdev) { - up(&dsi.bus_lock); + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + up(&dsi->bus_lock); } EXPORT_SYMBOL(dsi_bus_unlock); static bool dsi_bus_is_locked(struct platform_device *dsidev) { - return dsi.bus_lock.count == 0; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + return dsi->bus_lock.count == 0; } static void dsi_completion_handler(void *data, u32 mask) @@ -405,16 +423,19 @@ static inline int wait_for_bit_change(struct platform_device *dsidev, #ifdef DEBUG static void dsi_perf_mark_setup(struct platform_device *dsidev) { - dsi.perf_setup_time = ktime_get(); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + dsi->perf_setup_time = ktime_get(); } static void dsi_perf_mark_start(struct platform_device *dsidev) { - dsi.perf_start_time = ktime_get(); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + dsi->perf_start_time = ktime_get(); } static void dsi_perf_show(struct platform_device *dsidev, const char *name) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); ktime_t t, setup_time, trans_time; u32 total_bytes; u32 setup_us, trans_us, total_us; @@ -424,21 +445,21 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name) t = ktime_get(); - setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time); + setup_time = ktime_sub(dsi->perf_start_time, dsi->perf_setup_time); setup_us = (u32)ktime_to_us(setup_time); if (setup_us == 0) setup_us = 1; - trans_time = ktime_sub(t, dsi.perf_start_time); + trans_time = ktime_sub(t, dsi->perf_start_time); trans_us = (u32)ktime_to_us(trans_time); if (trans_us == 0) trans_us = 1; total_us = setup_us + trans_us; - total_bytes = dsi.update_region.w * - dsi.update_region.h * - dsi.update_region.device->ctrl.pixel_size / 8; + total_bytes = dsi->update_region.w * + dsi->update_region.h * + dsi->update_region.device->ctrl.pixel_size / 8; printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), " "%u bytes, %u kbytes/sec\n", @@ -562,19 +583,20 @@ static void print_irq_status_cio(u32 status) static void dsi_collect_irq_stats(struct platform_device *dsidev, u32 irqstatus, u32 *vcstatus, u32 ciostatus) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int i; - spin_lock(&dsi.irq_stats_lock); + spin_lock(&dsi->irq_stats_lock); - dsi.irq_stats.irq_count++; - dss_collect_irq_stats(irqstatus, dsi.irq_stats.dsi_irqs); + dsi->irq_stats.irq_count++; + dss_collect_irq_stats(irqstatus, dsi->irq_stats.dsi_irqs); for (i = 0; i < 4; ++i) - dss_collect_irq_stats(vcstatus[i], dsi.irq_stats.vc_irqs[i]); + dss_collect_irq_stats(vcstatus[i], dsi->irq_stats.vc_irqs[i]); - dss_collect_irq_stats(ciostatus, dsi.irq_stats.cio_irqs); + dss_collect_irq_stats(ciostatus, dsi->irq_stats.cio_irqs); - spin_unlock(&dsi.irq_stats_lock); + spin_unlock(&dsi->irq_stats_lock); } #else #define dsi_collect_irq_stats(dsidev, irqstatus, vcstatus, ciostatus) @@ -585,14 +607,15 @@ static int debug_irq; static void dsi_handle_irq_errors(struct platform_device *dsidev, u32 irqstatus, u32 *vcstatus, u32 ciostatus) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int i; if (irqstatus & DSI_IRQ_ERROR_MASK) { DSSERR("DSI error, irqstatus %x\n", irqstatus); print_irq_status(irqstatus); - spin_lock(&dsi.errors_lock); - dsi.errors |= irqstatus & DSI_IRQ_ERROR_MASK; - spin_unlock(&dsi.errors_lock); + spin_lock(&dsi->errors_lock); + dsi->errors |= irqstatus & DSI_IRQ_ERROR_MASK; + spin_unlock(&dsi->errors_lock); } else if (debug_irq) { print_irq_status(irqstatus); } @@ -654,18 +677,20 @@ 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; + struct dsi_data *dsi; u32 irqstatus, vcstatus[4], ciostatus; int i; dsidev = (struct platform_device *) arg; + dsi = dsi_get_dsi_data(dsidev); - spin_lock(&dsi.irq_lock); + spin_lock(&dsi->irq_lock); irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS); /* IRQ is not for us */ if (!irqstatus) { - spin_unlock(&dsi.irq_lock); + spin_unlock(&dsi->irq_lock); return IRQ_NONE; } @@ -698,16 +723,17 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) #ifdef DSI_CATCH_MISSING_TE if (irqstatus & DSI_IRQ_TE_TRIGGER) - del_timer(&dsi.te_timer); + del_timer(&dsi->te_timer); #endif /* make a copy and unlock, so that isrs can unregister * themselves */ - memcpy(&dsi.isr_tables_copy, &dsi.isr_tables, sizeof(dsi.isr_tables)); + memcpy(&dsi->isr_tables_copy, &dsi->isr_tables, + sizeof(dsi->isr_tables)); - spin_unlock(&dsi.irq_lock); + spin_unlock(&dsi->irq_lock); - dsi_handle_isrs(&dsi.isr_tables_copy, irqstatus, vcstatus, ciostatus); + dsi_handle_isrs(&dsi->isr_tables_copy, irqstatus, vcstatus, ciostatus); dsi_handle_irq_errors(dsidev, irqstatus, vcstatus, ciostatus); @@ -716,7 +742,7 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) return IRQ_HANDLED; } -/* dsi.irq_lock has to be locked by the caller */ +/* dsi->irq_lock has to be locked by the caller */ static void _omap_dsi_configure_irqs(struct platform_device *dsidev, struct dsi_isr_data *isr_array, unsigned isr_array_size, u32 default_mask, @@ -749,51 +775,57 @@ static void _omap_dsi_configure_irqs(struct platform_device *dsidev, dsi_read_reg(dsidev, status_reg); } -/* dsi.irq_lock has to be locked by the caller */ +/* dsi->irq_lock has to be locked by the caller */ static void _omap_dsi_set_irqs(struct platform_device *dsidev) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); u32 mask = DSI_IRQ_ERROR_MASK; #ifdef DSI_CATCH_MISSING_TE mask |= DSI_IRQ_TE_TRIGGER; #endif - _omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table, - ARRAY_SIZE(dsi.isr_tables.isr_table), mask, + _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 */ +/* dsi->irq_lock has to be locked by the caller */ static void _omap_dsi_set_irqs_vc(struct platform_device *dsidev, int vc) { - _omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_vc[vc], - ARRAY_SIZE(dsi.isr_tables.isr_table_vc[vc]), + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + _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 */ +/* dsi->irq_lock has to be locked by the caller */ static void _omap_dsi_set_irqs_cio(struct platform_device *dsidev) { - _omap_dsi_configure_irqs(dsidev, dsi.isr_tables.isr_table_cio, - ARRAY_SIZE(dsi.isr_tables.isr_table_cio), + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + _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(struct platform_device *dsidev) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; int vc; - spin_lock_irqsave(&dsi.irq_lock, flags); + spin_lock_irqsave(&dsi->irq_lock, flags); - memset(&dsi.isr_tables, 0, sizeof(dsi.isr_tables)); + memset(&dsi->isr_tables, 0, sizeof(dsi->isr_tables)); _omap_dsi_set_irqs(dsidev); for (vc = 0; vc < 4; ++vc) _omap_dsi_set_irqs_vc(dsidev, vc); _omap_dsi_set_irqs_cio(dsidev); - spin_unlock_irqrestore(&dsi.irq_lock, flags); + spin_unlock_irqrestore(&dsi->irq_lock, flags); } static int _dsi_register_isr(omap_dsi_isr_t isr, void *arg, u32 mask, @@ -855,18 +887,19 @@ static int _dsi_unregister_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) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; int r; - spin_lock_irqsave(&dsi.irq_lock, flags); + spin_lock_irqsave(&dsi->irq_lock, flags); - r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table, - ARRAY_SIZE(dsi.isr_tables.isr_table)); + r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table, + ARRAY_SIZE(dsi->isr_tables.isr_table)); if (r == 0) _omap_dsi_set_irqs(dsidev); - spin_unlock_irqrestore(&dsi.irq_lock, flags); + spin_unlock_irqrestore(&dsi->irq_lock, flags); return r; } @@ -874,18 +907,19 @@ static int dsi_register_isr(struct platform_device *dsidev, omap_dsi_isr_t isr, static int dsi_unregister_isr(struct platform_device *dsidev, omap_dsi_isr_t isr, void *arg, u32 mask) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; int r; - spin_lock_irqsave(&dsi.irq_lock, flags); + spin_lock_irqsave(&dsi->irq_lock, flags); - r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table, - ARRAY_SIZE(dsi.isr_tables.isr_table)); + r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table, + ARRAY_SIZE(dsi->isr_tables.isr_table)); if (r == 0) _omap_dsi_set_irqs(dsidev); - spin_unlock_irqrestore(&dsi.irq_lock, flags); + spin_unlock_irqrestore(&dsi->irq_lock, flags); return r; } @@ -893,19 +927,20 @@ static int dsi_unregister_isr(struct platform_device *dsidev, static int dsi_register_isr_vc(struct platform_device *dsidev, int channel, omap_dsi_isr_t isr, void *arg, u32 mask) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; int r; - spin_lock_irqsave(&dsi.irq_lock, flags); + spin_lock_irqsave(&dsi->irq_lock, flags); r = _dsi_register_isr(isr, arg, mask, - dsi.isr_tables.isr_table_vc[channel], - ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); + dsi->isr_tables.isr_table_vc[channel], + ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel])); if (r == 0) _omap_dsi_set_irqs_vc(dsidev, channel); - spin_unlock_irqrestore(&dsi.irq_lock, flags); + spin_unlock_irqrestore(&dsi->irq_lock, flags); return r; } @@ -913,19 +948,20 @@ static int dsi_register_isr_vc(struct platform_device *dsidev, int channel, static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel, omap_dsi_isr_t isr, void *arg, u32 mask) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; int r; - spin_lock_irqsave(&dsi.irq_lock, flags); + spin_lock_irqsave(&dsi->irq_lock, flags); r = _dsi_unregister_isr(isr, arg, mask, - dsi.isr_tables.isr_table_vc[channel], - ARRAY_SIZE(dsi.isr_tables.isr_table_vc[channel])); + dsi->isr_tables.isr_table_vc[channel], + ARRAY_SIZE(dsi->isr_tables.isr_table_vc[channel])); if (r == 0) _omap_dsi_set_irqs_vc(dsidev, channel); - spin_unlock_irqrestore(&dsi.irq_lock, flags); + spin_unlock_irqrestore(&dsi->irq_lock, flags); return r; } @@ -933,18 +969,19 @@ static int dsi_unregister_isr_vc(struct platform_device *dsidev, int channel, static int dsi_register_isr_cio(struct platform_device *dsidev, omap_dsi_isr_t isr, void *arg, u32 mask) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; int r; - spin_lock_irqsave(&dsi.irq_lock, flags); + spin_lock_irqsave(&dsi->irq_lock, flags); - r = _dsi_register_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio, - ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); + r = _dsi_register_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio, + ARRAY_SIZE(dsi->isr_tables.isr_table_cio)); if (r == 0) _omap_dsi_set_irqs_cio(dsidev); - spin_unlock_irqrestore(&dsi.irq_lock, flags); + spin_unlock_irqrestore(&dsi->irq_lock, flags); return r; } @@ -952,30 +989,32 @@ static int dsi_register_isr_cio(struct platform_device *dsidev, static int dsi_unregister_isr_cio(struct platform_device *dsidev, omap_dsi_isr_t isr, void *arg, u32 mask) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; int r; - spin_lock_irqsave(&dsi.irq_lock, flags); + spin_lock_irqsave(&dsi->irq_lock, flags); - r = _dsi_unregister_isr(isr, arg, mask, dsi.isr_tables.isr_table_cio, - ARRAY_SIZE(dsi.isr_tables.isr_table_cio)); + r = _dsi_unregister_isr(isr, arg, mask, dsi->isr_tables.isr_table_cio, + ARRAY_SIZE(dsi->isr_tables.isr_table_cio)); if (r == 0) _omap_dsi_set_irqs_cio(dsidev); - spin_unlock_irqrestore(&dsi.irq_lock, flags); + spin_unlock_irqrestore(&dsi->irq_lock, flags); return r; } static u32 dsi_get_errors(struct platform_device *dsidev) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; u32 e; - spin_lock_irqsave(&dsi.errors_lock, flags); - e = dsi.errors; - dsi.errors = 0; - spin_unlock_irqrestore(&dsi.errors_lock, flags); + spin_lock_irqsave(&dsi->errors_lock, flags); + e = dsi->errors; + dsi->errors = 0; + spin_unlock_irqrestore(&dsi->errors_lock, flags); return e; } @@ -992,12 +1031,14 @@ static inline void enable_clocks(bool enable) static inline void dsi_enable_pll_clock(struct platform_device *dsidev, bool enable) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + if (enable) dss_clk_enable(DSS_CLK_SYSCK); else dss_clk_disable(DSS_CLK_SYSCK); - if (enable && dsi.pll_locked) { + if (enable && dsi->pll_locked) { if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) DSSERR("cannot lock PLL when enabling clocks\n"); } @@ -1065,17 +1106,23 @@ static inline int dsi_if_enable(struct platform_device *dsidev, bool enable) unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) { - return dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk; } static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev) { - return dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk; } static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev) { - return dsi.current_cinfo.clkin4ddr / 16; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + return dsi->current_cinfo.clkin4ddr / 16; } static unsigned long dsi_fclk_rate(struct platform_device *dsidev) @@ -1096,13 +1143,14 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev) static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long dsi_fclk; unsigned lp_clk_div; unsigned long lp_clk; lp_clk_div = dssdev->clocks.dsi.lp_clk_div; - if (lp_clk_div == 0 || lp_clk_div > dsi.lpdiv_max) + if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max) return -EINVAL; dsi_fclk = dsi_fclk_rate(dsidev); @@ -1110,8 +1158,8 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) lp_clk = dsi_fclk / 2 / lp_clk_div; DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); - dsi.current_cinfo.lp_clk = lp_clk; - dsi.current_cinfo.lp_clk_div = lp_clk_div; + dsi->current_cinfo.lp_clk = lp_clk; + dsi->current_cinfo.lp_clk_div = lp_clk_div; /* LP_CLK_DIVISOR */ REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0); @@ -1124,14 +1172,18 @@ static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) static void dsi_enable_scp_clk(struct platform_device *dsidev) { - if (dsi.scp_clk_refcount++ == 0) + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + if (dsi->scp_clk_refcount++ == 0) REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 14, 14); /* CIO_CLK_ICG */ } static void dsi_disable_scp_clk(struct platform_device *dsidev) { - WARN_ON(dsi.scp_clk_refcount == 0); - if (--dsi.scp_clk_refcount == 0) + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + WARN_ON(dsi->scp_clk_refcount == 0); + if (--dsi->scp_clk_refcount == 0) REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 14, 14); /* CIO_CLK_ICG */ } @@ -1172,16 +1224,19 @@ static int dsi_pll_power(struct platform_device *dsidev, static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, struct dsi_clock_info *cinfo) { - if (cinfo->regn == 0 || cinfo->regn > dsi.regn_max) + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max) return -EINVAL; - if (cinfo->regm == 0 || cinfo->regm > dsi.regm_max) + if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max) return -EINVAL; - if (cinfo->regm_dispc > dsi.regm_dispc_max) + if (cinfo->regm_dispc > dsi->regm_dispc_max) return -EINVAL; - if (cinfo->regm_dsi > dsi.regm_dsi_max) + if (cinfo->regm_dsi > dsi->regm_dsi_max) return -EINVAL; if (cinfo->use_sys_clk) { @@ -1200,7 +1255,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev, cinfo->fint = cinfo->clkin / (cinfo->regn * (cinfo->highfreq ? 2 : 1)); - if (cinfo->fint > dsi.fint_max || cinfo->fint < dsi.fint_min) + if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min) return -EINVAL; cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint; @@ -1227,6 +1282,7 @@ 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_data *dsi = dsi_get_dsi_data(dsidev); struct dsi_clock_info cur, best; struct dispc_clock_info best_dispc; int min_fck_per_pck; @@ -1237,10 +1293,10 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); - if (req_pck == dsi.cache_req_pck && - dsi.cache_cinfo.clkin == dss_sys_clk) { + if (req_pck == dsi->cache_req_pck && + dsi->cache_cinfo.clkin == dss_sys_clk) { DSSDBG("DSI clock info found from cache\n"); - *dsi_cinfo = dsi.cache_cinfo; + *dsi_cinfo = dsi->cache_cinfo; dispc_find_clk_divs(is_tft, req_pck, dsi_cinfo->dsi_pll_hsdiv_dispc_clk, dispc_cinfo); return 0; @@ -1270,17 +1326,17 @@ retry: /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */ /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */ /* To reduce PLL lock time, keep Fint high (around 2 MHz) */ - for (cur.regn = 1; cur.regn < dsi.regn_max; ++cur.regn) { + for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) { if (cur.highfreq == 0) cur.fint = cur.clkin / cur.regn; else cur.fint = cur.clkin / (2 * cur.regn); - if (cur.fint > dsi.fint_max || cur.fint < dsi.fint_min) + if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min) continue; /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */ - for (cur.regm = 1; cur.regm < dsi.regm_max; ++cur.regm) { + for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) { unsigned long a, b; a = 2 * cur.regm * (cur.clkin/1000); @@ -1292,7 +1348,7 @@ retry: /* dsi_pll_hsdiv_dispc_clk(MHz) = * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */ - for (cur.regm_dispc = 1; cur.regm_dispc < dsi.regm_dispc_max; + for (cur.regm_dispc = 1; cur.regm_dispc < dsi->regm_dispc_max; ++cur.regm_dispc) { struct dispc_clock_info cur_dispc; cur.dsi_pll_hsdiv_dispc_clk = @@ -1353,9 +1409,9 @@ found: if (dispc_cinfo) *dispc_cinfo = best_dispc; - dsi.cache_req_pck = req_pck; - dsi.cache_clk_freq = 0; - dsi.cache_cinfo = best; + dsi->cache_req_pck = req_pck; + dsi->cache_clk_freq = 0; + dsi->cache_cinfo = best; return 0; } @@ -1363,6 +1419,7 @@ found: int dsi_pll_set_clock_div(struct platform_device *dsidev, struct dsi_clock_info *cinfo) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int r = 0; u32 l; int f = 0; @@ -1371,20 +1428,20 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, DSSDBGF(); - dsi.current_cinfo.use_sys_clk = cinfo->use_sys_clk; - dsi.current_cinfo.highfreq = cinfo->highfreq; + dsi->current_cinfo.use_sys_clk = cinfo->use_sys_clk; + dsi->current_cinfo.highfreq = cinfo->highfreq; - dsi.current_cinfo.fint = cinfo->fint; - dsi.current_cinfo.clkin4ddr = cinfo->clkin4ddr; - dsi.current_cinfo.dsi_pll_hsdiv_dispc_clk = + dsi->current_cinfo.fint = cinfo->fint; + dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr; + dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk = cinfo->dsi_pll_hsdiv_dispc_clk; - dsi.current_cinfo.dsi_pll_hsdiv_dsi_clk = + dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk = cinfo->dsi_pll_hsdiv_dsi_clk; - dsi.current_cinfo.regn = cinfo->regn; - dsi.current_cinfo.regm = cinfo->regm; - dsi.current_cinfo.regm_dispc = cinfo->regm_dispc; - dsi.current_cinfo.regm_dsi = cinfo->regm_dsi; + dsi->current_cinfo.regn = cinfo->regn; + dsi->current_cinfo.regm = cinfo->regm; + dsi->current_cinfo.regm_dispc = cinfo->regm_dispc; + dsi->current_cinfo.regm_dsi = cinfo->regm_dsi; DSSDBG("DSI Fint %ld\n", cinfo->fint); @@ -1439,7 +1496,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, regm_dsi_start, regm_dsi_end); dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l); - BUG_ON(cinfo->fint < dsi.fint_min || cinfo->fint > dsi.fint_max); + BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max); if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) { f = cinfo->fint < 1000000 ? 0x3 : @@ -1476,7 +1533,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev, goto err; } - dsi.pll_locked = 1; + dsi->pll_locked = 1; l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2); l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */ @@ -1503,22 +1560,23 @@ err: int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, bool enable_hsdiv) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int r = 0; enum dsi_pll_power_state pwstate; DSSDBG("PLL init\n"); - if (dsi.vdds_dsi_reg == NULL) { + if (dsi->vdds_dsi_reg == NULL) { struct regulator *vdds_dsi; - vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); + vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); if (IS_ERR(vdds_dsi)) { DSSERR("can't get VDDS_DSI regulator\n"); return PTR_ERR(vdds_dsi); } - dsi.vdds_dsi_reg = vdds_dsi; + dsi->vdds_dsi_reg = vdds_dsi; } enable_clocks(1); @@ -1528,11 +1586,11 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, */ dsi_enable_scp_clk(dsidev); - if (!dsi.vdds_dsi_enabled) { - r = regulator_enable(dsi.vdds_dsi_reg); + if (!dsi->vdds_dsi_enabled) { + r = regulator_enable(dsi->vdds_dsi_reg); if (r) goto err0; - dsi.vdds_dsi_enabled = true; + dsi->vdds_dsi_enabled = true; } /* XXX PLL does not come out of reset without this... */ @@ -1567,9 +1625,9 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, return 0; err1: - if (dsi.vdds_dsi_enabled) { - regulator_disable(dsi.vdds_dsi_reg); - dsi.vdds_dsi_enabled = false; + if (dsi->vdds_dsi_enabled) { + regulator_disable(dsi->vdds_dsi_reg); + dsi->vdds_dsi_enabled = false; } err0: dsi_disable_scp_clk(dsidev); @@ -1580,12 +1638,14 @@ err0: void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) { - dsi.pll_locked = 0; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + dsi->pll_locked = 0; 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; + WARN_ON(!dsi->vdds_dsi_enabled); + regulator_disable(dsi->vdds_dsi_reg); + dsi->vdds_dsi_enabled = false; } dsi_disable_scp_clk(dsidev); @@ -1598,7 +1658,8 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) void dsi_dump_clocks(struct seq_file *s) { struct platform_device *dsidev = dsi_get_dsi_device_module(0); - struct dsi_clock_info *cinfo = &dsi.current_cinfo; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + struct dsi_clock_info *cinfo = &dsi->current_cinfo; enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; dispc_clk_src = dss_get_dispc_clk_source(); @@ -1658,16 +1719,18 @@ void dsi_dump_clocks(struct seq_file *s) #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS void dsi_dump_irqs(struct seq_file *s) { + struct platform_device *dsidev = dsi_get_dsi_device_module(0); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned long flags; struct dsi_irq_stats stats; - spin_lock_irqsave(&dsi.irq_stats_lock, flags); + spin_lock_irqsave(&dsi->irq_stats_lock, flags); - stats = dsi.irq_stats; - memset(&dsi.irq_stats, 0, sizeof(dsi.irq_stats)); - dsi.irq_stats.last_reset = jiffies; + stats = dsi->irq_stats; + memset(&dsi->irq_stats, 0, sizeof(dsi->irq_stats)); + dsi->irq_stats.last_reset = jiffies; - spin_unlock_irqrestore(&dsi.irq_stats_lock, flags); + spin_unlock_irqrestore(&dsi->irq_stats_lock, flags); seq_printf(s, "period %u ms\n", jiffies_to_msecs(jiffies - stats.last_reset)); @@ -1897,14 +1960,18 @@ static void dsi_set_lane_config(struct omap_dss_device *dssdev) static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + /* convert time in ns to ddr ticks, rounding up */ - unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; + unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; } static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr) { - unsigned long ddr_clk = dsi.current_cinfo.clkin4ddr / 4; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; return ddr * 1000 * 1000 / (ddr_clk / 1000); } @@ -2095,13 +2162,14 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev) static int dsi_cio_init(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int r; u32 l; DSSDBGF(); - if (dsi.dsi_mux_pads) - dsi.dsi_mux_pads(true); + if (dsi->dsi_mux_pads) + dsi->dsi_mux_pads(true); dsi_enable_scp_clk(dsidev); @@ -2126,7 +2194,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) l = FLD_MOD(l, 0x1fff, 12, 0); /* STOP_STATE_COUNTER_IO */ dsi_write_reg(dsidev, DSI_TIMING1, l); - if (dsi.ulps_enabled) { + if (dsi->ulps_enabled) { DSSDBG("manual ulps exit\n"); /* ULPS is exited by Mark-1 state for 1ms, followed by @@ -2159,7 +2227,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) if (r) goto err_tx_clk_esc_rst; - if (dsi.ulps_enabled) { + if (dsi->ulps_enabled) { /* Keep Mark-1 state for 1ms (as per DSI spec) */ ktime_t wait = ns_to_ktime(1000 * 1000); set_current_state(TASK_UNINTERRUPTIBLE); @@ -2175,7 +2243,7 @@ static int dsi_cio_init(struct omap_dss_device *dssdev) dsi_cio_timings(dsidev); - dsi.ulps_enabled = false; + dsi->ulps_enabled = false; DSSDBG("CIO init done\n"); @@ -2186,21 +2254,23 @@ err_tx_clk_esc_rst: err_cio_pwr_dom: dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); err_cio_pwr: - if (dsi.ulps_enabled) + if (dsi->ulps_enabled) dsi_cio_disable_lane_override(dsidev); err_scp_clk_dom: dsi_disable_scp_clk(dsidev); - if (dsi.dsi_mux_pads) - dsi.dsi_mux_pads(false); + if (dsi->dsi_mux_pads) + dsi->dsi_mux_pads(false); return r; } static void dsi_cio_uninit(struct platform_device *dsidev) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF); dsi_disable_scp_clk(dsidev); - if (dsi.dsi_mux_pads) - dsi.dsi_mux_pads(false); + if (dsi->dsi_mux_pads) + dsi->dsi_mux_pads(false); } static int _dsi_wait_reset(struct platform_device *dsidev) @@ -2229,18 +2299,19 @@ static void dsi_config_tx_fifo(struct platform_device *dsidev, enum fifo_size size1, enum fifo_size size2, enum fifo_size size3, enum fifo_size size4) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); u32 r = 0; int add = 0; int i; - dsi.vc[0].fifo_size = size1; - dsi.vc[1].fifo_size = size2; - dsi.vc[2].fifo_size = size3; - dsi.vc[3].fifo_size = size4; + dsi->vc[0].fifo_size = size1; + dsi->vc[1].fifo_size = size2; + dsi->vc[2].fifo_size = size3; + dsi->vc[3].fifo_size = size4; for (i = 0; i < 4; i++) { u8 v; - int size = dsi.vc[i].fifo_size; + int size = dsi->vc[i].fifo_size; if (add + size > 4) { DSSERR("Illegal FIFO configuration\n"); @@ -2260,18 +2331,19 @@ static void dsi_config_rx_fifo(struct platform_device *dsidev, enum fifo_size size1, enum fifo_size size2, enum fifo_size size3, enum fifo_size size4) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); u32 r = 0; int add = 0; int i; - dsi.vc[0].fifo_size = size1; - dsi.vc[1].fifo_size = size2; - dsi.vc[2].fifo_size = size3; - dsi.vc[3].fifo_size = size4; + dsi->vc[0].fifo_size = size1; + dsi->vc[1].fifo_size = size2; + dsi->vc[2].fifo_size = size3; + dsi->vc[3].fifo_size = size4; for (i = 0; i < 4; i++) { u8 v; - int size = dsi.vc[i].fifo_size; + int size = dsi->vc[i].fifo_size; if (add + size > 4) { DSSERR("Illegal FIFO configuration\n"); @@ -2311,8 +2383,9 @@ static bool dsi_vc_is_enabled(struct platform_device *dsidev, int channel) static void dsi_packet_sent_handler_vp(void *data, u32 mask) { struct platform_device *dsidev = dsi_get_dsi_device_module(0); - const int channel = dsi.update_channel; - u8 bit = dsi.te_enabled ? 30 : 31; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + const int channel = dsi->update_channel; + u8 bit = dsi->te_enabled ? 30 : 31; if (REG_GET(dsidev, DSI_VC_TE(channel), bit, bit) == 0) complete((struct completion *)data); @@ -2320,12 +2393,13 @@ static void dsi_packet_sent_handler_vp(void *data, u32 mask) static int dsi_sync_vc_vp(struct platform_device *dsidev, int channel) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int r = 0; u8 bit; DECLARE_COMPLETION_ONSTACK(completion); - bit = dsi.te_enabled ? 30 : 31; + bit = dsi->te_enabled ? 30 : 31; r = dsi_register_isr_vc(dsidev, channel, dsi_packet_sent_handler_vp, &completion, DSI_VC_IRQ_PACKET_SENT); @@ -2356,7 +2430,8 @@ err0: static void dsi_packet_sent_handler_l4(void *data, u32 mask) { struct platform_device *dsidev = dsi_get_dsi_device_module(0); - const int channel = dsi.update_channel; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + const int channel = dsi->update_channel; if (REG_GET(dsidev, DSI_VC_CTRL(channel), 5, 5) == 0) complete((struct completion *)data); @@ -2396,6 +2471,8 @@ err0: static int dsi_sync_vc(struct platform_device *dsidev, int channel) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + WARN_ON(!dsi_bus_is_locked(dsidev)); WARN_ON(in_interrupt()); @@ -2403,7 +2480,7 @@ static int dsi_sync_vc(struct platform_device *dsidev, int channel) if (!dsi_vc_is_enabled(dsidev, channel)) return 0; - switch (dsi.vc[channel].mode) { + switch (dsi->vc[channel].mode) { case DSI_VC_MODE_VP: return dsi_sync_vc_vp(dsidev, channel); case DSI_VC_MODE_L4: @@ -2461,7 +2538,9 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel) static int dsi_vc_config_l4(struct platform_device *dsidev, int channel) { - if (dsi.vc[channel].mode == DSI_VC_MODE_L4) + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + if (dsi->vc[channel].mode == DSI_VC_MODE_L4) return 0; DSSDBGF("%d", channel); @@ -2484,14 +2563,16 @@ static int dsi_vc_config_l4(struct platform_device *dsidev, int channel) dsi_vc_enable(dsidev, channel, 1); - dsi.vc[channel].mode = DSI_VC_MODE_L4; + dsi->vc[channel].mode = DSI_VC_MODE_L4; return 0; } static int dsi_vc_config_vp(struct platform_device *dsidev, int channel) { - if (dsi.vc[channel].mode == DSI_VC_MODE_VP) + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + if (dsi->vc[channel].mode == DSI_VC_MODE_VP) return 0; DSSDBGF("%d", channel); @@ -2515,7 +2596,7 @@ static int dsi_vc_config_vp(struct platform_device *dsidev, int channel) dsi_vc_enable(dsidev, channel, 1); - dsi.vc[channel].mode = DSI_VC_MODE_VP; + dsi->vc[channel].mode = DSI_VC_MODE_VP; return 0; } @@ -2624,7 +2705,9 @@ static u16 dsi_vc_flush_receive_data(struct platform_device *dsidev, static int dsi_vc_send_bta(struct platform_device *dsidev, int channel) { - if (dsi.debug_write || dsi.debug_read) + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + if (dsi->debug_write || dsi->debug_read) DSSDBG("dsi_vc_send_bta %d\n", channel); WARN_ON(!dsi_bus_is_locked(dsidev)); @@ -2688,12 +2771,13 @@ EXPORT_SYMBOL(dsi_vc_send_bta_sync); static inline void dsi_vc_write_long_header(struct platform_device *dsidev, int channel, u8 data_type, u16 len, u8 ecc) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); u32 val; u8 data_id; WARN_ON(!dsi_bus_is_locked(dsidev)); - data_id = data_type | dsi.vc[channel].vc_id << 6; + data_id = data_type | dsi->vc[channel].vc_id << 6; val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | FLD_VAL(ecc, 31, 24); @@ -2718,16 +2802,17 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel, u8 data_type, u8 *data, u16 len, u8 ecc) { /*u32 val; */ + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int i; u8 *p; int r = 0; u8 b1, b2, b3, b4; - if (dsi.debug_write) + if (dsi->debug_write) DSSDBG("dsi_vc_send_long, %d bytes\n", len); /* len + header */ - if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) { + if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) { DSSERR("unable to send long packet: packet too long.\n"); return -EINVAL; } @@ -2738,7 +2823,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel, p = data; for (i = 0; i < len >> 2; i++) { - if (dsi.debug_write) + if (dsi->debug_write) DSSDBG("\tsending full packet %d\n", i); b1 = *p++; @@ -2753,7 +2838,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel, if (i) { b1 = 0; b2 = 0; b3 = 0; - if (dsi.debug_write) + if (dsi->debug_write) DSSDBG("\tsending remainder bytes %d\n", i); switch (i) { @@ -2780,12 +2865,13 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel, static int dsi_vc_send_short(struct platform_device *dsidev, int channel, u8 data_type, u16 data, u8 ecc) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); u32 r; u8 data_id; WARN_ON(!dsi_bus_is_locked(dsidev)); - if (dsi.debug_write) + if (dsi->debug_write) DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", channel, data_type, data & 0xff, (data >> 8) & 0xff); @@ -2797,7 +2883,7 @@ static int dsi_vc_send_short(struct platform_device *dsidev, int channel, return -EINVAL; } - data_id = data_type | dsi.vc[channel].vc_id << 6; + data_id = data_type | dsi->vc[channel].vc_id << 6; r = (data_id << 0) | (data << 8) | (ecc << 24); @@ -2890,11 +2976,12 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, u8 *buf, int buflen) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); u32 val; u8 dt; int r; - if (dsi.debug_read) + if (dsi->debug_read) DSSDBG("dsi_vc_dcs_read(ch%d, dcs_cmd %x)\n", channel, dcs_cmd); r = dsi_vc_send_short(dsidev, channel, DSI_DT_DCS_READ, dcs_cmd, 0); @@ -2913,7 +3000,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, } val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel)); - if (dsi.debug_read) + if (dsi->debug_read) DSSDBG("\theader: %08x\n", val); dt = FLD_GET(val, 5, 0); if (dt == DSI_DT_RX_ACK_WITH_ERR) { @@ -2924,7 +3011,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, } else if (dt == DSI_DT_RX_SHORT_READ_1) { u8 data = FLD_GET(val, 15, 8); - if (dsi.debug_read) + if (dsi->debug_read) DSSDBG("\tDCS short response, 1 byte: %02x\n", data); if (buflen < 1) { @@ -2937,7 +3024,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, return 1; } else if (dt == DSI_DT_RX_SHORT_READ_2) { u16 data = FLD_GET(val, 23, 8); - if (dsi.debug_read) + if (dsi->debug_read) DSSDBG("\tDCS short response, 2 byte: %04x\n", data); if (buflen < 2) { @@ -2952,7 +3039,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, } else if (dt == DSI_DT_RX_DCS_LONG_READ) { int w; int len = FLD_GET(val, 23, 8); - if (dsi.debug_read) + if (dsi->debug_read) DSSDBG("\tDCS long response, len %d\n", len); if (len > buflen) { @@ -2965,7 +3052,7 @@ int dsi_vc_dcs_read(struct omap_dss_device *dssdev, int channel, u8 dcs_cmd, int b; val = dsi_read_reg(dsidev, DSI_VC_SHORT_PACKET_HEADER(channel)); - if (dsi.debug_read) + if (dsi->debug_read) DSSDBG("\t\t%02x %02x %02x %02x\n", (val >> 0) & 0xff, (val >> 8) & 0xff, @@ -3046,6 +3133,7 @@ EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size); static int dsi_enter_ulps(struct platform_device *dsidev) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); DECLARE_COMPLETION_ONSTACK(completion); int r; @@ -3053,9 +3141,9 @@ static int dsi_enter_ulps(struct platform_device *dsidev) WARN_ON(!dsi_bus_is_locked(dsidev)); - WARN_ON(dsi.ulps_enabled); + WARN_ON(dsi->ulps_enabled); - if (dsi.ulps_enabled) + if (dsi->ulps_enabled) return 0; if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) { @@ -3109,7 +3197,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev) dsi_if_enable(dsidev, false); - dsi.ulps_enabled = true; + dsi->ulps_enabled = true; return 0; @@ -3381,6 +3469,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, { /* Note: supports only 24bit colors in 32bit container */ struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int first = 1; int fifo_stalls = 0; int max_dsi_packet_size; @@ -3419,7 +3508,7 @@ static int dsi_update_screen_l4(struct omap_dss_device *dssdev, * in fifo */ /* When using CPU, max long packet size is TX buffer size */ - max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4; + max_dsi_packet_size = dsi->vc[0].fifo_size * 32 * 4; /* we seem to get better perf if we divide the tx fifo to half, and while the other half is being sent, we fill the other half @@ -3514,6 +3603,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, u16 x, u16 y, u16 w, u16 h) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); unsigned bytespp; unsigned bytespl; unsigned bytespf; @@ -3522,7 +3612,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, unsigned packet_len; u32 l; int r; - const unsigned channel = dsi.update_channel; + const unsigned channel = dsi->update_channel; /* line buffer is 1024 x 24bits */ /* XXX: for some reason using full buffer size causes considerable TX * slowdown with update sizes that fill the whole buffer */ @@ -3557,7 +3647,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, dsi_vc_write_long_header(dsidev, channel, DSI_DT_DCS_LONG_WRITE, packet_len, 0); - if (dsi.te_enabled) + if (dsi->te_enabled) l = FLD_MOD(l, 1, 30, 30); /* TE_EN */ else l = FLD_MOD(l, 1, 31, 31); /* TE_START */ @@ -3573,13 +3663,13 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, dsi_perf_mark_start(dsidev); - r = queue_delayed_work(dsi.workqueue, &dsi.framedone_timeout_work, + r = queue_delayed_work(dsi->workqueue, &dsi->framedone_timeout_work, msecs_to_jiffies(250)); BUG_ON(r == 0); dss_start_update(dssdev); - if (dsi.te_enabled) { + if (dsi->te_enabled) { /* disable LP_RX_TO, so that we can receive TE. Time to wait * for TE is longer than the timer allows */ REG_FLD_MOD(dsidev, DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */ @@ -3587,7 +3677,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, dsi_vc_send_bta(dsidev, channel); #ifdef DSI_CATCH_MISSING_TE - mod_timer(&dsi.te_timer, jiffies + msecs_to_jiffies(250)); + mod_timer(&dsi->te_timer, jiffies + msecs_to_jiffies(250)); #endif } } @@ -3601,15 +3691,17 @@ static void dsi_te_timeout(unsigned long arg) static void dsi_handle_framedone(struct platform_device *dsidev, int error) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + /* SIDLEMODE back to smart-idle */ dispc_enable_sidle(); - if (dsi.te_enabled) { + if (dsi->te_enabled) { /* enable LP_RX_TO again after the TE */ REG_FLD_MOD(dsidev, DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */ } - dsi.framedone_callback(error, dsi.framedone_data); + dsi->framedone_callback(error, dsi->framedone_data); if (!error) dsi_perf_show(dsidev, "DISPC"); @@ -3617,6 +3709,8 @@ static void dsi_handle_framedone(struct platform_device *dsidev, int error) static void dsi_framedone_timeout_work_callback(struct work_struct *work) { + struct dsi_data *dsi = container_of(work, struct dsi_data, + framedone_timeout_work.work); /* XXX While extremely unlikely, we could get FRAMEDONE interrupt after * 250ms which would conflict with this timeout work. What should be * done is first cancel the transfer on the HW, and then cancel the @@ -3626,19 +3720,21 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work) DSSERR("Framedone not received for 250ms!\n"); - dsi_handle_framedone(dsi.pdev, -ETIMEDOUT); + dsi_handle_framedone(dsi->pdev, -ETIMEDOUT); } static void dsi_framedone_irq_callback(void *data, u32 mask) { struct omap_dss_device *dssdev = (struct omap_dss_device *) data; struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + /* Note: We get FRAMEDONE when DISPC has finished sending pixels and * turns itself off. However, DSI still has the pixels in its buffers, * and is sending the data. */ - __cancel_delayed_work(&dsi.framedone_timeout_work); + __cancel_delayed_work(&dsi->framedone_timeout_work); dsi_handle_framedone(dsidev, 0); @@ -3689,8 +3785,9 @@ int omap_dsi_update(struct omap_dss_device *dssdev, void (*callback)(int, void *), void *data) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); - dsi.update_channel = channel; + dsi->update_channel = channel; /* OMAP DSS cannot send updates of odd widths. * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON @@ -3699,14 +3796,14 @@ int omap_dsi_update(struct omap_dss_device *dssdev, BUG_ON(x % 2 == 1); if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) { - dsi.framedone_callback = callback; - dsi.framedone_data = data; + dsi->framedone_callback = callback; + dsi->framedone_data = data; - dsi.update_region.x = x; - dsi.update_region.y = y; - dsi.update_region.w = w; - dsi.update_region.h = h; - dsi.update_region.device = dssdev; + dsi->update_region.x = x; + dsi->update_region.y = y; + dsi->update_region.w = w; + dsi->update_region.h = h; + dsi->update_region.device = dssdev; dsi_update_screen_dispc(dssdev, x, y, w, h); } else { @@ -3886,8 +3983,9 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, bool disconnect_lanes, bool enter_ulps) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); - if (enter_ulps && !dsi.ulps_enabled) + if (enter_ulps && !dsi->ulps_enabled) dsi_enter_ulps(dsidev); /* disable interface */ @@ -3922,13 +4020,14 @@ static int dsi_core_init(struct platform_device *dsidev) int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int r = 0; DSSDBG("dsi_display_enable\n"); WARN_ON(!dsi_bus_is_locked(dsidev)); - mutex_lock(&dsi.lock); + mutex_lock(&dsi->lock); r = omap_dss_start_device(dssdev); if (r) { @@ -3953,7 +4052,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev) if (r) goto err2; - mutex_unlock(&dsi.lock); + mutex_unlock(&dsi->lock); return 0; @@ -3964,7 +4063,7 @@ err1: dsi_enable_pll_clock(dsidev, 0); omap_dss_stop_device(dssdev); err0: - mutex_unlock(&dsi.lock); + mutex_unlock(&dsi->lock); DSSDBG("dsi_display_enable FAILED\n"); return r; } @@ -3974,12 +4073,13 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, bool disconnect_lanes, bool enter_ulps) { struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); DSSDBG("dsi_display_disable\n"); WARN_ON(!dsi_bus_is_locked(dsidev)); - mutex_lock(&dsi.lock); + mutex_lock(&dsi->lock); dsi_display_uninit_dispc(dssdev); @@ -3990,13 +4090,16 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev, omap_dss_stop_device(dssdev); - mutex_unlock(&dsi.lock); + mutex_unlock(&dsi->lock); } EXPORT_SYMBOL(omapdss_dsi_display_disable); int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) { - dsi.te_enabled = enable; + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + dsi->te_enabled = enable; return 0; } EXPORT_SYMBOL(omapdss_dsi_enable_te); @@ -4016,23 +4119,26 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, int dsi_init_display(struct omap_dss_device *dssdev) { + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + DSSDBG("DSI init\n"); /* XXX these should be figured out dynamically */ dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; - if (dsi.vdds_dsi_reg == NULL) { + if (dsi->vdds_dsi_reg == NULL) { struct regulator *vdds_dsi; - vdds_dsi = regulator_get(&dsi.pdev->dev, "vdds_dsi"); + vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); if (IS_ERR(vdds_dsi)) { DSSERR("can't get VDDS_DSI regulator\n"); return PTR_ERR(vdds_dsi); } - dsi.vdds_dsi_reg = vdds_dsi; + dsi->vdds_dsi_reg = vdds_dsi; } return 0; @@ -4040,11 +4146,13 @@ int dsi_init_display(struct omap_dss_device *dssdev) int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) { + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); int i; - for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { - if (!dsi.vc[i].dssdev) { - dsi.vc[i].dssdev = dssdev; + for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) { + if (!dsi->vc[i].dssdev) { + dsi->vc[i].dssdev = dssdev; *channel = i; return 0; } @@ -4057,6 +4165,9 @@ EXPORT_SYMBOL(omap_dsi_request_vc); int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) { + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + if (vc_id < 0 || vc_id > 3) { DSSERR("VC ID out of range\n"); return -EINVAL; @@ -4067,13 +4178,13 @@ int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id) return -EINVAL; } - if (dsi.vc[channel].dssdev != dssdev) { + if (dsi->vc[channel].dssdev != dssdev) { DSSERR("Virtual Channel not allocated to display %s\n", dssdev->name); return -EINVAL; } - dsi.vc[channel].vc_id = vc_id; + dsi->vc[channel].vc_id = vc_id; return 0; } @@ -4081,10 +4192,13 @@ EXPORT_SYMBOL(omap_dsi_set_vc_id); void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel) { + struct platform_device *dsidev = dsi_get_dsi_device(dssdev); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + if ((channel >= 0 && channel <= 3) && - dsi.vc[channel].dssdev == dssdev) { - dsi.vc[channel].dssdev = NULL; - dsi.vc[channel].vc_id = 0; + dsi->vc[channel].dssdev == dssdev) { + dsi->vc[channel].dssdev = NULL; + dsi->vc[channel].vc_id = 0; } } EXPORT_SYMBOL(omap_dsi_release_vc); @@ -4107,13 +4221,15 @@ void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev) static void dsi_calc_clock_param_ranges(struct platform_device *dsidev) { - dsi.regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN); - dsi.regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM); - dsi.regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC); - dsi.regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI); - dsi.fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT); - dsi.fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT); - dsi.lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN); + dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM); + dsi->regm_dispc_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC); + dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI); + dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT); + dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT); + dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV); } static int dsi_init(struct platform_device *dsidev) @@ -4123,68 +4239,79 @@ static int dsi_init(struct platform_device *dsidev) u32 rev; int r, i; struct resource *dsi_mem; + struct dsi_data *dsi; + + dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); + if (!dsi) { + r = -ENOMEM; + goto err0; + } + dsi->pdev = dsidev; dsi_pdev_map[dsidev->id] = dsidev; + dev_set_drvdata(&dsidev->dev, dsi); dss_plat_data = dsidev->dev.platform_data; board_info = dss_plat_data->board_data; - dsi.dsi_mux_pads = board_info->dsi_mux_pads; + dsi->dsi_mux_pads = board_info->dsi_mux_pads; - spin_lock_init(&dsi.irq_lock); - spin_lock_init(&dsi.errors_lock); - dsi.errors = 0; + spin_lock_init(&dsi->irq_lock); + spin_lock_init(&dsi->errors_lock); + dsi->errors = 0; #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS - spin_lock_init(&dsi.irq_stats_lock); - dsi.irq_stats.last_reset = jiffies; + spin_lock_init(&dsi->irq_stats_lock); + dsi->irq_stats.last_reset = jiffies; #endif - mutex_init(&dsi.lock); - sema_init(&dsi.bus_lock, 1); + mutex_init(&dsi->lock); + sema_init(&dsi->bus_lock, 1); - dsi.workqueue = create_singlethread_workqueue("dsi"); - if (dsi.workqueue == NULL) - return -ENOMEM; + dsi->workqueue = create_singlethread_workqueue(dev_name(&dsidev->dev)); + if (dsi->workqueue == NULL) { + r = -ENOMEM; + goto err1; + } - INIT_DELAYED_WORK_DEFERRABLE(&dsi.framedone_timeout_work, + INIT_DELAYED_WORK_DEFERRABLE(&dsi->framedone_timeout_work, dsi_framedone_timeout_work_callback); #ifdef DSI_CATCH_MISSING_TE - init_timer(&dsi.te_timer); - dsi.te_timer.function = dsi_te_timeout; - dsi.te_timer.data = 0; + init_timer(&dsi->te_timer); + dsi->te_timer.function = dsi_te_timeout; + dsi->te_timer.data = 0; #endif - dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0); + dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0); if (!dsi_mem) { DSSERR("can't get IORESOURCE_MEM DSI\n"); r = -EINVAL; - goto err1; + goto err2; } - dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem)); - if (!dsi.base) { + dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); + if (!dsi->base) { DSSERR("can't ioremap DSI\n"); r = -ENOMEM; - goto err1; + goto err2; } - dsi.irq = platform_get_irq(dsi.pdev, 0); - if (dsi.irq < 0) { + dsi->irq = platform_get_irq(dsi->pdev, 0); + if (dsi->irq < 0) { DSSERR("platform_get_irq failed\n"); r = -ENODEV; - goto err2; + goto err3; } - r = request_irq(dsi.irq, omap_dsi_irq_handler, IRQF_SHARED, - "OMAP DSI1", dsi.pdev); + r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, + dev_name(&dsidev->dev), dsi->pdev); if (r < 0) { DSSERR("request_irq failed\n"); - goto err2; + goto err3; } /* DSI VCs initialization */ - for (i = 0; i < ARRAY_SIZE(dsi.vc); i++) { - dsi.vc[i].mode = DSI_VC_MODE_L4; - dsi.vc[i].dssdev = NULL; - dsi.vc[i].vc_id = 0; + for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) { + dsi->vc[i].mode = DSI_VC_MODE_L4; + dsi->vc[i].dssdev = NULL; + dsi->vc[i].vc_id = 0; } dsi_calc_clock_param_ranges(dsidev); @@ -4198,29 +4325,35 @@ static int dsi_init(struct platform_device *dsidev) enable_clocks(0); return 0; +err3: + iounmap(dsi->base); err2: - iounmap(dsi.base); + destroy_workqueue(dsi->workqueue); err1: - destroy_workqueue(dsi.workqueue); + kfree(dsi); +err0: return r; } static void dsi_exit(struct platform_device *dsidev) { - if (dsi.vdds_dsi_reg != NULL) { - if (dsi.vdds_dsi_enabled) { - regulator_disable(dsi.vdds_dsi_reg); - dsi.vdds_dsi_enabled = false; + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + + if (dsi->vdds_dsi_reg != NULL) { + if (dsi->vdds_dsi_enabled) { + regulator_disable(dsi->vdds_dsi_reg); + dsi->vdds_dsi_enabled = false; } - regulator_put(dsi.vdds_dsi_reg); - dsi.vdds_dsi_reg = NULL; + regulator_put(dsi->vdds_dsi_reg); + dsi->vdds_dsi_reg = NULL; } - free_irq(dsi.irq, dsi.pdev); - iounmap(dsi.base); + free_irq(dsi->irq, dsi->pdev); + iounmap(dsi->base); - destroy_workqueue(dsi.workqueue); + destroy_workqueue(dsi->workqueue); + kfree(dsi); DSSDBG("omap_dsi_exit\n"); } @@ -4229,7 +4362,7 @@ static void dsi_exit(struct platform_device *dsidev) static int omap_dsihw_probe(struct platform_device *dsidev) { int r; - dsi.pdev = dsidev; + r = dsi_init(dsidev); if (r) { DSSERR("Failed to initialize DSI\n"); @@ -4241,8 +4374,10 @@ err_dsi: static int omap_dsihw_remove(struct platform_device *dsidev) { + struct dsi_data *dsi = dsi_get_dsi_data(dsidev); + dsi_exit(dsidev); - WARN_ON(dsi.scp_clk_refcount > 0); + WARN_ON(dsi->scp_clk_refcount > 0); return 0; } -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html