static void hdmi_i2c_read(struct oaktrail_hdmi_dev *hdmi_dev)
{
	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
	struct i2c_msg *msg = i2c_dev->msg;
	u8 *buf = msg->buf;
	u32 temp;
	int i, offset;

	offset = i2c_dev->buf_offset;
	for (i = 0; i < 0x10; i++) {
		temp = HDMI_READ(HDMI_HI2CRDB0 + (i * 4));
		memcpy(buf + (offset + i * 4), &temp, 4);
	}
	i2c_dev->buf_offset += (0x10 * 4);

	/* clearing read buffer full intr */
	temp = HDMI_READ(HDMI_HISR);
	HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_FULL);
	HDMI_READ(HDMI_HISR);

	/* continue read transaction */
	temp = HDMI_READ(HDMI_HI2CHCR);
	HDMI_WRITE(HDMI_HI2CHCR, temp | HI2C_READ_CONTINUE);
	HDMI_READ(HDMI_HI2CHCR);

	i2c_dev->status = I2C_READ_DONE;
	return;
}
static void hdmi_i2c_irq_enable(struct oaktrail_hdmi_dev *hdmi_dev)
{
	u32 temp;

	temp = HDMI_READ(HDMI_HICR);
	temp |= (HDMI_INTR_I2C_ERROR | HDMI_INTR_I2C_FULL | HDMI_INTR_I2C_DONE);
	HDMI_WRITE(HDMI_HICR, temp);
	HDMI_READ(HDMI_HICR);
}
Exemple #3
0
static int
awin_hdmi_i2c_xfer_1_3(void *priv, i2c_addr_t addr, uint8_t block, uint8_t reg,
    size_t len, int type, int flags)
{
	struct awin_hdmi_softc *sc = priv;
	uint32_t val;
	int retry;

	val = HDMI_READ(sc, AWIN_HDMI_DDC_CTRL_REG);
	val &= ~AWIN_HDMI_DDC_CTRL_FIFO_DIR;
	HDMI_WRITE(sc, AWIN_HDMI_DDC_CTRL_REG, val);

	val |= __SHIFTIN(block, AWIN_HDMI_DDC_SLAVE_ADDR_0);
	val |= __SHIFTIN(0x60, AWIN_HDMI_DDC_SLAVE_ADDR_1);
	val |= __SHIFTIN(reg, AWIN_HDMI_DDC_SLAVE_ADDR_2);
	val |= __SHIFTIN(addr, AWIN_HDMI_DDC_SLAVE_ADDR_3);
	HDMI_WRITE(sc, AWIN_HDMI_DDC_SLAVE_ADDR_REG, val);

	val = HDMI_READ(sc, AWIN_HDMI_DDC_FIFO_CTRL_REG);
	val |= AWIN_HDMI_DDC_FIFO_CTRL_ADDR_CLEAR;
	HDMI_WRITE(sc, AWIN_HDMI_DDC_FIFO_CTRL_REG, val);

	HDMI_WRITE(sc, AWIN_HDMI_DDC_BYTE_COUNTER_REG, len);

	HDMI_WRITE(sc, AWIN_HDMI_DDC_COMMAND_REG, type);

	val = HDMI_READ(sc, AWIN_HDMI_DDC_CTRL_REG);
	val |= AWIN_HDMI_DDC_CTRL_ACCESS_CMD_START;
	HDMI_WRITE(sc, AWIN_HDMI_DDC_CTRL_REG, val);

	retry = 1000;
	while (--retry > 0) {
		val = HDMI_READ(sc, AWIN_HDMI_DDC_CTRL_REG);
		if ((val & AWIN_HDMI_DDC_CTRL_ACCESS_CMD_START) == 0)
			break;
		delay(1000);
	}
	if (retry == 0)
		return ETIMEDOUT;

	val = HDMI_READ(sc, AWIN_HDMI_DDC_INT_STATUS_REG);
	if ((val & AWIN_HDMI_DDC_INT_STATUS_TRANSFER_COMPLETE) == 0) {
		device_printf(sc->sc_dev, "xfer failed, status=%08x\n", val);
		return EIO;
	}

	return 0;
}
Exemple #4
0
void
awin_hdmi_dump_regs(void)
{
	static const struct {
		const char *name;
		uint16_t reg;
	} regs[] = {
		{ "CTRL", AWIN_HDMI_CTRL_REG },
		{ "INT_STATUS", AWIN_HDMI_INT_STATUS_REG },
		{ "VID_CTRL", AWIN_HDMI_VID_CTRL_REG },
		{ "VID_TIMING_0", AWIN_HDMI_VID_TIMING_0_REG },
		{ "VID_TIMING_1", AWIN_HDMI_VID_TIMING_1_REG },
		{ "VID_TIMING_2", AWIN_HDMI_VID_TIMING_2_REG },
		{ "VID_TIMING_3", AWIN_HDMI_VID_TIMING_3_REG },
		{ "VID_TIMING_4", AWIN_HDMI_VID_TIMING_4_REG },
		{ "PAD_CTRL0", AWIN_HDMI_PAD_CTRL0_REG },
		{ "PAD_CTRL1", AWIN_HDMI_PAD_CTRL1_REG },
		{ "PLL_CTRL", AWIN_HDMI_PLL_CTRL_REG },
		{ "PLL_DBG0", AWIN_HDMI_PLL_DBG0_REG },
		{ "PLL_DBG1", AWIN_HDMI_PLL_DBG1_REG },
	};
	struct awin_hdmi_softc *sc;
	device_t dev;

	dev = device_find_by_driver_unit("awinhdmi", 0);
	if (dev == NULL)
		return;
	sc = device_private(dev);

	for (int i = 0; i < __arraycount(regs); i++) {
		printf("%s: 0x%08x\n", regs[i].name,
		    HDMI_READ(sc, regs[i].reg));
	}
}
Exemple #5
0
static void
awin_hdmi_video_enable(struct awin_hdmi_softc *sc, bool enable)
{
	uint32_t val;

	val = HDMI_READ(sc, AWIN_HDMI_VID_CTRL_REG);
	val &= ~AWIN_HDMI_VID_CTRL_SRC_SEL;
#ifdef AWIN_HDMI_CBGEN
	val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_SRC_SEL_CBGEN,
			 AWIN_HDMI_VID_CTRL_SRC_SEL);
