#ifdef UDL_EVENT_COUNTERS
#define UDL_EVCNT_INCR(ev) (ev)->ev_count++
#else
#define UDL_EVCNT_INCR(ev) do {} while ( 0)
#endif
#define UDL_CMD_BUFFER_SIZE (64 * 1024)
#define UDL_CMD_HEADER_SIZE 6
#define UDL_CMD_WIDTH_MAX 256
#define UDL_CMD_DRAW_SIZE(width) \
(UDL_CMD_HEADER_SIZE + (width) * 2)
#define UDL_CMD_FILL_SIZE (UDL_CMD_HEADER_SIZE + 3)
#define UDL_CMD_COPY_SIZE (UDL_CMD_HEADER_SIZE + 3)
#define UDL_CMD_COMP_WORD_SIZE 4
#define UDL_CMD_COMP_MIN_SIZE (UDL_CMD_HEADER_SIZE + UDL_CMD_COMP_WORD_SIZE)
#define UDL_CMD_COMP_BLOCK_SIZE 512
#define UDL_CMD_COMP_THRESHOLD \
(UDL_CMD_BUFFER_SIZE - (UDL_CMD_COMP_BLOCK_SIZE * 2))
#define UDL_NCMDQ 32
struct udl_cmdq {
TAILQ_ENTRY(udl_cmdq) cq_chain;
struct udl_softc *cq_sc;
struct usbd_xfer *cq_xfer;
uint8_t *cq_buf;
};
struct udl_softc {
device_t sc_dev;
struct usbd_device * sc_udev;
struct usbd_interface * sc_iface;
struct usbd_pipe * sc_tx_pipeh;
enum {
UDL_INIT_NONE,
UDL_INIT_MIDWAY,
UDL_INIT_INITED
} sc_init_state;
struct udl_cmdq sc_cmdq[UDL_NCMDQ];
TAILQ_HEAD(udl_cmdq_head, udl_cmdq) sc_freecmd,
sc_xfercmd;
struct udl_cmdq *sc_cmd_cur;
uint8_t *sc_cmd_buf;
#define UDL_CMD_BUFINIT(sc) ((sc)->sc_cmd_buf = (sc)->sc_cmd_cur->cq_buf)
#define UDL_CMD_BUFSIZE(sc) ((sc)->sc_cmd_buf - (sc)->sc_cmd_cur->cq_buf)
int sc_cmd_cblen;
struct edid_info sc_ei;
int sc_width;
int sc_height;
int sc_offscreen;
uint8_t sc_depth;
struct wsscreen_descr sc_defaultscreen;
const struct wsscreen_descr *sc_screens[1];
struct wsscreen_list sc_screenlist;
struct rasops_info sc_ri;
device_t sc_wsdisplay;
u_int sc_mode;
u_int sc_blank;
bool sc_clear;
uint8_t sc_nscreens;
uint8_t *sc_fbmem;
uint8_t *sc_fbmem_prev;
#define UDL_FBMEM_SIZE(sc) \
((sc)->sc_width * (sc)->sc_height * ((sc)->sc_depth / 8))
uint8_t *sc_huffman;
uint8_t *sc_huffman_base;
size_t sc_huffman_size;
kcondvar_t sc_thread_cv;
kmutex_t sc_thread_mtx;
bool sc_dying;
bool sc_thread_stop;
lwp_t *sc_thread;
kcondvar_t sc_cv;
kmutex_t sc_mtx;
#define UDL_DECOMPRDY (1 << 0)
#define UDL_COMPRDY (1 << 1)
uint32_t sc_flags;
#ifdef UDL_EVENT_COUNTERS
struct evcnt sc_ev_cmdq_get;
struct evcnt sc_ev_cmdq_put;
struct evcnt sc_ev_cmdq_wait;
struct evcnt sc_ev_cmdq_timeout;
#endif
};
#define UDL_CTRL_CMD_READ_EDID 0x02
#define UDL_CTRL_CMD_WRITE_1 0x03
#define UDL_CTRL_CMD_READ_1 0x04
#define UDL_CTRL_CMD_READ_STATUS 0x06
#define UDL_CTRL_CMD_SET_KEY 0x12
#define UDL_BULK_SOC 0xaf
#define UDL_BULK_CMD_REG_WRITE_1 0x20
#define UDL_BULK_CMD_EOC 0xa0
#define UDL_BULK_CMD_DECOMP 0xe0
#define UDL_BULK_CMD_FB_BASE8 0x60
#define UDL_BULK_CMD_FB_WRITE8 (UDL_BULK_CMD_FB_BASE8 | 0x00)
#define UDL_BULK_CMD_FB_RLE8 (UDL_BULK_CMD_FB_BASE8 | 0x01)
#define UDL_BULK_CMD_FB_COPY8 (UDL_BULK_CMD_FB_BASE8 | 0x02)
#define UDL_BULK_CMD_FB_BASE16 0x68
#define UDL_BULK_CMD_FB_WRITE16 (UDL_BULK_CMD_FB_BASE16 | 0x00)
#define UDL_BULK_CMD_FB_RLE16 (UDL_BULK_CMD_FB_BASE16 | 0x01)
#define UDL_BULK_CMD_FB_COPY16 (UDL_BULK_CMD_FB_BASE16 | 0x02)
#define UDL_BULK_CMD_FB_COMP 0x10
#define UDL_REG_COLORDEPTH 0x00
#define UDL_REG_COLORDEPTH_16 0x00
#define UDL_REG_COLORDEPTH_24 0x01
#define UDL_REG_XDISPLAYSTART 0x01
#define UDL_REG_XDISPLAYEND 0x03
#define UDL_REG_YDISPLAYSTART 0x05
#define UDL_REG_YDISPLAYEND 0x07
#define UDL_REG_XENDCOUNT 0x09
#define UDL_REG_HSYNCSTART 0x0b
#define UDL_REG_HSYNCEND 0x0d
#define UDL_REG_HPIXELS 0x0f
#define UDL_REG_YENDCOUNT 0x11
#define UDL_REG_VSYNCSTART 0x13
#define UDL_REG_VSYNCEND 0x15
#define UDL_REG_VPIXELS 0x17
#define UDL_REG_PIXELCLOCK5KHZ 0x1b
#define UDL_REG_BLANK 0x1f
#define UDL_REG_BLANK_OFF 0x00
#define UDL_REG_BLANK_ON 0x01
#define UDL_REG_ADDR_START16 0x20
#define UDL_REG_ADDR_STRIDE16 0x23
#define UDL_REG_ADDR_START8 0x26
#define UDL_REG_ADDR_STRIDE8 0x29
#define UDL_REG_SYNC 0xff
struct udl_huffman {
uint8_t bit_count;
uint8_t pad[3];
uint32_t bit_pattern;
};
#define UDL_HUFFMAN_RECORD_SIZE sizeof(struct udl_huffman)
#define UDL_HUFFMAN_RECORDS (65536 + 1)
#define UDL_HUFFMAN_BASE (((UDL_HUFFMAN_RECORDS - 1) / 2) * \
UDL_HUFFMAN_RECORD_SIZE)