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