123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * Copyright (c) 2017 FriendlyARM (www.arm9.net)
- */
- #include <config.h>
- #include <common.h>
- #include <errno.h>
- #include <fdtdec.h>
- #include <fdt_support.h>
- #include <asm/io.h>
- #include <asm/arch/nexell.h>
- #include <asm/arch/display.h>
- #include <asm/arch/nx_gpio.h>
- #include "nxp-fb.h"
- /*
- * param @module_index for nx_gpio APIs and will be removed
- * after support pinctrl
- */
- #ifndef PAD_GPIO_A
- #define PAD_GPIO_A 0
- #endif
- static inline void common_gpio_init(void)
- {
- /* PVCLK */
- nx_gpio_set_fast_slew(PAD_GPIO_A, 0, 1);
- }
- static void s70_gpio_init(void)
- {
- int i;
- /* PVCLK */
- nx_gpio_set_drive_strength(PAD_GPIO_A, 0, 1);
- /* RGB24 */
- for (i = 1; i < 25; i++)
- nx_gpio_set_drive_strength(PAD_GPIO_A, i, 2);
- /* HS/VS/DE */
- for (; i < 28; i++)
- nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
- }
- static void s702_gpio_init(void)
- {
- int i;
- common_gpio_init();
- nx_gpio_set_drive_strength(PAD_GPIO_A, 0, 2);
- for (i = 1; i < 25; i++)
- nx_gpio_set_drive_strength(PAD_GPIO_A, i, 0);
- for (; i < 28; i++)
- nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
- }
- static void s430_gpio_init(void)
- {
- int i;
- for (i = 0; i < 28; i++)
- nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
- }
- static void hd101_gpio_init(void)
- {
- int i;
- common_gpio_init();
- nx_gpio_set_drive_strength(PAD_GPIO_A, 0, 2);
- for (i = 1; i < 25; i++)
- nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
- nx_gpio_set_drive_strength(PAD_GPIO_A, 27, 1);
- }
- static void hd700_gpio_init(void)
- {
- hd101_gpio_init();
- }
- /* NXP display configs for supported LCD */
- static struct nxp_lcd wxga_hd700 = {
- .width = 800,
- .height = 1280,
- .p_width = 94,
- .p_height = 151,
- .bpp = 24,
- .freq = 60,
- .timing = {
- .h_fp = 20,
- .h_bp = 20,
- .h_sw = 24,
- .v_fp = 4,
- .v_fpe = 1,
- .v_bp = 4,
- .v_bpe = 1,
- .v_sw = 8,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 0,
- .inv_vsync = 0,
- .inv_vden = 0,
- },
- .gpio_init = hd700_gpio_init,
- };
- static struct nxp_lcd wvga_s70 = {
- .width = 800,
- .height = 480,
- .p_width = 155,
- .p_height = 93,
- .bpp = 24,
- .freq = 61,
- .timing = {
- .h_fp = 48,
- .h_bp = 36,
- .h_sw = 10,
- .v_fp = 22,
- .v_fpe = 1,
- .v_bp = 15,
- .v_bpe = 1,
- .v_sw = 8,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- .gpio_init = s70_gpio_init,
- };
- static struct nxp_lcd wvga_s702 = {
- .width = 800,
- .height = 480,
- .p_width = 155,
- .p_height = 93,
- .bpp = 24,
- .freq = 61,
- .timing = {
- .h_fp = 44,
- .h_bp = 26,
- .h_sw = 20,
- .v_fp = 22,
- .v_fpe = 1,
- .v_bp = 15,
- .v_bpe = 1,
- .v_sw = 8,
- },
- .polarity = {
- .rise_vclk = 1,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- .gpio_init = s702_gpio_init,
- };
- static struct nxp_lcd wvga_s70d = {
- .width = 800,
- .height = 480,
- .p_width = 155,
- .p_height = 93,
- .bpp = 24,
- .freq = 61,
- .timing = {
- .h_fp = 80,
- .h_bp = 78,
- .h_sw = 10,
- .v_fp = 22,
- .v_fpe = 1,
- .v_bp = 24,
- .v_bpe = 1,
- .v_sw = 8,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- .gpio_init = s702_gpio_init,
- };
- static struct nxp_lcd wvga_w50 = {
- .width = 800,
- .height = 480,
- .p_width = 108,
- .p_height = 64,
- .bpp = 24,
- .freq = 61,
- .timing = {
- .h_fp = 40,
- .h_bp = 40,
- .h_sw = 48,
- .v_fp = 20,
- .v_fpe = 1,
- .v_bp = 20,
- .v_bpe = 1,
- .v_sw = 12,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- .gpio_init = s70_gpio_init,
- };
- static struct nxp_lcd wvga_s430 = {
- .width = 480,
- .height = 800,
- .p_width = 108,
- .p_height = 64,
- .bpp = 24,
- .freq = 60,
- .timing = {
- .h_fp = 64,
- .h_bp = 0,
- .h_sw = 16,
- .v_fp = 32,
- .v_fpe = 1,
- .v_bp = 0,
- .v_bpe = 1,
- .v_sw = 16,
- },
- .polarity = {
- .rise_vclk = 1,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- .gpio_init = s430_gpio_init,
- };
- static struct nxp_lcd wsvga_w101 = {
- .width = 1024,
- .height = 600,
- .p_width = 204,
- .p_height = 120,
- .bpp = 24,
- .freq = 60,
- .timing = {
- .h_fp = 40,
- .h_bp = 40,
- .h_sw = 200,
- .v_fp = 8,
- .v_fpe = 1,
- .v_bp = 8,
- .v_bpe = 1,
- .v_sw = 16,
- },
- .polarity = {
- .rise_vclk = 1,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct nxp_lcd wsvga_x710 = {
- .width = 1024,
- .height = 600,
- .p_width = 154,
- .p_height = 90,
- .bpp = 24,
- .freq = 61,
- .timing = {
- .h_fp = 84,
- .h_bp = 84,
- .h_sw = 88,
- .v_fp = 10,
- .v_fpe = 1,
- .v_bp = 10,
- .v_bpe = 1,
- .v_sw = 20,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- .gpio_init = hd101_gpio_init,
- };
- static struct nxp_lcd xga_a97 = {
- .width = 1024,
- .height = 768,
- .p_width = 200,
- .p_height = 150,
- .bpp = 24,
- .freq = 61,
- .timing = {
- .h_fp = 12,
- .h_bp = 12,
- .h_sw = 4,
- .v_fp = 8,
- .v_fpe = 1,
- .v_bp = 8,
- .v_bpe = 1,
- .v_sw = 4,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct nxp_lcd xga_lq150 = {
- .width = 1024,
- .height = 768,
- .p_width = 304,
- .p_height = 228,
- .bpp = 24,
- .freq = 60,
- .timing = {
- .h_fp = 12,
- .h_bp = 12,
- .h_sw = 40,
- .v_fp = 8,
- .v_fpe = 1,
- .v_bp = 8,
- .v_bpe = 1,
- .v_sw = 40,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct nxp_lcd vga_l80 = {
- .width = 640,
- .height = 480,
- .p_width = 160,
- .p_height = 120,
- .bpp = 32,
- .freq = 60,
- .timing = {
- .h_fp = 35,
- .h_bp = 53,
- .h_sw = 73,
- .v_fp = 3,
- .v_fpe = 1,
- .v_bp = 29,
- .v_bpe = 1,
- .v_sw = 6,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct nxp_lcd wxga_bp101 = {
- .width = 1280,
- .height = 800,
- .p_width = 218,
- .p_height = 136,
- .bpp = 24,
- .freq = 60,
- .timing = {
- .h_fp = 20,
- .h_bp = 20,
- .h_sw = 24,
- .v_fp = 4,
- .v_fpe = 1,
- .v_bp = 4,
- .v_bpe = 1,
- .v_sw = 8,
- },
- .polarity = {
- .rise_vclk = 1,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct nxp_lcd wxga_hd101 = {
- .width = 1280,
- .height = 800,
- .p_width = 218,
- .p_height = 136,
- .bpp = 24,
- .freq = 60,
- .timing = {
- .h_fp = 16,
- .h_bp = 16,
- .h_sw = 30,
- .v_fp = 8,
- .v_fpe = 1,
- .v_bp = 8,
- .v_bpe = 1,
- .v_sw = 12,
- },
- .polarity = {
- .rise_vclk = 1,
- .inv_hsync = 0,
- .inv_vsync = 0,
- .inv_vden = 0,
- },
- .gpio_init = hd101_gpio_init,
- };
- static struct nxp_lcd hvga_h43 = {
- .width = 480,
- .height = 272,
- .p_width = 96,
- .p_height = 54,
- .bpp = 32,
- .freq = 65,
- .timing = {
- .h_fp = 5,
- .h_bp = 40,
- .h_sw = 2,
- .v_fp = 8,
- .v_fpe = 1,
- .v_bp = 8,
- .v_bpe = 1,
- .v_sw = 2,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct nxp_lcd hvga_p43 = {
- .width = 480,
- .height = 272,
- .p_width = 96,
- .p_height = 54,
- .bpp = 32,
- .freq = 65,
- .timing = {
- .h_fp = 5,
- .h_bp = 40,
- .h_sw = 2,
- .v_fp = 8,
- .v_fpe = 1,
- .v_bp = 9,
- .v_bpe = 1,
- .v_sw = 2,
- },
- .polarity = {
- .rise_vclk = 1,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct nxp_lcd qvga_w35 = {
- .width = 320,
- .height = 240,
- .p_width = 70,
- .p_height = 52,
- .bpp = 16,
- .freq = 65,
- .timing = {
- .h_fp = 4,
- .h_bp = 70,
- .h_sw = 4,
- .v_fp = 4,
- .v_fpe = 1,
- .v_bp = 12,
- .v_bpe = 1,
- .v_sw = 4,
- },
- .polarity = {
- .rise_vclk = 1,
- .inv_hsync = 0,
- .inv_vsync = 0,
- .inv_vden = 0,
- },
- };
- /* HDMI */
- static struct nxp_lcd hdmi_def = {
- .width = 1920,
- .height = 1080,
- .p_width = 480,
- .p_height = 320,
- .bpp = 24,
- .freq = 60,
- .timing = {
- .h_fp = 12,
- .h_bp = 12,
- .h_sw = 4,
- .v_fp = 8,
- .v_fpe = 1,
- .v_bp = 8,
- .v_bpe = 1,
- .v_sw = 4,
- },
- .polarity = {
- .rise_vclk = 0,
- .inv_hsync = 1,
- .inv_vsync = 1,
- .inv_vden = 0,
- },
- };
- static struct hdmi_config {
- char *name;
- int width;
- int height;
- } bd_hdmi_config[] = {
- { "HDMI1080P60", 1920, 1080 },
- { "HDMI1080I60", 1920, 1080 },
- { "HDMI1080P30", 1920, 1080 },
- { "HDMI1080P50", 1920, 1080 },
- { "HDMI1080I50", 1920, 1080 },
- { "HDMI1080P60D", 960, 536 },
- { "HDMI1080I60D", 960, 536 },
- { "HDMI1080P30D", 960, 536 },
- { "HDMI1080P50D", 960, 536 },
- { "HDMI1080I50D", 960, 536 },
- { "HDMI720P60", 1280, 720 },
- { "HDMI720P60D", 640, 360 },
- { "HDMI720P50", 1280, 720 },
- { "HDMI720P50D", 640, 360 },
- { "HDMI576P16X9", 720, 576 },
- { "HDMI576P16X9D", 720, 576 },
- { "HDMI576P4X3", 720, 576 },
- { "HDMI576P4X3D", 720, 576 },
- { "HDMI480P16X9", 720, 480 },
- { "HDMI480P16X9D", 720, 480 },
- { "HDMI480P4X3", 720, 480 },
- { "HDMI480P4X3D", 720, 480 },
- };
- /* Try to guess LCD panel by kernel command line, or
- * using *HD101* as default
- */
- static struct {
- int id;
- char *name;
- struct nxp_lcd *lcd;
- int dpi;
- int ctp;
- enum lcd_format fmt;
- } bd_lcd_config[] = {
- { 25, "HD101", &wxga_hd101, 0, 1, LCD_RGB },
- { 32, "HD101B", &wxga_hd101, 0, 1, LCD_RGB },
- { 18, "HD700", &wxga_hd700, 213, 1, LCD_RGB },
- { 30, "HD702", &wxga_hd700, 213, 1, LCD_RGB },
- { 33, "H70", &wxga_hd700, 213, 0, LCD_VESA },
- { 3, "S70", &wvga_s70, 128, 1, LCD_RGB },
- { 36, "S701", &wvga_s70, 128, 1, LCD_RGB },
- { 24, "S702", &wvga_s702, 128, 3, LCD_RGB },
- { 26, "S70D", &wvga_s70d, 128, 0, LCD_RGB },
- { 14, "H43", &hvga_h43, 0, 0, LCD_RGB },
- { 19, "P43", &hvga_p43, 0, 0, LCD_RGB },
- { 8, "W35", &qvga_w35, 0, 0, LCD_RGB },
- { 28, "X710", &wsvga_x710, 0, 1, LCD_RGB },
- { 31, "S430", &wvga_s430, 180, 1, LCD_RGB },
- { 4, "W50", &wvga_w50, 0, 0, LCD_RGB },
- /* TODO: Testing */
- { 15, "W101", &wsvga_w101, 0, 1, LCD_RGB },
- { 5, "L80", &vga_l80, 0, 1, LCD_RGB },
- { -1, "A97", &xga_a97, 0, 0, LCD_RGB },
- { -1, "LQ150", &xga_lq150, 0, 1, LCD_RGB },
- { -1, "BP101", &wxga_bp101, 0, 1, LCD_RGB },
- /* Pls keep it at last */
- { 128, "HDMI", &hdmi_def, 0, 0, LCD_HDMI },
- };
- static int lcd_idx;
- int bd_setup_lcd_by_id(int id)
- {
- int i;
- for (i = 0; i < ARRAY_SIZE(bd_lcd_config); i++) {
- if (bd_lcd_config[i].id == id) {
- lcd_idx = i;
- break;
- }
- }
- if (i >= ARRAY_SIZE(bd_lcd_config)) {
- /* NOT found */
- return -19;
- }
- return bd_lcd_config[i].id;
- }
- int bd_setup_lcd_by_name(char *str)
- {
- char *delim;
- int i;
- delim = strchr(str, ',');
- if (delim)
- *delim++ = '\0';
- if (!strncasecmp("HDMI", str, 4)) {
- struct hdmi_config *cfg = &bd_hdmi_config[0];
- struct nxp_lcd *lcd;
- lcd_idx = ARRAY_SIZE(bd_lcd_config) - 1;
- lcd = bd_lcd_config[lcd_idx].lcd;
- for (i = 0; i < ARRAY_SIZE(bd_hdmi_config); i++, cfg++) {
- if (!strcasecmp(cfg->name, str)) {
- lcd->width = cfg->width;
- lcd->height = cfg->height;
- bd_lcd_config[lcd_idx].name = cfg->name;
- goto __ret;
- }
- }
- }
- for (i = 0; i < ARRAY_SIZE(bd_lcd_config); i++) {
- if (!strcasecmp(bd_lcd_config[i].name, str)) {
- lcd_idx = i;
- break;
- }
- }
- __ret:
- return 0;
- }
- struct nxp_lcd *bd_get_lcd(void)
- {
- return bd_lcd_config[lcd_idx].lcd;
- }
- const char *bd_get_lcd_name(void)
- {
- return bd_lcd_config[lcd_idx].name;
- }
- enum lcd_format bd_get_lcd_format(void)
- {
- return bd_lcd_config[lcd_idx].fmt;
- }
- int bd_get_lcd_density(void)
- {
- return bd_lcd_config[lcd_idx].dpi;
- }
- #if CONFIG_IS_ENABLED(OF_CONTROL)
- int bd_fixup_lcd_fdt(void *blob, struct nxp_lcd *lcd)
- {
- return 0;
- }
- #endif
|