~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to hw/sm501.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno, Aurelien Jarno
  • Date: 2009-03-22 10:13:17 UTC
  • mfrom: (1.2.1 upstream) (6.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20090322101317-iigjtnu5qil35dtb
Tags: 0.10.1-1
[ Aurelien Jarno ]
* New upstream stable release:
  - patches/80_stable-branch.patch: remove.
* debian/control: 
  - Remove depends on proll.
  - Move depends on device-tree-compiler to build-depends.
  - Bump Standards-Version to 3.8.1 (no changes).
* patches/82_qemu-img_decimal.patch: new patch from upstream to make
  qemu-img accept sizes with decimal values (closes: bug#501400).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}