Esempio n. 1
0
static int lcdc_unblank(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	HDMI_DBG("%s\n", __func__);

#if 0
	HDMI_DBG("%s: enable clocks\n", __func__);
	clk_enable(lcdc->mdp_clk);
	clk_enable(lcdc->pclk);
	clk_enable(lcdc->pad_pclk);

	panel_ops->unblank(panel_ops);

	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
	atomic_set(&lcdc->blank_count, 1);
#else
	lcdc_enable_video();
	/* TODO: need pre-test to see if it make any influence to HDCP,
	 * if ebi1_clk enabled here.
	 */
        panel_ops->unblank(panel_ops);
#endif
	return 0;
}
Esempio n. 2
0
/* FIXME: arrange the clock manipulating to proper place,
	  integrate with the counter of fb_hdmi
*/
int lcdc_enable_video(void)
{
        //struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
        struct mdp_lcdc_info *lcdc = _lcdc;
        struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	mutex_lock(&lcdc->blank_lock);
	if (atomic_read(&lcdc->blank_count))
		goto end_enable_video;
        HDMI_DBG("%s: enable clocks\n", __func__);
        clk_enable(lcdc->mdp_clk);
        clk_enable(lcdc->pclk);
        clk_enable(lcdc->pad_pclk);

	/* TODO: need pre-test to see if it make any influence to HDCP,
	 * if ebi1_clk doesn't enabled here.
	 */
	//panel_ops->unblank(panel_ops);

        mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
        atomic_inc(&lcdc->blank_count);
        HDMI_DBG("%s, blank_count=%d\n", __func__,
		atomic_read(&lcdc->blank_count));
end_enable_video:
	mutex_unlock(&lcdc->blank_lock);

        return 0;
}
Esempio n. 3
0
static int lcdc_blank(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	//struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

#if 0
	mutex_lock(&lcdc->blank_lock);
	if (atomic_read(&lcdc->blank_count) == 0)
		goto blank_done;
	if (atomic_dec_return(&lcdc->blank_count) == 0) {
		HDMI_DBG("%s: disable clocks\n", __func__);
		panel_ops->blank(panel_ops);
		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
		clk_disable(lcdc->pclk);
		clk_disable(lcdc->pad_pclk);
		clk_disable(lcdc->mdp_clk);
	}
blank_done:
	mutex_unlock(&lcdc->blank_lock);
	HDMI_DBG("%s, blank_count=%d\n", __func__,
		atomic_read(&lcdc->blank_count));
#else
	lcdc_disable_video();
#endif
	return 0;
}
Esempio n. 4
0
static void OnDownstreamRxPoweredUp(struct hdmi_info *hdmi)
{
        HDMI_DBG("%s\n", __func__);
	dsRxPoweredUp = true;
	HotPlugService(hdmi);
#ifdef CONFIG_HTC_HEADSET_MGR
	/* send cable in event */
	switch_send_event(BIT_HDMI_CABLE, 1);
	HDMI_DBG("Cable inserted.\n");
#endif
	pvid_mode = vid_mode;
        hdmi_active9022_dup(hdmi->client);
}
Esempio n. 5
0
bool ReleaseDDC(struct hdmi_info *hdmi, u8 SysCtrlRegVal)
{
	u8 DDCReqTimeout = T_DDC_ACCESS, TPI_ControlImage;

	HDMI_DBG("%s\n", __func__);
	/* Just to be sure bits [2:1] are 0 before it is written */
	SysCtrlRegVal &= ~(0x6);
	/* Loop till 0x1A[1] reads "0" */
	while (DDCReqTimeout--) {
		/* Cannot use ReadClearWriteTPI() here. A read of
		 * TPI_SYSTEM_CONTROL is invalid while DDC is granted.
		 * Doing so will return 0xFF, and cause an invalid value to be
		 * written back. 
		 */
		/* 0x1A[2:1] = "0" - release the DDC bus */
		//ReadClearWriteTPI(TPI_SYSTEM_CONTROL,BITS_2_1);

		hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, SysCtrlRegVal);
		TPI_ControlImage = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL);
		/* When 0x1A[2:1] read "0" */
		if (!(TPI_ControlImage & 0x6))
			return true;
	}

	/* Failed to release DDC bus control */
	return false;
}
Esempio n. 6
0
bool GetDDC_Access(struct hdmi_info *hdmi, u8* SysCtrlRegVal)
{
	u8 sysCtrl, TPI_ControlImage, DDCReqTimeout = T_DDC_ACCESS;

	HDMI_DBG("%s\n", __func__);
	/* Read and store original value. Will be passed into ReleaseDDC() */
	sysCtrl = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL);
	*SysCtrlRegVal = sysCtrl;

	sysCtrl |= BIT_DDC_BUS_REQ;
	hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl);

	/* Loop till 0x1A[1] reads "1" */
	while (DDCReqTimeout--) {
		TPI_ControlImage = hdmi_read(hdmi->client, TPI_SYSTEM_CONTROL);

		/* When 0x1A[1] reads "1" */
		if (TPI_ControlImage & BIT_DDC_BUS_GRANT) {
			sysCtrl |= BIT_DDC_BUS_GRANT;
			/* lock host DDC bus access (0x1A[2:1] = 11) */
			hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl);
			return true;
		}
		/* 0x1A[2] = "1" - Requst the DDC bus */
		hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl);
		mdelay(200);
	}

	/* Failure... restore original value. */
	hdmi_write_byte(hdmi->client, TPI_SYSTEM_CONTROL, sysCtrl);
	return false;
}
Esempio n. 7
0
int lcdc_disable_video(void)
{
        struct mdp_lcdc_info *lcdc = _lcdc;
        struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	mutex_lock(&lcdc->blank_lock);
	if (atomic_read(&lcdc->blank_count) == 0)
		goto disable_video_done;
	if (atomic_dec_return(&lcdc->blank_count) == 0) {
		HDMI_DBG("%s: disable clocks\n", __func__);
		panel_ops->blank(panel_ops);
		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
		clk_disable(lcdc->pclk);
		clk_disable(lcdc->pad_pclk);
		clk_disable(lcdc->mdp_clk);
	}
disable_video_done:
	mutex_unlock(&lcdc->blank_lock);
	HDMI_DBG("%s, blank_count=%d\n", __func__,
			atomic_read(&lcdc->blank_count));
	return 0;
}
static void suc_hdmi_gpio_off(void)
{
	int i = 0;

	HDMI_DBG("%s\n", __func__);
	config_gpio_table(hdmi_gpio_off_table, ARRAY_SIZE(hdmi_gpio_off_table));

	for (i = SUPERSONIC_LCD_R0; i <= SUPERSONIC_LCD_R4; i++)
		gpio_set_value(i, 0);
	for (i = SUPERSONIC_LCD_G0; i <= SUPERSONIC_LCD_G5; i++)
		gpio_set_value(i, 0);
	for (i = SUPERSONIC_LCD_B0; i <= SUPERSONIC_LCD_DE; i++)
		gpio_set_value(i, 0);
}
Esempio n. 9
0
static int lcdc_suspend(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	//pr_info("%s: suspending\n", __func__);
	HDMI_DBG("%s\n", __func__);

	if (panel_ops->uninit)
		panel_ops->uninit(panel_ops);
	lcdc_disable_video();

	return 0;
}
static int hdmi_power(int on)
{
	HDMI_DBG("%s(%d)\n", __func__, on);

	switch(on) {
	/* Power on/off sequence for normal or D2 sleep mode */
	case 0:
		gpio_set_value(HDMI_RST, 0);
		msleep(2);
		gpio_set_value(V_HDMI_3V3_EN, 0);
		gpio_set_value(V_VGA_5V_SIL9022A_EN, 0);
		msleep(2);
		gpio_set_value(V_HDMI_1V2_EN, 0);
		break;
	case 1:
		gpio_set_value(V_HDMI_1V2_EN, 1);
		msleep(2);
		gpio_set_value(V_VGA_5V_SIL9022A_EN, 1);
		gpio_set_value(V_HDMI_3V3_EN, 1);
		msleep(2);
		gpio_set_value(HDMI_RST, 1);
		msleep(2);
		break;

	/* Power on/off sequence for D3 sleep mode */
	case 2:
		gpio_set_value(V_HDMI_3V3_EN, 0);
		break;
	case 3:
		gpio_set_value(HDMI_RST, 0);
		msleep(2);
		gpio_set_value(V_HDMI_3V3_EN, 1);
		gpio_set_value(V_VGA_5V_SIL9022A_EN, 1);
		msleep(50);
		gpio_set_value(HDMI_RST, 1);
		msleep(10);
		break;
	case 4:
		gpio_set_value(V_VGA_5V_SIL9022A_EN, 0);
		break;
	case 5:
		gpio_set_value(V_VGA_5V_SIL9022A_EN, 1);
		break;

	default:
		return -EINVAL;
	}
	return 0;
}
Esempio n. 11
0
static void tpi_clear_pending_event(struct hdmi_info *hdmi)
{
	int retry = 100;

	if (hdmi->sleeping == SLEEP) return;
	while (retry--) {
		hdmi_write_byte(hdmi->client, 0x3c, 1);
		hdmi_write_byte(hdmi->client, 0x3d, 1);
		if (hdmi_read(hdmi->client, 0x3d) & 0x01)
			msleep(1);
		else
			break;
	}
	if (retry < 19) HDMI_DBG("%s: retry=%d\n", __func__, 19 - retry);
}
Esempio n. 12
0
static int lcdc_resume(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	//pr_info("%s: resuming\n", __func__);
	HDMI_DBG("%s\n", __func__);

	if (panel_ops->init) {
		if (panel_ops->init(panel_ops) < 0)
			printk(KERN_ERR "LCD init fail!\n");
	}

	return 0;
}
Esempio n. 13
0
void EnableTMDS(struct hdmi_info *hdmi)
{
#if 1
	/* 0x1A[4] = 0 */
	ReadClearWriteTPI(hdmi, TPI_SYSTEM_CONTROL, BIT_TMDS_OUTPUT);

	if (edid_check_sink_type(hdmi))
		hdmi_write_byte(hdmi->client, 0x26,
			hdmi_read(hdmi->client, 0x26) & ~0x10);

#else
	u8 val;
	struct i2c_client *client = hdmi->i2c_client;

	val = hdmi_read(client, TPI_SYSTEM_CONTROL);
	hdmi_write_byte(client, TPI_SYSTEM_CONTROL, val & ~BIT_TMDS_OUTPUT);
	HDMI_DBG("%s, reg 0x1a: %02x->%02x\n", __func__,
		val, val & ~BIT_TMDS_OUTPUT); 
#endif
	
}
Esempio n. 14
0
//////////////////////////////////////////////////////////////////////////////
// FUNCTION      :  EnableInterrupts()
// PURPOSE       :  Enable the interrupts specified in the input parameter
// INPUT PARAMS  :  A bit pattern with "1" for each interrupt that needs to be
//                  set in the Interrupt Enable Register (TPI offset 0x3C)
// OUTPUT PARAMS :  void
// GLOBALS USED  :  None
// RETURNS       :  TRUE
//////////////////////////////////////////////////////////////////////////////
bool tpi_enable_interrupts(struct hdmi_info *hdmi, u8 Interrupt_Pattern)
{
	HDMI_DBG("%s, reg=%02x, pat=%02x\n", __func__, TPI_INTERRUPT_EN, Interrupt_Pattern);
	ReadSetWriteTPI(hdmi, TPI_INTERRUPT_EN, Interrupt_Pattern);
	return true;
}
static void suc_hdmi_gpio_on(void)
{
	HDMI_DBG("%s\n", __func__);

	config_gpio_table(hdmi_gpio_on_table, ARRAY_SIZE(hdmi_gpio_on_table));
}
Esempio n. 16
0
static void OnDownstreamRxPoweredDown(struct hdmi_info *hdmi)
{
	HDMI_DBG("%s\n", __func__);
	dsRxPoweredUp = false;
	hdcp_off(hdmi);
}
Esempio n. 17
0
static int
lcdc_adjust_timing(struct msm_panel_data *fb_panel,
		struct msm_lcdc_timing *timing, u32 xres, u32 yres)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	unsigned int hsync_period;
	unsigned int hsync_start_x;
	unsigned int hsync_end_x;
	unsigned int vsync_period;
	unsigned int display_vstart;
	unsigned int display_vend;
	uint32_t dma_cfg;

	clk_set_rate(lcdc->pclk, timing->clk_rate);
	clk_set_rate(lcdc->pad_pclk, timing->clk_rate);
	HDMI_DBG("%s, clk=%d, xres=%d, yres=%d,\n", __func__,
		clk_get_rate(lcdc->pclk), xres, yres);

	hsync_period = (timing->hsync_pulse_width + timing->hsync_back_porch +
			xres + timing->hsync_front_porch);
	hsync_start_x = (timing->hsync_pulse_width + timing->hsync_back_porch);
	hsync_end_x = hsync_period - timing->hsync_front_porch - 1;

	vsync_period = (timing->vsync_pulse_width + timing->vsync_back_porch +
			yres + timing->vsync_front_porch);
	vsync_period *= hsync_period;

	display_vstart = timing->vsync_pulse_width + timing->vsync_back_porch;
	display_vstart *= hsync_period;
	display_vstart += timing->hsync_skew;

	display_vend = timing->vsync_front_porch * hsync_period;
	display_vend = vsync_period - display_vend + timing->hsync_skew - 1;

	/* register values we pre-compute at init time from the timing
	 * information in the panel info */
	lcdc->parms.hsync_ctl = (((hsync_period & 0xfff) << 16) |
				 (timing->hsync_pulse_width & 0xfff));
	lcdc->parms.vsync_period = vsync_period & 0xffffff;
	lcdc->parms.vsync_pulse_width = (timing->vsync_pulse_width *
					 hsync_period) & 0xffffff;

	lcdc->parms.display_hctl = (((hsync_end_x & 0xfff) << 16) |
				    (hsync_start_x & 0xfff));
	lcdc->parms.display_vstart = display_vstart & 0xffffff;
	lcdc->parms.display_vend = display_vend & 0xffffff;
	lcdc->parms.hsync_skew = timing->hsync_skew & 0xfff;
	lcdc->parms.polarity = ((timing->hsync_act_low << 0) |
				(timing->vsync_act_low << 1) |
				(timing->den_act_low << 2));
	lcdc->parms.clk_rate = timing->clk_rate;

	mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL);
	mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD);
	mdp_writel(lcdc->mdp, lcdc->parms.vsync_pulse_width,
		   MDP_LCDC_VSYNC_PULSE_WIDTH);
	mdp_writel(lcdc->mdp, lcdc->parms.display_hctl, MDP_LCDC_DISPLAY_HCTL);
	mdp_writel(lcdc->mdp, lcdc->parms.display_vstart,
		   MDP_LCDC_DISPLAY_V_START);
	mdp_writel(lcdc->mdp, lcdc->parms.display_vend, MDP_LCDC_DISPLAY_V_END);
	mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW);

	mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR);
	mdp_writel(lcdc->mdp, 0x0, MDP_LCDC_UNDERFLOW_CTL);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END);
	mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY);
	printk("solomon: polarity=%04x\n", mdp_readl(lcdc->mdp, MDP_LCDC_CTL_POLARITY));

	/* config the dma_p block that drives the lcdc data */
	mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR);
	mdp_writel(lcdc->mdp, (((yres & 0x7ff) << 16) |
			       (xres & 0x7ff)),
		   MDP_DMA_P_SIZE);
	/* TODO: pull in the bpp info from somewhere else? */
	mdp_writel(lcdc->mdp, xres * 2,
		   MDP_DMA_P_IBUF_Y_STRIDE);
	mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY);

	dma_cfg = (DMA_PACK_ALIGN_LSB |
		   DMA_PACK_PATTERN_RGB |
		   DMA_DITHER_EN);
	dma_cfg |= DMA_OUT_SEL_LCDC;
	dma_cfg |= DMA_IBUF_FORMAT_RGB565;
	dma_cfg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;

	mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG);
	return 0;
}