void
tx3912video_reset(struct video_chip *chip)
{
	tx_chipset_tag_t tc = chip->vc_v;
	txreg_t reg;
	
	reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);	

	/* Disable video logic at end of this frame */
	reg |= TX3912_VIDEOCTRL1_ENFREEZEFRAME; 
	tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);

	/* Wait for end of frame */
	delay(30 * 1000);

	/* Make sure to disable video logic */
	reg &= ~TX3912_VIDEOCTRL1_ENVID;
	tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);	

	delay(1000);

	/* Enable video logic again */
	reg &= ~TX3912_VIDEOCTRL1_ENFREEZEFRAME; 
	reg |= TX3912_VIDEOCTRL1_ENVID;
	tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);

	delay(1000);
}
int
tx3912video_power(void *ctx, int type, long id, void *msg)
{
	struct tx3912video_softc *sc = ctx;
	struct video_chip *chip = sc->sc_chip;
	tx_chipset_tag_t tc = chip->vc_v;
	int why = (int)msg;
	txreg_t val;

	switch (why) {
	case PWR_RESUME:
		if (!sc->sc_console)
			return (0); /* serial console */

		DPRINTF(("%s: ON\n", device_xname(sc->sc_dev)));
		val = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
		val |= (TX3912_VIDEOCTRL1_DISPON | TX3912_VIDEOCTRL1_ENVID);
		tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, val);
		break;
	case PWR_SUSPEND:
		/* FALLTHROUGH */
	case PWR_STANDBY:
		DPRINTF(("%s: OFF\n", device_xname(sc->sc_dev)));
		val = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
		val &= ~(TX3912_VIDEOCTRL1_DISPON | TX3912_VIDEOCTRL1_ENVID);
		tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, val);
		break;
	}

	return (0);
}
void
tx3912video_resolution_init(struct video_chip *chip)
{
	int h, v, split, horzval, lineval;
	tx_chipset_tag_t tc = chip->vc_v;
	txreg_t reg;
	u_int32_t val;
	
	h = chip->vc_fbwidth;
	v = chip->vc_fbheight;
	reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
	split = reg & TX3912_VIDEOCTRL1_DISPSPLIT;
	val = TX3912_VIDEOCTRL1_BITSEL(reg);

	if ((val == TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR) && !split) {
		/* (LCD horizontal pixels / 8bit) * RGB - 1 */
		horzval = (h / 8) * 3 - 1; 
	} else {
		horzval = h / 4 - 1;
	}
	lineval = (split ? v / 2 : v) - 1;

	/* Video rate */
	/* XXX 
	 *  probably This value should be determined from DFINT and LCDINT 
	 */
	reg = TX3912_VIDEOCTRL2_VIDRATE_SET(0, horzval + 1);
	/* Horizontal size of LCD */
	reg = TX3912_VIDEOCTRL2_HORZVAL_SET(reg, horzval);
	/* # of lines for the LCD */
	reg = TX3912_VIDEOCTRL2_LINEVAL_SET(reg, lineval);
	
	tx_conf_write(tc, TX3912_VIDEOCTRL2_REG, reg);
}
Example #4
0
int
optpoint_initialize(void *self)
{
	struct optpoint_softc *sc = (void*)self;
	struct hpcio_chip *hc = sc->sc_hc;
	tx_chipset_tag_t tc = sc->sc_tc;

	if (sc->index < 4){
		optpoint_send(sc, sc->packet[sc->index++]);
		(*hc->hc_portwrite)(hc, TELIOS_MFIO_OPTP_C_REQ, 1);
		(*hc->hc_portwrite)(hc, TELIOS_MFIO_OPTP_T_RDY, 1);
	} else {
		tx_intr_disestablish(tc,
			    (void *)MAKEINTR(4, TX39_INTRSTATUS4_OPTPOINTINT));
		sc->index = 0;
		memset(sc->packet, 0, 3);
		tx_intr_establish(tc,
				  MAKEINTR(4, TX39_INTRSTATUS4_OPTPOINTINT),
				  IST_EDGE, IPL_TTY, optpoint_intr, sc);
		(*hc->hc_portwrite)(hc, TELIOS_MFIO_OPTP_C_REQ, 0);
		(*hc->hc_portwrite)(hc, TELIOS_MFIO_OPTP_T_RDY, 1);
	}
	tx_conf_write(tc, TX39_INTRCLEAR4_REG, TX39_INTRSTATUS4_OPTPOINTINT);

	return 0;
}
Example #5
0
int
optpoint_intr(void *self)
{
	struct optpoint_softc *sc = (void*)self;
	tx_chipset_tag_t tc = sc->sc_tc;
	char data = optpoint_recv(sc) & 0xff;

#ifdef DIAGNOSTIC
	if (sc->index >= 3){
		printf("%s: Receive buffer overflow\n", sc->sc_dev.dv_xname);
		sc->index = 0;
		memset(sc->packet, 0, 3);
	}
#endif
	if ((sc->index == 1) && (data & 0xcc) != 0x08){
		DPRINTF(("%s: Bad second byte (0x%02x)\n",
			 sc->sc_dev.dv_xname, data));
		tx_conf_write(tc, TX39_INTRCLEAR4_REG,
				  TX39_INTRSTATUS4_OPTPOINTINT);
		return 0;
	}

	sc->packet[sc->index++] = data;
	if (sc->index >= 3){
		u_int newbuttons = ((sc->packet[1] & LBUTMASK) ? 0x1 : 0)
				 | ((sc->packet[1] & RBUTMASK) ? 0x2 : 0);
		int dx = sc->packet[2];
		int dy = sc->packet[0];
		u_int changed = (sc->buttons ^ newbuttons);

		if (dx || dy || changed){
			DPRINTF(("%s: buttons=0x%x, dx=%d, dy=%d\n",
				 sc->sc_dev.dv_xname, newbuttons, dx, dy));
			wsmouse_input(sc->sc_wsmousedev,
					newbuttons,
					dx, dy, 0, 0,
					WSMOUSE_INPUT_DELTA);
		}
		sc->buttons = newbuttons;
		sc->index = 0;
		memset(sc->packet, 0, 3);
	}
	tx_conf_write(tc, TX39_INTRCLEAR4_REG, TX39_INTRSTATUS4_OPTPOINTINT);

	return 0;
}
int
tx3912video_init(paddr_t fb_start, paddr_t *fb_end)
{
	struct video_chip *chip = &tx3912video_chip;
	tx_chipset_tag_t tc;
	txreg_t reg;
	int fbdepth, reverse, error;
	
	reverse = video_reverse_color();
	chip->vc_v = tc = tx_conf_get_tag();
	
	reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);	
	fbdepth = 1 << (TX3912_VIDEOCTRL1_BITSEL(reg));

	switch (fbdepth) {
	case 2:
		bootinfo->fb_type = reverse ? BIFB_D2_M2L_3 : BIFB_D2_M2L_0;
		break;
	case 4:
		/* XXX should implement rasops4.c */
		fbdepth = 2;
		bootinfo->fb_type = reverse ? BIFB_D2_M2L_3 : BIFB_D2_M2L_0;
		reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);	
		TX3912_VIDEOCTRL1_BITSEL_CLR(reg);
		reg = TX3912_VIDEOCTRL1_BITSEL_SET(reg,
		    TX3912_VIDEOCTRL1_BITSEL_2BITGREYSCALE);
		tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);
		break;
	case 8:
		bootinfo->fb_type = reverse ? BIFB_D8_FF : BIFB_D8_00;
		break;
	}

	chip->vc_fbdepth = fbdepth;
	chip->vc_fbwidth = bootinfo->fb_width;
	chip->vc_fbheight= bootinfo->fb_height;

	/* Allocate framebuffer area */
	error = tx3912video_framebuffer_alloc(chip, fb_start, fb_end);
	if (error != 0)
		return (1);