#else
	val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_SRC_SEL_RGB,
			 AWIN_HDMI_VID_CTRL_SRC_SEL);
#endif
	if (enable) {
		val |= AWIN_HDMI_VID_CTRL_VIDEO_EN;
	} else {
		val &= ~AWIN_HDMI_VID_CTRL_VIDEO_EN;
	}
	HDMI_WRITE(sc, AWIN_HDMI_VID_CTRL_REG, val);

#if defined(AWIN_HDMI_DEBUG) && defined(DDB)
	awin_hdmi_dump_regs();
#endif
}
Exemple #6
0
static int
awin_hdmi_i2c_reset(struct awin_hdmi_softc *sc, int flags)
{
	uint32_t hpd, ctrl;

	hpd = HDMI_READ(sc, AWIN_HDMI_HPD_REG);
	if ((hpd & AWIN_HDMI_HPD_HOTPLUG_DET) == 0) {
		device_printf(sc->sc_dev, "no device detected\n");
		return ENODEV;	/* no device plugged in */
	}

	if (HDMI_1_3_P(sc)) {
		HDMI_WRITE(sc, AWIN_HDMI_DDC_FIFO_CTRL_REG, 0);
		HDMI_WRITE(sc, AWIN_HDMI_DDC_CTRL_REG,
		    AWIN_HDMI_DDC_CTRL_EN | AWIN_HDMI_DDC_CTRL_SW_RST); 

		delay(1000);

		ctrl = HDMI_READ(sc, AWIN_HDMI_DDC_CTRL_REG);
		if (ctrl & AWIN_HDMI_DDC_CTRL_SW_RST) {
			device_printf(sc->sc_dev, "reset failed (1.3)\n");
			return EBUSY;
		}

		/* N=5,M=1 */
		HDMI_WRITE(sc, AWIN_HDMI_DDC_CLOCK_REG,
		    __SHIFTIN(5, AWIN_HDMI_DDC_CLOCK_N) |
		    __SHIFTIN(1, AWIN_HDMI_DDC_CLOCK_M));

		HDMI_WRITE(sc, AWIN_HDMI_DDC_DBG_REG, 0x300);
	} else {
		HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_CTRL_REG,
		    AWIN_A31_HDMI_DDC_CTRL_SW_RST);

		/* N=1,M=12 */
		HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_CLOCK_REG,
		    __SHIFTIN(1, AWIN_HDMI_DDC_CLOCK_N) |
		    __SHIFTIN(12, AWIN_HDMI_DDC_CLOCK_M));

		HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_CTRL_REG,
		    AWIN_A31_HDMI_DDC_CTRL_SDA_PAD_EN |
		    AWIN_A31_HDMI_DDC_CTRL_SCL_PAD_EN |
		    AWIN_A31_HDMI_DDC_CTRL_EN);
	}

	return 0;
}
static void hdmi_i2c_transaction_done(struct oaktrail_hdmi_dev *hdmi_dev)
{
	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
	u32 temp;

	/* clear transaction done intr */
	temp = HDMI_READ(HDMI_HISR);
	HDMI_WRITE(HDMI_HISR, temp | HDMI_INTR_I2C_DONE);
	HDMI_READ(HDMI_HISR);


	temp = HDMI_READ(HDMI_HI2CHCR);
	HDMI_WRITE(HDMI_HI2CHCR, temp & ~HI2C_ENABLE_TRANSACTION);
	HDMI_READ(HDMI_HI2CHCR);

	i2c_dev->status = I2C_TRANSACTION_DONE;
	return;
}
Exemple #8
0
static int
awin_hdmi_i2c_xfer_1_4(void *priv, i2c_addr_t addr, uint8_t block, uint8_t reg,
    size_t len, int type, int flags)
{
	struct awin_hdmi_softc *sc = priv;
	uint32_t val;
	int retry;

	val = HDMI_READ(sc, AWIN_A31_HDMI_DDC_FIFO_CTRL_REG);
	val |= AWIN_A31_HDMI_DDC_FIFO_CTRL_RST;
	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_FIFO_CTRL_REG, val);

	val = __SHIFTIN(block, AWIN_A31_HDMI_DDC_SLAVE_ADDR_SEG_PTR);
	val |= __SHIFTIN(0x60, AWIN_A31_HDMI_DDC_SLAVE_ADDR_DDC_CMD);
	val |= __SHIFTIN(reg, AWIN_A31_HDMI_DDC_SLAVE_ADDR_OFF_ADR);
	val |= __SHIFTIN(addr, AWIN_A31_HDMI_DDC_SLAVE_ADDR_DEV_ADR);
	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_SLAVE_ADDR_REG, val);

	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_COMMAND_REG,
	    __SHIFTIN(len, AWIN_A31_HDMI_DDC_COMMAND_DTC) |
	    __SHIFTIN(type, AWIN_A31_HDMI_DDC_COMMAND_CMD));

	val = HDMI_READ(sc, AWIN_A31_HDMI_DDC_CTRL_REG);
	val |= AWIN_A31_HDMI_DDC_CTRL_ACCESS_CMD_START;
	HDMI_WRITE(sc, AWIN_A31_HDMI_DDC_CTRL_REG, val);

	retry = 1000;
	while (--retry > 0) {
		val = HDMI_READ(sc, AWIN_A31_HDMI_DDC_CTRL_REG);
		if ((val & AWIN_A31_HDMI_DDC_CTRL_ACCESS_CMD_START) == 0)
			break;
		if (cold)
			delay(1000);
		else
			kpause("hdmiddc", false, mstohz(10), &sc->sc_ic_lock);
	}
	if (retry == 0)
		return ETIMEDOUT;

	return 0;
}
static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev)
{
	struct oaktrail_hdmi_dev *hdmi_dev = dev;
	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
	u32 stat;

	stat = HDMI_READ(HDMI_HISR);

	if (stat & HDMI_INTR_HPD) {
		HDMI_WRITE(HDMI_HISR, stat | HDMI_INTR_HPD);
		HDMI_READ(HDMI_HISR);
	}

	if (stat & HDMI_INTR_I2C_FULL)
		hdmi_i2c_read(hdmi_dev);

	if (stat & HDMI_INTR_I2C_DONE)
		hdmi_i2c_transaction_done(hdmi_dev);

	complete(&i2c_dev->complete);

	return IRQ_HANDLED;
}
Exemple #10
0
static int
awin_hdmi_intr(void *priv)
{
	struct awin_hdmi_softc *sc = priv;
	uint32_t intsts;

	intsts = HDMI_READ(sc, AWIN_HDMI_INT_STATUS_REG);
	if (!(intsts & 0x73))
		return 0;

	HDMI_WRITE(sc, AWIN_HDMI_INT_STATUS_REG, intsts);

	device_printf(sc->sc_dev, "INT_STATUS %08X\n", intsts);

	return 1;
}
Exemple #11
0
static void
awin_hdmi_hpd(struct awin_hdmi_softc *sc)
{
	uint32_t hpd = HDMI_READ(sc, AWIN_HDMI_HPD_REG);
	bool con = !!(hpd & AWIN_HDMI_HPD_HOTPLUG_DET);

	if (sc->sc_connected == con)
		return;

	if (con) {
		device_printf(sc->sc_dev, "display connected\n");
		awin_hdmi_read_edid(sc);
	} else {
		device_printf(sc->sc_dev, "display disconnected\n");
		awin_tcon_set_videomode(NULL);
	}

	sc->sc_connected = con;
}
static int xfer_read(struct i2c_adapter *adap, struct i2c_msg *pmsg)
{
	struct oaktrail_hdmi_dev *hdmi_dev = i2c_get_adapdata(adap);
	struct hdmi_i2c_dev *i2c_dev = hdmi_dev->i2c_dev;
	u32 temp;

	i2c_dev->status = I2C_STAT_INIT;
	i2c_dev->msg = pmsg;
	i2c_dev->buf_offset = 0;
	reinit_completion(&i2c_dev->complete);

	/* Enable I2C transaction */
	temp = ((pmsg->len) << 20) | HI2C_EDID_READ | HI2C_ENABLE_TRANSACTION;
	HDMI_WRITE(HDMI_HI2CHCR, temp);
	HDMI_READ(HDMI_HI2CHCR);

	while (i2c_dev->status != I2C_TRANSACTION_DONE)
		wait_for_completion_interruptible_timeout(&i2c_dev->complete,
								10 * HZ);

	return 0;
}
Exemple #13
0
static void
awin_hdmi_set_audiomode(struct awin_hdmi_softc *sc,
    const struct videomode *mode, u_int display_mode)
{
	uint32_t cts, n, val;

	/*
	 * Before changing audio parameters, disable and reset the
	 * audio module. Wait for the soft reset bit to clear before
	 * configuring the audio parameters.
	 */
	val = HDMI_READ(sc, AWIN_HDMI_AUD_CTRL_REG);
	val &= ~AWIN_HDMI_AUD_CTRL_EN;
	val |= AWIN_HDMI_AUD_CTRL_RST;
	HDMI_WRITE(sc, AWIN_HDMI_AUD_CTRL_REG, val);
	do {
		val = HDMI_READ(sc, AWIN_HDMI_AUD_CTRL_REG);
	} while (val & AWIN_HDMI_AUD_CTRL_RST);

	/* No audio support in DVI mode */
	if (display_mode != DISPLAY_MODE_HDMI) {
		return;
	}

	/* DMA & FIFO control */
	val = HDMI_READ(sc, AWIN_HDMI_ADMA_CTRL_REG);
	if (awin_chip_id() == AWIN_CHIP_ID_A31) {
		val |= AWIN_HDMI_ADMA_CTRL_SRC_DMA_MODE;	/* NDMA */
	} else {
		val &= ~AWIN_HDMI_ADMA_CTRL_SRC_DMA_MODE;	/* DDMA */
	}
	val &= ~AWIN_HDMI_ADMA_CTRL_SRC_DMA_SAMPLE_RATE;
	val &= ~AWIN_HDMI_ADMA_CTRL_SRC_SAMPLE_LAYOUT;
	val &= ~AWIN_HDMI_ADMA_CTRL_SRC_WORD_LEN;
	val &= ~AWIN_HDMI_ADMA_CTRL_DATA_SEL;
	HDMI_WRITE(sc, AWIN_HDMI_ADMA_CTRL_REG, val);

	/* Audio format control */
	val = HDMI_READ(sc, AWIN_HDMI_AUD_FMT_REG);
	val &= ~AWIN_HDMI_AUD_FMT_SRC_SEL;
	val &= ~AWIN_HDMI_AUD_FMT_SEL;
	val &= ~AWIN_HDMI_AUD_FMT_DSD_FMT;
	val &= ~AWIN_HDMI_AUD_FMT_LAYOUT;
	val &= ~AWIN_HDMI_AUD_FMT_SRC_CH_CFG;
	val |= __SHIFTIN(1, AWIN_HDMI_AUD_FMT_SRC_CH_CFG);
	HDMI_WRITE(sc, AWIN_HDMI_AUD_FMT_REG, val);

	/* PCM control (channel map) */
	HDMI_WRITE(sc, AWIN_HDMI_AUD_PCM_CTRL_REG, 0x76543210);

	/* Clock setup */
	n = 6144;	/* 48 kHz */
	cts = ((mode->dot_clock * 10) * (n / 128)) / 480;
	HDMI_WRITE(sc, AWIN_HDMI_AUD_CTS_REG, cts);
	HDMI_WRITE(sc, AWIN_HDMI_AUD_N_REG, n);

	/* Audio PCM channel status 0 */
	val = __SHIFTIN(AWIN_HDMI_AUD_CH_STATUS0_FS_FREQ_48,
			AWIN_HDMI_AUD_CH_STATUS0_FS_FREQ);
	HDMI_WRITE(sc, AWIN_HDMI_AUD_CH_STATUS0_REG, val);

	/* Audio PCM channel status 1 */
	val = HDMI_READ(sc, AWIN_HDMI_AUD_CH_STATUS1_REG);
	val &= ~AWIN_HDMI_AUD_CH_STATUS1_CGMS_A;
	val &= ~AWIN_HDMI_AUD_CH_STATUS1_ORIGINAL_FS;
	val &= ~AWIN_HDMI_AUD_CH_STATUS1_WORD_LEN;
	val |= __SHIFTIN(5, AWIN_HDMI_AUD_CH_STATUS1_WORD_LEN);
	val |= AWIN_HDMI_AUD_CH_STATUS1_WORD_LEN_MAX;
	HDMI_WRITE(sc, AWIN_HDMI_AUD_CH_STATUS1_REG, val);

	/* Re-enable */
	val = HDMI_READ(sc, AWIN_HDMI_AUD_CTRL_REG);
	val |= AWIN_HDMI_AUD_CTRL_EN;
	HDMI_WRITE(sc, AWIN_HDMI_AUD_CTRL_REG, val);

#if defined(AWIN_HDMI_DEBUG) && defined(DDB)
	awin_hdmi_dump_regs();
#endif
}
Exemple #14
0
static void
awin_hdmi_set_videomode(struct awin_hdmi_softc *sc,
    const struct videomode *mode, u_int display_mode)
{
	uint32_t val;
	const u_int dblscan_p = !!(mode->flags & VID_DBLSCAN);
	const u_int interlace_p = !!(mode->flags & VID_INTERLACE);
	const u_int phsync_p = !!(mode->flags & VID_PHSYNC);
	const u_int pvsync_p = !!(mode->flags & VID_PVSYNC);
	const u_int hfp = mode->hsync_start - mode->hdisplay;
	const u_int hspw = mode->hsync_end - mode->hsync_start;
	const u_int hbp = mode->htotal - mode->hsync_start;
	const u_int vfp = mode->vsync_start - mode->vdisplay;
	const u_int vspw = mode->vsync_end - mode->vsync_start;
	const u_int vbp = mode->vtotal - mode->vsync_start;

#ifdef AWIN_HDMI_DEBUG
	device_printf(sc->sc_dev,
	    "dblscan %d, interlace %d, phsync %d, pvsync %d\n",
	    dblscan_p, interlace_p, phsync_p, pvsync_p);
	device_printf(sc->sc_dev, "h: %u %u %u %u\n",
	    mode->hdisplay, hbp, hfp, hspw);
	device_printf(sc->sc_dev, "v: %u %u %u %u\n",
	    mode->vdisplay, vbp, vfp, vspw);
#endif

	HDMI_WRITE(sc, AWIN_HDMI_INT_STATUS_REG, 0xffffffff);

	u_int clk_div = awin_tcon_get_clk_div();
	bool clk_dbl = awin_tcon_get_clk_dbl();

#ifdef AWIN_HDMI_DEBUG
	device_printf(sc->sc_dev, "dot_clock: %d\n", mode->dot_clock);
	device_printf(sc->sc_dev, "clkdiv: %d\n", clk_div);
	device_printf(sc->sc_dev, "clkdbl: %c\n", clk_dbl ? 'Y' : 'N');
#endif

	if (clk_div == 0) {
		device_printf(sc->sc_dev, "ERROR: TCON clk not configured\n");
		return;
	}

	uint32_t pll_ctrl, pad_ctrl0, pad_ctrl1;
	if (HDMI_1_4_P(sc)) {
		pad_ctrl0 = 0x7e8000ff;
		pad_ctrl1 = 0x01ded030;
		pll_ctrl = 0xba48a308;
		pll_ctrl |= __SHIFTIN(clk_div-1, AWIN_HDMI_PLL_CTRL_PREDIV);
	} else {
		pad_ctrl0 = 0xfe800000;
		pad_ctrl1 = 0x00d8c830;
		pll_ctrl = 0xfa4ef708;
		pll_ctrl |= __SHIFTIN(clk_div, AWIN_HDMI_PLL_CTRL_PREDIV);
	}
	if (clk_dbl == false)
		pad_ctrl1 |= 0x40;

	HDMI_WRITE(sc, AWIN_HDMI_PAD_CTRL0_REG, pad_ctrl0);
	HDMI_WRITE(sc, AWIN_HDMI_PAD_CTRL1_REG, pad_ctrl1);
	HDMI_WRITE(sc, AWIN_HDMI_PLL_CTRL_REG, pll_ctrl);
#if AWIN_HDMI_PLL == 7
	HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (1<<21));
