Beispiel #1
0
static irqreturn_t imx_hdmi_irq(int irq, void *dev_id)
{
	struct imx_hdmi *hdmi = dev_id;
	u8 intr_stat;
	u8 phy_int_pol;

	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);

	phy_int_pol = hdmi_readb(hdmi, HDMI_PHY_POL0);

	if (intr_stat & HDMI_IH_PHY_STAT0_HPD) {
		if (phy_int_pol & HDMI_PHY_HPD) {
			dev_dbg(hdmi->dev, "EVENT=plugin\n");

			hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0);

			imx_hdmi_poweron(hdmi);
		} else {
			dev_dbg(hdmi->dev, "EVENT=plugout\n");

			hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD,
				HDMI_PHY_POL0);

			imx_hdmi_poweroff(hdmi);
		}
		drm_helper_hpd_irq_event(hdmi->connector.dev);
	}

	hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0);
	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);

	return IRQ_HANDLED;
}
Beispiel #2
0
static void hdmi_set_audio_infoframe(void)
{
	/* set to 0: means "refer to stream header" */
	hdmi_writeb(0x00, HDMI_FC_AUDICONF0);
	hdmi_writeb(0x00, HDMI_FC_AUDICONF1);
	hdmi_writeb(0x00, HDMI_FC_AUDICONF2);
}
Beispiel #3
0
static void hdmi_dma_irq_mute(int mute)
{
	if (mute)
		hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
	else
		hdmi_writeb(0x00, HDMI_IH_MUTE_AHBDMAAUD_STAT0);
}
Beispiel #4
0
/* HDMI Initialization Step B.4 */
static void imx_hdmi_enable_video_path(struct imx_hdmi *hdmi)
{
	u8 clkdis;

	/* control period minimum duration */
	hdmi_writeb(hdmi, 12, HDMI_FC_CTRLDUR);
	hdmi_writeb(hdmi, 32, HDMI_FC_EXCTRLDUR);
	hdmi_writeb(hdmi, 1, HDMI_FC_EXCTRLSPAC);

	/* Set to fill TMDS data channels */
	hdmi_writeb(hdmi, 0x0B, HDMI_FC_CH0PREAM);
	hdmi_writeb(hdmi, 0x16, HDMI_FC_CH1PREAM);
	hdmi_writeb(hdmi, 0x21, HDMI_FC_CH2PREAM);

	/* Enable pixel clock and tmds data path */
	clkdis = 0x7F;
	clkdis &= ~HDMI_MC_CLKDIS_PIXELCLK_DISABLE;
	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);

	clkdis &= ~HDMI_MC_CLKDIS_TMDSCLK_DISABLE;
	hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);

	/* Enable csc path */
	if (is_color_space_conversion(hdmi)) {
		clkdis &= ~HDMI_MC_CLKDIS_CSCCLK_DISABLE;
		hdmi_writeb(hdmi, clkdis, HDMI_MC_CLKDIS);
	}
}
Beispiel #5
0
static void hdmi_dma_irq_mask(int mask)
{
	u8 regvalue;
	regvalue = hdmi_readb(HDMI_AHB_DMA_MASK);

	if (mask) {
		regvalue |= HDMI_AHB_DMA_DONE;
		hdmi_writeb(regvalue, HDMI_AHB_DMA_MASK);
	} else {
		regvalue &= (u8)~HDMI_AHB_DMA_DONE;
		hdmi_writeb(regvalue, HDMI_AHB_DMA_MASK);
	}
}
Beispiel #6
0
static void __hdmi_phy_i2c_write(struct imx_hdmi *hdmi, unsigned short data,
			      unsigned char addr)
{
	hdmi_writeb(hdmi, 0xFF, HDMI_IH_I2CMPHY_STAT0);
	hdmi_writeb(hdmi, addr, HDMI_PHY_I2CM_ADDRESS_ADDR);
	hdmi_writeb(hdmi, (unsigned char)(data >> 8),
		HDMI_PHY_I2CM_DATAO_1_ADDR);
	hdmi_writeb(hdmi, (unsigned char)(data >> 0),
		HDMI_PHY_I2CM_DATAO_0_ADDR);
	hdmi_writeb(hdmi, HDMI_PHY_I2CM_OPERATION_ADDR_WRITE,
		HDMI_PHY_I2CM_OPERATION_ADDR);
	hdmi_phy_wait_i2c_done(hdmi, 1000);
}
Beispiel #7
0
static void hdmi_mask(int mask)
{
	u8 regvalue;
	regvalue = hdmi_readb(HDMI_AHB_DMA_MASK);

	if (mask) {
		regvalue |= HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY;
		hdmi_writeb(regvalue, HDMI_AHB_DMA_MASK);
	} else {
		regvalue &= (u8)~(HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY);
		hdmi_writeb(regvalue, HDMI_AHB_DMA_MASK);
	}
}
Beispiel #8
0
static void hdmi_modb(struct dw_hdmi *hdmi, u8 data, u8 mask, unsigned reg)
{
	u8 val = hdmi_readb(hdmi, reg) & ~mask;

	val |= data & mask;
	hdmi_writeb(hdmi, val, reg);
}
Beispiel #9
0
static void hdmi_video_csc(struct imx_hdmi *hdmi)
{
	int color_depth = 0;
	int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE;
	int decimation = 0;

	/* YCC422 interpolation to 444 mode */
	if (is_color_space_interpolation(hdmi))
		interpolation = HDMI_CSC_CFG_INTMODE_CHROMA_INT_FORMULA1;
	else if (is_color_space_decimation(hdmi))
		decimation = HDMI_CSC_CFG_DECMODE_CHROMA_INT_FORMULA3;

	if (hdmi->hdmi_data.enc_color_depth == 8)
		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_24BPP;
	else if (hdmi->hdmi_data.enc_color_depth == 10)
		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_30BPP;
	else if (hdmi->hdmi_data.enc_color_depth == 12)
		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_36BPP;
	else if (hdmi->hdmi_data.enc_color_depth == 16)
		color_depth = HDMI_CSC_SCALE_CSC_COLORDE_PTH_48BPP;
	else
		return;

	/* Configure the CSC registers */
	hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG);
	hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK,
		  HDMI_CSC_SCALE);

	imx_hdmi_update_csc_coeffs(hdmi);
}
Beispiel #10
0
void hdmi_write4(unsigned int value, unsigned int reg)
{
	/* write a four byte address to hdmi regs */
	hdmi_writeb(value & 0xff, reg);
	hdmi_writeb((value >> 8) & 0xff, reg + 1);
	hdmi_writeb((value >> 16) & 0xff, reg + 2);
	hdmi_writeb((value >> 24) & 0xff, reg + 3);
}
Beispiel #11
0
/* Wait until we are registered to enable interrupts */
static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi)
{
	hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL,
		    HDMI_PHY_I2CM_INT_ADDR);

	hdmi_writeb(hdmi, HDMI_PHY_I2CM_CTLINT_ADDR_NAC_POL |
		    HDMI_PHY_I2CM_CTLINT_ADDR_ARBITRATION_POL,
		    HDMI_PHY_I2CM_CTLINT_ADDR);

	/* enable cable hot plug irq */
	hdmi_writeb(hdmi, (u8)~HDMI_PHY_HPD, HDMI_PHY_MASK0);

	/* Clear Hotplug interrupts */
	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);

	return 0;
}
Beispiel #12
0
/* Workaround to clear the overflow condition */
static void imx_hdmi_clear_overflow(struct imx_hdmi *hdmi)
{
	int count;
	u8 val;

	/* TMDS software reset */
	hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ);

	val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF);
	if (hdmi->dev_type == IMX6DL_HDMI) {
		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
		return;
	}

	for (count = 0; count < 4; count++)
		hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF);
}
Beispiel #13
0
/*
 * this submodule is responsible for the video data synchronization.
 * for example, for RGB 4:4:4 input, the data map is defined as
 *			pin{47~40} <==> R[7:0]
 *			pin{31~24} <==> G[7:0]
 *			pin{15~8}  <==> B[7:0]
 */
