source: mainline/uspace/drv/fb/amdm37x_dispc/amdm37x_dispc.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 9.9 KB
Line 
1/*
2 * Copyright (c) 2013 Jan Vesely
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 amdm37x
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include <align.h>
37#include <assert.h>
38#include <errno.h>
39#include <ddf/log.h>
40#include <ddi.h>
41#include <as.h>
42
43#include "amdm37x_dispc.h"
44
45#ifndef CONFIG_BFB_BPP
46#define CONFIG_BFB_BPP 24
47#endif
48
49#ifndef CONFIG_BFB_WIDTH
50#define CONFIG_BFB_WIDTH 1024
51#endif
52
53#ifndef CONFIG_BFB_HEIGHT
54#define CONFIG_BFB_HEIGHT 768
55#endif
56
57
58static errno_t change_mode(visualizer_t *vis, vslmode_t mode);
59static errno_t handle_damage(visualizer_t *vs,
60 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
61 sysarg_t x_offset, sysarg_t y_offset);
62static errno_t dummy(visualizer_t *vs)
63{
64 return EOK;
65}
66
67static const visualizer_ops_t amdm37x_dispc_vis_ops = {
68 .change_mode = change_mode,
69 .handle_damage = handle_damage,
70 .claim = dummy,
71 .yield = dummy,
72 .suspend = dummy,
73 .wakeup = dummy,
74};
75
76static const struct {
77 unsigned bpp;
78 pixel2visual_t func;
79} pixel2visual_table[] = {
80 [VISUAL_INDIRECT_8] = { .bpp = 1, .func = pixel2bgr_323 },
81 [VISUAL_RGB_5_5_5_LE] = { .bpp = 2, .func = pixel2rgb_555_le },
82 [VISUAL_RGB_5_5_5_BE] = { .bpp = 2, .func = pixel2rgb_555_be },
83 [VISUAL_RGB_5_6_5_LE] = { .bpp = 2, .func = pixel2rgb_565_le },
84 [VISUAL_RGB_5_6_5_BE] = { .bpp = 2, .func = pixel2rgb_565_be },
85 [VISUAL_BGR_8_8_8] = { .bpp = 3, .func = pixel2bgr_888 },
86 [VISUAL_RGB_8_8_8] = { .bpp = 3, .func = pixel2rgb_888 },
87 [VISUAL_BGR_0_8_8_8] = { .bpp = 4, .func = pixel2rgb_0888 },
88 [VISUAL_BGR_8_8_8_0] = { .bpp = 4, .func = pixel2bgr_8880 },
89 [VISUAL_ABGR_8_8_8_8] = { .bpp = 4, .func = pixel2abgr_8888 },
90 [VISUAL_BGRA_8_8_8_8] = { .bpp = 4, .func = pixel2bgra_8888 },
91 [VISUAL_RGB_0_8_8_8] = { .bpp = 4, .func = pixel2rgb_0888 },
92 [VISUAL_RGB_8_8_8_0] = { .bpp = 4, .func = pixel2rgb_8880 },
93 [VISUAL_ARGB_8_8_8_8] = { .bpp = 4, .func = pixel2argb_8888 },
94 [VISUAL_RGBA_8_8_8_8] = { .bpp = 4, .func = pixel2rgba_8888 },
95};
96
97
98
99static void mode_init(vslmode_list_element_t *mode,
100 unsigned width, unsigned height, visual_t visual)
101{
102 mode->mode.index = 0;
103 mode->mode.version = 0;
104 mode->mode.refresh_rate = 0;
105 mode->mode.screen_aspect.width = width;
106 mode->mode.screen_aspect.height = height;
107 mode->mode.screen_width = width;
108 mode->mode.screen_height = height;
109 mode->mode.cell_aspect.width = 1;
110 mode->mode.cell_aspect.height = 1;
111 mode->mode.cell_visual.pixel_visual = visual;
112
113 link_initialize(&mode->link);
114
115}
116
117errno_t amdm37x_dispc_init(amdm37x_dispc_t *instance, visualizer_t *vis)
118{
119 assert(instance);
120 assert(vis);
121
122 instance->fb_data = NULL;
123 instance->size = 0;
124
125 /* Default is 24bpp, use config option if available */
126 visual_t visual = VISUAL_BGR_8_8_8;
127 switch (CONFIG_BFB_BPP) {
128 case 8: visual = VISUAL_INDIRECT_8; break;
129 case 16: visual = VISUAL_RGB_5_6_5_LE; break;
130 case 24: visual = VISUAL_BGR_8_8_8; break;
131 case 32: visual = VISUAL_RGB_8_8_8_0; break;
132 default:
133 return EINVAL;
134 }
135
136 errno_t ret = pio_enable((void*)AMDM37x_DISPC_BASE_ADDRESS,
137 AMDM37x_DISPC_SIZE, (void**)&instance->regs);
138 if (ret != EOK) {
139 return EIO;
140 }
141
142 mode_init(&instance->modes[0],
143 CONFIG_BFB_WIDTH, CONFIG_BFB_HEIGHT, visual);
144
145 /* Handle vis stuff */
146 vis->dev_ctx = instance;
147 vis->def_mode_idx = 0;
148 vis->ops = amdm37x_dispc_vis_ops;
149 list_append(&instance->modes[0].link, &vis->modes);
150
151 return EOK;
152};
153
154errno_t amdm37x_dispc_fini(amdm37x_dispc_t *instance)
155{
156 return EOK;
157};
158
159static errno_t amdm37x_dispc_setup_fb(amdm37x_dispc_regs_t *regs,
160 unsigned x, unsigned y, unsigned bpp, uint32_t pa)
161{
162 assert(regs);
163 /* Init sequence for dispc is in chapter 7.6.5.1.4 p. 1810,
164 * no idea what parts of that work. */
165
166 /* Disable all interrupts */
167 regs->irqenable = 0;
168
169 /* Pixel format specifics*/
170 uint32_t attrib_pixel_format = 0;
171 uint32_t control_data_lanes = 0;
172 switch (bpp)
173 {
174 case 32:
175 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGBX;
176 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_24B;
177 break;
178 case 24:
179 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGB24;
180 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_24B;
181 break;
182 case 16:
183 attrib_pixel_format = AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_RGB16;
184 control_data_lanes = AMDM37X_DISPC_CONTROL_TFTDATALINES_16B;
185 break;
186 default:
187 return EINVAL;
188 }
189
190 /* Prepare sizes */
191 const uint32_t size_reg =
192 (((x - 1) & AMDM37X_DISPC_SIZE_WIDTH_MASK)
193 << AMDM37X_DISPC_SIZE_WIDTH_SHIFT) |
194 (((y - 1) & AMDM37X_DISPC_SIZE_HEIGHT_MASK)
195 << AMDM37X_DISPC_SIZE_HEIGHT_SHIFT);
196
197 /* modes taken from u-boot, for 1024x768 */
198 // TODO replace magic values with actual correct values
199// regs->timing_h = 0x1a4024c9;
200// regs->timing_v = 0x02c00509;
201// regs->pol_freq = 0x00007028;
202// regs->divisor = 0x00010001;
203
204 /* setup output */
205 regs->size_lcd = size_reg;
206 regs->size_dig = size_reg;
207
208 /* Nice blue default color */
209 regs->default_color[0] = 0x0000ff;
210 regs->default_color[1] = 0x0000ff;
211
212 /* Setup control register */
213 uint32_t control = 0 |
214 AMDM37X_DISPC_CONTROL_PCKFREEENABLE_FLAG |
215 (control_data_lanes << AMDM37X_DISPC_CONTROL_TFTDATALINES_SHIFT) |
216 AMDM37X_DISPC_CONTROL_GPOUT0_FLAG |
217 AMDM37X_DISPC_CONTROL_GPOUT1_FLAG;
218 regs->control = control;
219
220 /* No gamma stuff only data */
221 uint32_t config = (AMDM37X_DISPC_CONFIG_LOADMODE_DATAEVERYFRAME
222 << AMDM37X_DISPC_CONFIG_LOADMODE_SHIFT);
223 regs->config = config;
224
225
226 /* Set framebuffer base address */
227 regs->gfx.ba[0] = pa;
228 regs->gfx.ba[1] = pa;
229 regs->gfx.position = 0;
230
231 /* Setup fb size */
232 regs->gfx.size = size_reg;
233
234 /* Set pixel format */
235 uint32_t attribs = 0 |
236 (attrib_pixel_format << AMDM37X_DISPC_GFX_ATTRIBUTES_FORMAT_SHIFT);
237 regs->gfx.attributes = attribs;
238
239 /* 0x03ff03c0 is the default */
240 regs->gfx.fifo_threshold = 0x03ff03c0;
241 /* This value should be stride - width, 1 means next pixel i.e.
242 * stride == width */
243 regs->gfx.row_inc = 1;
244 /* number of bytes to next pixel in BPP multiples */
245 regs->gfx.pixel_inc = 1;
246 /* only used if video is played over fb */
247 regs->gfx.window_skip = 0;
248 /* Gamma and palette table */
249 regs->gfx.table_ba = 0;
250
251 /* enable frame buffer graphics */
252 regs->gfx.attributes |= AMDM37X_DISPC_GFX_ATTRIBUTES_ENABLE_FLAG;
253 /* Update register values */
254 regs->control |= AMDM37X_DISPC_CONTROL_GOLCD_FLAG;
255 regs->control |= AMDM37X_DISPC_CONTROL_GODIGITAL_FLAG;
256 /* Enable output */
257 regs->control |= AMDM37X_DISPC_CONTROL_LCD_ENABLE_FLAG;
258 regs->control |= AMDM37X_DISPC_CONTROL_DIGITAL_ENABLE_FLAG;
259 return EOK;
260}
261
262static errno_t change_mode(visualizer_t *vis, vslmode_t mode)
263{
264 assert(vis);
265 assert(vis->dev_ctx);
266
267 amdm37x_dispc_t *dispc = vis->dev_ctx;
268 const visual_t visual = mode.cell_visual.pixel_visual;
269 assert((size_t)visual < sizeof(pixel2visual_table) / sizeof(pixel2visual_table[0]));
270 const unsigned bpp = pixel2visual_table[visual].bpp;
271 pixel2visual_t p2v = pixel2visual_table[visual].func;
272 const unsigned x = mode.screen_width;
273 const unsigned y = mode.screen_height;
274 ddf_log_note("Setting mode: %ux%ux%u\n", x, y, bpp*8);
275 const size_t size = ALIGN_UP(x * y * bpp, PAGE_SIZE);
276 uintptr_t pa;
277 void *buffer = AS_AREA_ANY;
278 errno_t ret = dmamem_map_anonymous(size, DMAMEM_4GiB,
279 AS_AREA_READ | AS_AREA_WRITE, 0, &pa, &buffer);
280 if (ret != EOK) {
281 ddf_log_error("Failed to get new FB\n");
282 return ret;
283 }
284 if (dispc->fb_data)
285 dmamem_unmap_anonymous(dispc->fb_data);
286
287 dispc->fb_data = buffer;
288 amdm37x_dispc_setup_fb(dispc->regs, x, y, bpp *8, (uint32_t)pa);
289 dispc->active_fb.idx = mode.index;
290 dispc->active_fb.width = x;
291 dispc->active_fb.height = y;
292 dispc->active_fb.pitch = 0;
293 dispc->active_fb.bpp = bpp;
294 dispc->active_fb.pixel2visual = p2v;
295 dispc->size = size;
296 assert(mode.index < 1);
297
298 return EOK;
299}
300
301static errno_t handle_damage(visualizer_t *vs,
302 sysarg_t x0, sysarg_t y0, sysarg_t width, sysarg_t height,
303 sysarg_t x_offset, sysarg_t y_offset)
304{
305 assert(vs);
306 assert(vs->dev_ctx);
307 amdm37x_dispc_t *dispc = vs->dev_ctx;
308 pixelmap_t *map = &vs->cells;
309
310#define FB_POS(x, y) \
311 (((y) * (dispc->active_fb.width + dispc->active_fb.pitch) + (x)) \
312 * dispc->active_fb.bpp)
313 if (x_offset == 0 && y_offset == 0) {
314 /* Faster damage routine ignoring offsets. */
315 for (sysarg_t y = y0; y < height + y0; ++y) {
316 pixel_t *pixel = pixelmap_pixel_at(map, x0, y);
317 for (sysarg_t x = x0; x < width + x0; ++x) {
318 dispc->active_fb.pixel2visual(
319 dispc->fb_data + FB_POS(x, y), *pixel++);
320 }
321 }
322 } else {
323 for (sysarg_t y = y0; y < height + y0; ++y) {
324 for (sysarg_t x = x0; x < width + x0; ++x) {
325 dispc->active_fb.pixel2visual(
326 dispc->fb_data + FB_POS(x, y),
327 *pixelmap_pixel_at(map,
328 (x + x_offset) % map->width,
329 (y + y_offset) % map->height));
330 }
331 }
332 }
333
334 return EOK;
335}
Note: See TracBrowser for help on using the repository browser.