1*63294167Skettenis /* $OpenBSD: machfb.c,v 1.13 2022/07/15 17:57:26 kettenis Exp $ */
2f1f6d7c6Skettenis
3f1f6d7c6Skettenis /*
4f1f6d7c6Skettenis * Copyright (c) 2009 Mark Kettenis.
5f1f6d7c6Skettenis *
6f1f6d7c6Skettenis * Permission to use, copy, modify, and distribute this software for any
7f1f6d7c6Skettenis * purpose with or without fee is hereby granted, provided that the above
8f1f6d7c6Skettenis * copyright notice and this permission notice appear in all copies.
9f1f6d7c6Skettenis *
10f1f6d7c6Skettenis * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11f1f6d7c6Skettenis * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12f1f6d7c6Skettenis * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13f1f6d7c6Skettenis * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14f1f6d7c6Skettenis * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15f1f6d7c6Skettenis * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16f1f6d7c6Skettenis * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17f1f6d7c6Skettenis */
18f1f6d7c6Skettenis
19f1f6d7c6Skettenis #include <sys/param.h>
20f1f6d7c6Skettenis #include <sys/device.h>
21f1f6d7c6Skettenis #include <sys/pciio.h>
22f1f6d7c6Skettenis #include <sys/systm.h>
23f1f6d7c6Skettenis
24f1f6d7c6Skettenis #include <machine/autoconf.h>
25f1f6d7c6Skettenis #include <machine/bus.h>
26f1f6d7c6Skettenis #include <machine/openfirm.h>
27f1f6d7c6Skettenis
28f1f6d7c6Skettenis #include <dev/pci/pcireg.h>
29f1f6d7c6Skettenis #include <dev/pci/pcivar.h>
30f1f6d7c6Skettenis #include <dev/pci/pcidevs.h>
31f1f6d7c6Skettenis
32f1f6d7c6Skettenis #include <dev/wscons/wsconsio.h>
33f1f6d7c6Skettenis #include <dev/wscons/wsdisplayvar.h>
34f1f6d7c6Skettenis
35f1f6d7c6Skettenis #include <dev/rasops/rasops.h>
36f1f6d7c6Skettenis
37f1f6d7c6Skettenis #include <machine/fbvar.h>
38f1f6d7c6Skettenis
39f1f6d7c6Skettenis #define M64_PCI_MEM 0x10
40f1f6d7c6Skettenis #define M64_PCI_MMIO 0x18
41f1f6d7c6Skettenis
42f1f6d7c6Skettenis #define M64_REG_OFF 0x007ffc00
43f1f6d7c6Skettenis #define M64_REG_SIZE 0x0400
44f1f6d7c6Skettenis
45f1f6d7c6Skettenis #define M64_CRTC_INT_CNTL 0x0018
46f1f6d7c6Skettenis
47f1f6d7c6Skettenis #define M64_BUS_CNTL 0x00a0
48f1f6d7c6Skettenis #define M64_BUS_FIFO_ERR_ACK 0x00200000
49f1f6d7c6Skettenis #define M64_BUS_HOST_ERR_ACK 0x00800000
50f1f6d7c6Skettenis #define M64_BUS_APER_REG_DIS 0x00000010
51f1f6d7c6Skettenis
52f1f6d7c6Skettenis #define M64_DAC_WINDEX 0x00c0
53f1f6d7c6Skettenis #define M64_DAC_DATA 0x00c1
54f1f6d7c6Skettenis #define M64_DAC_MASK 0x00c2
55f1f6d7c6Skettenis #define M64_DAC_RINDEX 0x00c3
56f1f6d7c6Skettenis #define M64_DAC_CNTL 0x00c4
57f1f6d7c6Skettenis #define M64_DAC_8BIT_EN 0x00000100
58f1f6d7c6Skettenis
59f1f6d7c6Skettenis #define M64_GEN_TEST_CNTL 0x00d0
60f1f6d7c6Skettenis #define M64_GEN_GUI_EN 0x00000100
61f1f6d7c6Skettenis
62f1f6d7c6Skettenis #define M64_DST_OFF_PITCH 0x0100
63f1f6d7c6Skettenis #define M64_DST_X 0x0104
64f1f6d7c6Skettenis #define M64_DST_Y 0x0108
65f1f6d7c6Skettenis #define M64_DST_Y_X 0x010c
66f1f6d7c6Skettenis #define M64_DST_WIDTH 0x0110
67f1f6d7c6Skettenis #define M64_DST_HEIGHT 0x0114
68f1f6d7c6Skettenis #define M64_DST_HEIGHT_WIDTH 0x0118
69f1f6d7c6Skettenis #define M64_DST_X_WIDTH 0x011c
70f1f6d7c6Skettenis #define M64_DST_BRES_LNTH 0x0120
71f1f6d7c6Skettenis #define M64_DST_BRES_ERR 0x0124
72f1f6d7c6Skettenis #define M64_DST_BRES_INC 0x0128
73f1f6d7c6Skettenis #define M64_DST_BRES_DEC 0x012c
74f1f6d7c6Skettenis #define M64_DST_CNTL 0x0130
75f1f6d7c6Skettenis #define M64_DST_X_RIGHT_TO_LEFT 0x00000000
76f1f6d7c6Skettenis #define M64_DST_X_LEFT_TO_RIGHT 0x00000001
77f1f6d7c6Skettenis #define M64_DST_Y_BOTTOM_TO_TOP 0x00000000
78f1f6d7c6Skettenis #define M64_DST_Y_TOP_TO_BOTTOM 0x00000002
79f1f6d7c6Skettenis #define M64_DST_X_MAJOR 0x00000000
80f1f6d7c6Skettenis #define M64_DST_Y_MAJOR 0x00000004
81f1f6d7c6Skettenis #define M64_DST_X_TILE 0x00000008
82f1f6d7c6Skettenis #define M64_DST_Y_TILE 0x00000010
83f1f6d7c6Skettenis #define M64_DST_LAST_PEL 0x00000020
84f1f6d7c6Skettenis #define M64_DST_POLYGON_EN 0x00000040
85f1f6d7c6Skettenis #define M64_DST_24_ROT_EN 0x00000080
86f1f6d7c6Skettenis
87f1f6d7c6Skettenis #define M64_SRC_OFF_PITCH 0x0180
88f1f6d7c6Skettenis #define M64_SRC_X 0x0184
89f1f6d7c6Skettenis #define M64_SRC_Y 0x0188
90f1f6d7c6Skettenis #define M64_SRC_Y_X 0x018c
91f1f6d7c6Skettenis #define M64_SRC_WIDTH1 0x0190
92f1f6d7c6Skettenis #define M64_SRC_HEIGHT1 0x0194
93f1f6d7c6Skettenis #define M64_SRC_HEIGHT1_WIDTH1 0x0198
94f1f6d7c6Skettenis #define M64_SRC_X_START 0x019c
95f1f6d7c6Skettenis #define M64_SRC_Y_START 0x01a0
96f1f6d7c6Skettenis #define M64_SRC_Y_X_START 0x01a4
97f1f6d7c6Skettenis #define M64_SRC_WIDTH2 0x01a8
98f1f6d7c6Skettenis #define M64_SRC_HEIGHT2 0x01ac
99f1f6d7c6Skettenis #define M64_SRC_HEIGHT2_WIDTH2 0x01b0
100f1f6d7c6Skettenis #define M64_SRC_CNTL 0x01b4
101f1f6d7c6Skettenis #define M64_SRC_PATT_EN 0x00000001
102f1f6d7c6Skettenis #define M64_SRC_PATT_ROT_EN 0x00000002
103f1f6d7c6Skettenis #define M64_SRC_LINEAR_EN 0x00000004
104f1f6d7c6Skettenis #define M64_SRC_BYTE_ALIGN 0x00000008
105f1f6d7c6Skettenis #define M64_SRC_LINE_X_RIGHT_TO_LEFT 0x00000000
106f1f6d7c6Skettenis #define M64_SRC_LINE_X_LEFT_TO_RIGHT 0x00000010
107f1f6d7c6Skettenis
108f1f6d7c6Skettenis #define M64_HOST_CNTL 0x0240
109f1f6d7c6Skettenis
110f1f6d7c6Skettenis #define M64_PAT_REG0 0x0280
111f1f6d7c6Skettenis #define M64_PAT_REG1 0x0284
112f1f6d7c6Skettenis #define M64_PAT_CNTL 0x0288
113f1f6d7c6Skettenis
114f1f6d7c6Skettenis #define M64_SC_LEFT 0x02a0
115f1f6d7c6Skettenis #define M64_SC_RIGHT 0x02a4
116f1f6d7c6Skettenis #define M64_SC_LEFT_RIGHT 0x02a8
117f1f6d7c6Skettenis #define M64_SC_TOP 0x02ac
118f1f6d7c6Skettenis #define M64_SC_BOTTOM 0x02b0
119f1f6d7c6Skettenis #define M64_SC_TOP_BOTTOM 0x02b4
120f1f6d7c6Skettenis
121f1f6d7c6Skettenis #define M64_DP_BKGD_CLR 0x02c0
122f1f6d7c6Skettenis #define M64_DP_FRGD_CLR 0x02c4
123f1f6d7c6Skettenis #define M64_DP_WRITE_MASK 0x02c8
124f1f6d7c6Skettenis
125f1f6d7c6Skettenis #define M64_DP_CHAIN_MASK 0x02cc
126f1f6d7c6Skettenis #define M64_DP_CHAIN_8BPP 0x00008080
127f1f6d7c6Skettenis #define M64_DP_PIX_WIDTH 0x02d0
128f1f6d7c6Skettenis #define M64_DST_8BPP 0x00000002
129f1f6d7c6Skettenis #define M64_SRC_8BPP 0x00000200
130f1f6d7c6Skettenis #define M64_HOST_8BPP 0x00020000
131f1f6d7c6Skettenis #define M64_DP_MIX 0x02d4
132f1f6d7c6Skettenis #define M64_MIX_DST 0x00000003
133f1f6d7c6Skettenis #define M64_MIX_SRC 0x00000007
134f1f6d7c6Skettenis #define M64_DP_SRC 0x02d8
135f1f6d7c6Skettenis #define M64_BKGD_SRC_BKGD_CLR 0x00000000
136f1f6d7c6Skettenis #define M64_BKGD_SRC_FRGD_CLR 0x00000001
137f1f6d7c6Skettenis #define M64_BKGD_SRC_HOST 0x00000002
138f1f6d7c6Skettenis #define M64_BKGD_SRC_BLIT 0x00000003
139f1f6d7c6Skettenis #define M64_BKGD_SRC_PATTERN 0x00000004
140f1f6d7c6Skettenis #define M64_FRGD_SRC_BKGD_CLR 0x00000000
141f1f6d7c6Skettenis #define M64_FRGD_SRC_FRGD_CLR 0x00000100
142f1f6d7c6Skettenis #define M64_FRGD_SRC_HOST 0x00000200
143f1f6d7c6Skettenis #define M64_FRGD_SRC_BLIT 0x00000300
144f1f6d7c6Skettenis #define M64_FRGD_SRC_PATTERN 0x00000400
145f1f6d7c6Skettenis #define M64_MONO_SRC_ONE 0x00000000
146f1f6d7c6Skettenis #define M64_MONO_SRC_PATTERN 0x00010000
147f1f6d7c6Skettenis #define M64_MONO_SRC_HOST 0x00020000
148f1f6d7c6Skettenis #define M64_MONO_SRC_BLIT 0x00030000
149f1f6d7c6Skettenis
150f1f6d7c6Skettenis #define M64_CLR_CMP_CLR 0x0300
151f1f6d7c6Skettenis #define M64_CLR_CMP_MASK 0x0304
152f1f6d7c6Skettenis #define M64_CLR_CMP_CNTL 0x0308
153f1f6d7c6Skettenis
154f1f6d7c6Skettenis #define M64_FIFO_STAT 0x0310
155f1f6d7c6Skettenis #define M64_FIFO_STAT_MASK 0x0000ffff
156f1f6d7c6Skettenis
157f1f6d7c6Skettenis #define M64_CONTEXT_MASK 0x0320
158f1f6d7c6Skettenis
159f1f6d7c6Skettenis #define M64_GUI_TRAJ_CNTL 0x0330
160f1f6d7c6Skettenis #define M64_GUI_STAT 0x0338
161f1f6d7c6Skettenis #define M64_GUI_ACTIVE 0x00000001
162f1f6d7c6Skettenis
163f1f6d7c6Skettenis #define M64_COORDS(x, y) ((x << 16) | (y))
164f1f6d7c6Skettenis
165f1f6d7c6Skettenis #ifdef APERTURE
166f1f6d7c6Skettenis extern int allowaperture;
167f1f6d7c6Skettenis #endif
168f1f6d7c6Skettenis
169f1f6d7c6Skettenis struct machfb_softc {
170f1f6d7c6Skettenis struct sunfb sc_sunfb;
171f1f6d7c6Skettenis
172f1f6d7c6Skettenis bus_space_tag_t sc_memt;
173f1f6d7c6Skettenis bus_space_handle_t sc_memh;
174f1f6d7c6Skettenis bus_addr_t sc_membase;
175f1f6d7c6Skettenis bus_size_t sc_memsize;
176f1f6d7c6Skettenis
177f1f6d7c6Skettenis bus_space_tag_t sc_regt;
178f1f6d7c6Skettenis bus_space_handle_t sc_regh;
179f1f6d7c6Skettenis
180f1f6d7c6Skettenis bus_space_tag_t sc_mmiot;
181f1f6d7c6Skettenis bus_space_handle_t sc_mmioh;
182f1f6d7c6Skettenis bus_addr_t sc_mmiobase;
183f1f6d7c6Skettenis bus_size_t sc_mmiosize;
184f1f6d7c6Skettenis
185f1f6d7c6Skettenis pcitag_t sc_pcitag;
186f1f6d7c6Skettenis
187f1f6d7c6Skettenis int sc_mode;
188f1f6d7c6Skettenis u_int8_t sc_cmap_red[256];
189f1f6d7c6Skettenis u_int8_t sc_cmap_green[256];
190f1f6d7c6Skettenis u_int8_t sc_cmap_blue[256];
191f1f6d7c6Skettenis };
192f1f6d7c6Skettenis
193f1f6d7c6Skettenis int machfb_ioctl(void *, u_long, caddr_t, int, struct proc *);
194f1f6d7c6Skettenis paddr_t machfb_mmap(void *, off_t, int);
195f1f6d7c6Skettenis
196f1f6d7c6Skettenis struct wsdisplay_accessops machfb_accessops = {
19787eec248Smiod .ioctl = machfb_ioctl,
19887eec248Smiod .mmap = machfb_mmap
199f1f6d7c6Skettenis };
200f1f6d7c6Skettenis
201f1f6d7c6Skettenis int machfb_match(struct device *, void *, void *);
202f1f6d7c6Skettenis void machfb_attach(struct device *, struct device *, void *);
203f1f6d7c6Skettenis
204eb7eaf8dSmpi const struct cfattach machfb_ca = {
205f1f6d7c6Skettenis sizeof(struct machfb_softc), machfb_match, machfb_attach
206f1f6d7c6Skettenis };
207f1f6d7c6Skettenis
208f1f6d7c6Skettenis struct cfdriver machfb_cd = {
209f1f6d7c6Skettenis NULL, "machfb", DV_DULL
210f1f6d7c6Skettenis };
211f1f6d7c6Skettenis
212f1f6d7c6Skettenis int machfb_is_console(int);
213f1f6d7c6Skettenis int machfb_getcmap(struct machfb_softc *, struct wsdisplay_cmap *);
214f1f6d7c6Skettenis int machfb_putcmap(struct machfb_softc *, struct wsdisplay_cmap *);
215f1f6d7c6Skettenis void machfb_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
216f1f6d7c6Skettenis
217072953e3Smiod int machfb_copycols(void *, int, int, int, int);
218e0c3e559Sjsg int machfb_erasecols(void *, int, int, int, uint32_t);
219072953e3Smiod int machfb_copyrows(void *, int, int, int);
220e0c3e559Sjsg int machfb_eraserows(void *, int, int, uint32_t);
221f1f6d7c6Skettenis
222f1f6d7c6Skettenis void machfb_init(struct machfb_softc *);
223f1f6d7c6Skettenis int machfb_wait_fifo(struct machfb_softc *, int);
224f1f6d7c6Skettenis int machfb_wait(struct machfb_softc *);
225f1f6d7c6Skettenis void machfb_copyrect(struct machfb_softc *, int, int, int, int, int, int);
226f1f6d7c6Skettenis void machfb_fillrect(struct machfb_softc *, int, int, int, int, int);
227f1f6d7c6Skettenis
228f1f6d7c6Skettenis int
machfb_match(struct device * parent,void * cf,void * aux)229f1f6d7c6Skettenis machfb_match(struct device *parent, void *cf, void *aux)
230f1f6d7c6Skettenis {
231f1f6d7c6Skettenis struct pci_attach_args *pa = aux;
232f1f6d7c6Skettenis char buf[32];
233f1f6d7c6Skettenis int node;
234f1f6d7c6Skettenis
235f1f6d7c6Skettenis node = PCITAG_NODE(pa->pa_tag);
236f1f6d7c6Skettenis OF_getprop(node, "name", buf, sizeof(buf));
237f1f6d7c6Skettenis if (strcmp(buf, "SUNW,m64B") == 0)
238f1f6d7c6Skettenis return (10);
239f1f6d7c6Skettenis
240f1f6d7c6Skettenis if (OF_getprop(node, "compatible", buf, sizeof(buf)) > 0 &&
241f1f6d7c6Skettenis strcmp(buf, "SUNW,m64B") == 0)
242f1f6d7c6Skettenis return (10);
243f1f6d7c6Skettenis
244f1f6d7c6Skettenis return (0);
245f1f6d7c6Skettenis }
246f1f6d7c6Skettenis
247f1f6d7c6Skettenis void
machfb_attach(struct device * parent,struct device * self,void * aux)248f1f6d7c6Skettenis machfb_attach(struct device *parent, struct device *self, void *aux)
249f1f6d7c6Skettenis {
250f1f6d7c6Skettenis struct machfb_softc *sc = (struct machfb_softc *)self;
251f1f6d7c6Skettenis struct pci_attach_args *pa = aux;
252f1f6d7c6Skettenis struct rasops_info *ri;
253f1f6d7c6Skettenis int node, console;
254f1f6d7c6Skettenis char *model;
255f1f6d7c6Skettenis
256f1f6d7c6Skettenis sc->sc_pcitag = pa->pa_tag;
257f1f6d7c6Skettenis
258f1f6d7c6Skettenis node = PCITAG_NODE(pa->pa_tag);
259f1f6d7c6Skettenis console = machfb_is_console(node);
260f1f6d7c6Skettenis
261f1f6d7c6Skettenis printf("\n");
262f1f6d7c6Skettenis
263f1f6d7c6Skettenis model = getpropstring(node, "model");
264f1f6d7c6Skettenis printf("%s: %s", self->dv_xname, model);
265f1f6d7c6Skettenis
266f1f6d7c6Skettenis if (pci_mapreg_map(pa, M64_PCI_MEM, PCI_MAPREG_TYPE_MEM,
267f1f6d7c6Skettenis BUS_SPACE_MAP_LINEAR, &sc->sc_memt, &sc->sc_memh,
268f1f6d7c6Skettenis &sc->sc_membase, &sc->sc_memsize, 0)) {
269f1f6d7c6Skettenis printf("\n%s: can't map video memory\n", self->dv_xname);
270f1f6d7c6Skettenis return;
271f1f6d7c6Skettenis }
272f1f6d7c6Skettenis
273f1f6d7c6Skettenis sc->sc_regt = sc->sc_memt;
274f1f6d7c6Skettenis if (bus_space_subregion(sc->sc_memt, sc->sc_memh,
275f1f6d7c6Skettenis M64_REG_OFF, M64_REG_SIZE, &sc->sc_regh)) {
276f1f6d7c6Skettenis printf("\n%s: can't map registers\n", self->dv_xname);
277f1f6d7c6Skettenis return;
278f1f6d7c6Skettenis }
279f1f6d7c6Skettenis
280f1f6d7c6Skettenis if (pci_mapreg_map(pa, M64_PCI_MMIO, PCI_MAPREG_TYPE_MEM, 0,
281f1f6d7c6Skettenis &sc->sc_mmiot, &sc->sc_mmioh, &sc->sc_mmiobase,
282f1f6d7c6Skettenis &sc->sc_mmiosize, 0)) {
283f1f6d7c6Skettenis printf("\n%s: can't map registers\n", self->dv_xname);
284f1f6d7c6Skettenis return;
285f1f6d7c6Skettenis }
286f1f6d7c6Skettenis
287f1f6d7c6Skettenis fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
288f1f6d7c6Skettenis if (sc->sc_sunfb.sf_depth == 24) {
289f1f6d7c6Skettenis sc->sc_sunfb.sf_depth = 32;
290f1f6d7c6Skettenis sc->sc_sunfb.sf_linebytes =
291f1f6d7c6Skettenis (sc->sc_sunfb.sf_depth / 8) * sc->sc_sunfb.sf_width;
292f1f6d7c6Skettenis sc->sc_sunfb.sf_fbsize =
293f1f6d7c6Skettenis sc->sc_sunfb.sf_height * sc->sc_sunfb.sf_linebytes;
294f1f6d7c6Skettenis }
295f1f6d7c6Skettenis
296f1f6d7c6Skettenis printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
297f1f6d7c6Skettenis
2983809ecbaSjsg #ifdef RAMDISK_HOOKS
2996de07763Skettenis printf("%s: aperture needed\n", self->dv_xname);
3006de07763Skettenis #endif
3016de07763Skettenis
302f1f6d7c6Skettenis ri = &sc->sc_sunfb.sf_ro;
303f1f6d7c6Skettenis ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
304f1f6d7c6Skettenis ri->ri_hw = sc;
305f1f6d7c6Skettenis
306f1f6d7c6Skettenis fbwscons_init(&sc->sc_sunfb, RI_BSWAP, console);
307f1f6d7c6Skettenis fbwscons_setcolormap(&sc->sc_sunfb, machfb_setcolor);
308f1f6d7c6Skettenis sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
309f1f6d7c6Skettenis
310f1f6d7c6Skettenis machfb_init(sc);
311f1f6d7c6Skettenis ri->ri_ops.copyrows = machfb_copyrows;
312f1f6d7c6Skettenis ri->ri_ops.copycols = machfb_copycols;
313f1f6d7c6Skettenis ri->ri_ops.eraserows = machfb_eraserows;
314f1f6d7c6Skettenis ri->ri_ops.erasecols = machfb_erasecols;
315f1f6d7c6Skettenis
316f1f6d7c6Skettenis if (console)
317f1f6d7c6Skettenis fbwscons_console_init(&sc->sc_sunfb, -1);
318f1f6d7c6Skettenis fbwscons_attach(&sc->sc_sunfb, &machfb_accessops, console);
319f1f6d7c6Skettenis }
320f1f6d7c6Skettenis
321f1f6d7c6Skettenis int
machfb_ioctl(void * v,u_long cmd,caddr_t data,int flags,struct proc * p)322f1f6d7c6Skettenis machfb_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
323f1f6d7c6Skettenis {
324f1f6d7c6Skettenis struct machfb_softc *sc = v;
325f1f6d7c6Skettenis struct wsdisplay_fbinfo *wdf;
326f1f6d7c6Skettenis struct pcisel *sel;
327f1f6d7c6Skettenis
328f1f6d7c6Skettenis switch (cmd) {
329f1f6d7c6Skettenis case WSDISPLAYIO_GTYPE:
330b1fcb574Skettenis *(u_int *)data = WSDISPLAY_TYPE_MACHFB;
331f1f6d7c6Skettenis break;
332f1f6d7c6Skettenis case WSDISPLAYIO_SMODE:
333f1f6d7c6Skettenis sc->sc_mode = *(u_int *)data;
334b54ada20Skettenis if (sc->sc_mode == WSDISPLAYIO_MODE_EMUL) {
335b54ada20Skettenis struct rasops_info *ri = &sc->sc_sunfb.sf_ro;
336b54ada20Skettenis
337b54ada20Skettenis /* Restore colormap. */
338f1f6d7c6Skettenis fbwscons_setcolormap(&sc->sc_sunfb, machfb_setcolor);
339b54ada20Skettenis
340b54ada20Skettenis /* Clear screen. */
341b54ada20Skettenis machfb_fillrect(sc, 0, 0, ri->ri_width, ri->ri_height,
342b54ada20Skettenis ri->ri_devcmap[WSCOL_WHITE]);
343b54ada20Skettenis }
344f1f6d7c6Skettenis break;
345f1f6d7c6Skettenis case WSDISPLAYIO_GINFO:
346f1f6d7c6Skettenis wdf = (void *)data;
347f1f6d7c6Skettenis wdf->height = sc->sc_sunfb.sf_height;
348f1f6d7c6Skettenis wdf->width = sc->sc_sunfb.sf_width;
349f1f6d7c6Skettenis wdf->depth = sc->sc_sunfb.sf_depth;
350*63294167Skettenis wdf->stride = sc->sc_sunfb.sf_linebytes;
351*63294167Skettenis wdf->offset = 0;
352f1f6d7c6Skettenis wdf->cmsize = 256;
353f1f6d7c6Skettenis break;
354f1f6d7c6Skettenis case WSDISPLAYIO_LINEBYTES:
355f1f6d7c6Skettenis *(u_int *)data = sc->sc_sunfb.sf_linebytes;
356f1f6d7c6Skettenis break;
357f1f6d7c6Skettenis
358f1f6d7c6Skettenis case WSDISPLAYIO_GETCMAP:
359f1f6d7c6Skettenis return machfb_getcmap(sc, (struct wsdisplay_cmap *)data);
360f1f6d7c6Skettenis case WSDISPLAYIO_PUTCMAP:
361f1f6d7c6Skettenis return machfb_putcmap(sc, (struct wsdisplay_cmap *)data);
362f1f6d7c6Skettenis
363f1f6d7c6Skettenis case WSDISPLAYIO_GPCIID:
364f1f6d7c6Skettenis sel = (struct pcisel *)data;
365f1f6d7c6Skettenis sel->pc_bus = PCITAG_BUS(sc->sc_pcitag);
366f1f6d7c6Skettenis sel->pc_dev = PCITAG_DEV(sc->sc_pcitag);
367f1f6d7c6Skettenis sel->pc_func = PCITAG_FUN(sc->sc_pcitag);
368f1f6d7c6Skettenis break;
369f1f6d7c6Skettenis
370f1f6d7c6Skettenis case WSDISPLAYIO_SVIDEO:
371f1f6d7c6Skettenis case WSDISPLAYIO_GVIDEO:
372f1f6d7c6Skettenis break;
373f1f6d7c6Skettenis
374f1f6d7c6Skettenis case WSDISPLAYIO_GCURPOS:
375f1f6d7c6Skettenis case WSDISPLAYIO_SCURPOS:
376f1f6d7c6Skettenis case WSDISPLAYIO_GCURMAX:
377f1f6d7c6Skettenis case WSDISPLAYIO_GCURSOR:
378f1f6d7c6Skettenis case WSDISPLAYIO_SCURSOR:
379f1f6d7c6Skettenis default:
380f1f6d7c6Skettenis return -1; /* not supported yet */
381f1f6d7c6Skettenis }
382f1f6d7c6Skettenis
383f1f6d7c6Skettenis return (0);
384f1f6d7c6Skettenis }
385f1f6d7c6Skettenis
386f1f6d7c6Skettenis paddr_t
machfb_mmap(void * v,off_t off,int prot)387f1f6d7c6Skettenis machfb_mmap(void *v, off_t off, int prot)
388f1f6d7c6Skettenis {
389f1f6d7c6Skettenis struct machfb_softc *sc = v;
390f1f6d7c6Skettenis
391f1f6d7c6Skettenis if (off & PGOFSET)
392f1f6d7c6Skettenis return (-1);
393f1f6d7c6Skettenis
394f1f6d7c6Skettenis switch (sc->sc_mode) {
395f1f6d7c6Skettenis case WSDISPLAYIO_MODE_MAPPED:
396f1f6d7c6Skettenis #ifdef APERTURE
397f1f6d7c6Skettenis if (allowaperture == 0)
398f1f6d7c6Skettenis return (-1);
399f1f6d7c6Skettenis #endif
400f1f6d7c6Skettenis
401f1f6d7c6Skettenis if (sc->sc_mmiosize == 0)
402f1f6d7c6Skettenis return (-1);
403f1f6d7c6Skettenis
404f1f6d7c6Skettenis if (off >= sc->sc_membase &&
405f1f6d7c6Skettenis off < (sc->sc_membase + sc->sc_memsize))
406f1f6d7c6Skettenis return (bus_space_mmap(sc->sc_memt,
407f1f6d7c6Skettenis sc->sc_membase, off - sc->sc_membase,
408f1f6d7c6Skettenis prot, BUS_SPACE_MAP_LINEAR));
409f1f6d7c6Skettenis
410f1f6d7c6Skettenis if (off >= sc->sc_mmiobase &&
411f1f6d7c6Skettenis off < (sc->sc_mmiobase + sc->sc_mmiosize))
412f1f6d7c6Skettenis return (bus_space_mmap(sc->sc_mmiot,
413f1f6d7c6Skettenis sc->sc_mmiobase, off - sc->sc_mmiobase,
414f1f6d7c6Skettenis prot, BUS_SPACE_MAP_LINEAR));
415f1f6d7c6Skettenis break;
416f1f6d7c6Skettenis
417f1f6d7c6Skettenis case WSDISPLAYIO_MODE_DUMBFB:
418f1f6d7c6Skettenis if (off >= 0 && off < sc->sc_memsize)
419f1f6d7c6Skettenis return (bus_space_mmap(sc->sc_memt, sc->sc_membase,
420f1f6d7c6Skettenis off, prot, BUS_SPACE_MAP_LINEAR));
421f1f6d7c6Skettenis break;
422f1f6d7c6Skettenis }
423f1f6d7c6Skettenis
424f1f6d7c6Skettenis return (-1);
425f1f6d7c6Skettenis }
426f1f6d7c6Skettenis
427f1f6d7c6Skettenis int
machfb_is_console(int node)428f1f6d7c6Skettenis machfb_is_console(int node)
429f1f6d7c6Skettenis {
430f1f6d7c6Skettenis extern int fbnode;
431f1f6d7c6Skettenis
432f1f6d7c6Skettenis return (fbnode == node);
433f1f6d7c6Skettenis }
434f1f6d7c6Skettenis
435f1f6d7c6Skettenis int
machfb_getcmap(struct machfb_softc * sc,struct wsdisplay_cmap * cm)436f1f6d7c6Skettenis machfb_getcmap(struct machfb_softc *sc, struct wsdisplay_cmap *cm)
437f1f6d7c6Skettenis {
438f1f6d7c6Skettenis u_int index = cm->index;
439f1f6d7c6Skettenis u_int count = cm->count;
440f1f6d7c6Skettenis int error;
441f1f6d7c6Skettenis
442f1f6d7c6Skettenis if (index >= 256 || count > 256 - index)
443f1f6d7c6Skettenis return (EINVAL);
444f1f6d7c6Skettenis
445f1f6d7c6Skettenis error = copyout(&sc->sc_cmap_red[index], cm->red, count);
446f1f6d7c6Skettenis if (error)
447f1f6d7c6Skettenis return (error);
448f1f6d7c6Skettenis error = copyout(&sc->sc_cmap_green[index], cm->green, count);
449f1f6d7c6Skettenis if (error)
450f1f6d7c6Skettenis return (error);
451f1f6d7c6Skettenis error = copyout(&sc->sc_cmap_blue[index], cm->blue, count);
452f1f6d7c6Skettenis if (error)
453f1f6d7c6Skettenis return (error);
454f1f6d7c6Skettenis return (0);
455f1f6d7c6Skettenis }
456f1f6d7c6Skettenis
457f1f6d7c6Skettenis int
machfb_putcmap(struct machfb_softc * sc,struct wsdisplay_cmap * cm)458f1f6d7c6Skettenis machfb_putcmap(struct machfb_softc *sc, struct wsdisplay_cmap *cm)
459f1f6d7c6Skettenis {
460f1f6d7c6Skettenis u_int index = cm->index;
461f1f6d7c6Skettenis u_int count = cm->count;
462f1f6d7c6Skettenis u_int i;
463f1f6d7c6Skettenis int error;
464f1f6d7c6Skettenis u_char *r, *g, *b;
465f1f6d7c6Skettenis
466f1f6d7c6Skettenis if (index >= 256 || count > 256 - index)
467f1f6d7c6Skettenis return (EINVAL);
468f1f6d7c6Skettenis
469f1f6d7c6Skettenis if ((error = copyin(cm->red, &sc->sc_cmap_red[index], count)) != 0)
470f1f6d7c6Skettenis return (error);
471f1f6d7c6Skettenis if ((error = copyin(cm->green, &sc->sc_cmap_green[index], count)) != 0)
472f1f6d7c6Skettenis return (error);
473f1f6d7c6Skettenis if ((error = copyin(cm->blue, &sc->sc_cmap_blue[index], count)) != 0)
474f1f6d7c6Skettenis return (error);
475f1f6d7c6Skettenis
476f1f6d7c6Skettenis r = &sc->sc_cmap_red[index];
477f1f6d7c6Skettenis g = &sc->sc_cmap_green[index];
478f1f6d7c6Skettenis b = &sc->sc_cmap_blue[index];
479f1f6d7c6Skettenis
480f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh, M64_DAC_MASK, 0xff);
481b8209d5eSkettenis bus_space_write_1(sc->sc_regt, sc->sc_regh, M64_DAC_WINDEX, index);
482f1f6d7c6Skettenis for (i = 0; i < count; i++) {
483f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh,
484f1f6d7c6Skettenis M64_DAC_DATA, *r);
485f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh,
486f1f6d7c6Skettenis M64_DAC_DATA, *g);
487f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh,
488f1f6d7c6Skettenis M64_DAC_DATA, *b);
489b8209d5eSkettenis r++, g++, b++;
490f1f6d7c6Skettenis }
491f1f6d7c6Skettenis return (0);
492f1f6d7c6Skettenis }
493f1f6d7c6Skettenis
494f1f6d7c6Skettenis void
machfb_setcolor(void * v,u_int index,u_int8_t r,u_int8_t g,u_int8_t b)495f1f6d7c6Skettenis machfb_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
496f1f6d7c6Skettenis {
497f1f6d7c6Skettenis struct machfb_softc *sc = v;
498f1f6d7c6Skettenis
499f1f6d7c6Skettenis sc->sc_cmap_red[index] = r;
500f1f6d7c6Skettenis sc->sc_cmap_green[index] = g;
501f1f6d7c6Skettenis sc->sc_cmap_blue[index] = b;
502f1f6d7c6Skettenis
503f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh, M64_DAC_MASK, 0xff);
504f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh, M64_DAC_WINDEX, index);
505f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh, M64_DAC_DATA, r);
506f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh, M64_DAC_DATA, g);
507f1f6d7c6Skettenis bus_space_write_1(sc->sc_regt, sc->sc_regh, M64_DAC_DATA, b);
508f1f6d7c6Skettenis }
509f1f6d7c6Skettenis
510f1f6d7c6Skettenis /*
511f1f6d7c6Skettenis * Accelerated routines.
512f1f6d7c6Skettenis */
513f1f6d7c6Skettenis
514072953e3Smiod int
machfb_copycols(void * cookie,int row,int src,int dst,int num)515f1f6d7c6Skettenis machfb_copycols(void *cookie, int row, int src, int dst, int num)
516f1f6d7c6Skettenis {
517f1f6d7c6Skettenis struct rasops_info *ri = cookie;
518f1f6d7c6Skettenis struct machfb_softc *sc = ri->ri_hw;
519f1f6d7c6Skettenis
520f1f6d7c6Skettenis num *= ri->ri_font->fontwidth;
521f1f6d7c6Skettenis src *= ri->ri_font->fontwidth;
522f1f6d7c6Skettenis dst *= ri->ri_font->fontwidth;
523f1f6d7c6Skettenis row *= ri->ri_font->fontheight;
524f1f6d7c6Skettenis
525f1f6d7c6Skettenis machfb_copyrect(sc, ri->ri_xorigin + src, ri->ri_yorigin + row,
526f1f6d7c6Skettenis ri->ri_xorigin + dst, ri->ri_yorigin + row,
527f1f6d7c6Skettenis num, ri->ri_font->fontheight);
528072953e3Smiod
529072953e3Smiod return 0;
530f1f6d7c6Skettenis }
531f1f6d7c6Skettenis
532072953e3Smiod int
machfb_erasecols(void * cookie,int row,int col,int num,uint32_t attr)533e0c3e559Sjsg machfb_erasecols(void *cookie, int row, int col, int num, uint32_t attr)
534f1f6d7c6Skettenis {
535f1f6d7c6Skettenis struct rasops_info *ri = cookie;
536f1f6d7c6Skettenis struct machfb_softc *sc = ri->ri_hw;
537f1f6d7c6Skettenis int bg, fg;
538f1f6d7c6Skettenis
539f1f6d7c6Skettenis ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
540f1f6d7c6Skettenis
541f1f6d7c6Skettenis row *= ri->ri_font->fontheight;
542f1f6d7c6Skettenis col *= ri->ri_font->fontwidth;
543f1f6d7c6Skettenis num *= ri->ri_font->fontwidth;
544f1f6d7c6Skettenis
545f1f6d7c6Skettenis machfb_fillrect(sc, ri->ri_xorigin + col, ri->ri_yorigin + row,
546f1f6d7c6Skettenis num, ri->ri_font->fontheight, ri->ri_devcmap[bg]);
547072953e3Smiod
548072953e3Smiod return 0;
549f1f6d7c6Skettenis }
550f1f6d7c6Skettenis
551072953e3Smiod int
machfb_copyrows(void * cookie,int src,int dst,int num)552f1f6d7c6Skettenis machfb_copyrows(void *cookie, int src, int dst, int num)
553f1f6d7c6Skettenis {
554f1f6d7c6Skettenis struct rasops_info *ri = cookie;
555f1f6d7c6Skettenis struct machfb_softc *sc = ri->ri_hw;
556f1f6d7c6Skettenis
557f1f6d7c6Skettenis num *= ri->ri_font->fontheight;
558f1f6d7c6Skettenis src *= ri->ri_font->fontheight;
559f1f6d7c6Skettenis dst *= ri->ri_font->fontheight;
560f1f6d7c6Skettenis
561f1f6d7c6Skettenis machfb_copyrect(sc, ri->ri_xorigin, ri->ri_yorigin + src,
562f1f6d7c6Skettenis ri->ri_xorigin, ri->ri_yorigin + dst, ri->ri_emuwidth, num);
563072953e3Smiod
564072953e3Smiod return 0;
565f1f6d7c6Skettenis }
566f1f6d7c6Skettenis
567072953e3Smiod int
machfb_eraserows(void * cookie,int row,int num,uint32_t attr)568e0c3e559Sjsg machfb_eraserows(void *cookie, int row, int num, uint32_t attr)
569f1f6d7c6Skettenis {
570f1f6d7c6Skettenis struct rasops_info *ri = cookie;
571f1f6d7c6Skettenis struct machfb_softc *sc = ri->ri_hw;
572f1f6d7c6Skettenis int bg, fg;
573f1f6d7c6Skettenis int x, y, w;
574f1f6d7c6Skettenis
575f1f6d7c6Skettenis ri->ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL);
576f1f6d7c6Skettenis
577f1f6d7c6Skettenis if ((num == ri->ri_rows) && ISSET(ri->ri_flg, RI_FULLCLEAR)) {
578f1f6d7c6Skettenis num = ri->ri_height;
579f1f6d7c6Skettenis x = y = 0;
580f1f6d7c6Skettenis w = ri->ri_width;
581f1f6d7c6Skettenis } else {
582f1f6d7c6Skettenis num *= ri->ri_font->fontheight;
583f1f6d7c6Skettenis x = ri->ri_xorigin;
584f1f6d7c6Skettenis y = ri->ri_yorigin + row * ri->ri_font->fontheight;
585f1f6d7c6Skettenis w = ri->ri_emuwidth;
586f1f6d7c6Skettenis }
587f1f6d7c6Skettenis machfb_fillrect(sc, x, y, w, num, ri->ri_devcmap[bg]);
588072953e3Smiod
589072953e3Smiod return 0;
590f1f6d7c6Skettenis }
591f1f6d7c6Skettenis
592f1f6d7c6Skettenis void
machfb_init(struct machfb_softc * sc)593f1f6d7c6Skettenis machfb_init(struct machfb_softc *sc)
594f1f6d7c6Skettenis {
595f1f6d7c6Skettenis uint32_t reg;
596f1f6d7c6Skettenis
597f1f6d7c6Skettenis /* Reset engine. */
598f1f6d7c6Skettenis reg = bus_space_read_4(sc->sc_regt, sc->sc_regh, M64_GEN_TEST_CNTL);
599f1f6d7c6Skettenis reg &= ~M64_GEN_GUI_EN;
600f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_GEN_TEST_CNTL, reg);
601f1f6d7c6Skettenis
602f1f6d7c6Skettenis /* Enable engine. */
603f1f6d7c6Skettenis reg = bus_space_read_4(sc->sc_regt, sc->sc_regh, M64_GEN_TEST_CNTL);
604f1f6d7c6Skettenis reg &= M64_GEN_GUI_EN;
605f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_GEN_TEST_CNTL, reg);
606f1f6d7c6Skettenis
607f1f6d7c6Skettenis /* Clearing any FIFO or host errors. */
608f1f6d7c6Skettenis reg = bus_space_read_4(sc->sc_regt, sc->sc_regh, M64_BUS_CNTL);
609f1f6d7c6Skettenis reg |= M64_BUS_HOST_ERR_ACK | M64_BUS_FIFO_ERR_ACK;
610f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_BUS_CNTL, reg);
611f1f6d7c6Skettenis
612f1f6d7c6Skettenis machfb_wait_fifo(sc, 14);
613f1f6d7c6Skettenis
614f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
615f1f6d7c6Skettenis M64_CONTEXT_MASK, 0xffffffff);
616f1f6d7c6Skettenis
617f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_OFF_PITCH,
618f1f6d7c6Skettenis (sc->sc_sunfb.sf_linebytes / 8) << 22);
619f1f6d7c6Skettenis
620f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_Y_X, 0);
621f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_HEIGHT, 0);
622f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_BRES_ERR, 0);
623f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_BRES_INC, 0);
624f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_BRES_DEC, 0);
625f1f6d7c6Skettenis
626f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_CNTL,
627f1f6d7c6Skettenis M64_DST_LAST_PEL | M64_DST_X_LEFT_TO_RIGHT |
628f1f6d7c6Skettenis M64_DST_Y_TOP_TO_BOTTOM);
629f1f6d7c6Skettenis
630f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SRC_OFF_PITCH,
631f1f6d7c6Skettenis (sc->sc_sunfb.sf_linebytes / 8) << 22);
632f1f6d7c6Skettenis
633f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SRC_Y_X, 0);
634f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
635f1f6d7c6Skettenis M64_SRC_HEIGHT1_WIDTH1, 1);
636f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SRC_Y_X_START, 0);
637f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
638f1f6d7c6Skettenis M64_SRC_HEIGHT2_WIDTH2, 1);
639f1f6d7c6Skettenis
640f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SRC_CNTL,
641f1f6d7c6Skettenis M64_SRC_LINE_X_LEFT_TO_RIGHT);
642f1f6d7c6Skettenis
643f1f6d7c6Skettenis machfb_wait_fifo(sc, 13);
644f1f6d7c6Skettenis
645f1f6d7c6Skettenis /* Host attributes. */
646f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_HOST_CNTL, 0);
647f1f6d7c6Skettenis
648f1f6d7c6Skettenis /* Pattern attributes. */
649f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_PAT_REG0, 0);
650f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_PAT_REG1, 0);
651f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_PAT_CNTL, 0);
652f1f6d7c6Skettenis
653f1f6d7c6Skettenis /* Scissors. */
654f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SC_LEFT, 0);
655f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SC_TOP, 0);
656f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SC_BOTTOM,
657f1f6d7c6Skettenis sc->sc_sunfb.sf_height - 1);
658f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SC_RIGHT,
659f1f6d7c6Skettenis sc->sc_sunfb.sf_linebytes - 1);
660f1f6d7c6Skettenis
661f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DP_BKGD_CLR, 0);
662f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
663f1f6d7c6Skettenis M64_DP_FRGD_CLR, 0xffffffff);
664f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
665f1f6d7c6Skettenis M64_DP_WRITE_MASK, 0xffffffff);
666f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
667f1f6d7c6Skettenis M64_DP_MIX, (M64_MIX_SRC << 16) | M64_MIX_DST);
668f1f6d7c6Skettenis
669f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
670f1f6d7c6Skettenis M64_DP_SRC, M64_FRGD_SRC_FRGD_CLR);
671f1f6d7c6Skettenis
672f1f6d7c6Skettenis machfb_wait_fifo(sc, 3);
673f1f6d7c6Skettenis
674f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_CLR_CMP_CLR, 0);
675f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
676f1f6d7c6Skettenis M64_CLR_CMP_MASK, 0xffffffff);
677f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_CLR_CMP_CNTL, 0);
678f1f6d7c6Skettenis
679f1f6d7c6Skettenis machfb_wait_fifo(sc, 3);
680f1f6d7c6Skettenis
681f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DP_PIX_WIDTH,
682f1f6d7c6Skettenis M64_HOST_8BPP | M64_SRC_8BPP | M64_DST_8BPP);
683f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DP_CHAIN_MASK,
684f1f6d7c6Skettenis M64_DP_CHAIN_8BPP);
685f1f6d7c6Skettenis
686f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_GUI_TRAJ_CNTL,
687f1f6d7c6Skettenis M64_DST_X_LEFT_TO_RIGHT | M64_DST_Y_TOP_TO_BOTTOM);
688f1f6d7c6Skettenis
689f1f6d7c6Skettenis machfb_wait(sc);
690f1f6d7c6Skettenis }
691f1f6d7c6Skettenis
692f1f6d7c6Skettenis int
machfb_wait_fifo(struct machfb_softc * sc,int v)693f1f6d7c6Skettenis machfb_wait_fifo(struct machfb_softc *sc, int v)
694f1f6d7c6Skettenis {
695f1f6d7c6Skettenis int i;
696f1f6d7c6Skettenis
697f1f6d7c6Skettenis for (i = 1000000; i != 0; i--) {
698f1f6d7c6Skettenis if ((bus_space_read_4(sc->sc_regt, sc->sc_regh,
699f1f6d7c6Skettenis M64_FIFO_STAT) & M64_FIFO_STAT_MASK) <= (0x8000 >> v))
700f1f6d7c6Skettenis break;
701f1f6d7c6Skettenis DELAY(1);
702f1f6d7c6Skettenis }
703f1f6d7c6Skettenis
704f1f6d7c6Skettenis return i;
705f1f6d7c6Skettenis }
706f1f6d7c6Skettenis
707f1f6d7c6Skettenis int
machfb_wait(struct machfb_softc * sc)708f1f6d7c6Skettenis machfb_wait(struct machfb_softc *sc)
709f1f6d7c6Skettenis {
710f1f6d7c6Skettenis int i;
711f1f6d7c6Skettenis
712f1f6d7c6Skettenis machfb_wait_fifo(sc, 16);
713f1f6d7c6Skettenis for (i = 1000000; i != 0; i--) {
714f1f6d7c6Skettenis if ((bus_space_read_4(sc->sc_regt, sc->sc_regh,
715f1f6d7c6Skettenis M64_GUI_STAT) & M64_GUI_ACTIVE) == 0)
716f1f6d7c6Skettenis break;
717f1f6d7c6Skettenis DELAY(1);
718f1f6d7c6Skettenis }
719f1f6d7c6Skettenis
720f1f6d7c6Skettenis return i;
721f1f6d7c6Skettenis }
722f1f6d7c6Skettenis
723f1f6d7c6Skettenis void
machfb_copyrect(struct machfb_softc * sc,int sx,int sy,int dx,int dy,int w,int h)724f1f6d7c6Skettenis machfb_copyrect(struct machfb_softc *sc, int sx, int sy, int dx, int dy,
725f1f6d7c6Skettenis int w, int h)
726f1f6d7c6Skettenis {
727f1f6d7c6Skettenis uint32_t dest_ctl = 0;
728f1f6d7c6Skettenis
729f1f6d7c6Skettenis machfb_wait_fifo(sc, 10);
730f1f6d7c6Skettenis
731f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
732f1f6d7c6Skettenis M64_DP_WRITE_MASK, 0xff);
733f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
734f1f6d7c6Skettenis M64_DP_SRC, M64_FRGD_SRC_BLIT);
735f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
736f1f6d7c6Skettenis M64_DP_MIX, M64_MIX_SRC << 16);
737f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_CLR_CMP_CNTL, 0);
738f1f6d7c6Skettenis if (dy < sy) {
739f1f6d7c6Skettenis dest_ctl = M64_DST_Y_TOP_TO_BOTTOM;
740f1f6d7c6Skettenis } else {
741f1f6d7c6Skettenis sy += h - 1;
742f1f6d7c6Skettenis dy += h - 1;
743f1f6d7c6Skettenis dest_ctl = M64_DST_Y_BOTTOM_TO_TOP;
744f1f6d7c6Skettenis }
745f1f6d7c6Skettenis if (dx < sx) {
746f1f6d7c6Skettenis dest_ctl |= M64_DST_X_LEFT_TO_RIGHT;
747f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
748f1f6d7c6Skettenis M64_SRC_CNTL, M64_SRC_LINE_X_LEFT_TO_RIGHT);
749f1f6d7c6Skettenis } else {
750f1f6d7c6Skettenis dest_ctl |= M64_DST_X_RIGHT_TO_LEFT;
751f1f6d7c6Skettenis sx += w - 1;
752f1f6d7c6Skettenis dx += w - 1;
753f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
754f1f6d7c6Skettenis M64_SRC_CNTL, M64_SRC_LINE_X_RIGHT_TO_LEFT);
755f1f6d7c6Skettenis }
756f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DST_CNTL, dest_ctl);
757f1f6d7c6Skettenis
758f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
759f1f6d7c6Skettenis M64_SRC_Y_X, M64_COORDS(sx, sy));
760f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SRC_WIDTH1, w);
761f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
762f1f6d7c6Skettenis M64_DST_Y_X, M64_COORDS(dx, dy));
763f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
764f1f6d7c6Skettenis M64_DST_HEIGHT_WIDTH, M64_COORDS(w, h));
765f1f6d7c6Skettenis
766f1f6d7c6Skettenis machfb_wait(sc);
767f1f6d7c6Skettenis }
768f1f6d7c6Skettenis
769f1f6d7c6Skettenis void
machfb_fillrect(struct machfb_softc * sc,int x,int y,int w,int h,int color)770f1f6d7c6Skettenis machfb_fillrect(struct machfb_softc *sc, int x, int y, int w, int h, int color)
771f1f6d7c6Skettenis {
772f1f6d7c6Skettenis machfb_wait_fifo(sc, 11);
773f1f6d7c6Skettenis
774f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
775f1f6d7c6Skettenis M64_DP_WRITE_MASK, 0xff);
776f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_DP_FRGD_CLR, color);
777f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
778f1f6d7c6Skettenis M64_DP_SRC, M64_FRGD_SRC_FRGD_CLR);
779f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
780f1f6d7c6Skettenis M64_DP_MIX, M64_MIX_SRC << 16);
781f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_CLR_CMP_CNTL, 0);
782f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
783f1f6d7c6Skettenis M64_SRC_CNTL, M64_SRC_LINE_X_LEFT_TO_RIGHT);
784f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
785f1f6d7c6Skettenis M64_DST_CNTL, M64_DST_X_LEFT_TO_RIGHT | M64_DST_Y_TOP_TO_BOTTOM);
786f1f6d7c6Skettenis
787f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
788f1f6d7c6Skettenis M64_SRC_Y_X, M64_COORDS(x, y));
789f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh, M64_SRC_WIDTH1, w);
790f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
791f1f6d7c6Skettenis M64_DST_Y_X, M64_COORDS(x, y));
792f1f6d7c6Skettenis bus_space_write_4(sc->sc_regt, sc->sc_regh,
793f1f6d7c6Skettenis M64_DST_HEIGHT_WIDTH, M64_COORDS(w, h));
794f1f6d7c6Skettenis
795f1f6d7c6Skettenis machfb_wait(sc);
796f1f6d7c6Skettenis }
797