|
|
1.1 ! root 1: /* ! 2: * QEMU SM501 Device ! 3: * ! 4: * Copyright (c) 2008 Shin-ichiro KAWASAKI ! 5: * ! 6: * Permission is hereby granted, free of charge, to any person obtaining a copy ! 7: * of this software and associated documentation files (the "Software"), to deal ! 8: * in the Software without restriction, including without limitation the rights ! 9: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ! 10: * copies of the Software, and to permit persons to whom the Software is ! 11: * furnished to do so, subject to the following conditions: ! 12: * ! 13: * The above copyright notice and this permission notice shall be included in ! 14: * all copies or substantial portions of the Software. ! 15: * ! 16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ! 17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ! 19: * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ! 20: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ! 21: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ! 22: * THE SOFTWARE. ! 23: */ ! 24: ! 25: #include <stdio.h> ! 26: #include <assert.h> ! 27: #include "hw.h" ! 28: #include "pc.h" ! 29: #include "console.h" ! 30: #include "devices.h" ! 31: ! 32: /* ! 33: * Status: 2008/11/02 ! 34: * - Minimum implementation for Linux console : mmio regs and CRT layer. ! 35: * - Always updates full screen. ! 36: * ! 37: * TODO: ! 38: * - Panel support ! 39: * - Hardware cursor support ! 40: * - Touch panel support ! 41: * - USB support ! 42: * - UART support ! 43: * - Performance tuning ! 44: */ ! 45: ! 46: //#define DEBUG_SM501 ! 47: //#define DEBUG_BITBLT ! 48: ! 49: #ifdef DEBUG_SM501 ! 50: #define SM501_DPRINTF(fmt...) printf(fmt) ! 51: #else ! 52: #define SM501_DPRINTF(fmt...) do {} while(0) ! 53: #endif ! 54: ! 55: ! 56: #define MMIO_BASE_OFFSET 0x3e00000 ! 57: ! 58: /* SM501 register definitions taken from "linux/include/linux/sm501-regs.h" */ ! 59: ! 60: /* System Configuration area */ ! 61: /* System config base */ ! 62: #define SM501_SYS_CONFIG (0x000000) ! 63: ! 64: /* config 1 */ ! 65: #define SM501_SYSTEM_CONTROL (0x000000) ! 66: ! 67: #define SM501_SYSCTRL_PANEL_TRISTATE (1<<0) ! 68: #define SM501_SYSCTRL_MEM_TRISTATE (1<<1) ! 69: #define SM501_SYSCTRL_CRT_TRISTATE (1<<2) ! 70: ! 71: #define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3<<4) ! 72: #define SM501_SYSCTRL_PCI_SLAVE_BURST_1 (0<<4) ! 73: #define SM501_SYSCTRL_PCI_SLAVE_BURST_2 (1<<4) ! 74: #define SM501_SYSCTRL_PCI_SLAVE_BURST_4 (2<<4) ! 75: #define SM501_SYSCTRL_PCI_SLAVE_BURST_8 (3<<4) ! 76: ! 77: #define SM501_SYSCTRL_PCI_CLOCK_RUN_EN (1<<6) ! 78: #define SM501_SYSCTRL_PCI_RETRY_DISABLE (1<<7) ! 79: #define SM501_SYSCTRL_PCI_SUBSYS_LOCK (1<<11) ! 80: #define SM501_SYSCTRL_PCI_BURST_READ_EN (1<<15) ! 81: ! 82: /* miscellaneous control */ ! 83: ! 84: #define SM501_MISC_CONTROL (0x000004) ! 85: ! 86: #define SM501_MISC_BUS_SH (0x0) ! 87: #define SM501_MISC_BUS_PCI (0x1) ! 88: #define SM501_MISC_BUS_XSCALE (0x2) ! 89: #define SM501_MISC_BUS_NEC (0x6) ! 90: #define SM501_MISC_BUS_MASK (0x7) ! 91: ! 92: #define SM501_MISC_VR_62MB (1<<3) ! 93: #define SM501_MISC_CDR_RESET (1<<7) ! 94: #define SM501_MISC_USB_LB (1<<8) ! 95: #define SM501_MISC_USB_SLAVE (1<<9) ! 96: #define SM501_MISC_BL_1 (1<<10) ! 97: #define SM501_MISC_MC (1<<11) ! 98: #define SM501_MISC_DAC_POWER (1<<12) ! 99: #define SM501_MISC_IRQ_INVERT (1<<16) ! 100: #define SM501_MISC_SH (1<<17) ! 101: ! 102: #define SM501_MISC_HOLD_EMPTY (0<<18) ! 103: #define SM501_MISC_HOLD_8 (1<<18) ! 104: #define SM501_MISC_HOLD_16 (2<<18) ! 105: #define SM501_MISC_HOLD_24 (3<<18) ! 106: #define SM501_MISC_HOLD_32 (4<<18) ! 107: #define SM501_MISC_HOLD_MASK (7<<18) ! 108: ! 109: #define SM501_MISC_FREQ_12 (1<<24) ! 110: #define SM501_MISC_PNL_24BIT (1<<25) ! 111: #define SM501_MISC_8051_LE (1<<26) ! 112: ! 113: ! 114: ! 115: #define SM501_GPIO31_0_CONTROL (0x000008) ! 116: #define SM501_GPIO63_32_CONTROL (0x00000C) ! 117: #define SM501_DRAM_CONTROL (0x000010) ! 118: ! 119: /* command list */ ! 120: #define SM501_ARBTRTN_CONTROL (0x000014) ! 121: ! 122: /* command list */ ! 123: #define SM501_COMMAND_LIST_STATUS (0x000024) ! 124: ! 125: /* interrupt debug */ ! 126: #define SM501_RAW_IRQ_STATUS (0x000028) ! 127: #define SM501_RAW_IRQ_CLEAR (0x000028) ! 128: #define SM501_IRQ_STATUS (0x00002C) ! 129: #define SM501_IRQ_MASK (0x000030) ! 130: #define SM501_DEBUG_CONTROL (0x000034) ! 131: ! 132: /* power management */ ! 133: #define SM501_POWERMODE_P2X_SRC (1<<29) ! 134: #define SM501_POWERMODE_V2X_SRC (1<<20) ! 135: #define SM501_POWERMODE_M_SRC (1<<12) ! 136: #define SM501_POWERMODE_M1_SRC (1<<4) ! 137: ! 138: #define SM501_CURRENT_GATE (0x000038) ! 139: #define SM501_CURRENT_CLOCK (0x00003C) ! 140: #define SM501_POWER_MODE_0_GATE (0x000040) ! 141: #define SM501_POWER_MODE_0_CLOCK (0x000044) ! 142: #define SM501_POWER_MODE_1_GATE (0x000048) ! 143: #define SM501_POWER_MODE_1_CLOCK (0x00004C) ! 144: #define SM501_SLEEP_MODE_GATE (0x000050) ! 145: #define SM501_POWER_MODE_CONTROL (0x000054) ! 146: ! 147: /* power gates for units within the 501 */ ! 148: #define SM501_GATE_HOST (0) ! 149: #define SM501_GATE_MEMORY (1) ! 150: #define SM501_GATE_DISPLAY (2) ! 151: #define SM501_GATE_2D_ENGINE (3) ! 152: #define SM501_GATE_CSC (4) ! 153: #define SM501_GATE_ZVPORT (5) ! 154: #define SM501_GATE_GPIO (6) ! 155: #define SM501_GATE_UART0 (7) ! 156: #define SM501_GATE_UART1 (8) ! 157: #define SM501_GATE_SSP (10) ! 158: #define SM501_GATE_USB_HOST (11) ! 159: #define SM501_GATE_USB_GADGET (12) ! 160: #define SM501_GATE_UCONTROLLER (17) ! 161: #define SM501_GATE_AC97 (18) ! 162: ! 163: /* panel clock */ ! 164: #define SM501_CLOCK_P2XCLK (24) ! 165: /* crt clock */ ! 166: #define SM501_CLOCK_V2XCLK (16) ! 167: /* main clock */ ! 168: #define SM501_CLOCK_MCLK (8) ! 169: /* SDRAM controller clock */ ! 170: #define SM501_CLOCK_M1XCLK (0) ! 171: ! 172: /* config 2 */ ! 173: #define SM501_PCI_MASTER_BASE (0x000058) ! 174: #define SM501_ENDIAN_CONTROL (0x00005C) ! 175: #define SM501_DEVICEID (0x000060) ! 176: /* 0x050100A0 */ ! 177: ! 178: #define SM501_DEVICEID_SM501 (0x05010000) ! 179: #define SM501_DEVICEID_IDMASK (0xffff0000) ! 180: #define SM501_DEVICEID_REVMASK (0x000000ff) ! 181: ! 182: #define SM501_PLLCLOCK_COUNT (0x000064) ! 183: #define SM501_MISC_TIMING (0x000068) ! 184: #define SM501_CURRENT_SDRAM_CLOCK (0x00006C) ! 185: ! 186: #define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074) ! 187: ! 188: /* GPIO base */ ! 189: #define SM501_GPIO (0x010000) ! 190: #define SM501_GPIO_DATA_LOW (0x00) ! 191: #define SM501_GPIO_DATA_HIGH (0x04) ! 192: #define SM501_GPIO_DDR_LOW (0x08) ! 193: #define SM501_GPIO_DDR_HIGH (0x0C) ! 194: #define SM501_GPIO_IRQ_SETUP (0x10) ! 195: #define SM501_GPIO_IRQ_STATUS (0x14) ! 196: #define SM501_GPIO_IRQ_RESET (0x14) ! 197: ! 198: /* I2C controller base */ ! 199: #define SM501_I2C (0x010040) ! 200: #define SM501_I2C_BYTE_COUNT (0x00) ! 201: #define SM501_I2C_CONTROL (0x01) ! 202: #define SM501_I2C_STATUS (0x02) ! 203: #define SM501_I2C_RESET (0x02) ! 204: #define SM501_I2C_SLAVE_ADDRESS (0x03) ! 205: #define SM501_I2C_DATA (0x04) ! 206: ! 207: /* SSP base */ ! 208: #define SM501_SSP (0x020000) ! 209: ! 210: /* Uart 0 base */ ! 211: #define SM501_UART0 (0x030000) ! 212: ! 213: /* Uart 1 base */ ! 214: #define SM501_UART1 (0x030020) ! 215: ! 216: /* USB host port base */ ! 217: #define SM501_USB_HOST (0x040000) ! 218: ! 219: /* USB slave/gadget base */ ! 220: #define SM501_USB_GADGET (0x060000) ! 221: ! 222: /* USB slave/gadget data port base */ ! 223: #define SM501_USB_GADGET_DATA (0x070000) ! 224: ! 225: /* Display controller/video engine base */ ! 226: #define SM501_DC (0x080000) ! 227: ! 228: /* common defines for the SM501 address registers */ ! 229: #define SM501_ADDR_FLIP (1<<31) ! 230: #define SM501_ADDR_EXT (1<<27) ! 231: #define SM501_ADDR_CS1 (1<<26) ! 232: #define SM501_ADDR_MASK (0x3f << 26) ! 233: ! 234: #define SM501_FIFO_MASK (0x3 << 16) ! 235: #define SM501_FIFO_1 (0x0 << 16) ! 236: #define SM501_FIFO_3 (0x1 << 16) ! 237: #define SM501_FIFO_7 (0x2 << 16) ! 238: #define SM501_FIFO_11 (0x3 << 16) ! 239: ! 240: /* common registers for panel and the crt */ ! 241: #define SM501_OFF_DC_H_TOT (0x000) ! 242: #define SM501_OFF_DC_V_TOT (0x008) ! 243: #define SM501_OFF_DC_H_SYNC (0x004) ! 244: #define SM501_OFF_DC_V_SYNC (0x00C) ! 245: ! 246: #define SM501_DC_PANEL_CONTROL (0x000) ! 247: ! 248: #define SM501_DC_PANEL_CONTROL_FPEN (1<<27) ! 249: #define SM501_DC_PANEL_CONTROL_BIAS (1<<26) ! 250: #define SM501_DC_PANEL_CONTROL_DATA (1<<25) ! 251: #define SM501_DC_PANEL_CONTROL_VDD (1<<24) ! 252: #define SM501_DC_PANEL_CONTROL_DP (1<<23) ! 253: ! 254: #define SM501_DC_PANEL_CONTROL_TFT_888 (0<<21) ! 255: #define SM501_DC_PANEL_CONTROL_TFT_333 (1<<21) ! 256: #define SM501_DC_PANEL_CONTROL_TFT_444 (2<<21) ! 257: ! 258: #define SM501_DC_PANEL_CONTROL_DE (1<<20) ! 259: ! 260: #define SM501_DC_PANEL_CONTROL_LCD_TFT (0<<18) ! 261: #define SM501_DC_PANEL_CONTROL_LCD_STN8 (1<<18) ! 262: #define SM501_DC_PANEL_CONTROL_LCD_STN12 (2<<18) ! 263: ! 264: #define SM501_DC_PANEL_CONTROL_CP (1<<14) ! 265: #define SM501_DC_PANEL_CONTROL_VSP (1<<13) ! 266: #define SM501_DC_PANEL_CONTROL_HSP (1<<12) ! 267: #define SM501_DC_PANEL_CONTROL_CK (1<<9) ! 268: #define SM501_DC_PANEL_CONTROL_TE (1<<8) ! 269: #define SM501_DC_PANEL_CONTROL_VPD (1<<7) ! 270: #define SM501_DC_PANEL_CONTROL_VP (1<<6) ! 271: #define SM501_DC_PANEL_CONTROL_HPD (1<<5) ! 272: #define SM501_DC_PANEL_CONTROL_HP (1<<4) ! 273: #define SM501_DC_PANEL_CONTROL_GAMMA (1<<3) ! 274: #define SM501_DC_PANEL_CONTROL_EN (1<<2) ! 275: ! 276: #define SM501_DC_PANEL_CONTROL_8BPP (0<<0) ! 277: #define SM501_DC_PANEL_CONTROL_16BPP (1<<0) ! 278: #define SM501_DC_PANEL_CONTROL_32BPP (2<<0) ! 279: ! 280: ! 281: #define SM501_DC_PANEL_PANNING_CONTROL (0x004) ! 282: #define SM501_DC_PANEL_COLOR_KEY (0x008) ! 283: #define SM501_DC_PANEL_FB_ADDR (0x00C) ! 284: #define SM501_DC_PANEL_FB_OFFSET (0x010) ! 285: #define SM501_DC_PANEL_FB_WIDTH (0x014) ! 286: #define SM501_DC_PANEL_FB_HEIGHT (0x018) ! 287: #define SM501_DC_PANEL_TL_LOC (0x01C) ! 288: #define SM501_DC_PANEL_BR_LOC (0x020) ! 289: #define SM501_DC_PANEL_H_TOT (0x024) ! 290: #define SM501_DC_PANEL_H_SYNC (0x028) ! 291: #define SM501_DC_PANEL_V_TOT (0x02C) ! 292: #define SM501_DC_PANEL_V_SYNC (0x030) ! 293: #define SM501_DC_PANEL_CUR_LINE (0x034) ! 294: ! 295: #define SM501_DC_VIDEO_CONTROL (0x040) ! 296: #define SM501_DC_VIDEO_FB0_ADDR (0x044) ! 297: #define SM501_DC_VIDEO_FB_WIDTH (0x048) ! 298: #define SM501_DC_VIDEO_FB0_LAST_ADDR (0x04C) ! 299: #define SM501_DC_VIDEO_TL_LOC (0x050) ! 300: #define SM501_DC_VIDEO_BR_LOC (0x054) ! 301: #define SM501_DC_VIDEO_SCALE (0x058) ! 302: #define SM501_DC_VIDEO_INIT_SCALE (0x05C) ! 303: #define SM501_DC_VIDEO_YUV_CONSTANTS (0x060) ! 304: #define SM501_DC_VIDEO_FB1_ADDR (0x064) ! 305: #define SM501_DC_VIDEO_FB1_LAST_ADDR (0x068) ! 306: ! 307: #define SM501_DC_VIDEO_ALPHA_CONTROL (0x080) ! 308: #define SM501_DC_VIDEO_ALPHA_FB_ADDR (0x084) ! 309: #define SM501_DC_VIDEO_ALPHA_FB_OFFSET (0x088) ! 310: #define SM501_DC_VIDEO_ALPHA_FB_LAST_ADDR (0x08C) ! 311: #define SM501_DC_VIDEO_ALPHA_TL_LOC (0x090) ! 312: #define SM501_DC_VIDEO_ALPHA_BR_LOC (0x094) ! 313: #define SM501_DC_VIDEO_ALPHA_SCALE (0x098) ! 314: #define SM501_DC_VIDEO_ALPHA_INIT_SCALE (0x09C) ! 315: #define SM501_DC_VIDEO_ALPHA_CHROMA_KEY (0x0A0) ! 316: #define SM501_DC_VIDEO_ALPHA_COLOR_LOOKUP (0x0A4) ! 317: ! 318: #define SM501_DC_PANEL_HWC_BASE (0x0F0) ! 319: #define SM501_DC_PANEL_HWC_ADDR (0x0F0) ! 320: #define SM501_DC_PANEL_HWC_LOC (0x0F4) ! 321: #define SM501_DC_PANEL_HWC_COLOR_1_2 (0x0F8) ! 322: #define SM501_DC_PANEL_HWC_COLOR_3 (0x0FC) ! 323: ! 324: #define SM501_HWC_EN (1<<31) ! 325: ! 326: #define SM501_OFF_HWC_ADDR (0x00) ! 327: #define SM501_OFF_HWC_LOC (0x04) ! 328: #define SM501_OFF_HWC_COLOR_1_2 (0x08) ! 329: #define SM501_OFF_HWC_COLOR_3 (0x0C) ! 330: ! 331: #define SM501_DC_ALPHA_CONTROL (0x100) ! 332: #define SM501_DC_ALPHA_FB_ADDR (0x104) ! 333: #define SM501_DC_ALPHA_FB_OFFSET (0x108) ! 334: #define SM501_DC_ALPHA_TL_LOC (0x10C) ! 335: #define SM501_DC_ALPHA_BR_LOC (0x110) ! 336: #define SM501_DC_ALPHA_CHROMA_KEY (0x114) ! 337: #define SM501_DC_ALPHA_COLOR_LOOKUP (0x118) ! 338: ! 339: #define SM501_DC_CRT_CONTROL (0x200) ! 340: ! 341: #define SM501_DC_CRT_CONTROL_TVP (1<<15) ! 342: #define SM501_DC_CRT_CONTROL_CP (1<<14) ! 343: #define SM501_DC_CRT_CONTROL_VSP (1<<13) ! 344: #define SM501_DC_CRT_CONTROL_HSP (1<<12) ! 345: #define SM501_DC_CRT_CONTROL_VS (1<<11) ! 346: #define SM501_DC_CRT_CONTROL_BLANK (1<<10) ! 347: #define SM501_DC_CRT_CONTROL_SEL (1<<9) ! 348: #define SM501_DC_CRT_CONTROL_TE (1<<8) ! 349: #define SM501_DC_CRT_CONTROL_PIXEL_MASK (0xF << 4) ! 350: #define SM501_DC_CRT_CONTROL_GAMMA (1<<3) ! 351: #define SM501_DC_CRT_CONTROL_ENABLE (1<<2) ! 352: ! 353: #define SM501_DC_CRT_CONTROL_8BPP (0<<0) ! 354: #define SM501_DC_CRT_CONTROL_16BPP (1<<0) ! 355: #define SM501_DC_CRT_CONTROL_32BPP (2<<0) ! 356: ! 357: #define SM501_DC_CRT_FB_ADDR (0x204) ! 358: #define SM501_DC_CRT_FB_OFFSET (0x208) ! 359: #define SM501_DC_CRT_H_TOT (0x20C) ! 360: #define SM501_DC_CRT_H_SYNC (0x210) ! 361: #define SM501_DC_CRT_V_TOT (0x214) ! 362: #define SM501_DC_CRT_V_SYNC (0x218) ! 363: #define SM501_DC_CRT_SIGNATURE_ANALYZER (0x21C) ! 364: #define SM501_DC_CRT_CUR_LINE (0x220) ! 365: #define SM501_DC_CRT_MONITOR_DETECT (0x224) ! 366: ! 367: #define SM501_DC_CRT_HWC_BASE (0x230) ! 368: #define SM501_DC_CRT_HWC_ADDR (0x230) ! 369: #define SM501_DC_CRT_HWC_LOC (0x234) ! 370: #define SM501_DC_CRT_HWC_COLOR_1_2 (0x238) ! 371: #define SM501_DC_CRT_HWC_COLOR_3 (0x23C) ! 372: ! 373: #define SM501_DC_PANEL_PALETTE (0x400) ! 374: ! 375: #define SM501_DC_VIDEO_PALETTE (0x800) ! 376: ! 377: #define SM501_DC_CRT_PALETTE (0xC00) ! 378: ! 379: /* Zoom Video port base */ ! 380: #define SM501_ZVPORT (0x090000) ! 381: ! 382: /* AC97/I2S base */ ! 383: #define SM501_AC97 (0x0A0000) ! 384: ! 385: /* 8051 micro controller base */ ! 386: #define SM501_UCONTROLLER (0x0B0000) ! 387: ! 388: /* 8051 micro controller SRAM base */ ! 389: #define SM501_UCONTROLLER_SRAM (0x0C0000) ! 390: ! 391: /* DMA base */ ! 392: #define SM501_DMA (0x0D0000) ! 393: ! 394: /* 2d engine base */ ! 395: #define SM501_2D_ENGINE (0x100000) ! 396: #define SM501_2D_SOURCE (0x00) ! 397: #define SM501_2D_DESTINATION (0x04) ! 398: #define SM501_2D_DIMENSION (0x08) ! 399: #define SM501_2D_CONTROL (0x0C) ! 400: #define SM501_2D_PITCH (0x10) ! 401: #define SM501_2D_FOREGROUND (0x14) ! 402: #define SM501_2D_BACKGROUND (0x18) ! 403: #define SM501_2D_STRETCH (0x1C) ! 404: #define SM501_2D_COLOR_COMPARE (0x20) ! 405: #define SM501_2D_COLOR_COMPARE_MASK (0x24) ! 406: #define SM501_2D_MASK (0x28) ! 407: #define SM501_2D_CLIP_TL (0x2C) ! 408: #define SM501_2D_CLIP_BR (0x30) ! 409: #define SM501_2D_MONO_PATTERN_LOW (0x34) ! 410: #define SM501_2D_MONO_PATTERN_HIGH (0x38) ! 411: #define SM501_2D_WINDOW_WIDTH (0x3C) ! 412: #define SM501_2D_SOURCE_BASE (0x40) ! 413: #define SM501_2D_DESTINATION_BASE (0x44) ! 414: #define SM501_2D_ALPHA (0x48) ! 415: #define SM501_2D_WRAP (0x4C) ! 416: #define SM501_2D_STATUS (0x50) ! 417: ! 418: #define SM501_CSC_Y_SOURCE_BASE (0xC8) ! 419: #define SM501_CSC_CONSTANTS (0xCC) ! 420: #define SM501_CSC_Y_SOURCE_X (0xD0) ! 421: #define SM501_CSC_Y_SOURCE_Y (0xD4) ! 422: #define SM501_CSC_U_SOURCE_BASE (0xD8) ! 423: #define SM501_CSC_V_SOURCE_BASE (0xDC) ! 424: #define SM501_CSC_SOURCE_DIMENSION (0xE0) ! 425: #define SM501_CSC_SOURCE_PITCH (0xE4) ! 426: #define SM501_CSC_DESTINATION (0xE8) ! 427: #define SM501_CSC_DESTINATION_DIMENSION (0xEC) ! 428: #define SM501_CSC_DESTINATION_PITCH (0xF0) ! 429: #define SM501_CSC_SCALE_FACTOR (0xF4) ! 430: #define SM501_CSC_DESTINATION_BASE (0xF8) ! 431: #define SM501_CSC_CONTROL (0xFC) ! 432: ! 433: /* 2d engine data port base */ ! 434: #define SM501_2D_ENGINE_DATA (0x110000) ! 435: ! 436: /* end of register definitions */ ! 437: ! 438: ! 439: /* SM501 local memory size taken from "linux/drivers/mfd/sm501.c" */ ! 440: static const uint32_t sm501_mem_local_size[] = { ! 441: [0] = 4*1024*1024, ! 442: [1] = 8*1024*1024, ! 443: [2] = 16*1024*1024, ! 444: [3] = 32*1024*1024, ! 445: [4] = 64*1024*1024, ! 446: [5] = 2*1024*1024, ! 447: }; ! 448: #define get_local_mem_size(s) sm501_mem_local_size[(s)->local_mem_size_index] ! 449: ! 450: typedef struct SM501State { ! 451: /* graphic console status */ ! 452: DisplayState *ds; ! 453: ! 454: /* status & internal resources */ ! 455: target_phys_addr_t base; ! 456: uint32_t local_mem_size_index; ! 457: uint8_t * local_mem; ! 458: uint32_t last_width; ! 459: uint32_t last_height; ! 460: ! 461: /* mmio registers */ ! 462: uint32_t system_control; ! 463: uint32_t misc_control; ! 464: uint32_t gpio_31_0_control; ! 465: uint32_t gpio_63_32_control; ! 466: uint32_t dram_control; ! 467: uint32_t irq_mask; ! 468: uint32_t misc_timing; ! 469: uint32_t power_mode_control; ! 470: ! 471: uint32_t uart0_ier; ! 472: uint32_t uart0_lcr; ! 473: uint32_t uart0_mcr; ! 474: uint32_t uart0_scr; ! 475: ! 476: uint8_t dc_palette[0x400 * 3]; ! 477: ! 478: uint32_t dc_panel_control; ! 479: uint32_t dc_panel_panning_control; ! 480: uint32_t dc_panel_fb_addr; ! 481: uint32_t dc_panel_fb_offset; ! 482: uint32_t dc_panel_fb_width; ! 483: uint32_t dc_panel_fb_height; ! 484: uint32_t dc_panel_tl_location; ! 485: uint32_t dc_panel_br_location; ! 486: uint32_t dc_panel_h_total; ! 487: uint32_t dc_panel_h_sync; ! 488: uint32_t dc_panel_v_total; ! 489: uint32_t dc_panel_v_sync; ! 490: ! 491: uint32_t dc_panel_hwc_addr; ! 492: uint32_t dc_panel_hwc_location; ! 493: uint32_t dc_panel_hwc_color_1_2; ! 494: uint32_t dc_panel_hwc_color_3; ! 495: ! 496: uint32_t dc_crt_control; ! 497: uint32_t dc_crt_fb_addr; ! 498: uint32_t dc_crt_fb_offset; ! 499: uint32_t dc_crt_h_total; ! 500: uint32_t dc_crt_h_sync; ! 501: uint32_t dc_crt_v_total; ! 502: uint32_t dc_crt_v_sync; ! 503: ! 504: uint32_t dc_crt_hwc_addr; ! 505: uint32_t dc_crt_hwc_location; ! 506: uint32_t dc_crt_hwc_color_1_2; ! 507: uint32_t dc_crt_hwc_color_3; ! 508: ! 509: } SM501State; ! 510: ! 511: static uint32_t get_local_mem_size_index(uint32_t size) ! 512: { ! 513: uint32_t norm_size = 0; ! 514: int i, index = 0; ! 515: ! 516: for (i = 0; i < ARRAY_SIZE(sm501_mem_local_size); i++) { ! 517: uint32_t new_size = sm501_mem_local_size[i]; ! 518: if (new_size >= size) { ! 519: if (norm_size == 0 || norm_size > new_size) { ! 520: norm_size = new_size; ! 521: index = i; ! 522: } ! 523: } ! 524: } ! 525: ! 526: return index; ! 527: } ! 528: ! 529: static uint32_t sm501_system_config_read(void *opaque, target_phys_addr_t addr) ! 530: { ! 531: SM501State * s = (SM501State *)opaque; ! 532: uint32_t ret = 0; ! 533: SM501_DPRINTF("sm501 system config regs : read addr=%x\n", (int)addr); ! 534: ! 535: switch(addr) { ! 536: case SM501_SYSTEM_CONTROL: ! 537: ret = s->system_control; ! 538: break; ! 539: case SM501_MISC_CONTROL: ! 540: ret = s->misc_control; ! 541: break; ! 542: case SM501_GPIO31_0_CONTROL: ! 543: ret = s->gpio_31_0_control; ! 544: break; ! 545: case SM501_GPIO63_32_CONTROL: ! 546: ret = s->gpio_63_32_control; ! 547: break; ! 548: case SM501_DEVICEID: ! 549: ret = 0x050100A0; ! 550: break; ! 551: case SM501_DRAM_CONTROL: ! 552: ret = (s->dram_control & 0x07F107C0) | s->local_mem_size_index << 13; ! 553: break; ! 554: case SM501_IRQ_MASK: ! 555: ret = s->irq_mask; ! 556: break; ! 557: case SM501_MISC_TIMING: ! 558: /* TODO : simulate gate control */ ! 559: ret = s->misc_timing; ! 560: break; ! 561: case SM501_CURRENT_GATE: ! 562: /* TODO : simulate gate control */ ! 563: ret = 0x00021807; ! 564: break; ! 565: case SM501_CURRENT_CLOCK: ! 566: ret = 0x2A1A0A09; ! 567: break; ! 568: case SM501_POWER_MODE_CONTROL: ! 569: ret = s->power_mode_control; ! 570: break; ! 571: ! 572: default: ! 573: printf("sm501 system config : not implemented register read." ! 574: " addr=%x\n", (int)addr); ! 575: assert(0); ! 576: } ! 577: ! 578: return ret; ! 579: } ! 580: ! 581: static void sm501_system_config_write(void *opaque, ! 582: target_phys_addr_t addr, uint32_t value) ! 583: { ! 584: SM501State * s = (SM501State *)opaque; ! 585: SM501_DPRINTF("sm501 system config regs : write addr=%x, val=%x\n", ! 586: addr, value); ! 587: ! 588: switch(addr) { ! 589: case SM501_SYSTEM_CONTROL: ! 590: s->system_control = value & 0xE300B8F7; ! 591: break; ! 592: case SM501_MISC_CONTROL: ! 593: s->misc_control = value & 0xFF7FFF20; ! 594: break; ! 595: case SM501_GPIO31_0_CONTROL: ! 596: s->gpio_31_0_control = value; ! 597: break; ! 598: case SM501_GPIO63_32_CONTROL: ! 599: s->gpio_63_32_control = value; ! 600: break; ! 601: case SM501_DRAM_CONTROL: ! 602: s->local_mem_size_index = (value >> 13) & 0x7; ! 603: /* rODO : check validity of size change */ ! 604: s->dram_control |= value & 0x7FFFFFC3; ! 605: break; ! 606: case SM501_IRQ_MASK: ! 607: s->irq_mask = value; ! 608: break; ! 609: case SM501_MISC_TIMING: ! 610: s->misc_timing = value & 0xF31F1FFF; ! 611: break; ! 612: case SM501_POWER_MODE_0_GATE: ! 613: case SM501_POWER_MODE_1_GATE: ! 614: case SM501_POWER_MODE_0_CLOCK: ! 615: case SM501_POWER_MODE_1_CLOCK: ! 616: /* TODO : simulate gate & clock control */ ! 617: break; ! 618: case SM501_POWER_MODE_CONTROL: ! 619: s->power_mode_control = value & 0x00000003; ! 620: break; ! 621: ! 622: default: ! 623: printf("sm501 system config : not implemented register write." ! 624: " addr=%x, val=%x\n", (int)addr, value); ! 625: assert(0); ! 626: } ! 627: } ! 628: ! 629: static CPUReadMemoryFunc *sm501_system_config_readfn[] = { ! 630: NULL, ! 631: NULL, ! 632: &sm501_system_config_read, ! 633: }; ! 634: ! 635: static CPUWriteMemoryFunc *sm501_system_config_writefn[] = { ! 636: NULL, ! 637: NULL, ! 638: &sm501_system_config_write, ! 639: }; ! 640: ! 641: static uint32_t sm501_palette_read(void *opaque, target_phys_addr_t addr) ! 642: { ! 643: SM501State * s = (SM501State *)opaque; ! 644: SM501_DPRINTF("sm501 palette read addr=%x\n", (int)addr); ! 645: ! 646: /* TODO : consider BYTE/WORD access */ ! 647: /* TODO : consider endian */ ! 648: ! 649: assert(0 <= addr && addr < 0x400 * 3); ! 650: return *(uint32_t*)&s->dc_palette[addr]; ! 651: } ! 652: ! 653: static void sm501_palette_write(void *opaque, ! 654: target_phys_addr_t addr, uint32_t value) ! 655: { ! 656: SM501State * s = (SM501State *)opaque; ! 657: SM501_DPRINTF("sm501 palette write addr=%x, val=%x\n", ! 658: (int)addr, value); ! 659: ! 660: /* TODO : consider BYTE/WORD access */ ! 661: /* TODO : consider endian */ ! 662: ! 663: assert(0 <= addr && addr < 0x400 * 3); ! 664: *(uint32_t*)&s->dc_palette[addr] = value; ! 665: } ! 666: ! 667: static uint32_t sm501_disp_ctrl_read(void *opaque, target_phys_addr_t addr) ! 668: { ! 669: SM501State * s = (SM501State *)opaque; ! 670: uint32_t ret = 0; ! 671: SM501_DPRINTF("sm501 disp ctrl regs : read addr=%x\n", (int)addr); ! 672: ! 673: switch(addr) { ! 674: ! 675: case SM501_DC_PANEL_CONTROL: ! 676: ret = s->dc_panel_control; ! 677: break; ! 678: case SM501_DC_PANEL_PANNING_CONTROL: ! 679: ret = s->dc_panel_panning_control; ! 680: break; ! 681: case SM501_DC_PANEL_FB_ADDR: ! 682: ret = s->dc_panel_fb_addr; ! 683: break; ! 684: case SM501_DC_PANEL_FB_OFFSET: ! 685: ret = s->dc_panel_fb_offset; ! 686: break; ! 687: case SM501_DC_PANEL_FB_WIDTH: ! 688: ret = s->dc_panel_fb_width; ! 689: break; ! 690: case SM501_DC_PANEL_FB_HEIGHT: ! 691: ret = s->dc_panel_fb_height; ! 692: break; ! 693: case SM501_DC_PANEL_TL_LOC: ! 694: ret = s->dc_panel_tl_location; ! 695: break; ! 696: case SM501_DC_PANEL_BR_LOC: ! 697: ret = s->dc_panel_br_location; ! 698: break; ! 699: ! 700: case SM501_DC_PANEL_H_TOT: ! 701: ret = s->dc_panel_h_total; ! 702: break; ! 703: case SM501_DC_PANEL_H_SYNC: ! 704: ret = s->dc_panel_h_sync; ! 705: break; ! 706: case SM501_DC_PANEL_V_TOT: ! 707: ret = s->dc_panel_v_total; ! 708: break; ! 709: case SM501_DC_PANEL_V_SYNC: ! 710: ret = s->dc_panel_v_sync; ! 711: break; ! 712: ! 713: case SM501_DC_CRT_CONTROL: ! 714: ret = s->dc_crt_control; ! 715: break; ! 716: case SM501_DC_CRT_FB_ADDR: ! 717: ret = s->dc_crt_fb_addr; ! 718: break; ! 719: case SM501_DC_CRT_FB_OFFSET: ! 720: ret = s->dc_crt_fb_offset; ! 721: break; ! 722: case SM501_DC_CRT_H_TOT: ! 723: ret = s->dc_crt_h_total; ! 724: break; ! 725: case SM501_DC_CRT_H_SYNC: ! 726: ret = s->dc_crt_h_sync; ! 727: break; ! 728: case SM501_DC_CRT_V_TOT: ! 729: ret = s->dc_crt_v_total; ! 730: break; ! 731: case SM501_DC_CRT_V_SYNC: ! 732: ret = s->dc_crt_v_sync; ! 733: break; ! 734: ! 735: case SM501_DC_CRT_HWC_ADDR: ! 736: ret = s->dc_crt_hwc_addr; ! 737: break; ! 738: case SM501_DC_CRT_HWC_LOC: ! 739: ret = s->dc_crt_hwc_addr; ! 740: break; ! 741: case SM501_DC_CRT_HWC_COLOR_1_2: ! 742: ret = s->dc_crt_hwc_addr; ! 743: break; ! 744: case SM501_DC_CRT_HWC_COLOR_3: ! 745: ret = s->dc_crt_hwc_addr; ! 746: break; ! 747: ! 748: case SM501_DC_PANEL_PALETTE ... SM501_DC_PANEL_PALETTE + 0x400*3 - 4: ! 749: ret = sm501_palette_read(opaque, addr - SM501_DC_PANEL_PALETTE); ! 750: break; ! 751: ! 752: default: ! 753: printf("sm501 disp ctrl : not implemented register read." ! 754: " addr=%x\n", (int)addr); ! 755: assert(0); ! 756: } ! 757: ! 758: return ret; ! 759: } ! 760: ! 761: static void sm501_disp_ctrl_write(void *opaque, ! 762: target_phys_addr_t addr, ! 763: uint32_t value) ! 764: { ! 765: SM501State * s = (SM501State *)opaque; ! 766: SM501_DPRINTF("sm501 disp ctrl regs : write addr=%x, val=%x\n", ! 767: addr, value); ! 768: ! 769: switch(addr) { ! 770: case SM501_DC_PANEL_CONTROL: ! 771: s->dc_panel_control = value & 0x0FFF73FF; ! 772: break; ! 773: case SM501_DC_PANEL_PANNING_CONTROL: ! 774: s->dc_panel_panning_control = value & 0xFF3FFF3F; ! 775: break; ! 776: case SM501_DC_PANEL_FB_ADDR: ! 777: s->dc_panel_fb_addr = value & 0x8FFFFFF0; ! 778: break; ! 779: case SM501_DC_PANEL_FB_OFFSET: ! 780: s->dc_panel_fb_offset = value & 0x3FF03FF0; ! 781: break; ! 782: case SM501_DC_PANEL_FB_WIDTH: ! 783: s->dc_panel_fb_width = value & 0x0FFF0FFF; ! 784: break; ! 785: case SM501_DC_PANEL_FB_HEIGHT: ! 786: s->dc_panel_fb_height = value & 0x0FFF0FFF; ! 787: break; ! 788: case SM501_DC_PANEL_TL_LOC: ! 789: s->dc_panel_tl_location = value & 0x07FF07FF; ! 790: break; ! 791: case SM501_DC_PANEL_BR_LOC: ! 792: s->dc_panel_br_location = value & 0x07FF07FF; ! 793: break; ! 794: ! 795: case SM501_DC_PANEL_H_TOT: ! 796: s->dc_panel_h_total = value & 0x0FFF0FFF; ! 797: break; ! 798: case SM501_DC_PANEL_H_SYNC: ! 799: s->dc_panel_h_sync = value & 0x00FF0FFF; ! 800: break; ! 801: case SM501_DC_PANEL_V_TOT: ! 802: s->dc_panel_v_total = value & 0x0FFF0FFF; ! 803: break; ! 804: case SM501_DC_PANEL_V_SYNC: ! 805: s->dc_panel_v_sync = value & 0x003F0FFF; ! 806: break; ! 807: ! 808: case SM501_DC_PANEL_HWC_ADDR: ! 809: s->dc_panel_hwc_addr = value & 0x8FFFFFF0; ! 810: break; ! 811: case SM501_DC_PANEL_HWC_LOC: ! 812: s->dc_panel_hwc_addr = value & 0x0FFF0FFF; ! 813: break; ! 814: case SM501_DC_PANEL_HWC_COLOR_1_2: ! 815: s->dc_panel_hwc_addr = value; ! 816: break; ! 817: case SM501_DC_PANEL_HWC_COLOR_3: ! 818: s->dc_panel_hwc_addr = value & 0x0000FFFF; ! 819: break; ! 820: ! 821: case SM501_DC_CRT_CONTROL: ! 822: s->dc_crt_control = value & 0x0003FFFF; ! 823: break; ! 824: case SM501_DC_CRT_FB_ADDR: ! 825: s->dc_crt_fb_addr = value & 0x8FFFFFF0; ! 826: break; ! 827: case SM501_DC_CRT_FB_OFFSET: ! 828: s->dc_crt_fb_offset = value & 0x3FF03FF0; ! 829: break; ! 830: case SM501_DC_CRT_H_TOT: ! 831: s->dc_crt_h_total = value & 0x0FFF0FFF; ! 832: break; ! 833: case SM501_DC_CRT_H_SYNC: ! 834: s->dc_crt_h_sync = value & 0x00FF0FFF; ! 835: break; ! 836: case SM501_DC_CRT_V_TOT: ! 837: s->dc_crt_v_total = value & 0x0FFF0FFF; ! 838: break; ! 839: case SM501_DC_CRT_V_SYNC: ! 840: s->dc_crt_v_sync = value & 0x003F0FFF; ! 841: break; ! 842: ! 843: case SM501_DC_CRT_HWC_ADDR: ! 844: s->dc_crt_hwc_addr = value & 0x8FFFFFF0; ! 845: break; ! 846: case SM501_DC_CRT_HWC_LOC: ! 847: s->dc_crt_hwc_addr = value & 0x0FFF0FFF; ! 848: break; ! 849: case SM501_DC_CRT_HWC_COLOR_1_2: ! 850: s->dc_crt_hwc_addr = value; ! 851: break; ! 852: case SM501_DC_CRT_HWC_COLOR_3: ! 853: s->dc_crt_hwc_addr = value & 0x0000FFFF; ! 854: break; ! 855: ! 856: case SM501_DC_PANEL_PALETTE ... SM501_DC_PANEL_PALETTE + 0x400*3 - 4: ! 857: sm501_palette_write(opaque, addr - SM501_DC_PANEL_PALETTE, value); ! 858: break; ! 859: ! 860: default: ! 861: printf("sm501 disp ctrl : not implemented register write." ! 862: " addr=%x, val=%x\n", (int)addr, value); ! 863: assert(0); ! 864: } ! 865: } ! 866: ! 867: static CPUReadMemoryFunc *sm501_disp_ctrl_readfn[] = { ! 868: NULL, ! 869: NULL, ! 870: &sm501_disp_ctrl_read, ! 871: }; ! 872: ! 873: static CPUWriteMemoryFunc *sm501_disp_ctrl_writefn[] = { ! 874: NULL, ! 875: NULL, ! 876: &sm501_disp_ctrl_write, ! 877: }; ! 878: ! 879: /* draw line functions for all console modes */ ! 880: ! 881: #include "pixel_ops.h" ! 882: ! 883: typedef void draw_line_func(uint8_t *d, const uint8_t *s, ! 884: int width, const uint32_t *pal); ! 885: ! 886: #define DEPTH 8 ! 887: #include "sm501_template.h" ! 888: ! 889: #define DEPTH 15 ! 890: #include "sm501_template.h" ! 891: ! 892: #define BGR_FORMAT ! 893: #define DEPTH 15 ! 894: #include "sm501_template.h" ! 895: ! 896: #define DEPTH 16 ! 897: #include "sm501_template.h" ! 898: ! 899: #define BGR_FORMAT ! 900: #define DEPTH 16 ! 901: #include "sm501_template.h" ! 902: ! 903: #define DEPTH 32 ! 904: #include "sm501_template.h" ! 905: ! 906: #define BGR_FORMAT ! 907: #define DEPTH 32 ! 908: #include "sm501_template.h" ! 909: ! 910: static draw_line_func * draw_line8_funcs[] = { ! 911: draw_line8_8, ! 912: draw_line8_15, ! 913: draw_line8_16, ! 914: draw_line8_32, ! 915: draw_line8_32bgr, ! 916: draw_line8_15bgr, ! 917: draw_line8_16bgr, ! 918: }; ! 919: ! 920: static draw_line_func * draw_line16_funcs[] = { ! 921: draw_line16_8, ! 922: draw_line16_15, ! 923: draw_line16_16, ! 924: draw_line16_32, ! 925: draw_line16_32bgr, ! 926: draw_line16_15bgr, ! 927: draw_line16_16bgr, ! 928: }; ! 929: ! 930: static draw_line_func * draw_line32_funcs[] = { ! 931: draw_line32_8, ! 932: draw_line32_15, ! 933: draw_line32_16, ! 934: draw_line32_32, ! 935: draw_line32_32bgr, ! 936: draw_line32_15bgr, ! 937: draw_line32_16bgr, ! 938: }; ! 939: ! 940: static inline int get_depth_index(DisplayState *s) ! 941: { ! 942: switch(ds_get_bits_per_pixel(s)) { ! 943: default: ! 944: case 8: ! 945: return 0; ! 946: case 15: ! 947: return 1; ! 948: case 16: ! 949: return 2; ! 950: case 32: ! 951: return 3; ! 952: } ! 953: } ! 954: ! 955: static void sm501_draw_crt(SM501State * s) ! 956: { ! 957: int y; ! 958: int width = (s->dc_crt_h_total & 0x00000FFF) + 1; ! 959: int height = (s->dc_crt_v_total & 0x00000FFF) + 1; ! 960: ! 961: uint8_t * src = s->local_mem; ! 962: int src_bpp = 0; ! 963: int dst_bpp = ds_get_bytes_per_pixel(s->ds) + (ds_get_bits_per_pixel(s->ds) % 8 ? 1 : 0); ! 964: uint32_t * palette = (uint32_t *)&s->dc_palette[SM501_DC_CRT_PALETTE ! 965: - SM501_DC_PANEL_PALETTE]; ! 966: int ds_depth_index = get_depth_index(s->ds); ! 967: draw_line_func * draw_line = NULL; ! 968: int full_update = 0; ! 969: int y_start = -1; ! 970: int page_min = 0x7fffffff; ! 971: int page_max = -1; ! 972: ! 973: /* choose draw_line function */ ! 974: switch (s->dc_crt_control & 3) { ! 975: case SM501_DC_CRT_CONTROL_8BPP: ! 976: src_bpp = 1; ! 977: draw_line = draw_line8_funcs[ds_depth_index]; ! 978: break; ! 979: case SM501_DC_CRT_CONTROL_16BPP: ! 980: src_bpp = 2; ! 981: draw_line = draw_line16_funcs[ds_depth_index]; ! 982: break; ! 983: case SM501_DC_CRT_CONTROL_32BPP: ! 984: src_bpp = 4; ! 985: draw_line = draw_line32_funcs[ds_depth_index]; ! 986: break; ! 987: default: ! 988: printf("sm501 draw crt : invalid DC_CRT_CONTROL=%x.\n", ! 989: s->dc_crt_control); ! 990: assert(0); ! 991: break; ! 992: } ! 993: ! 994: /* adjust console size */ ! 995: if (s->last_width != width || s->last_height != height) { ! 996: qemu_console_resize(s->ds, width, height); ! 997: s->last_width = width; ! 998: s->last_height = height; ! 999: full_update = 1; ! 1000: } ! 1001: ! 1002: /* draw each line according to conditions */ ! 1003: for (y = 0; y < height; y++) { ! 1004: int update = full_update; ! 1005: uint8_t * line_end = &src[width * src_bpp - 1]; ! 1006: int page0 = (src - phys_ram_base) & TARGET_PAGE_MASK; ! 1007: int page1 = (line_end - phys_ram_base) & TARGET_PAGE_MASK; ! 1008: int page; ! 1009: ! 1010: /* check dirty flags for each line */ ! 1011: for (page = page0; page <= page1; page += TARGET_PAGE_SIZE) ! 1012: if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG)) ! 1013: update = 1; ! 1014: ! 1015: /* draw line and change status */ ! 1016: if (update) { ! 1017: draw_line(&(ds_get_data(s->ds)[y * width * dst_bpp]), src, width, palette); ! 1018: if (y_start < 0) ! 1019: y_start = y; ! 1020: if (page0 < page_min) ! 1021: page_min = page0; ! 1022: if (page1 > page_max) ! 1023: page_max = page1; ! 1024: } else { ! 1025: if (y_start >= 0) { ! 1026: /* flush to display */ ! 1027: dpy_update(s->ds, 0, y_start, width, y - y_start); ! 1028: y_start = -1; ! 1029: } ! 1030: } ! 1031: ! 1032: src += width * src_bpp; ! 1033: } ! 1034: ! 1035: /* complete flush to display */ ! 1036: if (y_start >= 0) ! 1037: dpy_update(s->ds, 0, y_start, width, y - y_start); ! 1038: ! 1039: /* clear dirty flags */ ! 1040: if (page_max != -1) ! 1041: cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, ! 1042: VGA_DIRTY_FLAG); ! 1043: } ! 1044: ! 1045: static void sm501_update_display(void *opaque) ! 1046: { ! 1047: SM501State * s = (SM501State *)opaque; ! 1048: ! 1049: if (s->dc_crt_control & SM501_DC_CRT_CONTROL_ENABLE) ! 1050: sm501_draw_crt(s); ! 1051: } ! 1052: ! 1053: void sm501_init(uint32_t base, unsigned long local_mem_base, ! 1054: uint32_t local_mem_bytes, CharDriverState *chr) ! 1055: { ! 1056: SM501State * s; ! 1057: int sm501_system_config_index; ! 1058: int sm501_disp_ctrl_index; ! 1059: ! 1060: /* allocate management data region */ ! 1061: s = (SM501State *)qemu_mallocz(sizeof(SM501State)); ! 1062: s->base = base; ! 1063: s->local_mem_size_index ! 1064: = get_local_mem_size_index(local_mem_bytes); ! 1065: SM501_DPRINTF("local mem size=%x. index=%d\n", get_local_mem_size(s), ! 1066: s->local_mem_size_index); ! 1067: s->system_control = 0x00100000; ! 1068: s->misc_control = 0x00001000; /* assumes SH, active=low */ ! 1069: s->dc_panel_control = 0x00010000; ! 1070: s->dc_crt_control = 0x00010000; ! 1071: ! 1072: /* allocate local memory */ ! 1073: s->local_mem = (uint8 *)phys_ram_base + local_mem_base; ! 1074: cpu_register_physical_memory(base, local_mem_bytes, local_mem_base); ! 1075: ! 1076: /* map mmio */ ! 1077: sm501_system_config_index ! 1078: = cpu_register_io_memory(0, sm501_system_config_readfn, ! 1079: sm501_system_config_writefn, s); ! 1080: cpu_register_physical_memory(base + MMIO_BASE_OFFSET, ! 1081: 0x6c, sm501_system_config_index); ! 1082: sm501_disp_ctrl_index = cpu_register_io_memory(0, sm501_disp_ctrl_readfn, ! 1083: sm501_disp_ctrl_writefn, s); ! 1084: cpu_register_physical_memory(base + MMIO_BASE_OFFSET + SM501_DC, ! 1085: 0x1000, sm501_disp_ctrl_index); ! 1086: ! 1087: /* bridge to serial emulation module */ ! 1088: if (chr) ! 1089: serial_mm_init(base + MMIO_BASE_OFFSET + SM501_UART0, 2, ! 1090: 0, /* TODO : chain irq to IRL */ ! 1091: 115200, chr, 1); ! 1092: ! 1093: /* create qemu graphic console */ ! 1094: s->ds = graphic_console_init(sm501_update_display, NULL, ! 1095: NULL, NULL, s); ! 1096: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.