~jsvoboda/helenos/dnsr

« back to all changes in this revision

Viewing changes to kernel/arch/sparc64/src/drivers/scr.c

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/fb/fb.h>
 
38
#include <genarch/fb/visuals.h>
 
39
#include <arch/types.h>
 
40
#include <string.h>
 
41
#include <align.h>
 
42
#include <print.h>
 
43
 
 
44
#define FFB_REG_24BPP   7
 
45
 
 
46
scr_type_t scr_type = SCR_UNKNOWN;
 
47
 
 
48
/** Initialize screen.
 
49
 *
 
50
 * Traverse OpenFirmware device tree in order to find necessary
 
51
 * info about the screen device.
 
52
 *
 
53
 * @param node Screen device node.
 
54
 */
 
55
void scr_init(ofw_tree_node_t *node)
 
56
{
 
57
        ofw_tree_property_t *prop;
 
58
        ofw_pci_reg_t *pci_reg;
 
59
        ofw_pci_reg_t pci_abs_reg;
 
60
        ofw_upa_reg_t *upa_reg;
 
61
        ofw_sbus_reg_t *sbus_reg;
 
62
        const char *name;
 
63
        
 
64
        name = ofw_tree_node_name(node);
 
65
        
 
66
        if (str_cmp(name, "SUNW,m64B") == 0)
 
67
                scr_type = SCR_ATYFB;
 
68
        else if (str_cmp(name, "SUNW,XVR-100") == 0)
 
69
                scr_type = SCR_XVR;
 
70
        else if (str_cmp(name, "SUNW,ffb") == 0)
 
71
                scr_type = SCR_FFB;
 
72
        else if (str_cmp(name, "cgsix") == 0)
 
73
                scr_type = SCR_CGSIX;
 
74
        
 
75
        if (scr_type == SCR_UNKNOWN) {
 
76
                printf("Unknown screen device.\n");
 
77
                return;
 
78
        }
 
79
        
 
80
        uintptr_t fb_addr;
 
81
        unsigned int fb_offset = 0;
 
82
        uint32_t fb_width = 0;
 
83
        uint32_t fb_height = 0;
 
84
        uint32_t fb_depth = 0;
 
85
        uint32_t fb_linebytes = 0;
 
86
        uint32_t fb_scanline = 0;
 
87
        unsigned int visual;
 
88
 
 
89
        prop = ofw_tree_getprop(node, "width");
 
90
        if (prop && prop->value)
 
91
                fb_width = *((uint32_t *) prop->value);
 
92
 
 
93
        prop = ofw_tree_getprop(node, "height");
 
94
        if (prop && prop->value)
 
95
                fb_height = *((uint32_t *) prop->value);
 
96
 
 
97
        prop = ofw_tree_getprop(node, "depth");
 
98
        if (prop && prop->value)
 
99
                fb_depth = *((uint32_t *) prop->value);
 
100
 
 
101
        prop = ofw_tree_getprop(node, "linebytes");
 
102
        if (prop && prop->value)
 
103
                fb_linebytes = *((uint32_t *) prop->value);
 
104
 
 
105
        prop = ofw_tree_getprop(node, "reg");
 
106
        if (!prop)
 
107
                panic("Cannot find 'reg' property.");
 
108
 
 
109
        switch (scr_type) {
 
110
        case SCR_ATYFB:
 
111
                if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
 
112
                        printf("Too few screen registers.\n");
 
113
                        return;
 
114
                }
 
115
        
 
116
                pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
 
117
                
 
118
                if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
 
119
                        printf("Failed to absolutize fb register.\n");
 
120
                        return;
 
121
                }
 
122
        
 
123
                if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
 
124
                    &fb_addr)) {
 
125
                        printf("Failed to determine screen address.\n");
 
126
                        return;
 
127
                }
 
