blob: aebb56db134ca4beeeefafed3c3bf0be7a2ffe0d [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc. All Rights Reserved.
*
* Peng Fan <Peng.Fan@freescale.com>
*/
#include <common.h>
#include <lcd.h>
#include <linux/err.h>
#include <linux/types.h>
#include <malloc.h>
#include <mxc_epdc_fb.h>
#define is_digit(c) ((c) >= '0' && (c) <= '9')
__weak int mmc_get_env_devno(void)
{
return 0;
}
__weak int check_mmc_autodetect(void)
{
return 0;
}
int board_setup_waveform_file(ulong waveform_buf)
{
char *fs_argv[5];
char addr[17];
ulong file_len, mmc_dev;
if (!check_mmc_autodetect())
mmc_dev = env_get_ulong("mmcdev", 10, 0);
else
mmc_dev = mmc_get_env_devno();
sprintf(addr, "%lx", waveform_buf);
fs_argv[0] = "fatload";
fs_argv[1] = "mmc";
fs_argv[2] = simple_itoa(mmc_dev);
fs_argv[3] = addr;
fs_argv[4] = env_get("epdc_waveform");
if (!fs_argv[4])
fs_argv[4] = "epdc_splash.bin";
if (do_fat_fsload(NULL, 0, 5, fs_argv)) {
printf("File %s not found on MMC Device %lu!\n", fs_argv[4], mmc_dev);
return -1;
}
file_len = env_get_hex("filesize", 0);
if (!file_len)
return -1;
flush_cache(waveform_buf, roundup(file_len, ARCH_DMA_MINALIGN));
return 0;
}
int board_setup_logo_file(void *display_buf)
{
int logo_width, logo_height;
char *fs_argv[5];
char addr[17];
int array[3];
ulong file_len, mmc_dev;
char *buf, *s;
int arg = 0, val = 0, pos = 0;
int i, j, max_check_length;
int row, col, row_end, col_end;
if (!display_buf)
return -EINVAL;
/* Assume PGM header not exceeds 128 bytes */
max_check_length = 128;
if (!check_mmc_autodetect())
mmc_dev = env_get_ulong("mmcdev", 10, 0);
else
mmc_dev = mmc_get_env_devno();
memset(display_buf, 0xFF, panel_info.vl_col * panel_info.vl_row);
fs_argv[0] = "fatsize";
fs_argv[1] = "mmc";
fs_argv[2] = simple_itoa(mmc_dev);
fs_argv[3] = env_get("epdc_logo");
if (!fs_argv[3])
fs_argv[3] = "epdc_logo.pgm";
if (do_fat_size(NULL, 0, 4, fs_argv)) {
debug("File %s not found on MMC Device %lu, use black border\n", fs_argv[3], mmc_dev);
/* Draw black border around framebuffer*/
memset(display_buf, 0x0, 24 * panel_info.vl_col);
for (i = 24; i < (panel_info.vl_row - 24); i++) {
memset((u8 *)display_buf + i * panel_info.vl_col,
0x00, 24);
memset((u8 *)display_buf + i * panel_info.vl_col
+ panel_info.vl_col - 24, 0x00, 24);
}
memset((u8 *)display_buf +
panel_info.vl_col * (panel_info.vl_row - 24),
0x00, 24 * panel_info.vl_col);
return 0;
}
file_len = env_get_hex("filesize", 0);
if (!file_len)
return -EINVAL;
buf = memalign(ARCH_DMA_MINALIGN, file_len);
if (!buf)
return -ENOMEM;
sprintf(addr, "%lx", (ulong)buf);
fs_argv[0] = "fatload";
fs_argv[1] = "mmc";
fs_argv[2] = simple_itoa(mmc_dev);
fs_argv[3] = addr;
fs_argv[4] = env_get("epdc_logo");
if (!fs_argv[4])
fs_argv[4] = "epdc_logo.pgm";
if (do_fat_fsload(NULL, 0, 5, fs_argv)) {
printf("File %s not found on MMC Device %lu!\n", fs_argv[4], mmc_dev);
free(buf);
return -1;
}
if (strncmp(buf, "P5", 2)) {
printf("Wrong format for epdc logo, use PGM-P5 format.\n");
free(buf);
return -EINVAL;
}
/* Skip P5\n */
pos += 3;
arg = 0;
for (i = 3; i < max_check_length; ) {
/* skip \n \t and space */
if ((buf[i] == '\n') || (buf[i] == '\t') || (buf[i] == ' ')) {
i++;
continue;
}
/* skip comment */
if (buf[i] == '#') {
while (buf[i++] != '\n')
;
continue;
}
/* HEIGTH, WIDTH, MAX PIXEL VLAUE total 3 args */
if (arg > 2)
break;
val = 0;
while (is_digit(buf[i])) {
val = val * 10 + buf[i] - '0';
i++;
}
array[arg++] = val;
i++;
}
/* Point to data area */
pos = i;
logo_width = array[0];
logo_height = array[1];
if ((logo_width > panel_info.vl_col) ||
(logo_height > panel_info.vl_row)) {
printf("Picture: too big\n");
free(buf);
return -EINVAL;
}
/* m,m means center of screen */
row = 0;
col = 0;
s = env_get("splashpos");
if (s) {
if (s[0] == 'm')
col = (panel_info.vl_col - logo_width) >> 1;
else
col = simple_strtol(s, NULL, 0);
s = strchr(s + 1, ',');
if (s != NULL) {
if (s[1] == 'm')
row = (panel_info.vl_row - logo_height) >> 1;
else
row = simple_strtol(s + 1, NULL, 0);
}
}
if ((col + logo_width > panel_info.vl_col) ||
(row + logo_height > panel_info.vl_row)) {
printf("Incorrect pos, use (0, 0)\n");
row = 0;
col = 0;
}
/* Draw picture at the center of screen */
row_end = row + logo_height;
col_end = col + logo_width;
for (i = row; i < row_end; i++) {
for (j = col; j < col_end; j++) {
*((u8 *)display_buf + i * (panel_info.vl_col) + j) =
buf[pos++];
}
}
free(buf);
flush_cache((ulong)display_buf, file_len - pos - 1);
return 0;
}