source: mainline/kernel/arch/sparc64/src/drivers/scr.c@ 86018c1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 86018c1 was a71c158, checked in by Martin Decky <martin@…>, 16 years ago

kernel output devices now suport multiple instances (except ski and sgcn, which respect the same interface, but behave as singletons)
if more than one output device gets initialized, the output is cloned to all of them
get rid of arch_grab_console() and arch_release_console() (output devices can implement a generic "redraw" method, input devices respect the "silent" global variable)
related cleanups and modifications

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup sparc64
30 * @{
31 */
32/** @file
33 */
34
35#include <arch/drivers/scr.h>
36#include <genarch/ofw/ofw_tree.h>
37#include <genarch/ofw/pci.h>
38#include <genarch/ofw/sbus.h>
39#include <genarch/ofw/upa.h>
40#include <genarch/fb/fb.h>
41#include <genarch/fb/visuals.h>
42#include <console/chardev.h>
43#include <console/console.h>
44#include <arch/types.h>
45#include <string.h>
46#include <align.h>
47#include <print.h>
48
49#define FFB_REG_24BPP 7
50
51scr_type_t scr_type = SCR_UNKNOWN;
52
53/** Initialize screen.
54 *
55 * Traverse OpenFirmware device tree in order to find necessary
56 * info about the screen device.
57 *
58 * @param node Screen device node.
59 */
60void scr_init(ofw_tree_node_t *node)
61{
62 ofw_tree_property_t *prop;
63 ofw_pci_reg_t *pci_reg;
64 ofw_pci_reg_t pci_abs_reg;
65 ofw_upa_reg_t *upa_reg;
66 ofw_sbus_reg_t *sbus_reg;
67 const char *name;
68
69 name = ofw_tree_node_name(node);
70
71 if (str_cmp(name, "SUNW,m64B") == 0)
72 scr_type = SCR_ATYFB;
73 else if (str_cmp(name, "SUNW,XVR-100") == 0)
74 scr_type = SCR_XVR;
75 else if (str_cmp(name, "SUNW,ffb") == 0)
76 scr_type = SCR_FFB;
77 else if (str_cmp(name, "cgsix") == 0)
78 scr_type = SCR_CGSIX;
79
80 if (scr_type == SCR_UNKNOWN) {
81 printf("Unknown screen device.\n");
82 return;
83 }
84
85 uintptr_t fb_addr;
86 unsigned int fb_offset = 0;
87 uint32_t fb_width = 0;
88 uint32_t fb_height = 0;
89 uint32_t fb_depth = 0;
90 uint32_t fb_linebytes = 0;
91 uint32_t fb_scanline = 0;
92 unsigned int visual;
93
94 prop = ofw_tree_getprop(node, "width");
95 if (prop && prop->value)
96 fb_width = *((uint32_t *) prop->value);
97
98 prop = ofw_tree_getprop(node, "height");
99 if (prop && prop->value)
100 fb_height = *((uint32_t *) prop->value);
101
102 prop = ofw_tree_getprop(node, "depth");
103 if (prop && prop->value)
104 fb_depth = *((uint32_t *) prop->value);
105
106 prop = ofw_tree_getprop(node, "linebytes");
107 if (prop && prop->value)
108 fb_linebytes = *((uint32_t *) prop->value);
109
110 prop = ofw_tree_getprop(node, "reg");
111 if (!prop)
112 panic("Cannot find 'reg' property.");
113
114 switch (scr_type) {
115 case SCR_ATYFB:
116 if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
117 printf("Too few screen registers.\n");
118 return;
119 }
120
121 pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
122
123 if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
124 printf("Failed to absolutize fb register.\n");
125 return;
126 }
127
128 if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
129 &fb_addr)) {
130 printf("Failed to determine screen address.\n");
131 return;
132 }
133
134 switch (fb_depth) {
135 case 8:
136 fb_scanline = fb_linebytes * (fb_depth >> 3);
137 visual = VISUAL_INDIRECT_8;
138 break;
139 case 16:
140 fb_scanline = fb_linebytes * (fb_depth >> 3);
141 visual = VISUAL_RGB_5_6_5_BE;
142 break;
143 case 24:
144 fb_scanline = fb_linebytes * 4;
145 visual = VISUAL_BGR_8_8_8_0;
146 break;
147 case 32:
148 fb_scanline = fb_linebytes * (fb_depth >> 3);
149 visual = VISUAL_RGB_0_8_8_8;
150 break;
151 default:
152 printf("Unsupported bits per pixel.\n");
153 return;
154 }
155
156 break;
157 case SCR_XVR:
158 if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
159 printf("Too few screen registers.\n");
160 return;
161 }
162
163 pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
164
165 if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
166 printf("Failed to absolutize fb register.\n");
167 return;
168 }
169
170 if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
171 &fb_addr)) {
172 printf("Failed to determine screen address.\n");
173 return;
174 }
175
176 fb_offset = 4 * 0x2000;
177
178 switch (fb_depth) {
179 case 8:
180 fb_scanline = fb_linebytes * (fb_depth >> 3);
181 visual = VISUAL_INDIRECT_8;
182 break;
183 case 16:
184 fb_scanline = fb_linebytes * (fb_depth >> 3);
185 visual = VISUAL_RGB_5_6_5_BE;
186 break;
187 case 24:
188 fb_scanline = fb_linebytes * 4;
189 visual = VISUAL_BGR_8_8_8_0;
190 break;
191 case 32:
192 fb_scanline = fb_linebytes * (fb_depth >> 3);
193 visual = VISUAL_RGB_0_8_8_8;
194 break;
195 default:
196 printf("Unsupported bits per pixel.\n");
197 return;
198 }
199
200 break;
201 case SCR_FFB:
202 fb_scanline = 8192;
203 visual = VISUAL_BGR_0_8_8_8;
204
205 upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
206 if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) {
207 printf("Failed to determine screen address.\n");
208 return;
209 }
210
211 break;
212 case SCR_CGSIX:
213 switch (fb_depth) {
214 case 8:
215 fb_scanline = fb_linebytes;
216 visual = VISUAL_INDIRECT_8;
217 break;
218 default:
219 printf("Not implemented.\n");
220 return;
221 }
222
223 sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0];
224 if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) {
225 printf("Failed to determine screen address.\n");
226 return;
227 }
228
229 break;
230 default:
231 panic("Unexpected type.");
232 }
233
234 fb_properties_t props = {
235 .addr = fb_addr,
236 .offset = fb_offset,
237 .x = fb_width,
238 .y = fb_height,
239 .scan = fb_scanline,
240 .visual = visual,
241 };
242
243 outdev_t *fbdev = fb_init(&props);
244 if (fbdev)
245 stdout_wire(fbdev);
246}
247
248/** @}
249 */
Note: See TracBrowser for help on using the repository browser.