1/*
2 * Copyright 2004, Axel D��rfler, axeld@pinc-software.de.
3 * Copyright 2010 Andreas F��rber <andreas.faerber@web.de>
4 * All rights reserved. Distributed under the terms of the MIT License.
5 */
6
7
8#include <boot/platform.h>
9#include <boot/stage2.h>
10#include <boot/platform/generic/text_console.h>
11#include <boot/platform/generic/video.h>
12#include <edid.h>
13#include <platform/openfirmware/openfirmware.h>
14
15
16//#define TRACE_VIDEO
17
18
19static intptr_t sScreen;
20
21
22void
23platform_blit4(addr_t frameBuffer, const uint8 *data,
24	uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top)
25{
26	panic("platform_blit4(): not implemented\n");
27}
28
29
30extern "C" void
31platform_set_palette(const uint8 *palette)
32{
33	switch (gKernelArgs.frame_buffer.depth) {
34		case 8:
35			if (of_call_method(sScreen, "set-colors", 3, 0,
36					256, 0, palette) == OF_FAILED) {
37				for (int index = 0; index < 256; index++) {
38					of_call_method(sScreen, "color!", 4, 0, index,
39						palette[index * 3 + 2],
40						palette[index * 3 + 1],
41						palette[index * 3 + 0]);
42				}
43			}
44			break;
45		default:
46			break;
47	}
48}
49
50
51extern "C" void
52platform_switch_to_logo(void)
53{
54	// in debug mode, we'll never show the logo
55	if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0)
56		return;
57
58	sScreen = of_open("screen");
59	if (sScreen == OF_FAILED)
60		return;
61
62	intptr_t package = of_instance_to_package(sScreen);
63	if (package == OF_FAILED)
64		return;
65	uintptr_t width, height;
66	if (of_call_method(sScreen, "dimensions", 0, 2, &height, &width)
67			== OF_FAILED) {
68		if (of_getprop(package, "width", &width, sizeof(int32)) == OF_FAILED)
69			return;
70		if (of_getprop(package, "height", &height, sizeof(int32)) == OF_FAILED)
71			return;
72	}
73	uint32 depth;
74	if (of_getprop(package, "depth", &depth, sizeof(uint32)) == OF_FAILED)
75		return;
76	uint32 lineBytes;
77	if (of_getprop(package, "linebytes", &lineBytes, sizeof(uint32))
78			== OF_FAILED)
79		return;
80	uint32 address;
81		// address is always 32 bit
82	if (of_getprop(package, "address", &address, sizeof(uint32)) == OF_FAILED)
83		return;
84	gKernelArgs.frame_buffer.physical_buffer.start = address;
85	gKernelArgs.frame_buffer.physical_buffer.size = lineBytes * height;
86	gKernelArgs.frame_buffer.width = width;
87	gKernelArgs.frame_buffer.height = height;
88	gKernelArgs.frame_buffer.depth = depth;
89	gKernelArgs.frame_buffer.bytes_per_row = lineBytes;
90
91	// Move text to top of display so we don't scroll the boot logo out as soon
92	// as we display some text
93	console_set_cursor(0, 0);
94
95	dprintf("video mode: %ux%ux%u\n", gKernelArgs.frame_buffer.width,
96		gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth);
97
98	gKernelArgs.frame_buffer.enabled = true;
99
100	// the memory will be identity-mapped already
101	video_display_splash(gKernelArgs.frame_buffer.physical_buffer.start);
102}
103
104
105extern "C" void
106platform_switch_to_text_mode(void)
107{
108	// nothing to do if we're in text mode
109	if (!gKernelArgs.frame_buffer.enabled)
110		return;
111
112	// ToDo: implement me
113
114	gKernelArgs.frame_buffer.enabled = false;
115}
116
117
118extern "C" status_t
119platform_init_video(void)
120{
121	gKernelArgs.frame_buffer.enabled = false;
122
123	intptr_t screen = of_finddevice("screen");
124	if (screen == OF_FAILED)
125		return B_NO_INIT;
126	edid1_raw edidRaw;
127	if (of_getprop(screen, "EDID", &edidRaw, sizeof(edidRaw)) != OF_FAILED) {
128		edid1_info info;
129		edid_decode(&info, &edidRaw);
130#ifdef TRACE_VIDEO
131		edid_dump(&info);
132#endif
133		gKernelArgs.edid_info = kernel_args_malloc(sizeof(edid1_info));
134		if (gKernelArgs.edid_info != NULL)
135			memcpy(gKernelArgs.edid_info, &info, sizeof(edid1_info));
136	}
137
138	return B_OK;
139}
140
141