Module Name: src Committed By: tsutsui Date: Wed Dec 23 08:34:35 UTC 2020
Modified Files: src/sys/dev/ic: sti.c stivar.h Log Message: Pull the latest OpenBSD sti(4) changes for bitmap framebuffer support. - bitmap and colormap ops based on old HP ngle X11 driver: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/dev/ic/sti.c#rev1.76 > Work-in-progress support for non-accelerated X11 on *some* sti(4) > frame buffers; based upon the old HP ngle X11 driver. > Currently limited to CRX (720/735/750), Timber (710, old 715), > Artist (712, 715) and EG (B-series), however the > colormap isn't set up correctly on Timber and EG yet. > > Joint work with Artem Falcon, now in good enough shape to be worked further > in the tree. - misc other cosmetic changes to reduce diffs No particular comments on port-hp300@ and port-hppa@: https://mail-index.netbsd.org/port-hp300/2020/12/19/msg000184.html https://mail-index.netbsd.org/port-hp300/2020/12/20/msg000185.html The MD hp300 attachment for SGC CRX (A1659-66001) will be committed separately. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/dev/ic/sti.c cvs rdiff -u -r1.10 -r1.11 src/sys/dev/ic/stivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/sti.c diff -u src/sys/dev/ic/sti.c:1.22 src/sys/dev/ic/sti.c:1.23 --- src/sys/dev/ic/sti.c:1.22 Sat Sep 5 16:30:11 2020 +++ src/sys/dev/ic/sti.c Wed Dec 23 08:34:35 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: sti.c,v 1.22 2020/09/05 16:30:11 riastradh Exp $ */ +/* $NetBSD: sti.c,v 1.23 2020/12/23 08:34:35 tsutsui Exp $ */ /* $OpenBSD: sti.c,v 1.61 2009/09/05 14:09:35 miod Exp $ */ @@ -31,11 +31,11 @@ * TODO: * call sti procs asynchronously; * implement console scroll-back; - * X11 support. + * X11 support on more models. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.22 2020/09/05 16:30:11 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sti.c,v 1.23 2020/12/23 08:34:35 tsutsui Exp $"); #include "wsdisplay.h" @@ -80,32 +80,32 @@ void sti_eraserows(void *, int, int, lon int sti_alloc_attr(void *, int, int, int, long *); struct wsdisplay_emulops sti_emulops = { - sti_cursor, - sti_mapchar, - sti_putchar, - sti_copycols, - sti_erasecols, - sti_copyrows, - sti_eraserows, - sti_alloc_attr + .cursor = sti_cursor, + .mapchar = sti_mapchar, + .putchar = sti_putchar, + .copycols = sti_copycols, + .erasecols = sti_erasecols, + .copyrows = sti_copyrows, + .eraserows = sti_eraserows, + .allocattr = sti_alloc_attr }; const struct wsdisplay_accessops sti_accessops = { - sti_ioctl, - sti_mmap, - sti_alloc_screen, - sti_free_screen, - sti_show_screen, - sti_load_font + .ioctl = sti_ioctl, + .mmap = sti_mmap, + .alloc_screen = sti_alloc_screen, + .free_screen = sti_free_screen, + .show_screen = sti_show_screen, + .load_font = sti_load_font }; enum sti_bmove_funcs { bmf_clear, bmf_copy, bmf_invert, bmf_underline }; -int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); void sti_bmove(struct sti_screen *, int, int, int, int, int, int, enum sti_bmove_funcs); +int sti_inqcfg(struct sti_screen *, struct sti_inqconfout *); int sti_setcment(struct sti_screen *, u_int, u_char, u_char, u_char); struct sti_screen *sti_attach_screen(struct sti_softc *, int); @@ -118,6 +118,15 @@ int sti_rom_setup(struct sti_rom *, bus_ bus_space_handle_t, bus_addr_t *, u_int); int sti_screen_setup(struct sti_screen *, int); +int ngle_default_putcmap(struct sti_screen *, u_int, u_int); + +#ifndef SMALL_KERNEL +void ngle_artist_setupfb(struct sti_screen *); +void ngle_elk_setupfb(struct sti_screen *); +void ngle_timber_setupfb(struct sti_screen *); +int ngle_putcmap(struct sti_screen *, u_int, u_int); +#endif + #if NSTI_PCI > 0 #define STI_ENABLE_ROM(sc) \ do { \ @@ -210,51 +219,52 @@ sti_rom_setup(struct sti_rom *rom, bus_s /* * Get ROM header and code function pointers. */ + dd = &rom->rom_dd; rom->rom_devtype = bus_space_read_1(memt, romh, 3); if (rom->rom_devtype == STI_DEVTYPE1) { - dd->dd_type = bus_space_read_1(memt, romh, 0x03); - dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); - dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); - dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); - dd->dd_grid[0] = parseword(0x10); - dd->dd_grid[1] = parseword(0x20); - dd->dd_fntaddr = parseword(0x30) & ~3; - dd->dd_maxst = parseword(0x40); - dd->dd_romend = parseword(0x50) & ~3; - dd->dd_reglst = parseword(0x60) & ~3; - dd->dd_maxreent= parseshort(0x70); - dd->dd_maxtimo = parseshort(0x78); - dd->dd_montbl = parseword(0x80) & ~3; - dd->dd_udaddr = parseword(0x90) & ~3; - dd->dd_stimemreq=parseword(0xa0); - dd->dd_udsize = parseword(0xb0); - dd->dd_pwruse = parseshort(0xc0); - dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); - dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); - dd->dd_altcodet= bus_space_read_1(memt, romh, 0xd3); - dd->dd_eddst[0]= bus_space_read_1(memt, romh, 0xd7); - dd->dd_eddst[1]= bus_space_read_1(memt, romh, 0xdb); - dd->dd_eddst[2]= bus_space_read_1(memt, romh, 0xdf); - dd->dd_cfbaddr = parseword(0xe0) & ~3; + dd->dd_type = bus_space_read_1(memt, romh, 0x03); + dd->dd_nmon = bus_space_read_1(memt, romh, 0x07); + dd->dd_grrev = bus_space_read_1(memt, romh, 0x0b); + dd->dd_lrrev = bus_space_read_1(memt, romh, 0x0f); + dd->dd_grid[0] = parseword(0x10); + dd->dd_grid[1] = parseword(0x20); + dd->dd_fntaddr = parseword(0x30) & ~3; + dd->dd_maxst = parseword(0x40); + dd->dd_romend = parseword(0x50) & ~3; + dd->dd_reglst = parseword(0x60) & ~3; + dd->dd_maxreent = parseshort(0x70); + dd->dd_maxtimo = parseshort(0x78); + dd->dd_montbl = parseword(0x80) & ~3; + dd->dd_udaddr = parseword(0x90) & ~3; + dd->dd_stimemreq = parseword(0xa0); + dd->dd_udsize = parseword(0xb0); + dd->dd_pwruse = parseshort(0xc0); + dd->dd_bussup = bus_space_read_1(memt, romh, 0xcb); + dd->dd_ebussup = bus_space_read_1(memt, romh, 0xcf); + dd->dd_altcodet = bus_space_read_1(memt, romh, 0xd3); + dd->dd_eddst[0] = bus_space_read_1(memt, romh, 0xd7); + dd->dd_eddst[1] = bus_space_read_1(memt, romh, 0xdb); + dd->dd_eddst[2] = bus_space_read_1(memt, romh, 0xdf); + dd->dd_cfbaddr = parseword(0xe0) & ~3; codebase <<= 2; - dd->dd_pacode[0x0] = parseword(codebase + 0x00) & ~3; - dd->dd_pacode[0x1] = parseword(codebase + 0x10) & ~3; - dd->dd_pacode[0x2] = parseword(codebase + 0x20) & ~3; - dd->dd_pacode[0x3] = parseword(codebase + 0x30) & ~3; - dd->dd_pacode[0x4] = parseword(codebase + 0x40) & ~3; - dd->dd_pacode[0x5] = parseword(codebase + 0x50) & ~3; - dd->dd_pacode[0x6] = parseword(codebase + 0x60) & ~3; - dd->dd_pacode[0x7] = parseword(codebase + 0x70) & ~3; - dd->dd_pacode[0x8] = parseword(codebase + 0x80) & ~3; - dd->dd_pacode[0x9] = parseword(codebase + 0x90) & ~3; - dd->dd_pacode[0xa] = parseword(codebase + 0xa0) & ~3; - dd->dd_pacode[0xb] = parseword(codebase + 0xb0) & ~3; - dd->dd_pacode[0xc] = parseword(codebase + 0xc0) & ~3; - dd->dd_pacode[0xd] = parseword(codebase + 0xd0) & ~3; - dd->dd_pacode[0xe] = parseword(codebase + 0xe0) & ~3; - dd->dd_pacode[0xf] = parseword(codebase + 0xf0) & ~3; + dd->dd_pacode[0x0] = parseword(codebase + 0x000) & ~3; + dd->dd_pacode[0x1] = parseword(codebase + 0x010) & ~3; + dd->dd_pacode[0x2] = parseword(codebase + 0x020) & ~3; + dd->dd_pacode[0x3] = parseword(codebase + 0x030) & ~3; + dd->dd_pacode[0x4] = parseword(codebase + 0x040) & ~3; + dd->dd_pacode[0x5] = parseword(codebase + 0x050) & ~3; + dd->dd_pacode[0x6] = parseword(codebase + 0x060) & ~3; + dd->dd_pacode[0x7] = parseword(codebase + 0x070) & ~3; + dd->dd_pacode[0x8] = parseword(codebase + 0x080) & ~3; + dd->dd_pacode[0x9] = parseword(codebase + 0x090) & ~3; + dd->dd_pacode[0xa] = parseword(codebase + 0x0a0) & ~3; + dd->dd_pacode[0xb] = parseword(codebase + 0x0b0) & ~3; + dd->dd_pacode[0xc] = parseword(codebase + 0x0c0) & ~3; + dd->dd_pacode[0xd] = parseword(codebase + 0x0d0) & ~3; + dd->dd_pacode[0xe] = parseword(codebase + 0x0e0) & ~3; + dd->dd_pacode[0xf] = parseword(codebase + 0x0f0) & ~3; } else { /* STI_DEVTYPE4 */ bus_space_read_region_stream_4(memt, romh, 0, (uint32_t *)dd, sizeof(*dd) / 4); @@ -288,7 +298,7 @@ sti_rom_setup(struct sti_rom *rom, bus_s * Note there could be fewer than STI_END pointer entries * populated, especially on older devices. */ - for (i = STI_END; !dd->dd_pacode[i]; i--) + for (i = STI_END; dd->dd_pacode[i] == 0; i--) ; size = dd->dd_pacode[i] - dd->dd_pacode[STI_BEGIN]; @@ -300,13 +310,12 @@ sti_rom_setup(struct sti_rom *rom, bus_s return EINVAL; } - DPRINTF(("code size %x/%x\n", size, round_page(size))); - if (!(rom->rom_code = uvm_km_alloc(kernel_map, round_page(size), 0, UVM_KMF_WIRED))) { aprint_error(": cannot allocate %u bytes for code\n", size); return ENOMEM; } + DPRINTF(("code=0x%lx[%x]\n", rom->rom_code, size)); /* * Copy code into memory and make it executable. @@ -322,8 +331,7 @@ sti_rom_setup(struct sti_rom *rom, bus_s for (addr = dd->dd_pacode[STI_BEGIN], eaddr = addr + size * 4; addr < eaddr; addr += 4 ) { - *p++ = bus_space_read_4(memt, romh, addr) - & 0xff; + *p++ = bus_space_read_4(memt, romh, addr) & 0xff; } } else { /* STI_DEVTYPE4 */ bus_space_read_region_stream_4(memt, romh, @@ -349,26 +357,27 @@ sti_rom_setup(struct sti_rom *rom, bus_s (dd->dd_pacode[(i)] == 0 ? 0 : \ (rom->rom_code + (dd->dd_pacode[(i)] - dd->dd_pacode[0]) / \ (rom->rom_devtype == STI_DEVTYPE1 ? 4 : 1))) - rom->init = (sti_init_t) O(STI_INIT_GRAPH); - rom->mgmt = (sti_mgmt_t) O(STI_STATE_MGMT); - rom->unpmv = (sti_unpmv_t) O(STI_FONT_UNPMV); - rom->blkmv = (sti_blkmv_t) O(STI_BLOCK_MOVE); - rom->test = (sti_test_t) O(STI_SELF_TEST); - rom->exhdl = (sti_exhdl_t) O(STI_EXCEP_HDLR); + + rom->init = (sti_init_t)O(STI_INIT_GRAPH); + rom->mgmt = (sti_mgmt_t)O(STI_STATE_MGMT); + rom->unpmv = (sti_unpmv_t)O(STI_FONT_UNPMV); + rom->blkmv = (sti_blkmv_t)O(STI_BLOCK_MOVE); + rom->test = (sti_test_t)O(STI_SELF_TEST); + rom->exhdl = (sti_exhdl_t)O(STI_EXCEP_HDLR); rom->inqconf = (sti_inqconf_t)O(STI_INQ_CONF); rom->scment = (sti_scment_t)O(STI_SCM_ENT); - rom->dmac = (sti_dmac_t) O(STI_DMA_CTRL); - rom->flowc = (sti_flowc_t) O(STI_FLOW_CTRL); + rom->dmac = (sti_dmac_t)O(STI_DMA_CTRL); + rom->flowc = (sti_flowc_t)O(STI_FLOW_CTRL); rom->utiming = (sti_utiming_t)O(STI_UTIMING); - rom->pmgr = (sti_pmgr_t) O(STI_PROC_MGR); - rom->util = (sti_util_t) O(STI_UTIL); + rom->pmgr = (sti_pmgr_t)O(STI_PROC_MGR); + rom->util = (sti_util_t)O(STI_UTIL); #undef O + /* * Set colormap entry is not implemented until 8.04, so force * a NULL pointer here. */ - if (dd->dd_grrev < STI_REVISION(8, 4)) { rom->scment = NULL; } @@ -388,7 +397,6 @@ sti_region_setup(struct sti_screen *scr) bus_addr_t *bases = rom->bases; struct sti_dd *dd = &rom->rom_dd; struct sti_cfg *cc = &scr->scr_cfg; - bus_space_handle_t bh; struct sti_region regions[STI_REGION_MAX], *r; u_int regno, regcnt; bus_addr_t addr; @@ -449,14 +457,14 @@ sti_region_setup(struct sti_screen *scr) continue; } - /* XXXNH BUS_SPACE_MAP_CACHEABLE */ if (bus_space_map(memt, addr, r->length << PGSHIFT, - r->cache ? BUS_SPACE_MAP_CACHEABLE : 0, &bh)) { + BUS_SPACE_MAP_LINEAR | (r->cache ? + BUS_SPACE_MAP_CACHEABLE : 0), &rom->regh[regno]) != 0) { + rom->regh[regno] = romh; /* XXX */ DPRINTF((" - already mapped region\n")); } else { - - /* XXX should use bus_space_vaddr */ - addr = (bus_addr_t)bh; + addr = (bus_addr_t) + bus_space_vaddr(memt, rom->regh[regno]); if (regno == 1) { DPRINTF((" - fb")); scr->fbaddr = addr; @@ -616,6 +624,73 @@ sti_screen_setup(struct sti_screen *scr, scr->scr_screenlist.nscreens = 1; scr->scr_screenlist.screens = scr->scr_scrlist; +#ifndef SMALL_KERNEL + /* + * Decide which board-specific routines to use. + */ + + switch (dd->dd_grid[0]) { + case STI_DD_CRX: + scr->setupfb = ngle_elk_setupfb; + scr->putcmap = ngle_putcmap; + + scr->reg10_value = 0x13601000; + if (scr->scr_bpp > 8) + scr->reg12_value = NGLE_BUFF1_CMAP3; + else + scr->reg12_value = NGLE_BUFF1_CMAP0; + scr->cmap_finish_register = NGLE_REG_1; + break; + + case STI_DD_TIMBER: + scr->setupfb = ngle_timber_setupfb; + scr->putcmap = ngle_putcmap; + + scr->reg10_value = 0x13602000; + scr->reg12_value = NGLE_BUFF1_CMAP0; + scr->cmap_finish_register = NGLE_REG_1; + break; + + case STI_DD_ARTIST: + scr->setupfb = ngle_artist_setupfb; + scr->putcmap = ngle_putcmap; + + scr->reg10_value = 0x13601000; + scr->reg12_value = NGLE_ARTIST_CMAP0; + scr->cmap_finish_register = NGLE_REG_26; + break; + + case STI_DD_EG: + scr->setupfb = ngle_artist_setupfb; + scr->putcmap = ngle_putcmap; + + scr->reg10_value = 0x13601000; + if (scr->scr_bpp > 8) { + scr->reg12_value = NGLE_BUFF1_CMAP3; + scr->cmap_finish_register = NGLE_REG_1; + } else { + scr->reg12_value = NGLE_ARTIST_CMAP0; + scr->cmap_finish_register = NGLE_REG_26; + } + break; + + case STI_DD_GRX: + case STI_DD_CRX24: + case STI_DD_EVRX: + case STI_DD_3X2V: + case STI_DD_DUAL_CRX: + case STI_DD_HCRX: + case STI_DD_LEGO: + case STI_DD_SUMMIT: + case STI_DD_PINNACLE: + default: + scr->setupfb = NULL; + scr->putcmap = + rom->scment == NULL ? NULL : ngle_default_putcmap; + break; + } +#endif + return 0; fail: @@ -656,6 +731,11 @@ sti_describe(struct sti_softc *sc) sti_describe_screen(sc, sc->sc_scr); } +/* + * Final part of attachment. On hppa where we use the PDC console + * during autoconf, this has to be postponed until autoconf has + * completed. + */ void sti_end_attach(struct sti_softc *sc) { @@ -827,6 +907,7 @@ rescan: /* * Wrappers around STI code pointers */ + int sti_init(struct sti_screen *scr, int mode) { @@ -955,11 +1036,10 @@ int sti_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, struct lwp *l) { struct sti_screen *scr = (struct sti_screen *)v; - struct sti_rom *rom = scr->scr_rom; struct wsdisplay_fbinfo *wdf; struct wsdisplay_cmap *cmapp; u_int mode, idx, count; - int i, ret; + int ret; ret = 0; switch (cmd) { @@ -969,13 +1049,31 @@ sti_ioctl(void *v, void *vs, u_long cmd, case WSDISPLAYIO_SMODE: mode = *(u_int *)data; - if (scr->scr_wsmode == WSDISPLAYIO_MODE_EMUL && - mode == WSDISPLAYIO_MODE_DUMBFB) - ret = sti_init(scr, 0); - else if (scr->scr_wsmode == WSDISPLAYIO_MODE_DUMBFB && - mode == WSDISPLAYIO_MODE_EMUL) - ret = sti_init(scr, STI_TEXTMODE); - scr->scr_wsmode = mode; + switch (mode) { + case WSDISPLAYIO_MODE_EMUL: + if (scr->scr_wsmode != WSDISPLAYIO_MODE_EMUL) + ret = sti_init(scr, STI_TEXTMODE); + break; + case WSDISPLAYIO_MODE_DUMBFB: + if (scr->scr_wsmode != WSDISPLAYIO_MODE_DUMBFB) { + sti_init(scr, 0); + if (scr->setupfb != NULL) + scr->setupfb(scr); + else +#if 0 + ret = sti_init(scr, STI_FBMODE); +#else + ret = EINVAL; +#endif + } + break; + case WSDISPLAYIO_MODE_MAPPED: + default: + ret = EINVAL; + break; + } + if (ret == 0) + scr->scr_wsmode = mode; break; case WSDISPLAYIO_GTYPE: @@ -987,19 +1085,22 @@ sti_ioctl(void *v, void *vs, u_long cmd, wdf->height = scr->scr_cfg.scr_height; wdf->width = scr->scr_cfg.scr_width; wdf->depth = scr->scr_bpp; - if (rom->scment == NULL) + if (scr->putcmap == NULL || scr->scr_bpp > 8) wdf->cmsize = 0; else wdf->cmsize = STI_NCMAP; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = scr->scr_cfg.fb_width; + if (scr->scr_bpp > 8) + *(u_int *)data = scr->scr_cfg.fb_width * 4; + else + *(u_int *)data = scr->scr_cfg.fb_width; break; case WSDISPLAYIO_GETCMAP: - if (rom->scment == NULL) - return ENOTTY; + if (scr->putcmap == NULL || scr->scr_bpp > 8) + return ENODEV; cmapp = (struct wsdisplay_cmap *)data; idx = cmapp->index; count = cmapp->count; @@ -1014,8 +1115,8 @@ sti_ioctl(void *v, void *vs, u_long cmd, break; case WSDISPLAYIO_PUTCMAP: - if (rom->scment == NULL) - return ENOTTY; + if (scr->putcmap == NULL || scr->scr_bpp > 8) + return ENODEV; cmapp = (struct wsdisplay_cmap *)data; idx = cmapp->index; count = cmapp->count; @@ -1027,19 +1128,7 @@ sti_ioctl(void *v, void *vs, u_long cmd, break; if ((ret = copyin(cmapp->blue, &scr->scr_bcmap[idx], count))) break; - for (i = idx + count - 1; i >= idx; i--) - if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i], - scr->scr_gcmap[i], scr->scr_bcmap[i]))) { - - DPRINTF(("sti_ioctl: " - "sti_setcment(%d, %u, %u, %u): %%d\n", i, - (u_int)scr->scr_rcmap[i], - (u_int)scr->scr_gcmap[i], - (u_int)scr->scr_bcmap[i])); - - ret = EINVAL; - break; - } + ret = scr->putcmap(scr, idx, count); break; case WSDISPLAYIO_SVIDEO: @@ -1059,11 +1148,26 @@ sti_ioctl(void *v, void *vs, u_long cmd, paddr_t sti_mmap(void *v, void *vs, off_t offset, int prot) { -#if 0 struct sti_screen *scr = (struct sti_screen *)v; +#if 0 + struct sti_rom *rom = scr->scr_rom; #endif - /* XXX not finished */ - return -1; + paddr_t pa; + + if ((offset & PAGE_MASK) != 0) + return -1; + + if (offset < 0 || offset >= scr->fblen) + return -1; + +#if 0 /* XXX not all platforms provide bus_space_mmap() yet */ + pa = bus_space_mmap(rom->memt, scr->fbaddr, offset, prot, + BUS_SPACE_MAP_LINEAR); +#else + pa = scr->fbaddr + offset; +#endif + + return pa; } int @@ -1080,7 +1184,6 @@ sti_alloc_screen(void *v, const struct w *cyp = 0; sti_alloc_attr(scr, 0, 0, 0, defattr); scr->scr_nscreens++; - return 0; } @@ -1122,8 +1225,10 @@ sti_cursor(void *v, int on, int row, int struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; - sti_bmove(scr, col * fp->width, row * fp->height, col * fp->width, - row * fp->height, fp->height, fp->width, bmf_invert); + sti_bmove(scr, + col * fp->width, row * fp->height, + col * fp->width, row * fp->height, + fp->height, fp->width, bmf_invert); } /* @@ -1247,8 +1352,10 @@ sti_copycols(void *v, int row, int srcco struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; - sti_bmove(scr, srccol * fp->width, row * fp->height, dstcol * fp->width, - row * fp->height, fp->height, ncols * fp->width, bmf_copy); + sti_bmove(scr, + srccol * fp->width, row * fp->height, + dstcol * fp->width, row * fp->height, + fp->height, ncols * fp->width, bmf_copy); } void @@ -1257,9 +1364,10 @@ sti_erasecols(void *v, int row, int star struct sti_screen *scr = (struct sti_screen *)v; struct sti_font *fp = &scr->scr_curfont; - sti_bmove(scr, startcol * fp->width, row * fp->height, - startcol * fp->width, row * fp->height, fp->height, - ncols * fp->width, bmf_clear); + sti_bmove(scr, + startcol * fp->width, row * fp->height, + startcol * fp->width, row * fp->height, + fp->height, ncols * fp->width, bmf_clear); } void @@ -1333,3 +1441,185 @@ sti_cnattach(struct sti_rom *rom, struct return 0; } #endif + +int +ngle_default_putcmap(struct sti_screen *scr, u_int idx, u_int count) +{ + int i, ret; + + for (i = idx + count - 1; i >= (int)idx; i--) + if ((ret = sti_setcment(scr, i, scr->scr_rcmap[i], + scr->scr_gcmap[i], scr->scr_bcmap[i]))) + return EINVAL; + + return 0; +} + +#ifndef SMALL_KERNEL + +void ngle_setup_hw(bus_space_tag_t, bus_space_handle_t); +void ngle_setup_fb(bus_space_tag_t, bus_space_handle_t, uint32_t); +void ngle_setup_attr_planes(struct sti_screen *scr); +void ngle_setup_bt458(struct sti_screen *scr); + +#define ngle_bt458_write(memt, memh, r, v) \ + bus_space_write_4(memt, memh, NGLE_REG_RAMDAC + ((r) << 2), (v) << 24) + +void +ngle_artist_setupfb(struct sti_screen *scr) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t memh = rom->regh[2]; + + ngle_setup_bt458(scr); + + ngle_setup_hw(memt, memh); + ngle_setup_fb(memt, memh, scr->reg10_value); + + ngle_setup_attr_planes(scr); + + ngle_setup_hw(memt, memh); + bus_space_write_4(memt, memh, NGLE_REG_21, + bus_space_read_4(memt, memh, NGLE_REG_21) | 0x0a000000); + bus_space_write_4(memt, memh, NGLE_REG_27, + bus_space_read_4(memt, memh, NGLE_REG_27) | 0x00800000); +} + +void +ngle_elk_setupfb(struct sti_screen *scr) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t memh = rom->regh[2]; + + ngle_setup_bt458(scr); + + ngle_setup_hw(memt, memh); + ngle_setup_fb(memt, memh, scr->reg10_value); + + ngle_setup_attr_planes(scr); + + ngle_setup_hw(memt, memh); + /* enable overlay planes in Bt458 command register */ + ngle_bt458_write(memt, memh, 0x0c, 0x06); + ngle_bt458_write(memt, memh, 0x0e, 0x43); +} + +void +ngle_timber_setupfb(struct sti_screen *scr) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t memh = rom->regh[2]; + + ngle_setup_bt458(scr); + + ngle_setup_hw(memt, memh); + /* enable overlay planes in Bt458 command register */ + ngle_bt458_write(memt, memh, 0x0c, 0x06); + ngle_bt458_write(memt, memh, 0x0e, 0x43); +} + +void +ngle_setup_bt458(struct sti_screen *scr) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t memh = rom->regh[2]; + + ngle_setup_hw(memt, memh); + /* set Bt458 read mask register to all planes */ + ngle_bt458_write(memt, memh, 0x08, 0x04); + ngle_bt458_write(memt, memh, 0x0a, 0xff); +} + +void +ngle_setup_attr_planes(struct sti_screen *scr) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t memh = rom->regh[2]; + + ngle_setup_hw(memt, memh); + bus_space_write_4(memt, memh, NGLE_REG_11, 0x2ea0d000); + bus_space_write_4(memt, memh, NGLE_REG_14, 0x23000302); + bus_space_write_4(memt, memh, NGLE_REG_12, scr->reg12_value); + bus_space_write_4(memt, memh, NGLE_REG_8, 0xffffffff); + + bus_space_write_4(memt, memh, NGLE_REG_6, 0x00000000); + bus_space_write_4(memt, memh, NGLE_REG_9, + (scr->scr_cfg.scr_width << 16) | scr->scr_cfg.scr_height); + bus_space_write_4(memt, memh, NGLE_REG_6, 0x05000000); + bus_space_write_4(memt, memh, NGLE_REG_9, 0x00040001); + + ngle_setup_hw(memt, memh); + bus_space_write_4(memt, memh, NGLE_REG_12, 0x00000000); + + ngle_setup_fb(memt, memh, scr->reg10_value); +} + +int +ngle_putcmap(struct sti_screen *scr, u_int idx, u_int count) +{ + struct sti_rom *rom = scr->scr_rom; + bus_space_tag_t memt = rom->memt; + bus_space_handle_t memh = rom->regh[2]; + uint8_t *r, *g, *b; + uint32_t cmap_finish; + + if (scr->scr_bpp > 8) + cmap_finish = 0x83000100; + else + cmap_finish = 0x80000100; + + r = scr->scr_rcmap + idx; + g = scr->scr_gcmap + idx; + b = scr->scr_bcmap + idx; + + ngle_setup_hw(memt, memh); + bus_space_write_4(memt, memh, NGLE_REG_10, 0xbbe0f000); + bus_space_write_4(memt, memh, NGLE_REG_14, 0x03000300); + bus_space_write_4(memt, memh, NGLE_REG_13, 0xffffffff); + + while (count-- != 0) { + ngle_setup_hw(memt, memh); + bus_space_write_4(memt, memh, NGLE_REG_3, 0x400 | (idx << 2)); + bus_space_write_4(memt, memh, NGLE_REG_4, + (*r << 16) | (*g << 8) | *b); + + idx++; + r++, g++, b++; + } + + bus_space_write_4(memt, memh, NGLE_REG_2, 0x400); + bus_space_write_4(memt, memh, scr->cmap_finish_register, cmap_finish); + ngle_setup_fb(memt, memh, scr->reg10_value); + + + return 0; +} + +void +ngle_setup_hw(bus_space_tag_t memt, bus_space_handle_t memh) +{ + uint8_t stat; + + do { + stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); + if (stat == 0) + stat = bus_space_read_1(memt, memh, NGLE_REG_15b0); + } while (stat != 0); +} + +void +ngle_setup_fb(bus_space_tag_t memt, bus_space_handle_t memh, uint32_t reg10) +{ + + ngle_setup_hw(memt, memh); + bus_space_write_4(memt, memh, NGLE_REG_10, reg10); + bus_space_write_4(memt, memh, NGLE_REG_14, 0x83000300); + ngle_setup_hw(memt, memh); + bus_space_write_1(memt, memh, NGLE_REG_16b1, 1); +} +#endif /* SMALL_KERNEL */ Index: src/sys/dev/ic/stivar.h diff -u src/sys/dev/ic/stivar.h:1.10 src/sys/dev/ic/stivar.h:1.11 --- src/sys/dev/ic/stivar.h:1.10 Mon May 4 06:52:53 2020 +++ src/sys/dev/ic/stivar.h Wed Dec 23 08:34:35 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: stivar.h,v 1.10 2020/05/04 06:52:53 tsutsui Exp $ */ +/* $NetBSD: stivar.h,v 1.11 2020/12/23 08:34:35 tsutsui Exp $ */ /* $OpenBSD: stivar.h,v 1.24 2009/02/06 22:51:04 miod Exp $ */ @@ -42,11 +42,15 @@ struct sti_rom { bus_space_tag_t iot, memt; /* XXX iot unused */ bus_space_handle_t romh; + bus_space_handle_t regh[STI_REGION_MAX]; bus_addr_t *bases; struct sti_dd rom_dd; /* in word format */ - vaddr_t rom_code; + + /* + * ROM-provided function pointers + */ sti_init_t init; sti_mgmt_t mgmt; sti_unpmv_t unpmv; @@ -98,10 +102,20 @@ struct sti_screen { struct wsscreen_descr scr_wsd; const struct wsscreen_descr *scr_scrlist[1]; struct wsscreen_list scr_screenlist; + + /* + * Board-specific function data and pointers + */ + void (*setupfb)(struct sti_screen *); + int (*putcmap)(struct sti_screen *, u_int, u_int); + + uint32_t reg10_value; + uint32_t reg12_value; + bus_addr_t cmap_finish_register; }; /* - * STI Device state + * STI device state */ struct sti_softc { device_t sc_dev; @@ -134,6 +148,7 @@ u_int sti_rom_size(bus_space_tag_t, bus_ int sti_init(struct sti_screen *, int); #define STI_TEXTMODE 0x01 #define STI_CLEARSCR 0x02 +#define STI_FBMODE 0x04 int sti_ioctl(void *, void *, u_long, void *, int, struct lwp *); paddr_t sti_mmap(void *, void *, off_t, int); int sti_alloc_screen(void *, const struct wsscreen_descr *,