#elif AWIN_HDMI_PLL == 3
	HDMI_WRITE(sc, AWIN_HDMI_PLL_DBG0_REG, (0<<21));
#endif

	val = HDMI_READ(sc, AWIN_HDMI_VID_CTRL_REG);
	val &= ~AWIN_HDMI_VID_CTRL_HDMI_MODE;
	if (display_mode == DISPLAY_MODE_DVI) {
		val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_HDMI_MODE_DVI,
				 AWIN_HDMI_VID_CTRL_HDMI_MODE);
	} else {
		val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_HDMI_MODE_HDMI,
				 AWIN_HDMI_VID_CTRL_HDMI_MODE);
	}
	val &= ~AWIN_HDMI_VID_CTRL_REPEATER_SEL;
	if (dblscan_p) {
		val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_REPEATER_SEL_2X,
				 AWIN_HDMI_VID_CTRL_REPEATER_SEL);
	}
	val &= ~AWIN_HDMI_VID_CTRL_OUTPUT_FMT;
	if (interlace_p) {
		val |= __SHIFTIN(AWIN_HDMI_VID_CTRL_OUTPUT_FMT_INTERLACE,
				 AWIN_HDMI_VID_CTRL_OUTPUT_FMT);
	}
	HDMI_WRITE(sc, AWIN_HDMI_VID_CTRL_REG, val);

	val = __SHIFTIN((mode->hdisplay << dblscan_p) - 1,
			AWIN_HDMI_VID_TIMING_0_ACT_H);
	val |= __SHIFTIN(mode->vdisplay - 1,
			 AWIN_HDMI_VID_TIMING_0_ACT_V);
	HDMI_WRITE(sc, AWIN_HDMI_VID_TIMING_0_REG, val);

	val = __SHIFTIN((hbp << dblscan_p) - 1,
			AWIN_HDMI_VID_TIMING_1_HBP);
	val |= __SHIFTIN(vbp - 1,
			 AWIN_HDMI_VID_TIMING_1_VBP);
	HDMI_WRITE(sc, AWIN_HDMI_VID_TIMING_1_REG, val);

	val = __SHIFTIN((hfp << dblscan_p) - 1,
			AWIN_HDMI_VID_TIMING_2_HFP);
	val |= __SHIFTIN(vfp - 1,
			 AWIN_HDMI_VID_TIMING_2_VFP);
	HDMI_WRITE(sc, AWIN_HDMI_VID_TIMING_2_REG, val);

	val = __SHIFTIN((hspw << dblscan_p) - 1,
			AWIN_HDMI_VID_TIMING_3_HSPW);
	val |= __SHIFTIN(vspw - 1,
			 AWIN_HDMI_VID_TIMING_3_VSPW);
	HDMI_WRITE(sc, AWIN_HDMI_VID_TIMING_3_REG, val);

	val = 0;
	if (phsync_p) {
		val |= AWIN_HDMI_VID_TIMING_4_HSYNC_ACTIVE_SEL;
	}
	if (pvsync_p) {
		val |= AWIN_HDMI_VID_TIMING_4_VSYNC_ACTIVE_SEL;
	}
	val |= __SHIFTIN(AWIN_HDMI_VID_TIMING_4_TX_CLOCK_NORMAL,
			 AWIN_HDMI_VID_TIMING_4_TX_CLOCK);
	HDMI_WRITE(sc, AWIN_HDMI_VID_TIMING_4_REG, val);

	/* Packet control */
	HDMI_WRITE(sc, AWIN_HDMI_PKT_CTRL0_REG, 0x00005321);
	HDMI_WRITE(sc, AWIN_HDMI_PKT_CTRL1_REG, 0x0000000f);
}
Exemple #15
0
static void
awin_hdmi_attach(device_t parent, device_t self, void *aux)
{
	struct awin_hdmi_softc *sc = device_private(self);
	struct awinio_attach_args * const aio = aux;
	const struct awin_locators * const loc = &aio->aio_loc;
	prop_dictionary_t cfg = device_properties(self);
	uint32_t ver, clk;

	sc->sc_dev = self;
	sc->sc_bst = aio->aio_core_bst;
	bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);

