xref: /netbsd-src/sys/dev/usb/udl.h (revision 3b0c992f8b7226e6815546039ed096993d57a7b1)
1*3b0c992fSnat /*	$NetBSD: udl.h,v 1.6 2022/09/06 02:20:17 nat Exp $	*/
247f87355Stsutsui 
347f87355Stsutsui /*-
447f87355Stsutsui  * Copyright (c) 2009 FUKAUMI Naoki.
547f87355Stsutsui  * All rights reserved.
647f87355Stsutsui  *
747f87355Stsutsui  * Redistribution and use in source and binary forms, with or without
847f87355Stsutsui  * modification, are permitted provided that the following conditions
947f87355Stsutsui  * are met:
1047f87355Stsutsui  * 1. Redistributions of source code must retain the above copyright
1147f87355Stsutsui  *    notice, this list of conditions and the following disclaimer.
1247f87355Stsutsui  * 2. Redistributions in binary form must reproduce the above copyright
1347f87355Stsutsui  *    notice, this list of conditions and the following disclaimer in the
1447f87355Stsutsui  *    documentation and/or other materials provided with the distribution.
1547f87355Stsutsui  *
1647f87355Stsutsui  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1747f87355Stsutsui  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1847f87355Stsutsui  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1947f87355Stsutsui  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2047f87355Stsutsui  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2147f87355Stsutsui  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2247f87355Stsutsui  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2347f87355Stsutsui  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2447f87355Stsutsui  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2547f87355Stsutsui  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2647f87355Stsutsui  */
2747f87355Stsutsui 
2847f87355Stsutsui /*
2947f87355Stsutsui  * Copyright (c) 2009 Marcus Glocker <mglocker@openbsd.org>
3047f87355Stsutsui  *
3147f87355Stsutsui  * Permission to use, copy, modify, and distribute this software for any
3247f87355Stsutsui  * purpose with or without fee is hereby granted, provided that the above
3347f87355Stsutsui  * copyright notice and this permission notice appear in all copies.
3447f87355Stsutsui  *
3547f87355Stsutsui  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3647f87355Stsutsui  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3747f87355Stsutsui  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3847f87355Stsutsui  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3947f87355Stsutsui  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
4047f87355Stsutsui  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
4147f87355Stsutsui  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
4247f87355Stsutsui  */
4347f87355Stsutsui 
4447f87355Stsutsui #ifdef UDL_EVENT_COUNTERS
4547f87355Stsutsui #define UDL_EVCNT_INCR(ev)	(ev)->ev_count++
4647f87355Stsutsui #else
4747f87355Stsutsui #define UDL_EVCNT_INCR(ev)	do {} while (/* CONSTCOND */ 0)
4847f87355Stsutsui #endif
4947f87355Stsutsui 
5047f87355Stsutsui /*
5147f87355Stsutsui  * Bulk command xfer structure.
5247f87355Stsutsui  */
5347f87355Stsutsui #define UDL_CMD_BUFFER_SIZE	(64 * 1024)
5447f87355Stsutsui #define UDL_CMD_HEADER_SIZE	6
5547f87355Stsutsui #define UDL_CMD_WIDTH_MAX	256
5647f87355Stsutsui #define UDL_CMD_DRAW_SIZE(width) \
5747f87355Stsutsui 				(UDL_CMD_HEADER_SIZE + (width) * 2)
5847f87355Stsutsui #define UDL_CMD_FILL_SIZE	(UDL_CMD_HEADER_SIZE + 3)
5947f87355Stsutsui #define UDL_CMD_COPY_SIZE	(UDL_CMD_HEADER_SIZE + 3)
6047f87355Stsutsui #define UDL_CMD_COMP_WORD_SIZE	4
6147f87355Stsutsui #define UDL_CMD_COMP_MIN_SIZE	(UDL_CMD_HEADER_SIZE + UDL_CMD_COMP_WORD_SIZE)
6247f87355Stsutsui #define UDL_CMD_COMP_BLOCK_SIZE	512
6347f87355Stsutsui #define UDL_CMD_COMP_THRESHOLD \
6447f87355Stsutsui     (UDL_CMD_BUFFER_SIZE - (UDL_CMD_COMP_BLOCK_SIZE * 2))
6547f87355Stsutsui 
6647f87355Stsutsui #define UDL_NCMDQ	32
6747f87355Stsutsui 
6847f87355Stsutsui struct udl_cmdq {
6947f87355Stsutsui 	TAILQ_ENTRY(udl_cmdq)	 cq_chain;
7047f87355Stsutsui 	struct udl_softc	*cq_sc;
714e8e6643Sskrll 	struct usbd_xfer	*cq_xfer;
7247f87355Stsutsui 	uint8_t			*cq_buf;
7347f87355Stsutsui };
7447f87355Stsutsui 
7547f87355Stsutsui /*
7647f87355Stsutsui  * Our per device structure.
7747f87355Stsutsui  */
7847f87355Stsutsui struct udl_softc {
7947f87355Stsutsui 	device_t		 sc_dev;
804e8e6643Sskrll 	struct usbd_device *	 sc_udev;
814e8e6643Sskrll 	struct usbd_interface *	 sc_iface;
824e8e6643Sskrll 	struct usbd_pipe *	 sc_tx_pipeh;
8347f87355Stsutsui 
84ce2468caSmaxv 	enum {
85ce2468caSmaxv 		UDL_INIT_NONE,
86ce2468caSmaxv 		UDL_INIT_MIDWAY,
87ce2468caSmaxv 		UDL_INIT_INITED
88ce2468caSmaxv 	} sc_init_state;
89ce2468caSmaxv 
9047f87355Stsutsui 	struct udl_cmdq		 sc_cmdq[UDL_NCMDQ];
9147f87355Stsutsui 	TAILQ_HEAD(udl_cmdq_head, udl_cmdq)	sc_freecmd,
9247f87355Stsutsui 						sc_xfercmd;
9347f87355Stsutsui 
9447f87355Stsutsui 	struct udl_cmdq		*sc_cmd_cur;
9547f87355Stsutsui 	uint8_t			*sc_cmd_buf;
9647f87355Stsutsui #define UDL_CMD_BUFINIT(sc)	((sc)->sc_cmd_buf = (sc)->sc_cmd_cur->cq_buf)
9747f87355Stsutsui #define UDL_CMD_BUFSIZE(sc)	((sc)->sc_cmd_buf - (sc)->sc_cmd_cur->cq_buf)
9847f87355Stsutsui 	int			 sc_cmd_cblen;
9947f87355Stsutsui 
10047f87355Stsutsui 	struct edid_info	 sc_ei;
10147f87355Stsutsui 	int			 sc_width;
10247f87355Stsutsui 	int			 sc_height;
10347f87355Stsutsui 	int			 sc_offscreen;
10447f87355Stsutsui 	uint8_t			 sc_depth;
10547f87355Stsutsui 
10647f87355Stsutsui 	/* wsdisplay glue */
10747f87355Stsutsui 	struct wsscreen_descr	 sc_defaultscreen;
10847f87355Stsutsui 	const struct wsscreen_descr	*sc_screens[1];
10947f87355Stsutsui 	struct wsscreen_list	 sc_screenlist;
11047f87355Stsutsui 	struct rasops_info	 sc_ri;
11147f87355Stsutsui 	device_t		 sc_wsdisplay;
11247f87355Stsutsui 	u_int			 sc_mode;
11347f87355Stsutsui 	u_int			 sc_blank;
114*3b0c992fSnat 	bool			 sc_clear;
11547f87355Stsutsui 	uint8_t			 sc_nscreens;
11647f87355Stsutsui 
11747f87355Stsutsui 	uint8_t			*sc_fbmem;	/* framebuffer for X11 */
1187b977f0dSnat 	uint8_t			*sc_fbmem_prev;	/* prev. framebuffer */
11947f87355Stsutsui #define UDL_FBMEM_SIZE(sc) \
12047f87355Stsutsui     ((sc)->sc_width * (sc)->sc_height * ((sc)->sc_depth / 8))
12147f87355Stsutsui 
12247f87355Stsutsui 	uint8_t			*sc_huffman;
12347f87355Stsutsui 	uint8_t			*sc_huffman_base;
12447f87355Stsutsui 	size_t			 sc_huffman_size;
12547f87355Stsutsui 
1267b977f0dSnat 	kcondvar_t		 sc_thread_cv;
1277b977f0dSnat 	kmutex_t		 sc_thread_mtx;
1287b977f0dSnat 	bool			 sc_dying;
129c1b9bee0Snat 	bool			 sc_thread_stop;
1307b977f0dSnat 	lwp_t			*sc_thread;
1317b977f0dSnat 
13247f87355Stsutsui 	kcondvar_t		 sc_cv;
13347f87355Stsutsui 	kmutex_t		 sc_mtx;
13447f87355Stsutsui 
13547f87355Stsutsui #define UDL_DECOMPRDY	(1 << 0)
13647f87355Stsutsui #define UDL_COMPRDY	(1 << 1)
13747f87355Stsutsui 	uint32_t		 sc_flags;
13847f87355Stsutsui #ifdef UDL_EVENT_COUNTERS
13947f87355Stsutsui 	struct evcnt		 sc_ev_cmdq_get;
14047f87355Stsutsui 	struct evcnt		 sc_ev_cmdq_put;
14147f87355Stsutsui 	struct evcnt		 sc_ev_cmdq_wait;
14247f87355Stsutsui 	struct evcnt		 sc_ev_cmdq_timeout;
14347f87355Stsutsui #endif
14447f87355Stsutsui };
14547f87355Stsutsui 
14647f87355Stsutsui /*
14747f87355Stsutsui  * Chip commands.
14847f87355Stsutsui  */
14947f87355Stsutsui #define UDL_CTRL_CMD_READ_EDID		0x02
15047f87355Stsutsui #define UDL_CTRL_CMD_WRITE_1		0x03
15147f87355Stsutsui #define UDL_CTRL_CMD_READ_1		0x04
15247f87355Stsutsui #define UDL_CTRL_CMD_READ_STATUS	0x06
15347f87355Stsutsui #define UDL_CTRL_CMD_SET_KEY		0x12
15447f87355Stsutsui 
15547f87355Stsutsui #define UDL_BULK_SOC			0xaf	/* start of command token */
15647f87355Stsutsui 
15747f87355Stsutsui #define UDL_BULK_CMD_REG_WRITE_1	0x20	/* write 1 byte to register */
15847f87355Stsutsui #define UDL_BULK_CMD_EOC		0xa0	/* end of command stack */
15947f87355Stsutsui #define UDL_BULK_CMD_DECOMP		0xe0	/* send decompression table */
16047f87355Stsutsui 
16147f87355Stsutsui #define UDL_BULK_CMD_FB_BASE8		0x60
16247f87355Stsutsui #define UDL_BULK_CMD_FB_WRITE8		(UDL_BULK_CMD_FB_BASE8 | 0x00)
16347f87355Stsutsui #define UDL_BULK_CMD_FB_RLE8		(UDL_BULK_CMD_FB_BASE8 | 0x01)
16447f87355Stsutsui #define UDL_BULK_CMD_FB_COPY8		(UDL_BULK_CMD_FB_BASE8 | 0x02)
16547f87355Stsutsui #define UDL_BULK_CMD_FB_BASE16		0x68
16647f87355Stsutsui #define UDL_BULK_CMD_FB_WRITE16		(UDL_BULK_CMD_FB_BASE16 | 0x00)
16747f87355Stsutsui #define UDL_BULK_CMD_FB_RLE16		(UDL_BULK_CMD_FB_BASE16 | 0x01)
16847f87355Stsutsui #define UDL_BULK_CMD_FB_COPY16		(UDL_BULK_CMD_FB_BASE16 | 0x02)
16947f87355Stsutsui #define UDL_BULK_CMD_FB_COMP		0x10
17047f87355Stsutsui 
17147f87355Stsutsui /*
17247f87355Stsutsui  * Chip registers.
17347f87355Stsutsui  */
17447f87355Stsutsui #define UDL_REG_COLORDEPTH		0x00
17547f87355Stsutsui  #define UDL_REG_COLORDEPTH_16		0x00
17647f87355Stsutsui  #define UDL_REG_COLORDEPTH_24		0x01
17747f87355Stsutsui #define UDL_REG_XDISPLAYSTART		0x01
17847f87355Stsutsui #define UDL_REG_XDISPLAYEND		0x03
17947f87355Stsutsui #define UDL_REG_YDISPLAYSTART		0x05
18047f87355Stsutsui #define UDL_REG_YDISPLAYEND		0x07
18147f87355Stsutsui #define UDL_REG_XENDCOUNT		0x09
18247f87355Stsutsui #define UDL_REG_HSYNCSTART		0x0b
18347f87355Stsutsui #define UDL_REG_HSYNCEND		0x0d
18447f87355Stsutsui #define UDL_REG_HPIXELS			0x0f
18547f87355Stsutsui #define UDL_REG_YENDCOUNT		0x11
18647f87355Stsutsui #define UDL_REG_VSYNCSTART		0x13
18747f87355Stsutsui #define UDL_REG_VSYNCEND		0x15
18847f87355Stsutsui #define UDL_REG_VPIXELS			0x17
18947f87355Stsutsui #define UDL_REG_PIXELCLOCK5KHZ		0x1b
19047f87355Stsutsui #define UDL_REG_BLANK			0x1f
19147f87355Stsutsui  #define UDL_REG_BLANK_OFF		0x00
19247f87355Stsutsui  #define UDL_REG_BLANK_ON		0x01
19347f87355Stsutsui #define UDL_REG_ADDR_START16		0x20
19447f87355Stsutsui #define UDL_REG_ADDR_STRIDE16		0x23
19547f87355Stsutsui #define UDL_REG_ADDR_START8		0x26
19647f87355Stsutsui #define UDL_REG_ADDR_STRIDE8		0x29
19747f87355Stsutsui #define UDL_REG_SYNC			0xff
19847f87355Stsutsui 
19947f87355Stsutsui /*
20047f87355Stsutsui  * Compression.
20147f87355Stsutsui  */
20247f87355Stsutsui struct udl_huffman {
20347f87355Stsutsui 	uint8_t		bit_count;
20447f87355Stsutsui 	uint8_t		pad[3];
20547f87355Stsutsui 	uint32_t	bit_pattern;
20647f87355Stsutsui };
20747f87355Stsutsui #define UDL_HUFFMAN_RECORD_SIZE		sizeof(struct udl_huffman)
20847f87355Stsutsui #define UDL_HUFFMAN_RECORDS		(65536 + 1)
20947f87355Stsutsui #define UDL_HUFFMAN_BASE		(((UDL_HUFFMAN_RECORDS - 1) / 2) * \
21047f87355Stsutsui 					    UDL_HUFFMAN_RECORD_SIZE)
211