static void hdmi_video_sample(struct imx_hdmi *hdmi)
{
	int color_format = 0;
	u8 val;

	if (hdmi->hdmi_data.enc_in_format == RGB) {
		if (hdmi->hdmi_data.enc_color_depth == 8)
			color_format = 0x01;
		else if (hdmi->hdmi_data.enc_color_depth == 10)
			color_format = 0x03;
		else if (hdmi->hdmi_data.enc_color_depth == 12)
			color_format = 0x05;
		else if (hdmi->hdmi_data.enc_color_depth == 16)
			color_format = 0x07;
		else
			return;
	} else if (hdmi->hdmi_data.enc_in_format == YCBCR444) {
		if (hdmi->hdmi_data.enc_color_depth == 8)
			color_format = 0x09;
		else if (hdmi->hdmi_data.enc_color_depth == 10)
			color_format = 0x0B;
		else if (hdmi->hdmi_data.enc_color_depth == 12)
			color_format = 0x0D;
		else if (hdmi->hdmi_data.enc_color_depth == 16)
			color_format = 0x0F;
		else
			return;
	} else if (hdmi->hdmi_data.enc_in_format == YCBCR422_8BITS) {
		if (hdmi->hdmi_data.enc_color_depth == 8)
			color_format = 0x16;
		else if (hdmi->hdmi_data.enc_color_depth == 10)
			color_format = 0x14;
		else if (hdmi->hdmi_data.enc_color_depth == 12)
			color_format = 0x12;
		else
			return;
	}

	val = HDMI_TX_INVID0_INTERNAL_DE_GENERATOR_DISABLE |
		((color_format << HDMI_TX_INVID0_VIDEO_MAPPING_OFFSET) &
		HDMI_TX_INVID0_VIDEO_MAPPING_MASK);
	hdmi_writeb(hdmi, val, HDMI_TX_INVID0);

	/* Enable TX stuffing: When DE is inactive, fix the output data to 0 */
	val = HDMI_TX_INSTUFFING_BDBDATA_STUFFING_ENABLE |
		HDMI_TX_INSTUFFING_RCRDATA_STUFFING_ENABLE |
		HDMI_TX_INSTUFFING_GYDATA_STUFFING_ENABLE;
	hdmi_writeb(hdmi, val, HDMI_TX_INSTUFFING);
	hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA0);
	hdmi_writeb(hdmi, 0x0, HDMI_TX_GYDATA1);
	hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA0);
	hdmi_writeb(hdmi, 0x0, HDMI_TX_RCRDATA1);
	hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA0);
	hdmi_writeb(hdmi, 0x0, HDMI_TX_BCBDATA1);
}
Beispiel #14
0
static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
			   unsigned int n)
{
	/* Must be set/cleared first */
	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);

	/* nshift factor = 0 */
	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);

	hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
		    HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
	hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
	hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);

	hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3);
	hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2);
	hdmi_writeb(hdmi, n & 0xff, HDMI_AUD_N1);
}
Beispiel #15
0
static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts)
{
	/* Must be set/cleared first */
	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);

	hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
	hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
	hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
		    HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
}
Beispiel #16
0
static void hdmi_set_clock_regenerator_n(unsigned int value)
{
	u8 val;

	if (!hdmi_dma_running) {
		hdmi_writeb(value & 0xff, HDMI_AUD_N1);
		hdmi_writeb(0, HDMI_AUD_N2);
		hdmi_writeb(0, HDMI_AUD_N3);
	}

	hdmi_writeb(value & 0xff, HDMI_AUD_N1);
	hdmi_writeb((value >> 8) & 0xff, HDMI_AUD_N2);
	hdmi_writeb((value >> 16) & 0x0f, HDMI_AUD_N3);

	/* nshift factor = 0 */
	val = hdmi_readb(HDMI_AUD_CTS3);
	val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK;
	hdmi_writeb(val, HDMI_AUD_CTS3);
}
Beispiel #17
0
static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi,
					 unsigned int value)
{
	hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1);
	hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2);
	hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3);

	/* nshift factor = 0 */
	hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
}
Beispiel #18
0
static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi)
{
	const u16 (*csc_coeff)[3][4] = &csc_coeff_default;
	unsigned i;
	u32 csc_scale = 1;

	if (is_color_space_conversion(hdmi)) {
		if (hdmi->hdmi_data.enc_out_format == RGB) {
			if (hdmi->hdmi_data.colorimetry ==
					HDMI_COLORIMETRY_ITU_601)
				csc_coeff = &csc_coeff_rgb_out_eitu601;
			else
				csc_coeff = &csc_coeff_rgb_out_eitu709;
		} else if (hdmi->hdmi_data.enc_in_format == RGB) {
			if (hdmi->hdmi_data.colorimetry ==
					HDMI_COLORIMETRY_ITU_601)
				csc_coeff = &csc_coeff_rgb_in_eitu601;
			else
				csc_coeff = &csc_coeff_rgb_in_eitu709;
			csc_scale = 0;
		}
	}

	/* The CSC registers are sequential, alternating MSB then LSB */
	for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) {
		u16 coeff_a = (*csc_coeff)[0][i];
		u16 coeff_b = (*csc_coeff)[1][i];
		u16 coeff_c = (*csc_coeff)[2][i];

		hdmi_writeb(hdmi, coeff_a & 0xff,
			HDMI_CSC_COEF_A1_LSB + i * 2);
		hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2);
		hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2);
		hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2);
		hdmi_writeb(hdmi, coeff_c & 0xff,
			HDMI_CSC_COEF_C1_LSB + i * 2);
		hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2);
	}

	hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK,
		  HDMI_CSC_SCALE);
}
Beispiel #19
0
static void hdmi_mask(int mask)
{
	u8 regval = hdmi_readb(HDMI_AHB_DMA_MASK);

	if (mask)
		regval |= HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY;
	else
		regval &= (u8)~(HDMI_AHB_DMA_ERROR | HDMI_AHB_DMA_FIFO_EMPTY);

	hdmi_writeb(regval, HDMI_AHB_DMA_MASK);
}
Beispiel #20
0
static void hdmi_dma_irq_set(bool set)
{
	u8 val = hdmi_readb(HDMI_AHB_DMA_MASK);

	if (set)
		val |= HDMI_AHB_DMA_DONE;
	else
		val &= (u8)~HDMI_AHB_DMA_DONE;

	hdmi_writeb(val, HDMI_AHB_DMA_MASK);
}
static void hdmi_reg_init(struct hdmi_device *hdev)
{
	/* enable HPD interrupts */
	hdmi_write_mask(hdev, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
	/* choose HDMI mode */
	hdmi_write_mask(hdev, HDMI_MODE_SEL,
		HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
	/* disable bluescreen */
	hdmi_write_mask(hdev, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
	/* choose bluescreen (fecal) color */
	hdmi_writeb(hdev, HDMI_BLUE_SCREEN_0, 0x12);
	hdmi_writeb(hdev, HDMI_BLUE_SCREEN_1, 0x34);
	hdmi_writeb(hdev, HDMI_BLUE_SCREEN_2, 0x56);
	/* enable AVI packet every vsync, fixes purple line problem */
	hdmi_writeb(hdev, HDMI_AVI_CON, 0x02);
	/* force YUV444, look to CEA-861-D, table 7 for more detail */
	hdmi_writeb(hdev, HDMI_AVI_BYTE(0), 2 << 5);
	hdmi_write_mask(hdev, HDMI_CON_1, 2, 3 << 5);
}
Beispiel #22
0
static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id)
{
	struct imx_hdmi *hdmi = dev_id;
	u8 intr_stat;

	intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0);
	if (intr_stat)
		hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);

	return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE;
}
Beispiel #23
0
static void hdmi_set_clock_regenerator_cts(unsigned int cts)
{
	u8 val;

	if (!hdmi_dma_running) {
		hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
		hdmi_writeb(0, HDMI_AUD_CTS2);
		hdmi_writeb(0, HDMI_AUD_CTS3);
	}

	/* Must be set/cleared first */
	val = hdmi_readb(HDMI_AUD_CTS3);
	val &= ~HDMI_AUD_CTS3_CTS_MANUAL;
	hdmi_writeb(val, HDMI_AUD_CTS3);

	hdmi_writeb(cts & 0xff, HDMI_AUD_CTS1);
	hdmi_writeb((cts >> 8) & 0xff, HDMI_AUD_CTS2);
	hdmi_writeb(((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
		    HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
}
Beispiel #24
0
static bool hdmi_phy_wait_i2c_done(struct dw_hdmi *hdmi, int msec)
{
	u32 val;

	while ((val = hdmi_readb(hdmi, HDMI_IH_I2CMPHY_STAT0) & 0x3) == 0) {
		if (msec-- == 0)
			return false;
		udelay(1000);
	}
	hdmi_writeb(hdmi, val, HDMI_IH_I2CMPHY_STAT0);

	return true;
}
Beispiel #25
0
void dw_hdmi_unbind(struct device *dev, struct device *master, void *data)
{
	struct dw_hdmi *hdmi = dev_get_drvdata(dev);

	/* Disable all interrupts */
	hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0);

	hdmi->connector.funcs->destroy(&hdmi->connector);
	hdmi->encoder->funcs->destroy(hdmi->encoder);

	clk_disable_unprepare(hdmi->iahb_clk);
	clk_disable_unprepare(hdmi->isfr_clk);
	i2c_put_adapter(hdmi->ddc);
}
Beispiel #26
0
static void initialize_hdmi_ih_mutes(void)
{
	u8 ih_mute;

	/*
	 * Boot up defaults are:
	 * HDMI_IH_MUTE   = 0x03 (disabled)
	 * HDMI_IH_MUTE_* = 0x00 (enabled)
	 */

	/* Disable top level interrupt bits in HDMI block */
	ih_mute = hdmi_readb(HDMI_IH_MUTE) |
		  HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
		  HDMI_IH_MUTE_MUTE_ALL_INTERRUPT;

	hdmi_writeb(ih_mute, HDMI_IH_MUTE);

	/* by default mask all interrupts */
	hdmi_writeb(0xff, HDMI_VP_MASK);
	hdmi_writeb(0xff, HDMI_FC_MASK0);
	hdmi_writeb(0xff, HDMI_FC_MASK1);
	hdmi_writeb(0xff, HDMI_FC_MASK2);
	hdmi_writeb(0xff, HDMI_PHY_MASK0);
	hdmi_writeb(0xff, HDMI_PHY_I2CM_INT_ADDR);
	hdmi_writeb(0xff, HDMI_PHY_I2CM_CTLINT_ADDR);
	hdmi_writeb(0xff, HDMI_AUD_INT);
	hdmi_writeb(0xff, HDMI_AUD_SPDIFINT);
	hdmi_writeb(0xff, HDMI_AUD_HBR_MASK);
	hdmi_writeb(0xff, HDMI_GP_MASK);
	hdmi_writeb(0xff, HDMI_A_APIINTMSK);
	hdmi_writeb(0xff, HDMI_CEC_MASK);
	hdmi_writeb(0xff, HDMI_I2CM_INT);
	hdmi_writeb(0xff, HDMI_I2CM_CTLINT);

	/* Disable interrupts in the IH_MUTE_* registers */
	hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT0);
	hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT1);
	hdmi_writeb(0xff, HDMI_IH_MUTE_FC_STAT2);
	hdmi_writeb(0xff, HDMI_IH_MUTE_AS_STAT0);
	hdmi_writeb(0xff, HDMI_IH_MUTE_PHY_STAT0);
	hdmi_writeb(0xff, HDMI_IH_MUTE_I2CM_STAT0);
	hdmi_writeb(0xff, HDMI_IH_MUTE_CEC_STAT0);
	hdmi_writeb(0xff, HDMI_IH_MUTE_VP_STAT0);
	hdmi_writeb(0xff, HDMI_IH_MUTE_I2CMPHY_STAT0);
	hdmi_writeb(0xff, HDMI_IH_MUTE_AHBDMAAUD_STAT0);

	/* Enable top level interrupt bits in HDMI block */
	ih_mute &= ~(HDMI_IH_MUTE_MUTE_WAKEUP_INTERRUPT |
		    HDMI_IH_MUTE_MUTE_ALL_INTERRUPT);
	hdmi_writeb(ih_mute, HDMI_IH_MUTE);
}
Beispiel #27
0
static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep,
			      unsigned char res, int cscon)
{
	unsigned res_idx, i;
	u8 val, msec;

	if (prep)
		return -EINVAL;

	switch (res) {
	case 0:	/* color resolution 0 is 8 bit colour depth */
	case 8:
		res_idx = RES_8;
		break;
	case 10:
		res_idx = RES_10;
		break;
	case 12:
		res_idx = RES_12;
		break;
	default:
		return -EINVAL;
	}

	/* Enable csc path */
	if (cscon)
		val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_IN_PATH;
	else
		val = HDMI_MC_FLOWCTRL_FEED_THROUGH_OFF_CSC_BYPASS;

	hdmi_writeb(hdmi, val, HDMI_MC_FLOWCTRL);

	/* gen2 tx power off */
	imx_hdmi_phy_gen2_txpwron(hdmi, 0);

	/* gen2 pddq */
	imx_hdmi_phy_gen2_pddq(hdmi, 1);

	/* PHY reset */
	hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_DEASSERT, HDMI_MC_PHYRSTZ);
	hdmi_writeb(hdmi, HDMI_MC_PHYRSTZ_ASSERT, HDMI_MC_PHYRSTZ);

	hdmi_writeb(hdmi, HDMI_MC_HEACPHY_RST_ASSERT, HDMI_MC_HEACPHY_RST);

	hdmi_phy_test_clear(hdmi, 1);
	hdmi_writeb(hdmi, HDMI_PHY_I2CM_SLAVE_ADDR_PHY_GEN2,
			HDMI_PHY_I2CM_SLAVE_ADDR);
	hdmi_phy_test_clear(hdmi, 0);

	/* PLL/MPLL Cfg - always match on final entry */
	for (i = 0; i < ARRAY_SIZE(mpll_config) - 1; i++)
		if (hdmi->hdmi_data.video_mode.mpixelclock <=
		    mpll_config[i].mpixelclock)
			break;

	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].cpce, 0x06);
	hdmi_phy_i2c_write(hdmi, mpll_config[i].res[res_idx].gmp, 0x15);

	for (i = 0; i < ARRAY_SIZE(curr_ctrl); i++)
		if (hdmi->hdmi_data.video_mode.mpixelclock <=
		    curr_ctrl[i].mpixelclock)
			break;

	if (i >= ARRAY_SIZE(curr_ctrl)) {
		dev_err(hdmi->dev,
				"Pixel clock %d - unsupported by HDMI\n",
				hdmi->hdmi_data.video_mode.mpixelclock);
		return -EINVAL;
	}

	/* CURRCTRL */
	hdmi_phy_i2c_write(hdmi, curr_ctrl[i].curr[res_idx], 0x10);

	hdmi_phy_i2c_write(hdmi, 0x0000, 0x13);  /* PLLPHBYCTRL */
	hdmi_phy_i2c_write(hdmi, 0x0006, 0x17);
	/* RESISTANCE TERM 133Ohm Cfg */
	hdmi_phy_i2c_write(hdmi, 0x0005, 0x19);  /* TXTERM */
	/* PREEMP Cgf 0.00 */
	hdmi_phy_i2c_write(hdmi, 0x800d, 0x09);  /* CKSYMTXCTRL */
	/* TX/CK LVL 10 */
	hdmi_phy_i2c_write(hdmi, 0x01ad, 0x0E);  /* VLEVCTRL */
	/* REMOVE CLK TERM */
	hdmi_phy_i2c_write(hdmi, 0x8000, 0x05);  /* CKCALCTRL */

	imx_hdmi_phy_enable_power(hdmi, 1);

	/* toggle TMDS enable */
	imx_hdmi_phy_enable_tmds(hdmi, 0);
	imx_hdmi_phy_enable_tmds(hdmi, 1);

	/* gen2 tx power on */
	imx_hdmi_phy_gen2_txpwron(hdmi, 1);
	imx_hdmi_phy_gen2_pddq(hdmi, 0);

	/*Wait for PHY PLL lock */
	msec = 5;
	do {
		val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK;
		if (!val)
			break;

		if (msec == 0) {
			dev_err(hdmi->dev, "PHY PLL not locked\n");
			return -ETIMEDOUT;
		}

		udelay(1000);
		msec--;
	} while (1);

	return 0;
}
Beispiel #28
0
void hdmi_mask_writeb(u8 data, unsigned int reg, u8 shift, u8 mask)
{
	u8 value = hdmi_readb(reg) & ~mask;
	value |= (data << shift) & mask;
	hdmi_writeb(value, reg);
}
Beispiel #29
0
static void hdmi_config_AVI(struct imx_hdmi *hdmi)
{
	u8 val, pix_fmt, under_scan;
	u8 act_ratio, coded_ratio, colorimetry, ext_colorimetry;
	bool aspect_16_9;

	aspect_16_9 = false; /* FIXME */

	/* AVI Data Byte 1 */
	if (hdmi->hdmi_data.enc_out_format == YCBCR444)
		pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR444;
	else if (hdmi->hdmi_data.enc_out_format == YCBCR422_8BITS)
		pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_YCBCR422;
	else
		pix_fmt = HDMI_FC_AVICONF0_PIX_FMT_RGB;

		under_scan =  HDMI_FC_AVICONF0_SCAN_INFO_NODATA;

	/*
	 * Active format identification data is present in the AVI InfoFrame.
	 * Under scan info, no bar data
	 */
	val = pix_fmt | under_scan |
		HDMI_FC_AVICONF0_ACTIVE_FMT_INFO_PRESENT |
		HDMI_FC_AVICONF0_BAR_DATA_NO_DATA;

	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF0);

	/* AVI Data Byte 2 -Set the Aspect Ratio */
	if (aspect_16_9) {
		act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_16_9;
		coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_16_9;
	} else {
		act_ratio = HDMI_FC_AVICONF1_ACTIVE_ASPECT_RATIO_4_3;
		coded_ratio = HDMI_FC_AVICONF1_CODED_ASPECT_RATIO_4_3;
	}

	/* Set up colorimetry */
	if (hdmi->hdmi_data.enc_out_format == XVYCC444) {
		colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_EXTENDED_INFO;
		if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
			ext_colorimetry =
				HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
		else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
			ext_colorimetry =
				HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC709;
	} else if (hdmi->hdmi_data.enc_out_format != RGB) {
		if (hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_601)
			colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_SMPTE;
		else /*hdmi->hdmi_data.colorimetry == HDMI_COLORIMETRY_ITU_709*/
			colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_ITUR;
		ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
	} else { /* Carries no data */
		colorimetry = HDMI_FC_AVICONF1_COLORIMETRY_NO_DATA;
		ext_colorimetry = HDMI_FC_AVICONF2_EXT_COLORIMETRY_XVYCC601;
	}

	val = colorimetry | coded_ratio | act_ratio;
	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF1);

	/* AVI Data Byte 3 */
	val = HDMI_FC_AVICONF2_IT_CONTENT_NO_DATA | ext_colorimetry |
		HDMI_FC_AVICONF2_RGB_QUANT_DEFAULT |
		HDMI_FC_AVICONF2_SCALING_NONE;
	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF2);

	/* AVI Data Byte 4 */
	hdmi_writeb(hdmi, hdmi->vic, HDMI_FC_AVIVID);

	/* AVI Data Byte 5- set up input and output pixel repetition */
	val = (((hdmi->hdmi_data.video_mode.mpixelrepetitioninput + 1) <<
		HDMI_FC_PRCONF_INCOMING_PR_FACTOR_OFFSET) &
		HDMI_FC_PRCONF_INCOMING_PR_FACTOR_MASK) |
		((hdmi->hdmi_data.video_mode.mpixelrepetitionoutput <<
		HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET) &
		HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK);
	hdmi_writeb(hdmi, val, HDMI_FC_PRCONF);

	/* IT Content and quantization range = don't care */
	val = HDMI_FC_AVICONF3_IT_CONTENT_TYPE_GRAPHICS |
		HDMI_FC_AVICONF3_QUANT_RANGE_LIMITED;
	hdmi_writeb(hdmi, val, HDMI_FC_AVICONF3);

	/* AVI Data Bytes 6-13 */
	hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB0);
	hdmi_writeb(hdmi, 0, HDMI_FC_AVIETB1);
	hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB0);
	hdmi_writeb(hdmi, 0, HDMI_FC_AVISBB1);
	hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB0);
	hdmi_writeb(hdmi, 0, HDMI_FC_AVIELB1);
	hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB0);
	hdmi_writeb(hdmi, 0, HDMI_FC_AVISRB1);
}
Beispiel #30
0
static void hdmi_dma_clear_irq_status(u8 status)
{
	hdmi_writeb(status, HDMI_IH_AHBDMAAUD_STAT0);
}