Annotation of qemu/hw/sm501.c, revision 1.1.1.3

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 "hw.h"
                     27: #include "pc.h"
                     28: #include "console.h"
                     29: #include "devices.h"
                     30: 
                     31: /*
                     32:  * Status: 2008/11/02
                     33:  *   - Minimum implementation for Linux console : mmio regs and CRT layer.
                     34:  *   - Always updates full screen.
                     35:  *
                     36:  * TODO:
                     37:  *   - Panel support
                     38:  *   - Hardware cursor support
                     39:  *   - Touch panel support
                     40:  *   - USB support
                     41:  *   - UART support
                     42:  *   - Performance tuning
                     43:  */
                     44: 
                     45: //#define DEBUG_SM501
                     46: //#define DEBUG_BITBLT
                     47: 
                     48: #ifdef DEBUG_SM501
1.1.1.2   root       49: #define SM501_DPRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
1.1       root       50: #else
1.1.1.2   root       51: #define SM501_DPRINTF(fmt, ...) do {} while(0)
1.1       root       52: #endif
                     53: 
                     54: 
                     55: #define MMIO_BASE_OFFSET 0x3e00000
                     56: 
                     57: /* SM501 register definitions taken from "linux/include/linux/sm501-regs.h" */
                     58: 
                     59: /* System Configuration area */
                     60: /* System config base */
                     61: #define SM501_SYS_CONFIG               (0x000000)
                     62: 
                     63: /* config 1 */
                     64: #define SM501_SYSTEM_CONTROL           (0x000000)
                     65: 
                     66: #define SM501_SYSCTRL_PANEL_TRISTATE   (1<<0)
                     67: #define SM501_SYSCTRL_MEM_TRISTATE     (1<<1)
                     68: #define SM501_SYSCTRL_CRT_TRISTATE     (1<<2)
                     69: 
                     70: #define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3<<4)
                     71: #define SM501_SYSCTRL_PCI_SLAVE_BURST_1        (0<<4)
                     72: #define SM501_SYSCTRL_PCI_SLAVE_BURST_2        (1<<4)
                     73: #define SM501_SYSCTRL_PCI_SLAVE_BURST_4        (2<<4)
                     74: #define SM501_SYSCTRL_PCI_SLAVE_BURST_8        (3<<4)
                     75: 
                     76: #define SM501_SYSCTRL_PCI_CLOCK_RUN_EN (1<<6)
                     77: #define SM501_SYSCTRL_PCI_RETRY_DISABLE        (1<<7)
                     78: #define SM501_SYSCTRL_PCI_SUBSYS_LOCK  (1<<11)
                     79: #define SM501_SYSCTRL_PCI_BURST_READ_EN        (1<<15)
                     80: 
                     81: /* miscellaneous control */
                     82: 
                     83: #define SM501_MISC_CONTROL             (0x000004)
                     84: 
                     85: #define SM501_MISC_BUS_SH              (0x0)
                     86: #define SM501_MISC_BUS_PCI             (0x1)
                     87: #define SM501_MISC_BUS_XSCALE          (0x2)
                     88: #define SM501_MISC_BUS_NEC             (0x6)
                     89: #define SM501_MISC_BUS_MASK            (0x7)
                     90: 
                     91: #define SM501_MISC_VR_62MB             (1<<3)
                     92: #define SM501_MISC_CDR_RESET           (1<<7)
                     93: #define SM501_MISC_USB_LB              (1<<8)
                     94: #define SM501_MISC_USB_SLAVE           (1<<9)
                     95: #define SM501_MISC_BL_1                        (1<<10)
                     96: #define SM501_MISC_MC                  (1<<11)
                     97: #define SM501_MISC_DAC_POWER           (1<<12)
                     98: #define SM501_MISC_IRQ_INVERT          (1<<16)
                     99: #define SM501_MISC_SH                  (1<<17)
                    100: 
                    101: #define SM501_MISC_HOLD_EMPTY          (0<<18)
                    102: #define SM501_MISC_HOLD_8              (1<<18)
                    103: #define SM501_MISC_HOLD_16             (2<<18)
                    104: #define SM501_MISC_HOLD_24             (3<<18)
                    105: #define SM501_MISC_HOLD_32             (4<<18)
                    106: #define SM501_MISC_HOLD_MASK           (7<<18)
                    107: 
                    108: #define SM501_MISC_FREQ_12             (1<<24)
                    109: #define SM501_MISC_PNL_24BIT           (1<<25)
                    110: #define SM501_MISC_8051_LE             (1<<26)
                    111: 
                    112: 
                    113: 
                    114: #define SM501_GPIO31_0_CONTROL         (0x000008)
                    115: #define SM501_GPIO63_32_CONTROL                (0x00000C)
                    116: #define SM501_DRAM_CONTROL             (0x000010)
                    117: 
                    118: /* command list */
                    119: #define SM501_ARBTRTN_CONTROL          (0x000014)
                    120: 
                    121: /* command list */
                    122: #define SM501_COMMAND_LIST_STATUS      (0x000024)
                    123: 
                    124: /* interrupt debug */
                    125: #define SM501_RAW_IRQ_STATUS           (0x000028)
                    126: #define SM501_RAW_IRQ_CLEAR            (0x000028)
                    127: #define SM501_IRQ_STATUS               (0x00002C)
                    128: #define SM501_IRQ_MASK                 (0x000030)
                    129: #define SM501_DEBUG_CONTROL            (0x000034)
                    130: 
                    131: /* power management */
                    132: #define SM501_POWERMODE_P2X_SRC                (1<<29)
                    133: #define SM501_POWERMODE_V2X_SRC                (1<<20)
                    134: #define SM501_POWERMODE_M_SRC          (1<<12)
                    135: #define SM501_POWERMODE_M1_SRC         (1<<4)
                    136: 
                    137: #define SM501_CURRENT_GATE             (0x000038)
                    138: #define SM501_CURRENT_CLOCK            (0x00003C)
                    139: #define SM501_POWER_MODE_0_GATE                (0x000040)
                    140: #define SM501_POWER_MODE_0_CLOCK       (0x000044)
                    141: #define SM501_POWER_MODE_1_GATE                (0x000048)
                    142: #define SM501_POWER_MODE_1_CLOCK       (0x00004C)
                    143: #define SM501_SLEEP_MODE_GATE          (0x000050)
                    144: #define SM501_POWER_MODE_CONTROL       (0x000054)
                    145: 
                    146: /* power gates for units within the 501 */
                    147: #define SM501_GATE_HOST                        (0)
                    148: #define SM501_GATE_MEMORY              (1)
                    149: #define SM501_GATE_DISPLAY             (2)
                    150: #define SM501_GATE_2D_ENGINE           (3)
                    151: #define SM501_GATE_CSC                 (4)
                    152: #define SM501_GATE_ZVPORT              (5)
                    153: #define SM501_GATE_GPIO                        (6)
                    154: #define SM501_GATE_UART0               (7)
                    155: #define SM501_GATE_UART1               (8)
                    156: #define SM501_GATE_SSP                 (10)
                    157: #define SM501_GATE_USB_HOST            (11)
                    158: #define SM501_GATE_USB_GADGET          (12)
                    159: #define SM501_GATE_UCONTROLLER         (17)
                    160: #define SM501_GATE_AC97                        (18)
                    161: 
                    162: /* panel clock */
                    163: #define SM501_CLOCK_P2XCLK             (24)
                    164: /* crt clock */
                    165: #define SM501_CLOCK_V2XCLK             (16)
                    166: /* main clock */
                    167: #define SM501_CLOCK_MCLK               (8)
                    168: /* SDRAM controller clock */
                    169: #define SM501_CLOCK_M1XCLK             (0)
                    170: 
                    171: /* config 2 */
                    172: #define SM501_PCI_MASTER_BASE          (0x000058)
                    173: #define SM501_ENDIAN_CONTROL           (0x00005C)
                    174: #define SM501_DEVICEID                 (0x000060)
                    175: /* 0x050100A0 */
                    176: 
                    177: #define SM501_DEVICEID_SM501           (0x05010000)
                    178: #define SM501_DEVICEID_IDMASK          (0xffff0000)
                    179: #define SM501_DEVICEID_REVMASK         (0x000000ff)
                    180: 
                    181: #define SM501_PLLCLOCK_COUNT           (0x000064)
                    182: #define SM501_MISC_TIMING              (0x000068)
                    183: #define SM501_CURRENT_SDRAM_CLOCK      (0x00006C)
                    184: 
                    185: #define SM501_PROGRAMMABLE_PLL_CONTROL (0x000074)
                    186: 
                    187: /* GPIO base */
                    188: #define SM501_GPIO                     (0x010000)
                    189: #define SM501_GPIO_DATA_LOW            (0x00)
                    190: #define SM501_GPIO_DATA_HIGH           (0x04)
                    191: #define SM501_GPIO_DDR_LOW             (0x08)
                    192: #define SM501_GPIO_DDR_HIGH            (0x0C)
                    193: #define SM501_GPIO_IRQ_SETUP           (0x10)
                    194: #define SM501_GPIO_IRQ_STATUS          (0x14)
                    195: #define SM501_GPIO_IRQ_RESET           (0x14)
                    196: 
                    197: /* I2C controller base */
                    198: #define SM501_I2C                      (0x010040)
                    199: #define SM501_I2C_BYTE_COUNT           (0x00)
                    200: #define SM501_I2C_CONTROL              (0x01)
                    201: #define SM501_I2C_STATUS               (0x02)
                    202: #define SM501_I2C_RESET                        (0x02)
                    203: #define SM501_I2C_SLAVE_ADDRESS                (0x03)
                    204: #define SM501_I2C_DATA                 (0x04)
                    205: 
                    206: /* SSP base */
                    207: #define SM501_SSP                      (0x020000)
                    208: 
                    209: /* Uart 0 base */
                    210: #define SM501_UART0                    (0x030000)
                    211: 
                    212: /* Uart 1 base */
                    213: #define SM501_UART1                    (0x030020)
                    214: 
                    215: /* USB host port base */
                    216: #define SM501_USB_HOST                 (0x040000)
                    217: 
                    218: /* USB slave/gadget base */
                    219: #define SM501_USB_GADGET               (0x060000)
                    220: 
                    221: /* USB slave/gadget data port base */
                    222: #define SM501_USB_GADGET_DATA          (0x070000)
                    223: 
                    224: /* Display controller/video engine base */
                    225: #define SM501_DC                       (0x080000)
                    226: 
                    227: /* common defines for the SM501 address registers */
                    228: #define SM501_ADDR_FLIP                        (1<<31)
                    229: #define SM501_ADDR_EXT                 (1<<27)
                    230: #define SM501_ADDR_CS1                 (1<<26)
                    231: #define SM501_ADDR_MASK                        (0x3f << 26)
                    232: 
                    233: #define SM501_FIFO_MASK                        (0x3 << 16)
                    234: #define SM501_FIFO_1                   (0x0 << 16)
                    235: #define SM501_FIFO_3                   (0x1 << 16)
                    236: #define SM501_FIFO_7                   (0x2 << 16)
                    237: #define SM501_FIFO_11                  (0x3 << 16)
                    238: 
                    239: /* common registers for panel and the crt */
                    240: #define SM501_OFF_DC_H_TOT             (0x000)
                    241: #define SM501_OFF_DC_V_TOT             (0x008)
                    242: #define SM501_OFF_DC_H_SYNC            (0x004)
                    243: #define SM501_OFF_DC_V_SYNC            (0x00C)
                    244: 
                    245: #define SM501_DC_PANEL_CONTROL         (0x000)
                    246: 
                    247: #define SM501_DC_PANEL_CONTROL_FPEN    (1<<27)
                    248: #define SM501_DC_PANEL_CONTROL_BIAS    (1<<26)
                    249: #define SM501_DC_PANEL_CONTROL_DATA    (1<<25)
                    250: #define SM501_DC_PANEL_CONTROL_VDD     (1<<24)
                    251: #define SM501_DC_PANEL_CONTROL_DP      (1<<23)
                    252: 
                    253: #define SM501_DC_PANEL_CONTROL_TFT_888 (0<<21)
                    254: #define SM501_DC_PANEL_CONTROL_TFT_333 (1<<21)
                    255: #define SM501_DC_PANEL_CONTROL_TFT_444 (2<<21)
                    256: 
                    257: #define SM501_DC_PANEL_CONTROL_DE      (1<<20)
                    258: 
                    259: #define SM501_DC_PANEL_CONTROL_LCD_TFT (0<<18)
                    260: #define SM501_DC_PANEL_CONTROL_LCD_STN8        (1<<18)
                    261: #define SM501_DC_PANEL_CONTROL_LCD_STN12 (2<<18)
                    262: 
                    263: #define SM501_DC_PANEL_CONTROL_CP      (1<<14)
                    264: #define SM501_DC_PANEL_CONTROL_VSP     (1<<13)
                    265: #define SM501_DC_PANEL_CONTROL_HSP     (1<<12)
                    266: #define SM501_DC_PANEL_CONTROL_CK      (1<<9)
                    267: #define SM501_DC_PANEL_CONTROL_TE      (1<<8)
                    268: #define SM501_DC_PANEL_CONTROL_VPD     (1<<7)
                    269: #define SM501_DC_PANEL_CONTROL_VP      (1<<6)
                    270: #define SM501_DC_PANEL_CONTROL_HPD     (1<<5)
                    271: #define SM501_DC_PANEL_CONTROL_HP      (1<<4)
                    272: #define SM501_DC_PANEL_CONTROL_GAMMA   (1<<3)
                    273: #define SM501_DC_PANEL_CONTROL_EN      (1<<2)
                    274: 
                    275: #define SM501_DC_PANEL_CONTROL_8BPP    (0<<0)
                    276: #define SM501_DC_PANEL_CONTROL_16BPP   (1<<0)
                    277: #define SM501_DC_PANEL_CONTROL_32BPP   (2<<0)
                    278: 
                    279: 
                    280: #define SM501_DC_PANEL_PANNING_CONTROL (0x004)
                    281: #define SM501_DC_PANEL_COLOR_KEY       (0x008)
                    282: #define SM501_DC_PANEL_FB_ADDR         (0x00C)
                    283: #define SM501_DC_PANEL_FB_OFFSET       (0x010)
                    284: #define SM501_DC_PANEL_FB_WIDTH                (0x014)
                    285: #define SM501_DC_PANEL_FB_HEIGHT       (0x018)
                    286: #define SM501_DC_PANEL_TL_LOC          (0x01C)
                    287: #define SM501_DC_PANEL_BR_LOC          (0x020)
                    288: #define SM501_DC_PANEL_H_TOT           (0x024)
                    289: #define SM501_DC_PANEL_H_SYNC          (0x028)
                    290: #define SM501_DC_PANEL_V_TOT           (0x02C)
                    291: #define SM501_DC_PANEL_V_SYNC          (0x030)
                    292: #define SM501_DC_PANEL_CUR_LINE                (0x034)
                    293: 
                    294: #define SM501_DC_VIDEO_CONTROL         (0x040)
                    295: #define SM501_DC_VIDEO_FB0_ADDR                (0x044)
                    296: #define SM501_DC_VIDEO_FB_WIDTH                (0x048)
                    297: #define SM501_DC_VIDEO_FB0_LAST_ADDR   (0x04C)
                    298: #define SM501_DC_VIDEO_TL_LOC          (0x050)
                    299: #define SM501_DC_VIDEO_BR_LOC          (0x054)
                    300: #define SM501_DC_VIDEO_SCALE           (0x058)
                    301: #define SM501_DC_VIDEO_INIT_SCALE      (0x05C)
                    302: #define SM501_DC_VIDEO_YUV_CONSTANTS   (0x060)
                    303: #define SM501_DC_VIDEO_FB1_ADDR                (0x064)
                    304: #define SM501_DC_VIDEO_FB1_LAST_ADDR   (0x068)
                    305: 
                    306: #define SM501_DC_VIDEO_ALPHA_CONTROL   (0x080)
                    307: #define SM501_DC_VIDEO_ALPHA_FB_ADDR   (0x084)
                    308: #define SM501_DC_VIDEO_ALPHA_FB_OFFSET (0x088)
                    309: #define SM501_DC_VIDEO_ALPHA_FB_LAST_ADDR      (0x08C)
                    310: #define SM501_DC_VIDEO_ALPHA_TL_LOC    (0x090)
                    311: #define SM501_DC_VIDEO_ALPHA_BR_LOC    (0x094)
                    312: #define SM501_DC_VIDEO_ALPHA_SCALE     (0x098)
                    313: #define SM501_DC_VIDEO_ALPHA_INIT_SCALE        (0x09C)
                    314: #define SM501_DC_VIDEO_ALPHA_CHROMA_KEY        (0x0A0)
                    315: #define SM501_DC_VIDEO_ALPHA_COLOR_LOOKUP      (0x0A4)
                    316: 
                    317: #define SM501_DC_PANEL_HWC_BASE                (0x0F0)
                    318: #define SM501_DC_PANEL_HWC_ADDR                (0x0F0)
                    319: #define SM501_DC_PANEL_HWC_LOC         (0x0F4)
                    320: #define SM501_DC_PANEL_HWC_COLOR_1_2   (0x0F8)
                    321: #define SM501_DC_PANEL_HWC_COLOR_3     (0x0FC)
                    322: 
                    323: #define SM501_HWC_EN                   (1<<31)
                    324: 
                    325: #define SM501_OFF_HWC_ADDR             (0x00)
                    326: #define SM501_OFF_HWC_LOC              (0x04)
                    327: #define SM501_OFF_HWC_COLOR_1_2                (0x08)
                    328: #define SM501_OFF_HWC_COLOR_3          (0x0C)
                    329: 
                    330: #define SM501_DC_ALPHA_CONTROL         (0x100)
                    331: #define SM501_DC_ALPHA_FB_ADDR         (0x104)
                    332: #define SM501_DC_ALPHA_FB_OFFSET       (0x108)
                    333: #define SM501_DC_ALPHA_TL_LOC          (0x10C)
                    334: #define SM501_DC_ALPHA_BR_LOC          (0x110)
                    335: #define SM501_DC_ALPHA_CHROMA_KEY      (0x114)
                    336: #define SM501_DC_ALPHA_COLOR_LOOKUP    (0x118)
                    337: 
                    338: #define SM501_DC_CRT_CONTROL           (0x200)
                    339: 
                    340: #define SM501_DC_CRT_CONTROL_TVP       (1<<15)
                    341: #define SM501_DC_CRT_CONTROL_CP                (1<<14)
                    342: #define SM501_DC_CRT_CONTROL_VSP       (1<<13)
                    343: #define SM501_DC_CRT_CONTROL_HSP       (1<<12)
                    344: #define SM501_DC_CRT_CONTROL_VS                (1<<11)
                    345: #define SM501_DC_CRT_CONTROL_BLANK     (1<<10)
                    346: #define SM501_DC_CRT_CONTROL_SEL       (1<<9)
                    347: #define SM501_DC_CRT_CONTROL_TE                (1<<8)
                    348: #define SM501_DC_CRT_CONTROL_PIXEL_MASK (0xF << 4)
                    349: #define SM501_DC_CRT_CONTROL_GAMMA     (1<<3)
                    350: #define SM501_DC_CRT_CONTROL_ENABLE    (1<<2)
                    351: 
                    352: #define SM501_DC_CRT_CONTROL_8BPP      (0<<0)
                    353: #define SM501_DC_CRT_CONTROL_16BPP     (1<<0)
                    354: #define SM501_DC_CRT_CONTROL_32BPP     (2<<0)
                    355: 
                    356: #define SM501_DC_CRT_FB_ADDR           (0x204)
                    357: #define SM501_DC_CRT_FB_OFFSET         (0x208)
                    358: #define SM501_DC_CRT_H_TOT             (0x20C)
                    359: #define SM501_DC_CRT_H_SYNC            (0x210)
                    360: #define SM501_DC_CRT_V_TOT             (0x214)
                    361: #define SM501_DC_CRT_V_SYNC            (0x218)
                    362: #define SM501_DC_CRT_SIGNATURE_ANALYZER        (0x21C)
                    363: #define SM501_DC_CRT_CUR_LINE          (0x220)
                    364: #define SM501_DC_CRT_MONITOR_DETECT    (0x224)
                    365: 
                    366: #define SM501_DC_CRT_HWC_BASE          (0x230)
                    367: #define SM501_DC_CRT_HWC_ADDR          (0x230)
                    368: #define SM501_DC_CRT_HWC_LOC           (0x234)
                    369: #define SM501_DC_CRT_HWC_COLOR_1_2     (0x238)
                    370: #define SM501_DC_CRT_HWC_COLOR_3       (0x23C)
                    371: 
                    372: #define SM501_DC_PANEL_PALETTE         (0x400)
                    373: 
                    374: #define SM501_DC_VIDEO_PALETTE         (0x800)
                    375: 
                    376: #define SM501_DC_CRT_PALETTE           (0xC00)
                    377: 
                    378: /* Zoom Video port base */
                    379: #define SM501_ZVPORT                   (0x090000)
                    380: 
                    381: /* AC97/I2S base */
                    382: #define SM501_AC97                     (0x0A0000)
                    383: 
                    384: /* 8051 micro controller base */
                    385: #define SM501_UCONTROLLER              (0x0B0000)
                    386: 
                    387: /* 8051 micro controller SRAM base */
                    388: #define SM501_UCONTROLLER_SRAM         (0x0C0000)
                    389: 
                    390: /* DMA base */
                    391: #define SM501_DMA                      (0x0D0000)
                    392: 
                    393: /* 2d engine base */
                    394: #define SM501_2D_ENGINE                        (0x100000)
                    395: #define SM501_2D_SOURCE                        (0x00)
                    396: #define SM501_2D_DESTINATION           (0x04)
                    397: #define SM501_2D_DIMENSION             (0x08)
                    398: #define SM501_2D_CONTROL               (0x0C)
                    399: #define SM501_2D_PITCH                 (0x10)
                    400: #define SM501_2D_FOREGROUND            (0x14)
                    401: #define SM501_2D_BACKGROUND            (0x18)
                    402: #define SM501_2D_STRETCH               (0x1C)
                    403: #define SM501_2D_COLOR_COMPARE         (0x20)
                    404: #define SM501_2D_COLOR_COMPARE_MASK    (0x24)
                    405: #define SM501_2D_MASK                  (0x28)
                    406: #define SM501_2D_CLIP_TL               (0x2C)
                    407: #define SM501_2D_CLIP_BR               (0x30)
                    408: #define SM501_2D_MONO_PATTERN_LOW      (0x34)
                    409: #define SM501_2D_MONO_PATTERN_HIGH     (0x38)
                    410: #define SM501_2D_WINDOW_WIDTH          (0x3C)
                    411: #define SM501_2D_SOURCE_BASE           (0x40)
                    412: #define SM501_2D_DESTINATION_BASE      (0x44)
                    413: #define SM501_2D_ALPHA                 (0x48)
                    414: #define SM501_2D_WRAP                  (0x4C)
                    415: #define SM501_2D_STATUS                        (0x50)
                    416: 
                    417: #define SM501_CSC_Y_SOURCE_BASE                (0xC8)
                    418: #define SM501_CSC_CONSTANTS            (0xCC)
                    419: #define SM501_CSC_Y_SOURCE_X           (0xD0)
                    420: #define SM501_CSC_Y_SOURCE_Y           (0xD4)
                    421: #define SM501_CSC_U_SOURCE_BASE                (0xD8)
                    422: #define SM501_CSC_V_SOURCE_BASE                (0xDC)
                    423: #define SM501_CSC_SOURCE_DIMENSION     (0xE0)
                    424: #define SM501_CSC_SOURCE_PITCH         (0xE4)
                    425: #define SM501_CSC_DESTINATION          (0xE8)
                    426: #define SM501_CSC_DESTINATION_DIMENSION        (0xEC)
                    427: #define SM501_CSC_DESTINATION_PITCH    (0xF0)
                    428: #define SM501_CSC_SCALE_FACTOR         (0xF4)
                    429: #define SM501_CSC_DESTINATION_BASE     (0xF8)
                    430: #define SM501_CSC_CONTROL              (0xFC)
                    431: 
                    432: /* 2d engine data port base */
                    433: #define SM501_2D_ENGINE_DATA           (0x110000)
                    434: 
                    435: /* end of register definitions */
                    436: 
                    437: 
                    438: /* SM501 local memory size taken from "linux/drivers/mfd/sm501.c" */
                    439: static const uint32_t sm501_mem_local_size[] = {
                    440:        [0]     = 4*1024*1024,
                    441:        [1]     = 8*1024*1024,
                    442:        [2]     = 16*1024*1024,
                    443:        [3]     = 32*1024*1024,
                    444:        [4]     = 64*1024*1024,
                    445:        [5]     = 2*1024*1024,
                    446: };
                    447: #define get_local_mem_size(s) sm501_mem_local_size[(s)->local_mem_size_index]
                    448: 
                    449: typedef struct SM501State {
                    450:     /* graphic console status */
                    451:     DisplayState *ds;
                    452: 
                    453:     /* status & internal resources */
                    454:     target_phys_addr_t base;
                    455:     uint32_t local_mem_size_index;
                    456:     uint8_t * local_mem;
1.1.1.2   root      457:     ram_addr_t local_mem_offset;
1.1       root      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: 
1.1.1.3 ! root      629: static CPUReadMemoryFunc * const sm501_system_config_readfn[] = {
1.1       root      630:     NULL,
                    631:     NULL,
                    632:     &sm501_system_config_read,
                    633: };
                    634: 
1.1.1.3 ! root      635: static CPUWriteMemoryFunc * const sm501_system_config_writefn[] = {
1.1       root      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: 
1.1.1.3 ! root      867: static CPUReadMemoryFunc * const sm501_disp_ctrl_readfn[] = {
1.1       root      868:     NULL,
                    869:     NULL,
                    870:     &sm501_disp_ctrl_read,
                    871: };
                    872: 
1.1.1.3 ! root      873: static CPUWriteMemoryFunc * const sm501_disp_ctrl_writefn[] = {
1.1       root      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:
1.1.1.2   root      951:        if (is_surface_bgr(s->surface))
                    952:            return 4;
                    953:        else
                    954:            return 3;
1.1       root      955:     }
                    956: }
                    957: 
                    958: static void sm501_draw_crt(SM501State * s)
                    959: {
                    960:     int y;
                    961:     int width = (s->dc_crt_h_total & 0x00000FFF) + 1;
                    962:     int height = (s->dc_crt_v_total & 0x00000FFF) + 1;
                    963: 
                    964:     uint8_t  * src = s->local_mem;
                    965:     int src_bpp = 0;
                    966:     int dst_bpp = ds_get_bytes_per_pixel(s->ds) + (ds_get_bits_per_pixel(s->ds) % 8 ? 1 : 0);
                    967:     uint32_t * palette = (uint32_t *)&s->dc_palette[SM501_DC_CRT_PALETTE
                    968:                                                    - SM501_DC_PANEL_PALETTE];
                    969:     int ds_depth_index = get_depth_index(s->ds);
                    970:     draw_line_func * draw_line = NULL;
                    971:     int full_update = 0;
                    972:     int y_start = -1;
                    973:     int page_min = 0x7fffffff;
                    974:     int page_max = -1;
1.1.1.2   root      975:     ram_addr_t offset = s->local_mem_offset;
1.1       root      976: 
                    977:     /* choose draw_line function */
                    978:     switch (s->dc_crt_control & 3) {
                    979:     case SM501_DC_CRT_CONTROL_8BPP:
                    980:        src_bpp = 1;
                    981:        draw_line = draw_line8_funcs[ds_depth_index];
                    982:        break;
                    983:     case SM501_DC_CRT_CONTROL_16BPP:
                    984:        src_bpp = 2;
                    985:        draw_line = draw_line16_funcs[ds_depth_index];
                    986:        break;
                    987:     case SM501_DC_CRT_CONTROL_32BPP:
                    988:        src_bpp = 4;
                    989:        draw_line = draw_line32_funcs[ds_depth_index];
                    990:        break;
                    991:     default:
                    992:        printf("sm501 draw crt : invalid DC_CRT_CONTROL=%x.\n",
                    993:               s->dc_crt_control);
                    994:        assert(0);
                    995:        break;
                    996:     }
                    997: 
                    998:     /* adjust console size */
                    999:     if (s->last_width != width || s->last_height != height) {
                   1000:        qemu_console_resize(s->ds, width, height);
                   1001:        s->last_width = width;
                   1002:        s->last_height = height;
                   1003:        full_update = 1;
                   1004:     }
                   1005: 
                   1006:     /* draw each line according to conditions */
                   1007:     for (y = 0; y < height; y++) {
                   1008:        int update = full_update;
1.1.1.2   root     1009:        ram_addr_t page0 = offset & TARGET_PAGE_MASK;
                   1010:        ram_addr_t page1 = (offset + width * src_bpp - 1) & TARGET_PAGE_MASK;
                   1011:        ram_addr_t page;
1.1       root     1012: 
                   1013:        /* check dirty flags for each line */
                   1014:        for (page = page0; page <= page1; page += TARGET_PAGE_SIZE)
                   1015:            if (cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG))
                   1016:                update = 1;
                   1017: 
                   1018:        /* draw line and change status */
                   1019:        if (update) {
                   1020:            draw_line(&(ds_get_data(s->ds)[y * width * dst_bpp]), src, width, palette);
                   1021:            if (y_start < 0)
                   1022:                y_start = y;
                   1023:            if (page0 < page_min)
                   1024:                page_min = page0;
                   1025:            if (page1 > page_max)
                   1026:                page_max = page1;
                   1027:        } else {
                   1028:            if (y_start >= 0) {
                   1029:                /* flush to display */
                   1030:                dpy_update(s->ds, 0, y_start, width, y - y_start);
                   1031:                y_start = -1;
                   1032:            }
                   1033:        }
                   1034: 
                   1035:        src += width * src_bpp;
1.1.1.2   root     1036:        offset += width * src_bpp;
1.1       root     1037:     }
                   1038: 
                   1039:     /* complete flush to display */
                   1040:     if (y_start >= 0)
                   1041:        dpy_update(s->ds, 0, y_start, width, y - y_start);
                   1042: 
                   1043:     /* clear dirty flags */
                   1044:     if (page_max != -1)
                   1045:        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
                   1046:                                        VGA_DIRTY_FLAG);
                   1047: }
                   1048: 
                   1049: static void sm501_update_display(void *opaque)
                   1050: {
                   1051:     SM501State * s = (SM501State *)opaque;
                   1052: 
                   1053:     if (s->dc_crt_control & SM501_DC_CRT_CONTROL_ENABLE)
                   1054:        sm501_draw_crt(s);
                   1055: }
                   1056: 