#if notyet 
	tx3912video_resolution_init(chip);
#else
	/* Use Windows CE setting. */
#endif
	/* Set DMA transfer address to VID module */
	tx3912video_framebuffer_init(chip);
	
	/* Syncronize framebuffer addr to frame signal */
	tx3912video_reset(chip);

	bootinfo->fb_line_bytes = (chip->vc_fbwidth * fbdepth) / NBBY;
	bootinfo->fb_addr = (void *)MIPS_PHYS_TO_KSEG1(chip->vc_fbpaddr);
	
	return (0);
}
int
tx39biu_intr(void *arg)
{
	struct tx39biu_softc *sc = __sc;
	tx_chipset_tag_t tc;
	txreg_t reg;

	if (!sc) {
		return (0);
	}
	tc = sc->sc_tc;
	/* Clear interrupt */
	reg = tx_conf_read(tc, TX39_MEMCONFIG4_REG);
	reg |= TX39_MEMCONFIG4_CLRWRBUSERRINT;
	tx_conf_write(tc, TX39_MEMCONFIG4_REG, reg);
	reg = tx_conf_read(tc, TX39_MEMCONFIG4_REG);
	reg &= ~TX39_MEMCONFIG4_CLRWRBUSERRINT;
	tx_conf_write(tc, TX39_MEMCONFIG4_REG, reg);

	return (0);
}
void
tx3912video_framebuffer_init(struct video_chip *chip)
{
	u_int32_t fb_addr, fb_size, vaddr, bank, base;
	txreg_t reg;
	tx_chipset_tag_t tc = chip->vc_v;

	fb_addr = chip->vc_fbpaddr;
	fb_size = chip->vc_fbsize;

	/*  XXX currently I don't set DFVAL, so force DF signal toggled on
         *  XXX each frame. */
	reg = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
	reg &= ~TX3912_VIDEOCTRL1_DFMODE; 
	tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, reg);

	/* Set DMA transfer start and end address */
	
	bank = TX3912_VIDEOCTRL3_VIDBANK(fb_addr);
	base = TX3912_VIDEOCTRL3_VIDBASEHI(fb_addr);
	reg = TX3912_VIDEOCTRL3_VIDBANK_SET(0, bank);
	/* Upper address counter */
	reg = TX3912_VIDEOCTRL3_VIDBASEHI_SET(reg, base);
	tx_conf_write(tc, TX3912_VIDEOCTRL3_REG, reg);

	/* Lower address counter  */
	base = TX3912_VIDEOCTRL4_VIDBASELO(fb_addr + fb_size);
	reg = TX3912_VIDEOCTRL4_VIDBASELO_SET(0, base);

	/* Set DF-signal rate */
	reg = TX3912_VIDEOCTRL4_DFVAL_SET(reg, 0); /* XXX not yet*/

	/* Set VIDDONE signal delay after FRAME signal */
	/* XXX not yet*/	
	tx_conf_write(tc, TX3912_VIDEOCTRL4_REG, reg);

	/* Clear frame buffer */
	vaddr = MIPS_PHYS_TO_KSEG1(fb_addr);
	memset((void*)vaddr, 0, fb_size);
}
Example #9
0
void
tx39ir_attach(struct device *parent, struct device *self, void *aux)
{
	struct txcom_attach_args *tca = aux;
	struct tx39ir_softc *sc = (void*)self;
	tx_chipset_tag_t tc;
	txreg_t reg;

	sc->sc_tc = tc = tca->tca_tc;
	sc->sc_parent = tca->tca_parent;

	printf("\n");

	/* setup IR module */
	reg = tx_conf_read(tc, TX39_IRCTRL1_REG);
	reg |= TX39_IRCTRL1_RXPWR;
	tx_conf_write(tc, TX39_IRCTRL1_REG, reg);

	/* power up IR module */
	reg = tx_conf_read(tc, TX39_CLOCKCTRL_REG);
	reg |= TX39_CLOCK_ENIRCLK | TX39_CLOCK_ENUARTBCLK;
	tx_conf_write(tc, TX39_CLOCKCTRL_REG, reg);

	/* turn to pulse mode UARTB */
	txcom_pulse_mode(sc->sc_parent);

#if not_required_yet
	tx_intr_establish(tc, MAKEINTR(5, TX39_INTRSTATUS5_CARSTINT),
	    IST_EDGE, IPL_TTY, tx39ir_intr, sc);
	tx_intr_establish(tc, MAKEINTR(5, TX39_INTRSTATUS5_POSCARINT),
	    IST_EDGE, IPL_TTY, tx39ir_intr, sc);
	tx_intr_establish(tc, MAKEINTR(5, TX39_INTRSTATUS5_NEGCARINT),
	    IST_EDGE, IPL_TTY, tx39ir_intr, sc);
#endif

#ifdef TX39IRDEBUG
	tx39ir_dump(sc);
#endif	
}
void
tx39biu_attach(device_t parent, device_t self, void *aux)
{
	struct txsim_attach_args *ta = aux;
	struct tx39biu_softc *sc = device_private(self);
	tx_chipset_tag_t tc;
#ifdef TX39_WATCHDOGTIMER
	txreg_t reg;
#endif

	sc->sc_tc = tc = ta->ta_tc;
	printf("\n");
#ifdef TX39BIU_DEBUG
	tx39biu_dump(tc);
#endif

#ifdef TX39_WATCHDOGTIMER
	/*
	 * CLRWRBUSERRINT Bus error connected CPU HwInt0
	 */
	reg = tx_conf_read(tc, TX39_MEMCONFIG4_REG);
	reg |= TX39_MEMCONFIG4_ENWATCH;
	reg = TX39_MEMCONFIG4_WATCHTIMEVAL_SET(reg, 0xf);
	tx_conf_write(tc, TX39_MEMCONFIG4_REG, reg);
	
	reg = tx_conf_read(tc, TX39_MEMCONFIG4_REG);
	if (reg & TX39_MEMCONFIG4_ENWATCH) {
		int i;
		i = TX39_MEMCONFIG4_WATCHTIMEVAL(reg);
		i = (1000 * (i + 1) * 64) / 36864;
		printf("WatchDogTimerRate: %dus\n", i);
	}
#endif
	__sc = sc;

	/*	Clear watch dog timer interrupt */
	tx39biu_intr(sc);

	/* 
	 *	Chip select virtual bridge
	 */
	config_defer(self, tx39biu_callback);
}
void
tx3912video_clut_init(struct tx3912video_softc *sc)
{
	tx_chipset_tag_t tc = sc->sc_chip->vc_v;

	if (sc->sc_chip->vc_fbdepth != 8) {
		return; /* XXX 2bit gray scale LUT not supported */
	}

	/* 
	 * time-based dithering pattern (TOSHIBA recommended pattern)
	 */
	/* 2/3, 1/3 */
	tx_conf_write(tc, TX3912_VIDEOCTRL8_REG, 
	    TX3912_VIDEOCTRL8_PAT2_3_DEFAULT);
	/* 3/4, 2/4 */
	tx_conf_write(tc, TX3912_VIDEOCTRL9_REG, 
	    (TX3912_VIDEOCTRL9_PAT3_4_DEFAULT << 16) |
	    TX3912_VIDEOCTRL9_PAT2_4_DEFAULT);
	/* 4/5, 1/5 */
	tx_conf_write(tc, TX3912_VIDEOCTRL10_REG, 
	    TX3912_VIDEOCTRL10_PAT4_5_DEFAULT);
	/* 3/5, 2/5 */
	tx_conf_write(tc, TX3912_VIDEOCTRL11_REG, 
	    TX3912_VIDEOCTRL11_PAT3_5_DEFAULT);
	/* 6/7, 1/7 */
	tx_conf_write(tc, TX3912_VIDEOCTRL12_REG, 
	    TX3912_VIDEOCTRL12_PAT6_7_DEFAULT);
	/* 5/7, 2/7 */
	tx_conf_write(tc, TX3912_VIDEOCTRL13_REG, 
	    TX3912_VIDEOCTRL13_PAT5_7_DEFAULT);
	/* 4/7, 3/7 */
	tx_conf_write(tc, TX3912_VIDEOCTRL14_REG, 
	    TX3912_VIDEOCTRL14_PAT4_7_DEFAULT);

	/* 
	 * dither-pattern look-up table. (selected by uch)
	 */
	/* red */
	tx_conf_write(tc, TX3912_VIDEOCTRL5_REG,
	    (dither_level8[7] << 28) |
	    (dither_level8[6] << 24) |
	    (dither_level8[5] << 20) |
	    (dither_level8[4] << 16) |
	    (dither_level8[3] << 12) |
	    (dither_level8[2] << 8) |
	    (dither_level8[1] << 4) |
	    (dither_level8[0] << 0));
	/* green */
	tx_conf_write(tc, TX3912_VIDEOCTRL6_REG,
	    (dither_level8[7] << 28) |
	    (dither_level8[6] << 24) |
	    (dither_level8[5] << 20) |
	    (dither_level8[4] << 16) |
	    (dither_level8[3] << 12) |
	    (dither_level8[2] << 8) |
	    (dither_level8[1] << 4) |
	    (dither_level8[0] << 0));
	/* blue (2bit gray scale also use this look-up table) */
	tx_conf_write(tc, TX3912_VIDEOCTRL7_REG,
	    (dither_level4[3] << 12) |
	    (dither_level4[2] << 8) |
	    (dither_level4[1] << 4) |
	    (dither_level4[0] << 0));

	tx3912video_reset(sc->sc_chip);
}
void
tx3912video_attach(device_t parent, device_t self, void *aux)
{
	struct tx3912video_softc *sc = device_private(self);
	struct video_chip *chip;
	static const char *const depth_print[] = { 
		[TX3912_VIDEOCTRL1_BITSEL_MONOCHROME] = "monochrome",
		[TX3912_VIDEOCTRL1_BITSEL_2BITGREYSCALE] = "2bit greyscale",
		[TX3912_VIDEOCTRL1_BITSEL_4BITGREYSCALE] = "4bit greyscale",
		[TX3912_VIDEOCTRL1_BITSEL_8BITCOLOR] = "8bit color"
	};
	struct hpcfb_attach_args ha;
	tx_chipset_tag_t tc;
	txreg_t val;
	int console;

	sc->sc_dev = self;
	sc->sc_console = console = cn_tab ? 0 : 1;
	sc->sc_chip = chip = &tx3912video_chip;

	/* print video module information */
	printf(": %s, frame buffer 0x%08x-0x%08x\n",
	    depth_print[(ffs(chip->vc_fbdepth) - 1) & 0x3],
	    (unsigned)chip->vc_fbpaddr, 
	    (unsigned)(chip->vc_fbpaddr + chip->vc_fbsize));

	/* don't inverse VDAT[3:0] signal */
	tc = chip->vc_v;
	val = tx_conf_read(tc, TX3912_VIDEOCTRL1_REG);
	val &= ~TX3912_VIDEOCTRL1_INVVID;
	tx_conf_write(tc, TX3912_VIDEOCTRL1_REG, val);

	/* install default CLUT */
	tx3912video_clut_init(sc);

	/* if serial console, power off video module */
	tx3912video_power(sc, 0, 0, (void *)
	    (console ? PWR_RESUME : PWR_SUSPEND));
	
	/* Add a hard power hook to power saving */
	sc->sc_powerhook = config_hook(CONFIG_HOOK_PMEVENT,
	    CONFIG_HOOK_PMEVENT_HARDPOWER, CONFIG_HOOK_SHARE,
	    tx3912video_power, sc);
	if (sc->sc_powerhook == 0)
		printf("WARNING unable to establish hard power hook");

#ifdef TX3912VIDEO_DEBUG
	/* attach debug draw routine (debugging use) */
	video_attach_drawfunc(sc->sc_chip);
	tx_conf_register_video(tc, sc->sc_chip);
#endif
	
	/* Attach frame buffer device */
	tx3912video_hpcfbinit(sc);

	if (console && hpcfb_cnattach(&sc->sc_fbconf) != 0) {
		panic("tx3912video_attach: can't init fb console");
	}

	ha.ha_console = console;
	ha.ha_accessops = &tx3912video_ha;
	ha.ha_accessctx = sc;
	ha.ha_curfbconf = 0;
	ha.ha_nfbconf = 1;
	ha.ha_fbconflist = &sc->sc_fbconf;
	ha.ha_curdspconf = 0;
	ha.ha_ndspconf = 1;
	ha.ha_dspconflist = &sc->sc_dspconf;

	config_found(self, &ha, hpcfbprint);
#if NBIVIDEO > 0
	/* bivideo is no longer need */
	bivideo_dont_attach = 1;
#endif /* NBIVIDEO > 0 */
}