blob: 885ce8735533c7245377f101668563dedf4d3d5e [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>
Channagoud Kadabi875a2a72015-04-24 17:26:38 -070039#if ENABLE_WBC
40#include <pm_app_smbchg.h>
41#endif
Dima Zavind5b0b6a2009-01-15 18:09:25 -080042
43#include "font5x12.h"
44
45struct pos {
46 int x;
47 int y;
48};
49
50static struct fbcon_config *config = NULL;
51
Chandan Uddaraju2943fd62010-06-21 10:56:39 -070052#define RGB565_BLACK 0x0000
Dima Zavind5b0b6a2009-01-15 18:09:25 -080053#define RGB565_WHITE 0xffff
54
Chandan Uddaraju78ae6752010-10-19 12:57:10 -070055#define RGB888_BLACK 0x000000
56#define RGB888_WHITE 0xffffff
57
Dima Zavind5b0b6a2009-01-15 18:09:25 -080058#define FONT_WIDTH 5
59#define FONT_HEIGHT 12
60
Sandeep Pandadf39f752015-05-08 14:01:16 +053061#define SCALE_FACTOR 2
62
63static uint32_t BGCOLOR;
64static uint32_t FGCOLOR;
Dima Zavind5b0b6a2009-01-15 18:09:25 -080065
66static struct pos cur_pos;
67static struct pos max_pos;
68
Sandeep Pandadf39f752015-05-08 14:01:16 +053069static void fbcon_drawglyph(char *pixels, uint32_t paint, unsigned stride,
70 unsigned bpp, unsigned *glyph)
Dima Zavind5b0b6a2009-01-15 18:09:25 -080071{
Sandeep Pandadf39f752015-05-08 14:01:16 +053072 unsigned x, y, i, j, k;
73 unsigned data, temp;
74 uint32_t fg_color = paint;
75 stride -= FONT_WIDTH * SCALE_FACTOR;
Dima Zavind5b0b6a2009-01-15 18:09:25 -080076
77 data = glyph[0];
Sandeep Pandadf39f752015-05-08 14:01:16 +053078 for (y = 0; y < FONT_HEIGHT / 2; ++y) {
79 temp = data;
80 for (i = 0; i < SCALE_FACTOR; i++) {
81 data = temp;
82 for (x = 0; x < FONT_WIDTH; ++x) {
83 if (data & 1) {
84 for (j = 0; j < SCALE_FACTOR; j++) {
85 fg_color = paint;
86 for (k = 0; k < bpp; k++) {
87 *pixels = (unsigned char) fg_color;
88 fg_color = fg_color >> 8;
89 pixels++;
90 }
91 }
92 }
93 else
94 {
95 for (j = 0; j < SCALE_FACTOR; j++) {
96 pixels = pixels + bpp;
97 }
98 }
99 data >>= 1;
100 }
101 pixels += (stride * bpp);
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800102 }
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800103 }
104
105 data = glyph[1];
Sandeep Pandadf39f752015-05-08 14:01:16 +0530106 for (y = 0; y < FONT_HEIGHT / 2; ++y) {
107 temp = data;
108 for (i = 0; i < SCALE_FACTOR; i++) {
109 data = temp;
110 for (x = 0; x < FONT_WIDTH; ++x) {
111 if (data & 1) {
112 for (j = 0; j < SCALE_FACTOR; j++) {
113 fg_color = paint;
114 for (k = 0; k < bpp; k++) {
115 *pixels = (unsigned char) fg_color;
116 fg_color = fg_color >> 8;
117 pixels++;
118 }
119 }
120 }
121 else
122 {
123 for (j = 0; j < SCALE_FACTOR; j++) {
124 pixels = pixels + bpp;
125 }
126 }
127 data >>= 1;
128 }
129 pixels += (stride * bpp);
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800130 }
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800131 }
Sandeep Pandadf39f752015-05-08 14:01:16 +0530132
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800133}
134
Dima Zavin25ed9942009-01-28 17:04:19 -0800135static void fbcon_flush(void)
136{
Mao Flynn7b379f32015-04-20 00:28:30 +0800137 unsigned total_x, total_y;
138 unsigned bytes_per_bpp;
139
Dima Zavin25ed9942009-01-28 17:04:19 -0800140 if (config->update_start)
141 config->update_start();
142 if (config->update_done)
143 while (!config->update_done());
Mao Flynn7b379f32015-04-20 00:28:30 +0800144
145 total_x = config->width;
146 total_y = config->height;
147 bytes_per_bpp = ((config->bpp) / 8);
148 arch_clean_invalidate_cache_range((addr_t) config->base, (total_x * total_y * bytes_per_bpp));
Dima Zavin25ed9942009-01-28 17:04:19 -0800149}
150
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800151/* TODO: Take stride into account */
152static void fbcon_scroll_up(void)
153{
154 unsigned short *dst = config->base;
155 unsigned short *src = dst + (config->width * FONT_HEIGHT);
156 unsigned count = config->width * (config->height - FONT_HEIGHT);
157
158 while(count--) {
159 *dst++ = *src++;
160 }
161
162 count = config->width * FONT_HEIGHT;
163 while(count--) {
164 *dst++ = BGCOLOR;
165 }
Dima Zavin25ed9942009-01-28 17:04:19 -0800166
167 fbcon_flush();
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800168}
169
170/* TODO: take stride into account */
Shashank Mittal4f99a882010-02-01 13:58:50 -0800171void fbcon_clear(void)
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800172{
Sandeep Pandadf39f752015-05-08 14:01:16 +0530173 unsigned long i = 0, j = 0;
174 unsigned char *pixels = config->base;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800175 unsigned count = config->width * config->height;
Sandeep Pandadf39f752015-05-08 14:01:16 +0530176 uint32_t bg_color;
177 for (i = 0; i < count; i++) {
178 bg_color = BGCOLOR;
179 for (j = 0; j < (config->bpp / 8); j++) {
180 *pixels = (unsigned char) bg_color;
181 bg_color = bg_color >> 8;
182 pixels++;
183 }
184 }
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800185}
186
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800187
188static void fbcon_set_colors(unsigned bg, unsigned fg)
189{
190 BGCOLOR = bg;
191 FGCOLOR = fg;
192}
193
194void fbcon_putc(char c)
195{
Sandeep Pandadf39f752015-05-08 14:01:16 +0530196 char *pixels;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800197
198 /* ignore anything that happens before fbcon is initialized */
199 if (!config)
200 return;
201
202 if((unsigned char)c > 127)
203 return;
Sandeep Pandadf39f752015-05-08 14:01:16 +0530204
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800205 if((unsigned char)c < 32) {
206 if(c == '\n')
207 goto newline;
Sandeep Pandadf39f752015-05-08 14:01:16 +0530208 else if (c == '\r') {
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800209 cur_pos.x = 0;
Sandeep Pandadf39f752015-05-08 14:01:16 +0530210 return;
211 }
212 else
213 return;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800214 }
215
216 pixels = config->base;
Sandeep Pandadf39f752015-05-08 14:01:16 +0530217 pixels += cur_pos.y * SCALE_FACTOR * ((config->bpp / 8) * FONT_HEIGHT * config->width);
218 pixels += cur_pos.x * SCALE_FACTOR * ((config->bpp / 8) * (FONT_WIDTH + 1));
219 fbcon_drawglyph(pixels, FGCOLOR, config->stride, (config->bpp / 8),
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800220 font5x12 + (c - 32) * 2);
221
222 cur_pos.x++;
223 if (cur_pos.x < max_pos.x)
224 return;
225
226newline:
227 cur_pos.y++;
228 cur_pos.x = 0;
229 if(cur_pos.y >= max_pos.y) {
230 cur_pos.y = max_pos.y - 1;
231 fbcon_scroll_up();
Dima Zavin25ed9942009-01-28 17:04:19 -0800232 } else
233 fbcon_flush();
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800234}
235
236void fbcon_setup(struct fbcon_config *_config)
237{
Sandeep Pandadf39f752015-05-08 14:01:16 +0530238 uint32_t bg = 0;
239 uint32_t fg = 0;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800240
241 ASSERT(_config);
242
243 config = _config;
244
245 switch (config->format) {
246 case FB_FORMAT_RGB565:
Shashank Mittalc648e712010-10-06 18:37:42 -0700247 fg = RGB565_WHITE;
248 bg = RGB565_BLACK;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800249 break;
Mao Flynn7b379f32015-04-20 00:28:30 +0800250 case FB_FORMAT_RGB888:
251 fg = RGB888_WHITE;
252 bg = RGB888_BLACK;
253 break;
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800254 default:
255 dprintf(CRITICAL, "unknown framebuffer pixel format\n");
256 ASSERT(0);
257 break;
258 }
259
260 fbcon_set_colors(bg, fg);
261
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800262 cur_pos.x = 0;
263 cur_pos.y = 0;
Sandeep Pandadf39f752015-05-08 14:01:16 +0530264 max_pos.x = config->width / ((FONT_WIDTH + 1) * SCALE_FACTOR);
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800265 max_pos.y = (config->height - 1) / FONT_HEIGHT;
Shashank Mittal37040832010-08-24 15:57:57 -0700266#if !DISPLAY_SPLASH_SCREEN
267 fbcon_clear();
268#endif
Dima Zavind5b0b6a2009-01-15 18:09:25 -0800269}
Shashank Mittal4f99a882010-02-01 13:58:50 -0800270
271struct fbcon_config* fbcon_display(void)
272{
Mao Flynn7b379f32015-04-20 00:28:30 +0800273 return config;
Shashank Mittal4f99a882010-02-01 13:58:50 -0800274}
Chandan Uddaraju40b227d2010-08-03 19:25:41 -0700275
Mao Flynn7b379f32015-04-20 00:28:30 +0800276void fbcon_extract_to_screen(logo_img_header *header, void* address)
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530277{
Mao Flynn7b379f32015-04-20 00:28:30 +0800278 const uint8_t *imagestart = (const uint8_t *)address;
279 uint pos = 0, offset;
280 uint count = 0;
281 uint x = 0, y = 0;
282 uint8_t *base, *p;
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530283
Mao Flynn7b379f32015-04-20 00:28:30 +0800284 if (!config || header->width > config->width
285 || header->height > config->height) {
286 dprintf(INFO, "the logo img is too large\n");
287 return;
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530288 }
289
Mao Flynn7b379f32015-04-20 00:28:30 +0800290 base = (uint8_t *) config->base;
291
292 /* put the logo to be center */
293 offset = (config->height - header->height) / 2;
294 if (offset)
295 base += (offset * config->width) * 3;
296 offset = (config->width - header->width ) / 2;
297
298 x = offset;
299 while (count < (uint)header->height * (uint)header->width) {
300 uint8_t run = *(imagestart + pos);
301 bool repeat_run = (run & 0x80);
302 uint runlen = (run & 0x7f) + 1;
303 uint runpos;
304
305 /* consume the run byte */
306 pos++;
307
308 p = base + (y * config->width + x) * 3;
309
310 /* start of a run */
311 for (runpos = 0; runpos < runlen; runpos++) {
312 *p++ = *(imagestart + pos);
313 *p++ = *(imagestart + pos + 1);
314 *p++ = *(imagestart + pos + 2);
315 count++;
316
317 x++;
318
319 /* if a run of raw pixels, consume an input pixel */
320 if (!repeat_run)
321 pos += 3;
322 }
323
324 /* if this was a run of repeated pixels, consume the one input pixel we repeated */
325 if (repeat_run)
326 pos += 3;
327
328 /* the generator will keep compressing data line by line */
329 /* don't cross the lines */
330 if (x == header->width + offset) {
331 y++;
332 x = offset;
333 }
334 }
335
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530336}
337
Mao Flynn7b379f32015-04-20 00:28:30 +0800338void display_default_image_on_screen(void)
Chandan Uddaraju40b227d2010-08-03 19:25:41 -0700339{
Mao Flynn7b379f32015-04-20 00:28:30 +0800340 unsigned i = 0;
341 unsigned total_x;
342 unsigned total_y;
343 unsigned bytes_per_bpp;
344 unsigned image_base;
Channagoud Kadabi875a2a72015-04-24 17:26:38 -0700345#if DISPLAY_TYPE_MIPI
346 char *image = NULL;
347#endif
Channagoud Kadabi956cf502012-03-08 03:49:50 +0530348
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530349 if (!config) {
350 dprintf(CRITICAL,"NULL configuration, image cannot be displayed\n");
351 return;
352 }
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700353
Mao Flynn7b379f32015-04-20 00:28:30 +0800354 fbcon_clear(); // clear screen with Black color
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530355
356 total_x = config->width;
357 total_y = config->height;
358 bytes_per_bpp = ((config->bpp) / 8);
Mao Flynn7b379f32015-04-20 00:28:30 +0800359 image_base = ((((total_y/2) - (SPLASH_IMAGE_HEIGHT / 2) - 1) *
360 (config->width)) + (total_x/2 - (SPLASH_IMAGE_WIDTH / 2)));
Channagoud Kadabi956cf502012-03-08 03:49:50 +0530361
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700362#if DISPLAY_TYPE_MIPI
Channagoud Kadabi875a2a72015-04-24 17:26:38 -0700363#if ENABLE_WBC
364 image = (pm_appsbl_charging_in_progress() ? image_batt888 : imageBuffer_rgb888);
365#else
366 image = imageBuffer_rgb888;
367#endif
368
Mao Flynn7b379f32015-04-20 00:28:30 +0800369 if (bytes_per_bpp == 3) {
370 for (i = 0; i < SPLASH_IMAGE_HEIGHT; i++) {
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530371 memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp),
Channagoud Kadabi875a2a72015-04-24 17:26:38 -0700372 image + (i * SPLASH_IMAGE_WIDTH * bytes_per_bpp),
Mao Flynn7b379f32015-04-20 00:28:30 +0800373 SPLASH_IMAGE_WIDTH * bytes_per_bpp);
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530374 }
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700375 }
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530376 fbcon_flush();
Kinson Chike5c93432011-06-17 09:10:29 -0700377#if DISPLAY_MIPI_PANEL_NOVATEK_BLUE
Aparna Mallavarapuce06a012013-09-06 23:03:24 +0530378 if(is_cmd_mode_enabled())
Mao Flynn7b379f32015-04-20 00:28:30 +0800379 mipi_dsi_cmd_mode_trigger();
Kinson Chike5c93432011-06-17 09:10:29 -0700380#endif
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800381
Chandan Uddaraju78ae6752010-10-19 12:57:10 -0700382#else
Zohaib Alam03708752014-10-23 17:51:57 -0400383
Mao Flynn7b379f32015-04-20 00:28:30 +0800384 if (bytes_per_bpp == 2) {
385 for (i = 0; i < SPLASH_IMAGE_HEIGHT; i++) {
386 memcpy (config->base + ((image_base + (i * (config->width))) * bytes_per_bpp),
387 imageBuffer + (i * SPLASH_IMAGE_WIDTH * bytes_per_bpp),
388 SPLASH_IMAGE_WIDTH * bytes_per_bpp);
Zohaib Alam03708752014-10-23 17:51:57 -0400389 }
390 }
391 fbcon_flush();
Chandan Uddarajufe93e822010-11-21 20:44:47 -0800392#endif
Chandan Uddaraju40b227d2010-08-03 19:25:41 -0700393}
Mao Flynn7b379f32015-04-20 00:28:30 +0800394
395
396void display_image_on_screen(void)
397{
398#if DISPLAY_TYPE_MIPI
399 int fetch_image_from_partition();
400
401 if (fetch_image_from_partition() < 0) {
402 display_default_image_on_screen();
403 } else {
404 /* data has been put into the right place */
405 fbcon_flush();
406 }
407#else
408 display_default_image_on_screen();
409#endif
410}