1/*
2 * Copyright 2013, winocm. <winocm@icloud.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 *   Redistributions of source code must retain the above copyright notice, this
9 *   list of conditions and the following disclaimer.
10 *
11 *   Redistributions in binary form must reproduce the above copyright notice, this
12 *   list of conditions and the following disclaimer in the documentation and/or
13 *   other materials provided with the distribution.
14 *
15 *   If you are going to use this software in any form that does not involve
16 *   releasing the source to this project or improving it, let me know beforehand.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * Platform Expert for Samsung S5L8720X devices.
31 *
32 * Now includes S5L8920X and S5L8922X!
33 */
34
35#if defined(BOARD_CONFIG_S5L8720X)
36
37#include <mach/mach_types.h>
38
39#include <IOKit/IOPlatformExpert.h>
40
41#include <pexpert/pexpert.h>
42#include <pexpert/arm/protos.h>
43#include <pexpert/arm/boot.h>
44
45#include <machine/machine_routines.h>
46
47#include <vm/pmap.h>
48#include <arm/pmap.h>
49
50/*
51 * This is board specific stuff.
52 */
53#define KPRINTF_PREFIX  "PE_SamsungS5L: "
54
55#define HwReg(x) *((volatile unsigned long*)(x))
56
57extern void rtclock_intr(arm_saved_state_t * regs);
58extern void rtc_configure(uint64_t hz);
59
60#define uart_base   gS5L8720XUartBase
61vm_offset_t gS5L8720XUartBase;
62vm_offset_t gS5L8720XClockGateBase;
63
64vm_offset_t gS5L8720XPmgrBase;
65
66/* The 8720 has 4 PL192 compatible VICs. */
67vm_offset_t gS5L8720XVic0Base;
68vm_offset_t gS5L8720XVic1Base;
69vm_offset_t gS5L8720XVic2Base;
70vm_offset_t gS5L8720XVic3Base;
71
72vm_offset_t gS5L8720XTimerBase;
73
74#ifdef BOARD_CONFIG_S5L8720X
75static boolean_t avoid_uarts = FALSE;
76#else
77/* Busted... */
78static boolean_t avoid_uarts = TRUE;
79#endif
80
81static uint64_t clock_decrementer = 0;
82static boolean_t clock_initialized = FALSE;
83static boolean_t clock_had_irq = FALSE;
84static uint64_t clock_absolute_time = 0;
85
86static void timer_configure(void)
87{
88    return;
89}
90
91void S5L8720X_putc(int c)
92{
93    return;
94}
95
96int S5L8720X_getc(void)
97{
98    return 'A';
99}
100
101void S5L8720X_uart_init(void)
102{
103    return;
104}
105
106void S5L8720X_interrupt_init(void)
107{
108    return;
109}
110
111uint64_t S5L8720X_timer_value(void);
112void S5L8720X_timer_enabled(int enable);
113
114void S5L8720X_timebase_init(void)
115{
116    return;
117}
118
119void S5L8720X_handle_interrupt(void *context)
120{
121    return;
122}
123
124uint64_t S5L8720X_get_timebase(void)
125{
126    uint32_t timestamp;
127
128    if (!clock_initialized)
129        return 0;
130
131    timestamp = S5L8720X_timer_value();
132
133    if (timestamp) {
134        uint64_t v = clock_absolute_time;
135        v += (uint64_t) (((uint64_t) clock_decrementer) - (uint64_t) (timestamp));
136        return v;
137    } else {
138        clock_absolute_time += clock_decrementer;
139        return clock_absolute_time;
140    }
141}
142
143uint64_t S5L8720X_timer_value(void)
144{
145    uint64_t ret = 0;
146    return ret;
147}
148
149void S5L8720X_timer_enabled(int enable)
150{
151    return;
152}
153
154/*
155 * Stub for printing out to framebuffer.
156 */
157void vcputc(__unused int l, __unused int u, int c);
158
159static void _fb_putc(int c)
160{
161    if (c == '\n') {
162        vcputc(0, 0, '\r');
163    }
164    vcputc(0, 0, c);
165}
166
167void S5L8720X_framebuffer_init(void)
168{
169    char tempbuf[16];
170
171    /*
172     * Technically, iBoot should initialize this.. Haven't bothered
173     * to reverse this part properly, if you're using a 16-bit panel, then use
174     * the 'rgb565' boot-argument if you care about a working framebuffer...
175     */
176    PE_state.video.v_depth = 4 * (8);   // 32bpp
177    if (PE_parse_boot_argn("rgb565", tempbuf, sizeof(tempbuf))) {
178        PE_state.video.v_depth = 2 * (8);   // 16bpp
179    }
180
181    kprintf(KPRINTF_PREFIX "framebuffer initialized\n");
182
183    /*
184     * Enable early framebuffer.
185     */
186
187    if (PE_parse_boot_argn("-early-fb-debug", tempbuf, sizeof(tempbuf))) {
188        initialize_screen((void *) &PE_state.video, kPEAcquireScreen);
189    }
190
191    if (PE_parse_boot_argn("-graphics-mode", tempbuf, sizeof(tempbuf))) {
192        initialize_screen((void *) &PE_state.video, kPEGraphicsMode);
193    } else {
194        initialize_screen((void *) &PE_state.video, kPETextMode);
195    }
196    return;
197}
198
199int S5L8720X_halt_restart(int type)
200{
201    return 0;
202}
203
204void PE_init_SocSupport_S5L8720X(void)
205{
206    gPESocDispatch.uart_getc = S5L8720X_getc;
207    gPESocDispatch.uart_putc = S5L8720X_putc;
208    gPESocDispatch.uart_init = S5L8720X_uart_init;
209
210    gPESocDispatch.interrupt_init = S5L8720X_interrupt_init;
211    gPESocDispatch.timebase_init = S5L8720X_timebase_init;
212
213    gPESocDispatch.get_timebase = S5L8720X_get_timebase;
214
215    gPESocDispatch.handle_interrupt = S5L8720X_handle_interrupt;
216
217    gPESocDispatch.timer_value = S5L8720X_timer_value;
218    gPESocDispatch.timer_enabled = S5L8720X_timer_enabled;
219
220    gPESocDispatch.framebuffer_init = S5L8720X_framebuffer_init;
221
222    char tempbuf[16];
223    if (PE_parse_boot_argn("-avoid-uarts", tempbuf, sizeof(tempbuf))) {
224        avoid_uarts = 1;
225    }
226
227    if (PE_parse_boot_argn("-force-uarts", tempbuf, sizeof(tempbuf))) {
228        avoid_uarts = 0;
229    }
230
231    S5L8720X_framebuffer_init();
232    S5L8720X_uart_init();
233
234    PE_halt_restart = S5L8720X_halt_restart;
235}
236
237void PE_init_SocSupport_stub(void)
238{
239    PE_early_puts("PE_init_SocSupport: Initializing for S5L8720X\n");
240    PE_init_SocSupport_S5L8720X();
241}
242
243#endif /* !BOARD_CONFIG_S5L8720X */
244