1.1.1.2   root     1057: void sm501_init(uint32_t base, uint32_t local_mem_bytes, qemu_irq irq,
                   1058:                 CharDriverState *chr)
1.1       root     1059: {
                   1060:     SM501State * s;
                   1061:     int sm501_system_config_index;
                   1062:     int sm501_disp_ctrl_index;
                   1063: 
                   1064:     /* allocate management data region */
                   1065:     s = (SM501State *)qemu_mallocz(sizeof(SM501State));
                   1066:     s->base = base;
                   1067:     s->local_mem_size_index
                   1068:        = get_local_mem_size_index(local_mem_bytes);
                   1069:     SM501_DPRINTF("local mem size=%x. index=%d\n", get_local_mem_size(s),
                   1070:                  s->local_mem_size_index);
                   1071:     s->system_control = 0x00100000;
                   1072:     s->misc_control = 0x00001000; /* assumes SH, active=low */
                   1073:     s->dc_panel_control = 0x00010000;
                   1074:     s->dc_crt_control = 0x00010000;
                   1075: 
                   1076:     /* allocate local memory */
1.1.1.2   root     1077:     s->local_mem_offset = qemu_ram_alloc(local_mem_bytes);
                   1078:     s->local_mem = qemu_get_ram_ptr(s->local_mem_offset);
                   1079:     cpu_register_physical_memory(base, local_mem_bytes, s->local_mem_offset);
1.1       root     1080: 
                   1081:     /* map mmio */
                   1082:     sm501_system_config_index
1.1.1.2   root     1083:        = cpu_register_io_memory(sm501_system_config_readfn,
1.1       root     1084:                                 sm501_system_config_writefn, s);
                   1085:     cpu_register_physical_memory(base + MMIO_BASE_OFFSET,
                   1086:                                 0x6c, sm501_system_config_index);
1.1.1.2   root     1087:     sm501_disp_ctrl_index = cpu_register_io_memory(sm501_disp_ctrl_readfn,
1.1       root     1088:                                                   sm501_disp_ctrl_writefn, s);
                   1089:     cpu_register_physical_memory(base + MMIO_BASE_OFFSET + SM501_DC,
                   1090:                                  0x1000, sm501_disp_ctrl_index);
                   1091: 
1.1.1.2   root     1092:     /* bridge to usb host emulation module */
                   1093:     usb_ohci_init_sm501(base + MMIO_BASE_OFFSET + SM501_USB_HOST, base,
                   1094:                         2, -1, irq);
                   1095: 
1.1       root     1096:     /* bridge to serial emulation module */
                   1097:     if (chr)
                   1098:        serial_mm_init(base + MMIO_BASE_OFFSET + SM501_UART0, 2,
1.1.1.3 ! root     1099:                       NULL, /* TODO : chain irq to IRL */
1.1       root     1100:                       115200, chr, 1);
                   1101: 
                   1102:     /* create qemu graphic console */
                   1103:     s->ds = graphic_console_init(sm501_update_display, NULL,
                   1104:                                 NULL, NULL, s);
                   1105: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.