1 /* $OpenBSD: udl.h,v 1.21 2013/04/15 09:23:02 mglocker Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Marcus Glocker <mglocker@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #ifndef _UDL_H_ 20 #define _UDL_H_ 21 22 #include <sys/types.h> 23 #include <sys/queue.h> 24 25 /* 26 * BULK command transfer structure. 27 */ 28 #define UDL_CMD_MAX_FRAMES 64 /* units */ 29 #define UDL_CMD_MAX_DATA_SIZE 512 /* bytes */ 30 #define UDL_CMD_MAX_HEAD_SIZE 16 /* bytes */ 31 #define UDL_CMD_MAX_PIXEL_COUNT ((UDL_CMD_MAX_DATA_SIZE - UDL_CMD_MAX_HEAD_SIZE) / 2) 32 #define UDL_CMD_MAX_BUFFERS (3 * UDL_CMD_MAX_FRAMES) 33 #define UDL_FONT_HEIGHT 16 /* pixels */ 34 #define UDL_MAX_MODES 25 /* units */ 35 36 MALLOC_DECLARE(M_USB_DL); 37 38 struct udl_buffer { 39 TAILQ_ENTRY(udl_buffer) entry; 40 uint32_t size; 41 }; 42 43 TAILQ_HEAD(udl_buffer_head, udl_buffer); 44 45 struct udl_cmd_buf { 46 TAILQ_ENTRY(udl_cmd_buf) entry; 47 uint32_t off; 48 uint8_t buf[UDL_CMD_MAX_DATA_SIZE] __aligned(4); 49 }; 50 51 TAILQ_HEAD(udl_cmd_head, udl_cmd_buf); 52 53 enum { 54 UDL_BULK_WRITE_0, 55 UDL_BULK_WRITE_1, 56 UDL_N_TRANSFER, 57 }; 58 59 /* 60 * Our per device structure. 61 */ 62 struct udl_softc { 63 struct mtx sc_mtx; 64 struct cv sc_cv; 65 struct callout sc_callout; 66 struct usb_xfer *sc_xfer[UDL_N_TRANSFER]; 67 struct usb_device *sc_udev; 68 device_t sc_fbdev; 69 struct fb_info sc_fb_info; 70 uint8_t sc_edid[128]; 71 struct edid_info sc_edid_info; 72 struct udl_cmd_head sc_xfer_head[2]; 73 struct udl_cmd_head sc_cmd_buf_free; 74 struct udl_cmd_head sc_cmd_buf_pending; 75 struct udl_cmd_buf sc_cmd_buf_temp[UDL_CMD_MAX_BUFFERS]; 76 uint32_t sc_sync_off; 77 uint32_t sc_fb_size; 78 uint8_t *sc_fb_addr; 79 uint8_t *sc_fb_copy; 80 int sc_def_chip; /* default chip version */ 81 int sc_chip; 82 #define DLALL 0x0000 83 #define DL125 0x0000 /* max 1280x1024, 1440x900 */ 84 #define DL120 0x0001 /* max 1280x1024, 1440x1050 */ 85 #define DL160 0x0002 /* max 1600x1200, 1680x1050 */ 86 #define DL165 0x0003 /* max 1600x1200, 1920x1080 */ 87 #define DL195 0x0004 /* max 1920x1200, 2048x1152 */ 88 #define DLMAX 0x0004 89 #define DLUNK 0x00ff /* unknown */ 90 int sc_def_mode; /* default mode */ 91 int sc_cur_mode; 92 uint8_t sc_power_save; /* set if power save is enabled */ 93 uint8_t sc_gone; 94 }; 95 96 #define UDL_LOCK(sc) mtx_lock(&(sc)->sc_mtx) 97 #define UDL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) 98 99 /* 100 * Chip commands. 101 */ 102 #define UDL_CTRL_CMD_READ_EDID 0x02 103 #define UDL_CTRL_CMD_WRITE_1 0x03 104 #define UDL_CTRL_CMD_READ_1 0x04 105 #define UDL_CTRL_CMD_POLL 0x06 106 #define UDL_CTRL_CMD_SET_KEY 0x12 107 108 #define UDL_BULK_SOC 0xaf /* start of command token */ 109 110 #define UDL_BULK_CMD_REG_WRITE_1 0x20 /* write 1 byte to register */ 111 #define UDL_BULK_CMD_EOC 0xa0 /* end of command stack */ 112 #define UDL_BULK_CMD_DECOMP 0xe0 /* send decompression table */ 113 114 #define UDL_BULK_CMD_FB_BASE 0x60 115 #define UDL_BULK_CMD_FB_WORD 0x08 116 #define UDL_BULK_CMD_FB_COMP 0x10 117 #define UDL_BULK_CMD_FB_WRITE (UDL_BULK_CMD_FB_BASE | 0x00) 118 #define UDL_BULK_CMD_FB_COPY (UDL_BULK_CMD_FB_BASE | 0x02) 119 120 /* 121 * Chip registers. 122 */ 123 #define UDL_REG_ADDR_START16 0x20 124 #define UDL_REG_ADDR_STRIDE16 0x23 125 #define UDL_REG_ADDR_START8 0x26 126 #define UDL_REG_ADDR_STRIDE8 0x29 127 128 #define UDL_REG_SCREEN 0x1f 129 #define UDL_REG_SCREEN_ON 0x00 130 #define UDL_REG_SCREEN_OFF 0x01 131 #define UDL_REG_SYNC 0xff 132 133 #define UDL_MODE_SIZE 29 134 135 /* 136 * Register values for screen resolution initialization. 137 */ 138 static const uint8_t udl_reg_vals_640x480_60[UDL_MODE_SIZE] = { /* 25.17 Mhz 59.9 Hz 139 * VESA std */ 140 0x00, 0x99, 0x30, 0x26, 0x94, 0x60, 0xa9, 0xce, 0x60, 0x07, 0xb3, 0x0f, 141 0x79, 0xff, 0xff, 0x02, 0x80, 0x83, 0xbc, 0xff, 0xfc, 0xff, 0xff, 0x01, 142 0xe0, 0x01, 0x02, 0xab, 0x13 143 }; 144 static const uint8_t udl_reg_vals_640x480_67[UDL_MODE_SIZE] = { /* 30.25 MHz 66.6 Hz MAC 145 * std */ 146 0x00, 0x1d, 0x33, 0x07, 0xb3, 0x60, 0xa9, 0xce, 0x60, 0xb6, 0xa8, 0xff, 147 0xff, 0xbf, 0x70, 0x02, 0x80, 0x83, 0xbc, 0xff, 0xff, 0xff, 0xf9, 0x01, 148 0xe0, 0x01, 0x02, 0xa2, 0x17 149 }; 150 static const uint8_t udl_reg_vals_640x480_72[UDL_MODE_SIZE] = { /* 31.50 Mhz 72.8 Hz 151 * VESA std */ 152 0x00, 0x2b, 0xeb, 0x35, 0xd3, 0x0a, 0x95, 0xe6, 0x0e, 0x0f, 0xb5, 0x15, 153 0x2a, 0xff, 0xff, 0x02, 0x80, 0xcc, 0x1d, 0xff, 0xf9, 0xff, 0xff, 0x01, 154 0xe0, 0x01, 0x02, 0x9c, 0x18 155 }; 156 static const uint8_t udl_reg_vals_640x480_75[UDL_MODE_SIZE] = { /* 31.50 Mhz 75.7 Hz 157 * VESA std */ 158 0x00, 0xeb, 0xf7, 0xd3, 0x0f, 0x4f, 0x93, 0xfa, 0x47, 0xb5, 0x58, 0xff, 159 0xff, 0xbf, 0x70, 0x02, 0x80, 0xf4, 0x8f, 0xff, 0xff, 0xff, 0xf9, 0x01, 160 0xe0, 0x01, 0x02, 0x9c, 0x18 161 }; 162 static const uint8_t udl_reg_vals_800x480_61[UDL_MODE_SIZE] = { /* 33.00 MHz 61.9 Hz */ 163 0x00, 0x20, 0x3c, 0x7a, 0xc9, 0xf2, 0x6c, 0x48, 0xf9, 0x70, 0x53, 0xff, 164 0xff, 0x21, 0x27, 0x03, 0x20, 0x91, 0xf3, 0xff, 0xff, 0xff, 0xf9, 0x01, 165 0xe0, 0x01, 0x02, 0xc8, 0x19 166 }; 167 static const uint8_t udl_reg_vals_800x600_56[UDL_MODE_SIZE] = { /* 36.00 MHz 56.2 Hz 168 * VESA std */ 169 0x00, 0x65, 0x35, 0x48, 0xf4, 0xf2, 0x6c, 0x19, 0x18, 0xc9, 0x4b, 0xff, 170 0xff, 0x70, 0x35, 0x03, 0x20, 0x32, 0x31, 0xff, 0xff, 0xff, 0xfc, 0x02, 171 0x58, 0x01, 0x02, 0x20, 0x1c 172 }; 173 static const uint8_t udl_reg_vals_800x600_60[UDL_MODE_SIZE] = { /* 40.00 MHz 60.3 Hz 174 * VESA std */ 175 0x00, 0x20, 0x3c, 0x7a, 0xc9, 0x93, 0x60, 0xc8, 0xc7, 0x70, 0x53, 0xff, 176 0xff, 0x21, 0x27, 0x03, 0x20, 0x91, 0x8f, 0xff, 0xff, 0xff, 0xf2, 0x02, 177 0x58, 0x01, 0x02, 0x40, 0x1f 178 }; 179 static const uint8_t udl_reg_vals_800x600_72[UDL_MODE_SIZE] = { /* 50.00 MHz 72.1 Hz 180 * VESA std */ 181 0x00, 0xeb, 0xf7, 0xd1, 0x90, 0x4d, 0x82, 0x23, 0x1f, 0x39, 0xcf, 0xff, 182 0xff, 0x43, 0x21, 0x03, 0x20, 0x62, 0xc5, 0xff, 0xff, 0xff, 0xca, 0x02, 183 0x58, 0x01, 0x02, 0x10, 0x27 184 }; 185 static const uint8_t udl_reg_vals_800x600_74[UDL_MODE_SIZE] = { /* 50.00 MHz 74.4 Hz */ 186 0x00, 0xb3, 0x76, 0x39, 0xcf, 0x60, 0xa9, 0xc7, 0xf4, 0x70, 0x53, 0xff, 187 0xff, 0x35, 0x33, 0x03, 0x20, 0x8f, 0xe9, 0xff, 0xff, 0xff, 0xf9, 0x02, 188 0x58, 0x01, 0x02, 0x10, 0x27 189 }; 190 static const uint8_t udl_reg_vals_800x600_75[UDL_MODE_SIZE] = { /* 49.50 MHz 75.0 Hz 191 * VESA std */ 192 0x00, 0xb3, 0x76, 0x39, 0xcf, 0xf2, 0x6c, 0x19, 0x18, 0x70, 0x53, 0xff, 193 0xff, 0x35, 0x33, 0x03, 0x20, 0x32, 0x31, 0xff, 0xff, 0xff, 0xf9, 0x02, 194 0x58, 0x01, 0x02, 0xac, 0x26 195 }; 196 static const uint8_t udl_reg_vals_1024x768_60[UDL_MODE_SIZE] = { /* 65.00 MHz 60.0 Hz 197 * VESA std */ 198 0x00, 0x36, 0x18, 0xd5, 0x10, 0x60, 0xa9, 0x7b, 0x33, 0xa1, 0x2b, 0x27, 199 0x32, 0xff, 0xff, 0x04, 0x00, 0xd9, 0x9a, 0xff, 0xca, 0xff, 0xff, 0x03, 200 0x00, 0x04, 0x03, 0xc8, 0x32 201 }; 202 static const uint8_t udl_reg_vals_1024x768_70[UDL_MODE_SIZE] = { /* 75.00 MHz 70.0 Hz 203 * VESA std */ 204 0x00, 0xb4, 0xed, 0x4c, 0x5e, 0x60, 0xa9, 0x7b, 0x33, 0x10, 0x4d, 0xff, 205 0xff, 0x27, 0x32, 0x04, 0x00, 0xd9, 0x9a, 0xff, 0xff, 0xff, 0xca, 0x03, 206 0x00, 0x04, 0x02, 0x98, 0x3a 207 }; 208 static const uint8_t udl_reg_vals_1024x768_75[UDL_MODE_SIZE] = { /* 78.75 MHz 75.0 Hz 209 * VESA std */ 210 0x00, 0xec, 0xb4, 0xa0, 0x4c, 0x36, 0x0a, 0x07, 0xb3, 0x5e, 0xd5, 0xff, 211 0xff, 0x0f, 0x79, 0x04, 0x00, 0x0f, 0x66, 0xff, 0xff, 0xff, 0xf9, 0x03, 212 0x00, 0x04, 0x02, 0x86, 0x3d 213 }; 214 static const uint8_t udl_reg_vals_1280x800_60[UDL_MODE_SIZE] = { /* 83.46 MHz 59.9 MHz */ 215 0x00, 0xb2, 0x19, 0x34, 0xdf, 0x93, 0x60, 0x30, 0xfb, 0x9f, 0xca, 0xff, 216 0xff, 0x27, 0x32, 0x05, 0x00, 0x61, 0xf6, 0xff, 0xff, 0xff, 0xf9, 0x03, 217 0x20, 0x04, 0x02, 0x34, 0x41 218 }; 219 static const uint8_t udl_reg_vals_1280x960_60[UDL_MODE_SIZE] = { /* 108.00 MHz 60.0 Hz 220 * VESA std */ 221 0x00, 0xa6, 0x03, 0x5c, 0x7e, 0x0a, 0x95, 0x48, 0xf4, 0x61, 0xbd, 0xff, 222 0xff, 0x94, 0x43, 0x05, 0x00, 0x91, 0xe8, 0xff, 0xff, 0xff, 0xf9, 0x03, 223 0xc0, 0x04, 0x02, 0x60, 0x54 224 }; 225 static const uint8_t udl_reg_vals_1280x1024_60[UDL_MODE_SIZE] = { /* 108.00 MHz 60.0 Hz 226 * VESA std */ 227 0x00, 0x98, 0xf8, 0x0d, 0x57, 0x2a, 0x55, 0x4d, 0x54, 0xca, 0x0d, 0xff, 228 0xff, 0x94, 0x43, 0x05, 0x00, 0x9a, 0xa8, 0xff, 0xff, 0xff, 0xf9, 0x04, 229 0x00, 0x04, 0x02, 0x60, 0x54 230 }; 231 static const uint8_t udl_reg_vals_1280x1024_75[UDL_MODE_SIZE] = { /* 135.00 MHz 75.0 Hz 232 * VESA std */ 233 0x00, 0xce, 0x12, 0x3f, 0x9f, 0x2a, 0x55, 0x4d, 0x54, 0xca, 0x0d, 0xff, 234 0xff, 0x32, 0x60, 0x05, 0x00, 0x9a, 0xa8, 0xff, 0xff, 0xff, 0xf9, 0x04, 235 0x00, 0x04, 0x02, 0x78, 0x69 236 }; 237 static const uint8_t udl_reg_vals_1366x768_60[UDL_MODE_SIZE] = { /* 90 MHz 60.0 Hz */ 238 0x01, 0x19, 0x1e, 0x1f, 0xb0, 0x93, 0x60, 0x40, 0x7b, 0x36, 0xe8, 0x27, 239 0x32, 0xff, 0xff, 0x05, 0x56, 0x03, 0xd9, 0xff, 0xff, 0xfc, 0xa7, 0x03, 240 0x00, 0x04, 0x02, 0x9a, 0x42 241 }; 242 static const uint8_t udl_reg_vals_1440x900_60[UDL_MODE_SIZE] = { /* 106.47 MHz 59.9 Hz */ 243 0x00, 0x24, 0xce, 0xe7, 0x72, 0x36, 0x0a, 0x86, 0xca, 0x1c, 0x10, 0xff, 244 0xff, 0x60, 0x3a, 0x05, 0xa0, 0x0d, 0x94, 0xff, 0xff, 0xff, 0xf9, 0x03, 245 0x84, 0x04, 0x02, 0x2e, 0x53 246 }; 247 static const uint8_t udl_reg_vals_1440x900_59[UDL_MODE_SIZE] = { /* 106.50 MHz 59.8 Hz */ 248 0x00, 0x24, 0xce, 0xe7, 0x72, 0xd8, 0x2a, 0x1b, 0x28, 0x1c, 0x10, 0xff, 249 0xff, 0x60, 0x3a, 0x05, 0xa0, 0x36, 0x50, 0xff, 0xff, 0xff, 0xf9, 0x03, 250 0x84, 0x04, 0x02, 0x34, 0x53 251 }; 252 static const uint8_t udl_reg_vals_1440x900_75[UDL_MODE_SIZE] = { /* 136.49 MHz 75.0 Hz */ 253 0x00, 0x73, 0xa6, 0x14, 0xea, 0x0a, 0x95, 0xca, 0x10, 0x7f, 0x46, 0xff, 254 0xff, 0x60, 0x3a, 0x05, 0xa0, 0x94, 0x20, 0xff, 0xff, 0xff, 0xf9, 0x03, 255 0x84, 0x04, 0x02, 0xa2, 0x6a 256 }; 257 static const uint8_t udl_reg_vals_1680x1050_60[UDL_MODE_SIZE] = { /* 147.14 MHz 60.0 Hz */ 258 0x00, 0x53, 0x43, 0xa6, 0x71, 0xc1, 0x52, 0xd9, 0x29, 0x69, 0x9f, 0xff, 259 0xff, 0xd7, 0xee, 0x06, 0x90, 0xb2, 0x53, 0xff, 0xff, 0xff, 0xf9, 0x04, 260 0x1a, 0x04, 0x02, 0xf4, 0x72 261 }; 262 static const uint8_t udl_reg_vals_1600x1200_60[UDL_MODE_SIZE] = { /* 162.00 MHz 60.0 Hz 263 * VESA std */ 264 0x00, 0xcf, 0xa4, 0x3c, 0x4e, 0x55, 0x73, 0x71, 0x2b, 0x71, 0x52, 0xff, 265 0xff, 0xee, 0xca, 0x06, 0x40, 0xe2, 0x57, 0xff, 0xff, 0xff, 0xf9, 0x04, 266 0xb0, 0x04, 0x02, 0x90, 0x7e 267 }; 268 static const uint8_t udl_reg_vals_1920x1080_60[UDL_MODE_SIZE] = { /* 138.50 MHz 59.9 Hz */ 269 0x00, 0x73, 0xa6, 0x28, 0xb3, 0x54, 0xaa, 0x41, 0x5d, 0x0d, 0x9f, 0x32, 270 0x60, 0xff, 0xff, 0x07, 0x80, 0x0a, 0xea, 0xff, 0xf9, 0xff, 0xff, 0x04, 271 0x38, 0x04, 0x02, 0xe0, 0x7c 272 }; 273 274 struct udl_mode { 275 uint16_t hdisplay; 276 uint16_t vdisplay; 277 uint8_t hz; 278 uint16_t chip; 279 uint32_t clock; 280 const uint8_t *mode; 281 }; 282 283 static const struct udl_mode udl_modes[UDL_MAX_MODES] = { 284 {640, 480, 60, DLALL, 2520, udl_reg_vals_640x480_60}, 285 {640, 480, 67, DLALL, 3025, udl_reg_vals_640x480_67}, 286 {640, 480, 72, DLALL, 3150, udl_reg_vals_640x480_72}, 287 {640, 480, 75, DLALL, 3150, udl_reg_vals_640x480_75}, 288 {800, 480, 59, DLALL, 5000, udl_reg_vals_800x480_61}, 289 {800, 480, 61, DLALL, 3300, udl_reg_vals_800x480_61}, 290 {800, 600, 56, DLALL, 3600, udl_reg_vals_800x600_56}, 291 {800, 600, 60, DLALL, 4000, udl_reg_vals_800x600_60}, 292 {800, 600, 72, DLALL, 5000, udl_reg_vals_800x600_72}, 293 {800, 600, 74, DLALL, 5000, udl_reg_vals_800x600_74}, 294 {800, 600, 75, DLALL, 4950, udl_reg_vals_800x600_75}, 295 {1024, 768, 60, DLALL, 6500, udl_reg_vals_1024x768_60}, 296 {1024, 768, 70, DLALL, 7500, udl_reg_vals_1024x768_70}, 297 {1024, 768, 75, DLALL, 7850, udl_reg_vals_1024x768_75}, 298 {1280, 800, 60, DLALL, 8346, udl_reg_vals_1280x800_60}, 299 {1280, 960, 60, DLALL, 10800, udl_reg_vals_1280x960_60}, 300 {1280, 1024, 60, DLALL, 10800, udl_reg_vals_1280x1024_60}, 301 {1280, 1024, 75, DLALL, 13500, udl_reg_vals_1280x1024_75}, 302 {1366, 768, 60, DLALL, 9000, udl_reg_vals_1366x768_60}, 303 {1440, 900, 59, DL125, 10650, udl_reg_vals_1440x900_59}, 304 {1440, 900, 60, DL125, 10647, udl_reg_vals_1440x900_60}, 305 {1440, 900, 75, DL125, 13649, udl_reg_vals_1440x900_75}, 306 {1680, 1050, 60, DL160, 14714, udl_reg_vals_1680x1050_60}, 307 {1600, 1200, 60, DL160, 16200, udl_reg_vals_1600x1200_60}, 308 {1920, 1080, 60, DL165, 13850, udl_reg_vals_1920x1080_60} 309 }; 310 311 /* 312 * Encryption. 313 */ 314 static const uint8_t udl_null_key_1[] = { 315 0x57, 0xcd, 0xdc, 0xa7, 0x1c, 0x88, 0x5e, 0x15, 0x60, 0xfe, 0xc6, 0x97, 316 0x16, 0x3d, 0x47, 0xf2 317 }; 318 319 #endif /* _UDL_H_ */ 320