#if AWIN_HDMI_PLL == 3
	awin_pll3_enable();
#elif AWIN_HDMI_PLL == 7
	awin_pll7_enable();
#else
#error AWIN_HDMI_PLL must be 3 or 7
#endif

	if (awin_chip_id() == AWIN_CHIP_ID_A31) {
		awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
		    AWIN_A31_AHB_RESET1_REG, AWIN_A31_AHB_RESET1_HDMI_RST, 0);
	}

#if AWIN_HDMI_PLL == 3
	clk = __SHIFTIN(AWIN_HDMI_CLK_SRC_SEL_PLL3, AWIN_HDMI_CLK_SRC_SEL);
#else
	clk = __SHIFTIN(AWIN_HDMI_CLK_SRC_SEL_PLL7, AWIN_HDMI_CLK_SRC_SEL);
#endif
	clk |= AWIN_CLK_ENABLE;
	if (awin_chip_id() == AWIN_CHIP_ID_A31) {
		clk |= AWIN_A31_HDMI_CLK_DDC_GATING;
	}
	awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
	    AWIN_HDMI_CLK_REG, clk, AWIN_HDMI_CLK_SRC_SEL);
	awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
	    AWIN_AHB_GATING1_REG, AWIN_AHB_GATING1_HDMI, 0);

	ver = HDMI_READ(sc, AWIN_HDMI_VERSION_ID_REG);

	const int vmaj = __SHIFTOUT(ver, AWIN_HDMI_VERSION_ID_H);
	const int vmin = __SHIFTOUT(ver, AWIN_HDMI_VERSION_ID_L);

	aprint_naive("\n");
	aprint_normal(": HDMI %d.%d\n", vmaj, vmin);

	sc->sc_ver = ver;
	sc->sc_i2c_blklen = 16;

	const char *display_mode = NULL;
	prop_dictionary_get_cstring_nocopy(cfg, "display-mode", &display_mode);
	if (display_mode) {
		if (strcasecmp(display_mode, "hdmi") == 0)
			sc->sc_display_mode = DISPLAY_MODE_HDMI;
		else if (strcasecmp(display_mode, "dvi") == 0)
			sc->sc_display_mode = DISPLAY_MODE_DVI;
	}

#if 0
	sc->sc_ih = intr_establish(loc->loc_intr, IPL_SCHED, IST_LEVEL,
	    awin_hdmi_intr, sc);
	if (sc->sc_ih == NULL) {
		aprint_error_dev(self, "couldn't establish interrupt %d\n",
		    loc->loc_intr);
		return;
	}
	aprint_normal_dev(self, "interrupting on irq %d\n", loc->loc_intr);
#endif

	awin_hdmi_i2c_init(sc);

	awin_hdmi_enable(sc);

	delay(50000);

	awin_hdmi_hpd(sc);

	kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, awin_hdmi_thread, sc,
	    &sc->sc_thread, "%s", device_xname(sc->sc_dev));
}
static void hdmi_i2c_irq_disable(struct oaktrail_hdmi_dev *hdmi_dev)
{
	HDMI_WRITE(HDMI_HICR, 0x0);
	HDMI_READ(HDMI_HICR);
}