128
                
 
129
                switch (fb_depth) {
 
130
                case 8:
 
131
                        fb_scanline = fb_linebytes * (fb_depth >> 3);
 
132
                        visual = VISUAL_INDIRECT_8;
 
133
                        break;
 
134
                case 16:
 
135
                        fb_scanline = fb_linebytes * (fb_depth >> 3);
 
136
                        visual = VISUAL_RGB_5_6_5_BE;
 
137
                        break;
 
138
                case 24:
 
139
                        fb_scanline = fb_linebytes * 4;
 
140
                        visual = VISUAL_BGR_8_8_8_0;
 
141
                        break;
 
142
                case 32:
 
143
                        fb_scanline = fb_linebytes * (fb_depth >> 3);
 
144
                        visual = VISUAL_RGB_0_8_8_8;
 
145
                        break;
 
146
                default:
 
147
                        printf("Unsupported bits per pixel.\n");
 
148
                        return;
 
149
                }
 
150
                
 
151
                break;
 
152
        case SCR_XVR:
 
153
                if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
 
154
                        printf("Too few screen registers.\n");
 
155
                        return;
 
156
                }
 
157
        
 
158
                pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
 
159
                
 
160
                if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
 
161
                        printf("Failed to absolutize fb register.\n");
 
162
                        return;
 
163
                }
 
164
        
 
165
                if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
 
166
                    &fb_addr)) {
 
167
                        printf("Failed to determine screen address.\n");
 
168
                        return;
 
169
                }
 
170
 
 
171
                fb_offset = 4 * 0x2000;
 
172
 
 
173
                switch (fb_depth) {
 
174
                case 8:
 
175
                        fb_scanline = fb_linebytes * (fb_depth >> 3);
 
176
                        visual = VISUAL_INDIRECT_8;
 
177
                        break;
 
178
                case 16:
 
179
                        fb_scanline = fb_linebytes * (fb_depth >> 3);
 
180
                        visual = VISUAL_RGB_5_6_5_BE;
 
181
                        break;
 
182
                case 24:
 
183
                        fb_scanline = fb_linebytes * 4;
 
184
                        visual = VISUAL_BGR_8_8_8_0;
 
185
                        break;
 
186
                case 32:
 
187
                        fb_scanline = fb_linebytes * (fb_depth >> 3);
 
188
                        visual = VISUAL_RGB_0_8_8_8;
 
189
                        break;
 
190
                default:
 
191
                        printf("Unsupported bits per pixel.\n");
 
192
                        return;
 
193
                }
 
194
                
 
195
                break;
 
196
        case SCR_FFB:   
 
197
                fb_scanline = 8192;
 
198
                visual = VISUAL_BGR_0_8_8_8;
 
199
 
 
200
                upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
 
201
                if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) {
 
202
                        printf("Failed to determine screen address.\n");
 
203
                        return;
 
204
                }
 
205
 
 
206
                break;
 
207
        case SCR_CGSIX:
 
208
                switch (fb_depth) {
 
209
                case 8:
 
210
                        fb_scanline = fb_linebytes;
 
211
                        visual = VISUAL_INDIRECT_8;
 
212
                        break;
 
213
                default:
 
214
                        printf("Not implemented.\n");
 
215
                        return;
 
216
                }
 
217
                
 
218
                sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0];
 
219
                if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) {
 
220
                        printf("Failed to determine screen address.\n");
 
221
                        return;
 
222
                }
 
223
        
 
224
                break;
 
225
        default:
 
226
                panic("Unexpected type.");
 
227
        }
 
228
 
 
229
        fb_properties_t props = {
 
230
                .addr = fb_addr,
 
231
                .offset = fb_offset,
 
232
                .x = fb_width,
 
233
                .y = fb_height,
 
234
                .scan = fb_scanline,
 
235
                .visual = visual,
 
236
        };
 
237
        fb_init(&props);
 
238
}
 
239
 
 
240
void scr_redraw(void)
 
241
{
 
242
        fb_redraw();
 
243
}
 
244
 
 
245
/** @}
 
246
 */