blob: ce79a3e2a9077881927092adcd25675ca21727a2 [file] [log] [blame]
Dima Zavind5b0b6a2009-01-15 18:09:25 -08001/*
2 * Copyright (c) 2008, Google Inc.
3 * All rights reserved.
4 *
Channagoud Kadabi7af9fbc2015-02-13 20:09:55 -08005 * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
Shashank Mittal4f99a882010-02-01 13:58:50 -08006 *
Dima Zavind5b0b6a2009-01-15 18:09:25 -08007 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <debug.h>
32#include <err.h>
33#include <stdlib.h>
34#include <dev/fbcon.h>
Chandan Uddaraju40b227d2010-08-03 19:25:41 -070035#include <splash.h>
Greg Griscod6250552011-06-29 14:40:23 -070036#include <platform.h>
37#include <string.h>
Channagoud Kadabi7af9fbc2015-02-13 20:09:55 -080038#include <arch/ops.h>
Dima Zavind5b0b6a2009-01-15 18:09:25 -080039
40#include "font5x12.h"
41
42struct pos {
43 int x;
44 int y;
45};
46
47static struct fbcon_config *config = NULL;
48
Chandan Uddaraju2943fd62010-06-21 10:56:39 -070049#define RGB565_BLACK 0x0000
Dima Zavind5b0b6a2009-01-15 18:09:25 -080050#define RGB565_WHITE 0xffff
51
Chandan Uddaraju78ae6752010-10-19 12:57:10 -070052#define RGB888_BLACK 0x000000
53#define RGB888_WHITE 0xffffff
54
Dima Zavind5b0b6a2009-01-15 18:09:25 -080055#define FONT_WIDTH 5
56#define FONT_HEIGHT 12
57
58static uint16_t BGCOLOR;
59static uint16_t FGCOLOR;
60
61static struct pos cur_pos;
62static struct pos max_pos;
63
64static void fbcon_drawglyph(uint16_t *pixels, uint16_t paint, unsigned stride,
65 unsigned *glyph)
66{
67 unsigned x, y, data;
68 stride -= FONT_WIDTH;
69
70 data = glyph[0];
71 for (y = 0; y < (FONT_HEIGHT / 2); ++y) {
72 for (x = 0; x < FONT_WIDTH; ++x) {
73 if (data & 1)
74 *pixels = paint;
75 data >>= 1;
76 pixels++;
77 }
78 pixels += stride;
79 }
80
81 data = glyph[1];
82 for (y = 0; y < (FONT_HEIGHT / 2); y++) {
83 for (x = 0; x < FONT_WIDTH; x++) {
84 if (data & 1)
85 *pixels = paint;
86 data >>= 1;
87 pixels++;
88 }
89 pixels += stride;
90 }
91}
92
Dima Zavin25ed9942009-01-28 17:04:19 -080093static void fbcon_flush(void)
94{
95 if (config->update_start)
96 config->update_start();
97 if (config->update_done)
98 while (!config->update_done());
99}
100
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800101/* TODO: Take stride into account */
102static void fbcon_scroll_up(void)
103{
104 unsigned short *dst = config->base;
105 unsigned short *src = dst + (config->width * FONT_HEIGHT);
106 unsigned count = config->width * (config->height - FONT_HEIGHT);
107
108 while(count--) {
109 *dst++ = *src++;
110 }
111
112 count = config->width * FONT_HEIGHT;
113 while(count--) {
114 *dst++ = BGCOLOR;
115 }
Dima Zavin25ed9942009-01-28 17:04:19 -0800116
117 fbcon_flush();
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800118}
119
120/* TODO: take stride into account */
Shashank Mittal4f99a882010-02-01 13:58:50 -0800121void fbcon_clear(void)
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800122{
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800123 unsigned count = config->width * config->height;
Chandan Uddaraju40b227d2010-08-03 19:25:41 -0700124 memset(config->base, BGCOLOR, count * ((config->bpp) / 8));
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800125}
126
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800127
128static void fbcon_set_colors(unsigned bg, unsigned fg)
129{
130 BGCOLOR = bg;
131 FGCOLOR = fg;
132}
133
134void fbcon_putc(char c)
135{
136 uint16_t *pixels;
137
138 /* ignore anything that happens before fbcon is initialized */
139 if (!config)
140 return;
141
142 if((unsigned char)c > 127)
143 return;
144 if((unsigned char)c < 32) {
145 if(c == '\n')
146 goto newline;
147 else if (c == '\r')
148 cur_pos.x = 0;
149 return;
150 }
151
152 pixels = config->base;
153 pixels += cur_pos.y * FONT_HEIGHT * config->width;
154 pixels += cur_pos.x * (FONT_WIDTH + 1);
155 fbcon_drawglyph(pixels, FGCOLOR, config->stride,
156 font5x12 + (c - 32) * 2);
157
158 cur_pos.x++;
159 if (cur_pos.x < max_pos.x)
160 return;
161
162newline:
163 cur_pos.y++;
164 cur_pos.x = 0;
165 if(cur_pos.y >= max_pos.y) {
166 cur_pos.y = max_pos.y - 1;
167 fbcon_scroll_up();
Dima Zavin25ed9942009-01-28 17:04:19 -0800168 } else
169 fbcon_flush();
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800170}
171
172void fbcon_setup(struct fbcon_config *_config)
173{
174 uint32_t bg;
175 uint32_t fg;
176
177 ASSERT(_config);
178
179 config = _config;
180
181 switch (config->format) {
182 case FB_FORMAT_RGB565:
Shashank Mittalc648e712010-10-06 18:37:42 -0700183 fg = RGB565_WHITE;
184 bg = RGB565_BLACK;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800185 break;
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700186 case FB_FORMAT_RGB888:
187 fg = RGB888_WHITE;
188 bg = RGB888_BLACK;
189 break;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800190 default:
191 dprintf(CRITICAL, "unknown framebuffer pixel format\n");
192 ASSERT(0);
193 break;
194 }
195
196 fbcon_set_colors(bg, fg);
197
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800198 cur_pos.x = 0;
199 cur_pos.y = 0;
200 max_pos.x = config->width / (FONT_WIDTH+1);
201 max_pos.y = (config->height - 1) / FONT_HEIGHT;
Shashank Mittal37040832010-08-24 15:57:57 -0700202#if !DISPLAY_SPLASH_SCREEN
203 fbcon_clear();
204#endif
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800205}
Shashank Mittal4f99a882010-02-01 13:58:50 -0800206
207struct fbcon_config* fbcon_display(void)
208{
209 return config;
210}
Chandan Uddaraju40b227d2010-08-03 19:25:41 -0700211
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530212
213extern struct fbimage* fetch_image_from_partition();
214void fbcon_putImage(struct fbimage *fbimg, bool flag);
215
216void display_image_on_screen()
217{
218 struct fbimage default_fbimg, *fbimg;
219 bool flag = true;
220
221 fbcon_clear();
222 fbimg = fetch_image_from_partition();
223
224 if(!fbimg) {
225 flag = false;
226 fbimg = &default_fbimg;
Zohaib Alam03708752014-10-23 17:51:57 -0400227 fbimg->header.width = SPLASH_IMAGE_WIDTH;
228 fbimg->header.height = SPLASH_IMAGE_HEIGHT;
Aparna Mallavarapu057a74b2013-09-12 23:22:46 +0530229#if DISPLAY_TYPE_MIPI
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530230 fbimg->image = (unsigned char *)imageBuffer_rgb888;
Aparna Mallavarapu057a74b2013-09-12 23:22:46 +0530231#else
232 fbimg->image = (unsigned char *)imageBuffer;
233#endif
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530234 }
235
236 fbcon_putImage(fbimg, flag);
vijay kumar2fca1a82014-12-10 12:34:15 +0530237 if(flag)
Channagoud Kadabi31a6db02014-12-03 12:45:02 -0800238 free(fbimg);
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530239}
240
241void fbcon_putImage(struct fbimage *fbimg, bool flag)
Chandan Uddaraju40b227d2010-08-03 19:25:41 -0700242{
243 unsigned i = 0;
Channagoud Kadabi956cf502012-03-08 03:49:50 +0530244 unsigned total_x;
245 unsigned total_y;
246 unsigned bytes_per_bpp;
247 unsigned image_base;
Veera Sundaram Sankaran8596eb72014-12-09 13:53:13 -0800248 unsigned width = 0, pitch = 0, height = 0;
Sridhar Parasuramfa56fa72014-12-29 13:37:23 -0800249#if DISPLAY_TYPE_MIPI
Veera Sundaram Sankaran8596eb72014-12-09 13:53:13 -0800250 unsigned char *logo_base = NULL;
Sridhar Parasuramfa56fa72014-12-29 13:37:23 -0800251#endif
Veera Sundaram Sankaran8596eb72014-12-09 13:53:13 -0800252 struct logo_img_header *header = NULL;
Channagoud Kadabi956cf502012-03-08 03:49:50 +0530253
Channagoud Kadabi956cf502012-03-08 03:49:50 +0530254
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530255 if (!config) {
256 dprintf(CRITICAL,"NULL configuration, image cannot be displayed\n");
257 return;
258 }
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700259
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530260 if(fbimg) {
261 header = &fbimg->header;
262 width = pitch = header->width;
263 height = header->height;
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530264 }
265
266 total_x = config->width;
267 total_y = config->height;
268 bytes_per_bpp = ((config->bpp) / 8);
Channagoud Kadabi956cf502012-03-08 03:49:50 +0530269
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700270#if DISPLAY_TYPE_MIPI
Sridhar Parasuramfa56fa72014-12-29 13:37:23 -0800271 if(fbimg) {
272 logo_base = (unsigned char *)fbimg->image;
273 }
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530274 if (bytes_per_bpp == 3)
275 {
Veera Sundaram Sankaran8596eb72014-12-09 13:53:13 -0800276 if(flag && header) {
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530277 if (header->width == config->width && header->height == config->height)
278 return;
279 else {
280 logo_base = (unsigned char *)config->base + LOGO_IMG_OFFSET;
281 if (header->width > config->width) {
282 width = config->width;
283 pitch = header->width;
284 logo_base += (header->width - config->width) / 2 * bytes_per_bpp;
285 } else {
286 width = pitch = header->width;
287 }
288
289 if (header->height > config->height) {
290 height = config->height;
291 logo_base += (header->height - config->height) / 2 * pitch * bytes_per_bpp;
292 } else {
293 height = header->height;
294 }
295 }
296 }
297
298 image_base = ((((total_y/2) - (height / 2) ) *
299 (config->width)) + (total_x/2 - (width / 2)));
300 for (i = 0; i < height; i++) {
301 memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp),
302 logo_base + (i * pitch * bytes_per_bpp), width * bytes_per_bpp);
303 }
Channagoud Kadabi7af9fbc2015-02-13 20:09:55 -0800304 /* Flush the contents to memory before giving the data to dma */
305 arch_clean_invalidate_cache_range((addr_t) config->base, (total_x * total_y * bytes_per_bpp));
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700306 }
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530307
308 fbcon_flush();
309
Kinson Chike5c93432011-06-17 09:10:29 -0700310#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530311 if(is_cmd_mode_enabled())
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800312 mipi_dsi_cmd_mode_trigger();
Kinson Chike5c93432011-06-17 09:10:29 -0700313#endif
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800314
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700315#else
Zohaib Alam03708752014-10-23 17:51:57 -0400316 if (bytes_per_bpp == 2)
317 {
318 image_base = ((((total_y/2) - (height / 2) ) *
319 (config->width)) + (total_x/2 - (width / 2)));
320
321 for (i = 0; i < header->width; i++)
322 {
323 memcpy (config->base +
324 ((image_base + (i * (config->width))) * bytes_per_bpp),
325 (fbimg->image + (i * header->height * bytes_per_bpp)),
326 (header->height * bytes_per_bpp));
327 }
328 }
Channagoud Kadabi7af9fbc2015-02-13 20:09:55 -0800329 /* Flush the contents to memory before giving the data to dma */
330 arch_clean_invalidate_cache_range((addr_t) config->base, (total_x * total_y * bytes_per_bpp));
Zohaib Alam03708752014-10-23 17:51:57 -0400331 fbcon_flush();
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800332#endif
Chandan Uddaraju40b227d2010-08-03 19:25:41 -0700333}