diff options
Diffstat (limited to 'drivers/video/omap2/dss/dsi.c')
| -rw-r--r-- | drivers/video/omap2/dss/dsi.c | 247 | 
1 files changed, 122 insertions, 125 deletions
| diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index bee92846cfab..28d41d16b7be 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -45,7 +45,6 @@  #include "dss.h"  #include "dss_features.h" -/*#define VERBOSE_IRQ*/  #define DSI_CATCH_MISSING_TE  struct dsi_reg { u16 idx; }; @@ -535,42 +534,38 @@ static inline void dsi_perf_show(struct platform_device *dsidev,  }  #endif +static int verbose_irq; +  static void print_irq_status(u32 status)  {  	if (status == 0)  		return; -#ifndef VERBOSE_IRQ -	if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0) +	if (!verbose_irq && (status & ~DSI_IRQ_CHANNEL_MASK) == 0)  		return; -#endif -	printk(KERN_DEBUG "DSI IRQ: 0x%x: ", status); -#define PIS(x) \ -	if (status & DSI_IRQ_##x) \ -		printk(#x " "); -#ifdef VERBOSE_IRQ -	PIS(VC0); -	PIS(VC1); -	PIS(VC2); -	PIS(VC3); -#endif -	PIS(WAKEUP); -	PIS(RESYNC); -	PIS(PLL_LOCK); -	PIS(PLL_UNLOCK); -	PIS(PLL_RECALL); -	PIS(COMPLEXIO_ERR); -	PIS(HS_TX_TIMEOUT); -	PIS(LP_RX_TIMEOUT); -	PIS(TE_TRIGGER); -	PIS(ACK_TRIGGER); -	PIS(SYNC_LOST); -	PIS(LDO_POWER_GOOD); -	PIS(TA_TIMEOUT); +#define PIS(x) (status & DSI_IRQ_##x) ? (#x " ") : "" + +	pr_debug("DSI IRQ: 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", +		status, +		verbose_irq ? PIS(VC0) : "", +		verbose_irq ? PIS(VC1) : "", +		verbose_irq ? PIS(VC2) : "", +		verbose_irq ? PIS(VC3) : "", +		PIS(WAKEUP), +		PIS(RESYNC), +		PIS(PLL_LOCK), +		PIS(PLL_UNLOCK), +		PIS(PLL_RECALL), +		PIS(COMPLEXIO_ERR), +		PIS(HS_TX_TIMEOUT), +		PIS(LP_RX_TIMEOUT), +		PIS(TE_TRIGGER), +		PIS(ACK_TRIGGER), +		PIS(SYNC_LOST), +		PIS(LDO_POWER_GOOD), +		PIS(TA_TIMEOUT));  #undef PIS - -	printk("\n");  }  static void print_irq_status_vc(int channel, u32 status) @@ -578,28 +573,24 @@ static void print_irq_status_vc(int channel, u32 status)  	if (status == 0)  		return; -#ifndef VERBOSE_IRQ -	if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0) +	if (!verbose_irq && (status & ~DSI_VC_IRQ_PACKET_SENT) == 0)  		return; -#endif -	printk(KERN_DEBUG "DSI VC(%d) IRQ 0x%x: ", channel, status); -#define PIS(x) \ -	if (status & DSI_VC_IRQ_##x) \ -		printk(#x " "); -	PIS(CS); -	PIS(ECC_CORR); -#ifdef VERBOSE_IRQ -	PIS(PACKET_SENT); -#endif -	PIS(FIFO_TX_OVF); -	PIS(FIFO_RX_OVF); -	PIS(BTA); -	PIS(ECC_NO_CORR); -	PIS(FIFO_TX_UDF); -	PIS(PP_BUSY_CHANGE); +#define PIS(x) (status & DSI_VC_IRQ_##x) ? (#x " ") : "" + +	pr_debug("DSI VC(%d) IRQ 0x%x: %s%s%s%s%s%s%s%s%s\n", +		channel, +		status, +		PIS(CS), +		PIS(ECC_CORR), +		PIS(ECC_NO_CORR), +		verbose_irq ? PIS(PACKET_SENT) : "", +		PIS(BTA), +		PIS(FIFO_TX_OVF), +		PIS(FIFO_RX_OVF), +		PIS(FIFO_TX_UDF), +		PIS(PP_BUSY_CHANGE));  #undef PIS -	printk("\n");  }  static void print_irq_status_cio(u32 status) @@ -607,34 +598,31 @@ static void print_irq_status_cio(u32 status)  	if (status == 0)  		return; -	printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status); - -#define PIS(x) \ -	if (status & DSI_CIO_IRQ_##x) \ -		printk(#x " "); -	PIS(ERRSYNCESC1); -	PIS(ERRSYNCESC2); -	PIS(ERRSYNCESC3); -	PIS(ERRESC1); -	PIS(ERRESC2); -	PIS(ERRESC3); -	PIS(ERRCONTROL1); -	PIS(ERRCONTROL2); -	PIS(ERRCONTROL3); -	PIS(STATEULPS1); -	PIS(STATEULPS2); -	PIS(STATEULPS3); -	PIS(ERRCONTENTIONLP0_1); -	PIS(ERRCONTENTIONLP1_1); -	PIS(ERRCONTENTIONLP0_2); -	PIS(ERRCONTENTIONLP1_2); -	PIS(ERRCONTENTIONLP0_3); -	PIS(ERRCONTENTIONLP1_3); -	PIS(ULPSACTIVENOT_ALL0); -	PIS(ULPSACTIVENOT_ALL1); +#define PIS(x) (status & DSI_CIO_IRQ_##x) ? (#x " ") : "" + +	pr_debug("DSI CIO IRQ 0x%x: %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", +		status, +		PIS(ERRSYNCESC1), +		PIS(ERRSYNCESC2), +		PIS(ERRSYNCESC3), +		PIS(ERRESC1), +		PIS(ERRESC2), +		PIS(ERRESC3), +		PIS(ERRCONTROL1), +		PIS(ERRCONTROL2), +		PIS(ERRCONTROL3), +		PIS(STATEULPS1), +		PIS(STATEULPS2), +		PIS(STATEULPS3), +		PIS(ERRCONTENTIONLP0_1), +		PIS(ERRCONTENTIONLP1_1), +		PIS(ERRCONTENTIONLP0_2), +		PIS(ERRCONTENTIONLP1_2), +		PIS(ERRCONTENTIONLP0_3), +		PIS(ERRCONTENTIONLP1_3), +		PIS(ULPSACTIVENOT_ALL0), +		PIS(ULPSACTIVENOT_ALL1));  #undef PIS - -	printk("\n");  }  #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS @@ -1116,28 +1104,16 @@ static inline void dsi_enable_pll_clock(struct platform_device *dsidev,  	}  } -#ifdef DEBUG  static void _dsi_print_reset_status(struct platform_device *dsidev)  {  	u32 l;  	int b0, b1, b2; -	if (!dss_debug) -		return; -  	/* 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(dsidev, DSI_DSIPHY_CFG5); -	printk(KERN_DEBUG "DSI resets: "); - -	l = dsi_read_reg(dsidev, DSI_PLL_STATUS); -	printk("PLL (%d) ", FLD_GET(l, 0, 0)); - -	l = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1); -	printk("CIO (%d) ", FLD_GET(l, 29, 29)); -  	if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {  		b0 = 28;  		b1 = 27; @@ -1148,18 +1124,21 @@ static void _dsi_print_reset_status(struct platform_device *dsidev)  		b2 = 26;  	} -	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), -			FLD_GET(l, b2, b2), -			FLD_GET(l, 29, 29), -			FLD_GET(l, 30, 30), -			FLD_GET(l, 31, 31)); +#define DSI_FLD_GET(fld, start, end)\ +	FLD_GET(dsi_read_reg(dsidev, DSI_##fld), start, end) + +	pr_debug("DSI resets: PLL (%d) CIO (%d) PHY (%x%x%x, %d, %d, %d)\n", +		DSI_FLD_GET(PLL_STATUS, 0, 0), +		DSI_FLD_GET(COMPLEXIO_CFG1, 29, 29), +		DSI_FLD_GET(DSIPHY_CFG5, b0, b0), +		DSI_FLD_GET(DSIPHY_CFG5, b1, b1), +		DSI_FLD_GET(DSIPHY_CFG5, b2, b2), +		DSI_FLD_GET(DSIPHY_CFG5, 29, 29), +		DSI_FLD_GET(DSIPHY_CFG5, 30, 30), +		DSI_FLD_GET(DSIPHY_CFG5, 31, 31)); + +#undef DSI_FLD_GET  } -#else -#define _dsi_print_reset_status(x) -#endif  static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)  { @@ -1407,6 +1386,11 @@ retry:  				cur.dsi_pll_hsdiv_dispc_clk =  					cur.clkin4ddr / cur.regm_dispc; +				if (cur.regm_dispc > 1 && +						cur.regm_dispc % 2 != 0 && +						req_pck >= 1000000) +					continue; +  				/* this will narrow down the search a bit,  				 * but still give pixclocks below what was  				 * requested */ @@ -1621,7 +1605,7 @@ int dsi_pll_set_clock_div(struct platform_device *dsidev,  	u8 regn_start, regn_end, regm_start, regm_end;  	u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end; -	DSSDBGF(); +	DSSDBG("DSI PLL clock config starts");  	dsi->current_cinfo.clkin = cinfo->clkin;  	dsi->current_cinfo.fint = cinfo->fint; @@ -1757,11 +1741,21 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,  	DSSDBG("PLL init\n"); +	/* +	 * It seems that on many OMAPs we need to enable both to have a +	 * functional HSDivider. +	 */ +	enable_hsclk = enable_hsdiv = true; +  	if (dsi->vdds_dsi_reg == NULL) {  		struct regulator *vdds_dsi;  		vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); +		/* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */ +		if (IS_ERR(vdds_dsi)) +			vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO"); +  		if (IS_ERR(vdds_dsi)) {  			DSSERR("can't get VDDS_DSI regulator\n");  			return PTR_ERR(vdds_dsi); @@ -2440,7 +2434,7 @@ static int dsi_cio_init(struct platform_device *dsidev)  	int r;  	u32 l; -	DSSDBGF(); +	DSSDBG("DSI CIO init starts");  	r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));  	if (r) @@ -2791,7 +2785,7 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)  {  	u32 r; -	DSSDBGF("%d", channel); +	DSSDBG("Initial config of virtual channel %d", channel);  	r = dsi_read_reg(dsidev, DSI_VC_CTRL(channel)); @@ -2823,7 +2817,7 @@ static int dsi_vc_config_source(struct platform_device *dsidev, int channel,  	if (dsi->vc[channel].source == source)  		return 0; -	DSSDBGF("%d", channel); +	DSSDBG("Source config of virtual channel %d", channel);  	dsi_sync_vc(dsidev, channel); @@ -3581,7 +3575,7 @@ static int dsi_enter_ulps(struct platform_device *dsidev)  	int r, i;  	unsigned mask; -	DSSDBGF(); +	DSSDBG("Entering ULPS");  	WARN_ON(!dsi_bus_is_locked(dsidev)); @@ -4285,7 +4279,7 @@ int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,  	unsigned long pck;  	int r; -	DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk); +	DSSDBG("Setting DSI clocks: ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);  	mutex_lock(&dsi->lock); @@ -4541,7 +4535,7 @@ static void dsi_framedone_timeout_work_callback(struct work_struct *work)  	dsi_handle_framedone(dsi->pdev, -ETIMEDOUT);  } -static void dsi_framedone_irq_callback(void *data, u32 mask) +static void dsi_framedone_irq_callback(void *data)  {  	struct platform_device *dsidev = (struct platform_device *) data;  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); @@ -4615,7 +4609,6 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);  	struct omap_overlay_manager *mgr = dssdev->output->manager;  	int r; -	u32 irq = 0;  	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {  		dsi->timings.hsw = 1; @@ -4625,12 +4618,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)  		dsi->timings.vfp = 0;  		dsi->timings.vbp = 0; -		irq = dispc_mgr_get_framedone_irq(mgr->id); - -		r = omap_dispc_register_isr(dsi_framedone_irq_callback, -			(void *) dsidev, irq); +		r = dss_mgr_register_framedone_handler(mgr, +				dsi_framedone_irq_callback, dsidev);  		if (r) { -			DSSERR("can't get FRAMEDONE irq\n"); +			DSSERR("can't register FRAMEDONE handler\n");  			goto err;  		} @@ -4668,8 +4659,8 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)  	return 0;  err1:  	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) -		omap_dispc_unregister_isr(dsi_framedone_irq_callback, -			(void *) dsidev, irq); +		dss_mgr_unregister_framedone_handler(mgr, +				dsi_framedone_irq_callback, dsidev);  err:  	return r;  } @@ -4680,14 +4671,9 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);  	struct omap_overlay_manager *mgr = dssdev->output->manager; -	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { -		u32 irq; - -		irq = dispc_mgr_get_framedone_irq(mgr->id); - -		omap_dispc_unregister_isr(dsi_framedone_irq_callback, -			(void *) dsidev, irq); -	} +	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) +		dss_mgr_unregister_framedone_handler(mgr, +				dsi_framedone_irq_callback, dsidev);  }  static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) @@ -4730,7 +4716,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)  	if (r)  		goto err1; -	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);  	dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);  	dss_select_lcd_clk_source(mgr->id,  			dssdev->clocks.dispc.channel.lcd_clk_src); @@ -4765,7 +4750,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)  err3:  	dsi_cio_uninit(dsidev);  err2: -	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);  	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);  	dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); @@ -4792,7 +4776,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,  	dsi_vc_enable(dsidev, 2, 0);  	dsi_vc_enable(dsidev, 3, 0); -	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);  	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);  	dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);  	dsi_cio_uninit(dsidev); @@ -4981,6 +4964,10 @@ static int __init dsi_init_display(struct omap_dss_device *dssdev)  		vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); +		/* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */ +		if (IS_ERR(vdds_dsi)) +			vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO"); +  		if (IS_ERR(vdds_dsi)) {  			DSSERR("can't get VDDS_DSI regulator\n");  			return PTR_ERR(vdds_dsi); @@ -5121,7 +5108,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p  {  	struct omap_dss_board_info *pdata = pdev->dev.platform_data;  	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); -	const char *def_disp_name = dss_get_default_display_name(); +	const char *def_disp_name = omapdss_get_default_display_name();  	struct omap_dss_device *def_dssdev;  	int i; @@ -5151,6 +5138,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p  static void __init dsi_probe_pdata(struct platform_device *dsidev)  { +	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);  	struct omap_dss_device *plat_dssdev;  	struct omap_dss_device *dssdev;  	int r; @@ -5173,9 +5161,18 @@ static void __init dsi_probe_pdata(struct platform_device *dsidev)  		return;  	} +	r = omapdss_output_set_device(&dsi->output, dssdev); +	if (r) { +		DSSERR("failed to connect output to new device: %s\n", +				dssdev->name); +		dss_put_device(dssdev); +		return; +	} +  	r = dss_add_device(dssdev);  	if (r) {  		DSSERR("device %s register failed: %d\n", dssdev->name, r); +		omapdss_output_unset_device(&dsi->output);  		dss_put_device(dssdev);  		return;  	} |