Пример #1
0
static void
awin_tve_attach(device_t parent, device_t self, void *aux)
{
	struct awin_tve_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);
	int8_t	tcon_unit = -1;

	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 (prop_dictionary_get_int8(cfg, "tcon_unit", &tcon_unit)) {
		sc->sc_tcon_unit = tcon_unit;
	} else {
		sc->sc_tcon_unit = 0; /* default value */
	}
	sc->sc_tcon_pll = awin_tcon_get_clk_pll(sc->sc_tcon_unit);
	switch (sc->sc_tcon_pll) {
	case 3:
		awin_pll3_enable();
		break;
	case 7:
		awin_pll7_enable();
		break;
	default:
		panic("awin_tve pll");
	}

	/* for now assume we're always at 0 */
	awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
	    AWIN_AHB_GATING1_REG, AWIN_AHB_GATING1_TVE0, 0);

	aprint_naive("\n");
	aprint_normal(": TV Encoder / VGA output\n");
	if (tcon_unit >= 0) {
		aprint_verbose_dev(self, ": using TCON%d, pll%d\n",
		    sc->sc_tcon_unit, sc->sc_tcon_pll);
	}

	sc->sc_i2c_blklen = 16;

#if 0
	sc->sc_ih = intr_establish(loc->loc_intr, IPL_SCHED, IST_LEVEL,
	    awin_tve_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_tve_i2c_init(sc);

	awin_tve_enable(sc);
	awin_tve_read_edid(sc);
}
Пример #2
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));
}
Пример #3
0
static void
awin_tcon_attach(device_t parent, device_t self, void *aux)
{
	struct awin_tcon_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);
	const char *output;

	sc->sc_dev = self;
	sc->sc_bst = aio->aio_core_bst;
	sc->sc_port = loc->loc_port;
	bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
	    loc->loc_offset, loc->loc_size, &sc->sc_bsh);
	bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh,
	    AWIN_LCD0_CH0_CLK_REG + (loc->loc_port * 4), 4, &sc->sc_ch0clk_bsh);
	bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh,
	    AWIN_LCD0_CH1_CLK_REG + (loc->loc_port * 4), 4, &sc->sc_ch1clk_bsh);
	if (!tcon_mux_inited) {
		/* the mux register is only in LCD0 */
		bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
		    AWIN_LCD0_OFFSET + AWIN_TCON_MUX_CTL_REG, 4, &tcon_mux_bsh);
		tcon_mux_inited = true;
		/* always enable tcon0, the mux is there */
		awin_tcon_clear_reset(aio, 0);
	}

	if (prop_dictionary_get_cstring_nocopy(cfg, "output", &output)) {
		if (strcmp(output, "hdmi") == 0) {
			sc->sc_output_type = OUTPUT_HDMI;
		} else if (strcmp(output, "lvds") == 0) {
			sc->sc_output_type = OUTPUT_LVDS;
		} else if (strcmp(output, "vga") == 0) {
			sc->sc_output_type = OUTPUT_VGA;
		} else {
			panic("tcon: wrong mode %s", output);
		}
	} else {
		sc->sc_output_type = OUTPUT_HDMI; /* default */
	}

	aprint_naive("\n");
	aprint_normal(": LCD/TV timing controller (TCON%d)\n", loc->loc_port);
	switch (sc->sc_port) {
	case 0:
		awin_pll3_enable();
		sc->sc_clk_pll = 3;
		break;
	case 1:
		awin_pll7_enable();
		sc->sc_clk_pll = 7;
		break;
	default:
		panic("awin_tcon port\n");
	}

	aprint_verbose_dev(self, ": using DEBE%d, pll%d\n",
		    device_unit(self), sc->sc_clk_pll);

	awin_tcon_clear_reset(aio, sc->sc_port);
	
	TCON_WRITE(sc, AWIN_TCON_GCTL_REG, 0);
	TCON_WRITE(sc, AWIN_TCON_GINT0_REG, 0);
	TCON_WRITE(sc, AWIN_TCON_GINT1_REG,
	    __SHIFTIN(0x20, AWIN_TCON_GINT1_TCON0_LINENO));
	TCON_WRITE(sc, AWIN_TCON0_DCLK_REG, 0xf0000000);
	TCON_WRITE(sc, AWIN_TCON0_CTL_REG, 0);
	TCON_WRITE(sc, AWIN_TCON0_IO_TRI_REG, 0xffffffff);
	TCON_WRITE(sc, AWIN_TCON1_CTL_REG, 0);
	TCON_WRITE(sc, AWIN_TCON1_IO_TRI_REG, 0xffffffff);
	if (sc->sc_output_type == OUTPUT_LVDS) {
		awin_reg_set_clear(aio->aio_core_bst, aio->aio_ccm_bsh,
		    AWIN_LVDS_CLK_REG, AWIN_LVDS_CLK_ENABLE, 0);
		awin_tcon0_set_video(sc);
	}
}