1 // license:BSD-3-Clause
2 // copyright-holders:Tim Schuerewegen
3 /*******************************************************************************
4 
5     Samsung S3C44B0
6 
7     (c) 2011 Tim Schuerewegen
8 
9 *******************************************************************************/
10 
11 #ifndef MAME_MACHINE_S3C44B0_H
12 #define MAME_MACHINE_S3C44B0_H
13 
14 #pragma once
15 
16 
17 /*******************************************************************************
18     MACROS & CONSTANTS
19 *******************************************************************************/
20 
21 /* Memory Controller */
22 
23 #define S3C44B0_BASE_MEMCON 0x01C80000
24 
25 /* Interrupt Controller */
26 
27 #define S3C44B0_BASE_INT 0x01E00000
28 
29 /* ZDMA & BDMA */
30 
31 #define S3C44B0_BASE_ZDMA_0 0x01E80000
32 #define S3C44B0_BASE_ZDMA_1 0x01E80020
33 #define S3C44B0_BASE_BDMA_0 0x01F80000
34 #define S3C44B0_BASE_BDMA_1 0x01F80020
35 
36 /* Clock & Power Management */
37 
38 #define S3C44B0_BASE_CLKPOW 0x01D80000
39 
40 /* LCD Controller */
41 
42 #define S3C44B0_BASE_LCD    0x01F00000
43 
44 /* UART */
45 
46 #define S3C44B0_BASE_UART_0 0x01D00000
47 #define S3C44B0_BASE_UART_1 0x01D04000
48 
49 /* SIO */
50 
51 #define S3C44B0_BASE_SIO 0x01D14000
52 
53 #define S3C44B0_SIOCON  (0x00 / 4) // SIO Control
54 #define S3C44B0_SIODAT  (0x04 / 4) // SIO Data
55 #define S3C44B0_SBRDR   (0x08 / 4) // SIO Baud Rate Prescaler
56 #define S3C44B0_ITVCNT  (0x0C / 4) // SIO Interval Counter
57 #define S3C44B0_DCNTZ   (0x10 / 4) // SIO DMA Count Zero
58 
59 /* PWM Timer */
60 
61 #define S3C44B0_BASE_PWM 0x01D50000
62 
63 /* USB Device */
64 
65 #define S3C44B0_BASE_USBDEV 0x15200140
66 
67 /* Watchdog Timer */
68 
69 #define S3C44B0_BASE_WDT 0x01D30000
70 
71 /* IIC */
72 
73 #define S3C44B0_BASE_IIC 0x01D60000
74 
75 /* IIS */
76 
77 #define S3C44B0_BASE_IIS 0x01D18000
78 
79 /* I/O Port */
80 
81 #define S3C44B0_BASE_GPIO 0x01D20000
82 
83 /* RTC */
84 
85 #define S3C44B0_BASE_RTC 0x01D70040
86 
87 /* A/D Converter */
88 
89 #define S3C44B0_BASE_ADC 0x01D40000
90 
91 /* CPU Wrapper */
92 
93 #define S3C44B0_BASE_CPU_WRAPPER 0x01C00000
94 
95 /* ... */
96 
97 
98 /*******************************************************************************
99  MACROS / CONSTANTS
100  *******************************************************************************/
101 
102 enum
103 {
104 	S3C44B0_GPIO_PORT_A = 0,
105 	S3C44B0_GPIO_PORT_B,
106 	S3C44B0_GPIO_PORT_C,
107 	S3C44B0_GPIO_PORT_D,
108 	S3C44B0_GPIO_PORT_E,
109 	S3C44B0_GPIO_PORT_F,
110 	S3C44B0_GPIO_PORT_G
111 };
112 
113 
114 class s3c44b0_device : public device_t, public device_video_interface
115 {
116 public:
117 	s3c44b0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
118 
set_cpu(T && tag)119 	template <class T> void set_cpu(T &&tag) { m_cpu.set_tag(std::forward<T>(tag)); }
gpio_port_r_cb()120 	auto gpio_port_r_cb() { return m_port_r_cb.bind(); }
gpio_port_w_cb()121 	auto gpio_port_w_cb() { return m_port_w_cb.bind(); }
i2c_scl_w_cb()122 	auto i2c_scl_w_cb() { return m_scl_w_cb.bind(); }
i2c_sda_r_cb()123 	auto i2c_sda_r_cb() { return m_sda_r_cb.bind(); }
i2c_sda_w_cb()124 	auto i2c_sda_w_cb() { return m_sda_w_cb.bind(); }
adc_data_r_cb()125 	auto adc_data_r_cb() { return m_data_r_cb.bind(); }
i2s_data_w_cb()126 	auto i2s_data_w_cb() { return m_data_w_cb.bind(); }
127 
128 	uint32_t lcd_r(offs_t offset, uint32_t mem_mask = ~0);
129 	uint32_t clkpow_r(offs_t offset, uint32_t mem_mask = ~0);
130 	uint32_t irq_r(offs_t offset, uint32_t mem_mask = ~0);
131 	uint32_t pwm_r(offs_t offset, uint32_t mem_mask = ~0);
132 	uint32_t iic_r(offs_t offset, uint32_t mem_mask = ~0);
133 	uint32_t gpio_r(offs_t offset, uint32_t mem_mask = ~0);
134 	uint32_t uart_0_r(offs_t offset, uint32_t mem_mask = ~0);
135 	uint32_t uart_1_r(offs_t offset, uint32_t mem_mask = ~0);
136 	uint32_t wdt_r(offs_t offset, uint32_t mem_mask = ~0);
137 	uint32_t cpuwrap_r(offs_t offset, uint32_t mem_mask = ~0);
138 	uint32_t adc_r(offs_t offset, uint32_t mem_mask = ~0);
139 	uint32_t sio_r(offs_t offset, uint32_t mem_mask = ~0);
140 	uint32_t iis_r(offs_t offset, uint32_t mem_mask = ~0);
141 	uint32_t zdma_0_r(offs_t offset, uint32_t mem_mask = ~0);
142 	uint32_t zdma_1_r(offs_t offset, uint32_t mem_mask = ~0);
143 	uint32_t bdma_0_r(offs_t offset, uint32_t mem_mask = ~0);
144 	uint32_t bdma_1_r(offs_t offset, uint32_t mem_mask = ~0);
145 
146 	void lcd_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
147 	void clkpow_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
148 	void irq_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
149 	void pwm_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
150 	void iic_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
151 	void gpio_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
152 	void uart_0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
153 	void uart_1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
154 	void wdt_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
155 	void cpuwrap_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
156 	void adc_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
157 	void sio_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
158 	void iis_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
159 	void zdma_0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
160 	void zdma_1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
161 	void bdma_0_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
162 	void bdma_1_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
163 
164 	void request_eint(uint32_t number);
165 	uint32_t video_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
166 
167 protected:
168 	// device-level overrides
169 	virtual void device_start() override;
170 	virtual void device_post_load() override;
171 	virtual void device_reset() override;
172 
173 private:
174 	struct s3c44b0_memcon_regs_t
175 	{
176 		uint32_t data[0x34/4];
177 	};
178 
179 	struct s3c44b0_irq_regs_t
180 	{
181 		uint32_t intcon;
182 		uint32_t intpnd;
183 		uint32_t intmod;
184 		uint32_t intmsk;
185 		uint32_t i_pslv;
186 		uint32_t i_pmst;
187 		uint32_t i_cslv;
188 		uint32_t i_cmst;
189 		uint32_t i_ispr;
190 		uint32_t i_ispc;
191 		uint32_t reserved[4];
192 		uint32_t f_ispr;
193 		uint32_t f_ispc;
194 	};
195 
196 	struct s3c44b0_dma_regs_t
197 	{
198 		uint32_t dcon;
199 		uint32_t disrc;
200 		uint32_t didst;
201 		uint32_t dicnt;
202 		uint32_t dcsrc;
203 		uint32_t dcdst;
204 		uint32_t dccnt;
205 	};
206 
207 	struct s3c44b0_clkpow_regs_t
208 	{
209 		uint32_t pllcon;
210 		uint32_t clkcon;
211 		uint32_t clkslow;
212 		uint32_t locktime;
213 	};
214 
215 	struct s3c44b0_lcd_regs_t
216 	{
217 		uint32_t lcdcon1;
218 		uint32_t lcdcon2;
219 		uint32_t lcdsaddr1;
220 		uint32_t lcdsaddr2;
221 		uint32_t lcdsaddr3;
222 		uint32_t redlut;
223 		uint32_t greenlut;
224 		uint32_t bluelut;
225 		uint32_t reserved[8];
226 		uint32_t lcdcon3;
227 		uint32_t dithmode;
228 	};
229 
230 	struct s3c44b0_uart_regs_t
231 	{
232 		uint32_t ulcon;
233 		uint32_t ucon;
234 		uint32_t ufcon;
235 		uint32_t umcon;
236 		uint32_t utrstat;
237 		uint32_t uerstat;
238 		uint32_t ufstat;
239 		uint32_t umstat;
240 		uint32_t utxh;
241 		uint32_t urxh;
242 		uint32_t ubrdiv;
243 	};
244 
245 	struct s3c44b0_sio_regs_t
246 	{
247 		uint32_t siocon;
248 		uint32_t siodat;
249 		uint32_t sbrdr;
250 		uint32_t itvcnt;
251 		uint32_t dcntz;
252 	};
253 
254 	struct s3c44b0_pwm_regs_t
255 	{
256 		uint32_t tcfg0;
257 		uint32_t tcfg1;
258 		uint32_t tcon;
259 		uint32_t tcntb0;
260 		uint32_t tcmpb0;
261 		uint32_t tcnto0;
262 		uint32_t tcntb1;
263 		uint32_t tcmpb1;
264 		uint32_t tcnto1;
265 		uint32_t tcntb2;
266 		uint32_t tcmpb2;
267 		uint32_t tcnto2;
268 		uint32_t tcntb3;
269 		uint32_t tcmpb3;
270 		uint32_t tcnto3;
271 		uint32_t tcntb4;
272 		uint32_t tcmpb4;
273 		uint32_t tcnto4;
274 		uint32_t tcntb5;
275 		uint32_t tcnto5;
276 	};
277 
278 	struct s3c44b0_wdt_regs_t
279 	{
280 		uint32_t wtcon;
281 		uint32_t wtdat;
282 		uint32_t wtcnt;
283 	};
284 
285 	struct s3c44b0_iic_regs_t
286 	{
287 		uint32_t iiccon;
288 		uint32_t iicstat;
289 		uint32_t iicadd;
290 		uint32_t iicds;
291 	};
292 
293 	struct s3c44b0_iis_regs_t
294 	{
295 		uint32_t iiscon;
296 		uint32_t iismod;
297 		uint32_t iispsr;
298 		uint32_t iisfcon;
299 		uint32_t iisfifo;
300 	};
301 
302 	struct s3c44b0_gpio_regs_t
303 	{
304 		uint32_t gpacon;
305 		uint32_t gpadat;
306 		uint32_t gpbcon;
307 		uint32_t gpbdat;
308 		uint32_t gpccon;
309 		uint32_t gpcdat;
310 		uint32_t gpcup;
311 		uint32_t gpdcon;
312 		uint32_t gpddat;
313 		uint32_t gpdup;
314 		uint32_t gpecon;
315 		uint32_t gpedat;
316 		uint32_t gpeup;
317 		uint32_t gpfcon;
318 		uint32_t gpfdat;
319 		uint32_t gpfup;
320 		uint32_t gpgcon;
321 		uint32_t gpgdat;
322 		uint32_t gpgup;
323 		uint32_t spucr;
324 		uint32_t extint;
325 		uint32_t extintpnd;
326 	};
327 
328 	struct s3c44b0_rtc_regs_t
329 	{
330 		uint32_t rtccon;
331 		uint32_t reserved[3];
332 		uint32_t rtcalm;
333 		uint32_t almsec;
334 		uint32_t almmin;
335 		uint32_t almhour;
336 		uint32_t almday;
337 		uint32_t almmon;
338 		uint32_t almyear;
339 		uint32_t rtcrst;
340 		uint32_t bcdsec;
341 		uint32_t bcdmin;
342 		uint32_t bcdhour;
343 		uint32_t bcdday;
344 		uint32_t bcddow;
345 		uint32_t bcdmon;
346 		uint32_t bcdyear;
347 		uint32_t ticnt;
348 	};
349 
350 	struct s3c44b0_adc_regs_t
351 	{
352 		uint32_t adccon;
353 		uint32_t adcpsr;
354 		uint32_t adcdat;
355 	};
356 
357 	struct s3c44b0_cpuwrap_regs_t
358 	{
359 		uint32_t syscfg;
360 		uint32_t ncachbe0;
361 		uint32_t ncachbe1;
362 	};
363 
364 	struct s3c44b0_memcon_t
365 	{
366 		s3c44b0_memcon_regs_t regs;
367 	};
368 
369 	struct s3c44b0_irq_t
370 	{
371 		s3c44b0_irq_regs_t regs;
372 		int line_irq, line_fiq;
373 	};
374 
375 	struct s3c44b0_dma_t
376 	{
377 		s3c44b0_dma_regs_t regs;
378 		emu_timer *timer;
379 	};
380 
381 	struct s3c44b0_clkpow_t
382 	{
383 		s3c44b0_clkpow_regs_t regs;
384 	};
385 
386 	struct rectangle_t
387 	{
388 		int x1, y1, x2, y2;
389 	};
390 
391 	struct s3c44b0_lcd_t
392 	{
393 		s3c44b0_lcd_regs_t regs;
394 		emu_timer *timer;
395 		std::unique_ptr<uint8_t[]> bitmap;
396 		uint32_t vramaddr_cur;
397 		uint32_t vramaddr_max;
398 		uint32_t offsize;
399 		uint32_t pagewidth_cur;
400 		uint32_t pagewidth_max;
401 		uint32_t modesel;
402 		uint32_t bswp;
403 		int vpos, hpos;
404 		double framerate;
405 		uint32_t hpos_min, hpos_max, hpos_end, vpos_min, vpos_max, vpos_end;
406 		attotime frame_time;
407 		attoseconds_t frame_period, pixeltime, scantime;
408 	};
409 
410 	struct s3c44b0_uart_t
411 	{
412 		s3c44b0_uart_regs_t regs;
413 		emu_timer *timer;
414 	};
415 
416 	struct s3c44b0_sio_t
417 	{
418 		s3c44b0_sio_regs_t regs;
419 		emu_timer *timer;
420 	};
421 
422 	struct s3c44b0_pwm_t
423 	{
424 		s3c44b0_pwm_regs_t regs;
425 		emu_timer *timer[6];
426 		uint32_t cnt[6];
427 		uint32_t cmp[6];
428 		uint32_t freq[6];
429 	};
430 
431 	struct s3c44b0_wdt_t
432 	{
433 		s3c44b0_wdt_regs_t regs;
434 		emu_timer *timer;
435 	};
436 
437 	struct s3c44b0_iic_t
438 	{
439 		s3c44b0_iic_regs_t regs;
440 		emu_timer *timer;
441 		int count;
442 	};
443 
444 	struct s3c44b0_iis_t
445 	{
446 		s3c44b0_iis_regs_t regs;
447 		emu_timer *timer;
448 		uint16_t fifo[16/2];
449 		int fifo_index;
450 	};
451 
452 	struct s3c44b0_gpio_t
453 	{
454 		s3c44b0_gpio_regs_t regs;
455 	};
456 
457 	struct s3c44b0_rtc_t
458 	{
459 		s3c44b0_rtc_regs_t regs;
460 		emu_timer *timer_tick_count;
461 		emu_timer *timer_update;
462 	};
463 
464 	struct s3c44b0_adc_t
465 	{
466 		s3c44b0_adc_regs_t regs;
467 		emu_timer *timer;
468 	};
469 
470 	struct s3c44b0_cpuwrap_t
471 	{
472 		s3c44b0_cpuwrap_regs_t regs;
473 	};
474 
475 
476 	// internal state
477 	// LCD Controller
478 	rgb_t lcd_get_color_stn_04(uint8_t data);
479 	uint8_t lcd_get_color_stn_08_r(uint8_t data);
480 	uint8_t lcd_get_color_stn_08_g(uint8_t data);
481 	uint8_t lcd_get_color_stn_08_b(uint8_t data);
482 	void lcd_dma_reload();
483 	void lcd_dma_init();
484 	void lcd_dma_read(int count, uint8_t *data);
485 	void lcd_render_stn_04();
486 	void lcd_render_stn_08();
487 	attotime time_until_pos(int vpos, int hpos);
488 	int lcd_get_vpos();
489 	int lcd_get_hpos();
490 	void video_start();
491 	void lcd_configure();
492 	void lcd_start();
493 	void lcd_stop();
494 	void lcd_recalc();
495 	TIMER_CALLBACK_MEMBER(lcd_timer_exp);
496 
497 	// Clock & Power Management
498 	uint32_t get_mclk();
499 
500 	// Interrupt Controller
501 	void check_pending_irq();
502 	void request_irq(uint32_t int_type);
503 	void check_pending_eint();
504 
505 	// PWM Timer
506 	uint16_t pwm_calc_observation(int ch);
507 	void pwm_start(int timer);
508 	void pwm_stop(int timer);
509 	void pwm_recalc(int timer);
510 	TIMER_CALLBACK_MEMBER(pwm_timer_exp);
511 	//void dma_request_pwm();
512 
513 	// IIC
514 	inline void iface_i2c_scl_w(int state);
515 	inline void iface_i2c_sda_w(int state);
516 	inline int iface_i2c_sda_r();
517 	void i2c_send_start();
518 	void i2c_send_stop();
519 	uint8_t i2c_receive_byte(int ack);
520 	int i2c_send_byte(uint8_t data);
521 	void iic_start();
522 	void iic_stop();
523 	void iic_resume();
524 	TIMER_CALLBACK_MEMBER(iic_timer_exp);
525 
526 	// I/O Port
527 	inline uint32_t iface_gpio_port_r(int port);
528 	inline void iface_gpio_port_w(int port, uint32_t data);
529 
530 	// UART
531 	uint32_t uart_r(int ch, uint32_t offset);
532 	void uart_w(int ch, uint32_t offset, uint32_t data, uint32_t mem_mask);
533 	void uart_fifo_w(int uart, uint8_t data);
534 	TIMER_CALLBACK_MEMBER(uart_timer_exp);
535 
536 	// Watchdog Timer
537 	uint16_t wdt_calc_current_count();
538 	void wdt_start();
539 	void wdt_stop();
540 	void wdt_recalc();
541 	TIMER_CALLBACK_MEMBER(wdt_timer_exp);
542 
543 	// A/D Converter
544 	void adc_start();
545 	void adc_stop();
546 	void adc_recalc();
547 	TIMER_CALLBACK_MEMBER(adc_timer_exp);
548 
549 	// SIO
550 	void sio_start();
551 	void sio_stop();
552 	void sio_recalc();
553 	TIMER_CALLBACK_MEMBER(sio_timer_exp);
554 
555 	// IIS
556 	inline void iface_i2s_data_w(int ch, uint16_t data);
557 	void iis_start();
558 	void iis_stop();
559 	TIMER_CALLBACK_MEMBER(iis_timer_exp);
560 
561 	// ZDMA
562 	void zdma_trigger(int ch);
563 	void zdma_start(int ch);
564 	uint32_t zdma_r(int ch, uint32_t offset);
565 	void zdma_w(int ch, uint32_t offset, uint32_t data, uint32_t mem_mask);
566 	TIMER_CALLBACK_MEMBER(zdma_timer_exp);
567 
568 	// BDMA
569 	void bdma_trigger(int ch);
570 	void bdma_request_iis();
571 	uint32_t bdma_r(int ch, uint32_t offset);
572 	void bdma_start(int ch);
573 	void bdma_stop(int ch);
574 	void bdma_w(int ch, uint32_t offset, uint32_t data, uint32_t mem_mask);
575 	TIMER_CALLBACK_MEMBER(bdma_timer_exp);
576 
577 	required_device<cpu_device> m_cpu;
578 	//s3c44b0_memcon_t m_memcon;
579 	s3c44b0_irq_t m_irq;
580 	s3c44b0_dma_t m_zdma[2];
581 	s3c44b0_dma_t m_bdma[2];
582 	s3c44b0_clkpow_t m_clkpow;
583 	s3c44b0_lcd_t m_lcd;
584 	s3c44b0_uart_t m_uart[2];
585 	s3c44b0_sio_t m_sio;
586 	s3c44b0_pwm_t m_pwm;
587 	s3c44b0_wdt_t m_wdt;
588 	s3c44b0_iic_t m_iic;
589 	s3c44b0_iis_t m_iis;
590 	s3c44b0_gpio_t m_gpio;
591 	//s3c44b0_rtc_t m_rtc;
592 	s3c44b0_adc_t m_adc;
593 	s3c44b0_cpuwrap_t m_cpuwrap;
594 
595 	devcb_read32 m_port_r_cb;
596 	devcb_write32 m_port_w_cb;
597 	devcb_write_line m_scl_w_cb;
598 	devcb_read_line m_sda_r_cb;
599 	devcb_write_line m_sda_w_cb;
600 	devcb_read32 m_data_r_cb;
601 	devcb_write16 m_data_w_cb;
602 
603 	memory_access<32, 2, 0, ENDIANNESS_LITTLE>::cache m_cache;
604 };
605 
606 DECLARE_DEVICE_TYPE(S3C44B0, s3c44b0_device)
607 
608 
609 #endif // MAME_MACHINE_S3C44B0_H
610