Commit 7878ca51f2d6e2c131c96451e8727fda247d794e

Authored by Nikita Kiryanov
Committed by Tom Rini
1 parent 581bb41980

cm-t35: add support for dvi displays

Add support for dvi displays with user selectable dvi presets.

Cc: Wolfgang Denk <wd@denx.de>
Cc: Jeroen Hofstee <jeroen@myspectrum.nl>
Cc: Anatolij Gustschin <agust@denx.de>
Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>

Showing 4 changed files with 231 additions and 0 deletions Side-by-side Diff

board/cm_t35/Makefile
... ... @@ -26,6 +26,7 @@
26 26 LIB = $(obj)lib$(BOARD).o
27 27  
28 28 COBJS-$(CONFIG_DRIVER_OMAP34XX_I2C) += eeprom.o
  29 +COBJS-$(CONFIG_LCD) += display.o
29 30  
30 31 COBJS := cm_t35.o leds.o $(COBJS-y)
31 32  
board/cm_t35/cm_t35.c
... ... @@ -217,6 +217,9 @@
217 217 /* SB-T35 Ethernet */
218 218 MUX_VAL(CP(GPMC_NCS4), (IEN | PTU | EN | M0)); /*GPMC_nCS4*/
219 219  
  220 + /* DVI enable */
  221 + MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | DIS | M4));/*GPMC_nCS3*/
  222 +
220 223 /* CM-T3x Ethernet */
221 224 MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | DIS | M0)); /*GPMC_nCS5*/
222 225 MUX_VAL(CP(GPMC_CLK), (IEN | PTD | DIS | M4)); /*GPIO_59*/
board/cm_t35/display.c
  1 +/*
  2 + * (C) Copyright 2012 CompuLab, Ltd. <www.compulab.co.il>
  3 + *
  4 + * Authors: Nikita Kiryanov <nikita@compulab.co.il>
  5 + *
  6 + * See file CREDITS for list of people who contributed to this
  7 + * project.
  8 + *
  9 + * This program is free software; you can redistribute it and/or
  10 + * modify it under the terms of the GNU General Public License as
  11 + * published by the Free Software Foundation; either version 2 of
  12 + * the License, or (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program; if not, write to the Free Software
  21 + * Foundation, Inc.
  22 + */
  23 +#include <common.h>
  24 +#include <asm/gpio.h>
  25 +#include <asm/io.h>
  26 +#include <stdio_dev.h>
  27 +#include <asm/arch/dss.h>
  28 +#include <lcd.h>
  29 +#include <asm/arch-omap3/dss.h>
  30 +
  31 +DECLARE_GLOBAL_DATA_PTR;
  32 +
  33 +enum display_type {
  34 + NONE,
  35 + DVI,
  36 +};
  37 +
  38 +#define CMAP_ADDR 0x80100000
  39 +
  40 +/*
  41 + * The frame buffer is allocated before we have the chance to parse user input.
  42 + * To make sure enough memory is allocated for all resolutions, we define
  43 + * vl_{col | row} to the maximal resolution supported by OMAP3.
  44 + */
  45 +vidinfo_t panel_info = {
  46 + .vl_col = 1400,
  47 + .vl_row = 1050,
  48 + .vl_bpix = LCD_BPP,
  49 + .cmap = (ushort *)CMAP_ADDR,
  50 +};
  51 +
  52 +static struct panel_config panel_cfg;
  53 +static enum display_type lcd_def;
  54 +
  55 +/*
  56 + * A note on DVI presets;
  57 + * U-Boot can convert 8 bit BMP data to 16 bit BMP data, and OMAP DSS can
  58 + * convert 16 bit data into 24 bit data. Thus, GFXFORMAT_RGB16 allows us to
  59 + * support two BMP types with one setting.
  60 + */
  61 +static const struct panel_config preset_dvi_640X480 = {
  62 + .lcd_size = PANEL_LCD_SIZE(640, 480),
  63 + .timing_h = DSS_HBP(48) | DSS_HFP(16) | DSS_HSW(96),
  64 + .timing_v = DSS_VBP(33) | DSS_VFP(10) | DSS_VSW(2),
  65 + .divisor = 12 | (1 << 16),
  66 + .data_lines = LCD_INTERFACE_24_BIT,
  67 + .panel_type = ACTIVE_DISPLAY,
  68 + .load_mode = 2,
  69 + .gfx_format = GFXFORMAT_RGB16,
  70 +};
  71 +
  72 +static const struct panel_config preset_dvi_800X600 = {
  73 + .lcd_size = PANEL_LCD_SIZE(800, 600),
  74 + .timing_h = DSS_HBP(88) | DSS_HFP(40) | DSS_HSW(128),
  75 + .timing_v = DSS_VBP(23) | DSS_VFP(1) | DSS_VSW(4),
  76 + .divisor = 8 | (1 << 16),
  77 + .data_lines = LCD_INTERFACE_24_BIT,
  78 + .panel_type = ACTIVE_DISPLAY,
  79 + .load_mode = 2,
  80 + .gfx_format = GFXFORMAT_RGB16,
  81 +};
  82 +
  83 +static const struct panel_config preset_dvi_1024X768 = {
  84 + .lcd_size = PANEL_LCD_SIZE(1024, 768),
  85 + .timing_h = DSS_HBP(160) | DSS_HFP(24) | DSS_HSW(136),
  86 + .timing_v = DSS_VBP(29) | DSS_VFP(3) | DSS_VSW(6),
  87 + .divisor = 5 | (1 << 16),
  88 + .data_lines = LCD_INTERFACE_24_BIT,
  89 + .panel_type = ACTIVE_DISPLAY,
  90 + .load_mode = 2,
  91 + .gfx_format = GFXFORMAT_RGB16,
  92 +};
  93 +
  94 +static const struct panel_config preset_dvi_1152X864 = {
  95 + .lcd_size = PANEL_LCD_SIZE(1152, 864),
  96 + .timing_h = DSS_HBP(256) | DSS_HFP(64) | DSS_HSW(128),
  97 + .timing_v = DSS_VBP(32) | DSS_VFP(1) | DSS_VSW(3),
  98 + .divisor = 3 | (1 << 16),
  99 + .data_lines = LCD_INTERFACE_24_BIT,
  100 + .panel_type = ACTIVE_DISPLAY,
  101 + .load_mode = 2,
  102 + .gfx_format = GFXFORMAT_RGB16,
  103 +};
  104 +
  105 +static const struct panel_config preset_dvi_1280X960 = {
  106 + .lcd_size = PANEL_LCD_SIZE(1280, 960),
  107 + .timing_h = DSS_HBP(312) | DSS_HFP(96) | DSS_HSW(112),
  108 + .timing_v = DSS_VBP(36) | DSS_VFP(1) | DSS_VSW(3),
  109 + .divisor = 3 | (1 << 16),
  110 + .data_lines = LCD_INTERFACE_24_BIT,
  111 + .panel_type = ACTIVE_DISPLAY,
  112 + .load_mode = 2,
  113 + .gfx_format = GFXFORMAT_RGB16,
  114 +};
  115 +
  116 +static const struct panel_config preset_dvi_1280X1024 = {
  117 + .lcd_size = PANEL_LCD_SIZE(1280, 1024),
  118 + .timing_h = DSS_HBP(248) | DSS_HFP(48) | DSS_HSW(112),
  119 + .timing_v = DSS_VBP(38) | DSS_VFP(1) | DSS_VSW(3),
  120 + .divisor = 3 | (1 << 16),
  121 + .data_lines = LCD_INTERFACE_24_BIT,
  122 + .panel_type = ACTIVE_DISPLAY,
  123 + .load_mode = 2,
  124 + .gfx_format = GFXFORMAT_RGB16,
  125 +};
  126 +
  127 +/*
  128 + * set_resolution_params()
  129 + *
  130 + * Due to usage of multiple display related APIs resolution data is located in
  131 + * more than one place. This function updates them all.
  132 + */
  133 +static void set_resolution_params(int x, int y)
  134 +{
  135 + panel_cfg.lcd_size = PANEL_LCD_SIZE(x, y);
  136 + panel_info.vl_col = x;
  137 + panel_info.vl_row = y;
  138 + lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
  139 +}
  140 +
  141 +static void set_preset(const struct panel_config preset, int x_res, int y_res)
  142 +{
  143 + panel_cfg = preset;
  144 + set_resolution_params(x_res, y_res);
  145 +}
  146 +
  147 +static enum display_type set_dvi_preset(const struct panel_config preset,
  148 + int x_res, int y_res)
  149 +{
  150 + set_preset(preset, x_res, y_res);
  151 + return DVI;
  152 +}
  153 +
  154 +/*
  155 + * env_parse_displaytype() - parse display type.
  156 + *
  157 + * Parses the environment variable "displaytype", which contains the
  158 + * name of the display type or preset, in which case it applies its
  159 + * configurations.
  160 + *
  161 + * Returns the type of display that was specified.
  162 + */
  163 +static enum display_type env_parse_displaytype(char *displaytype)
  164 +{
  165 + if (!strncmp(displaytype, "dvi640x480", 10))
  166 + return set_dvi_preset(preset_dvi_640X480, 640, 480);
  167 + else if (!strncmp(displaytype, "dvi800x600", 10))
  168 + return set_dvi_preset(preset_dvi_800X600, 800, 600);
  169 + else if (!strncmp(displaytype, "dvi1024x768", 11))
  170 + return set_dvi_preset(preset_dvi_1024X768, 1024, 768);
  171 + else if (!strncmp(displaytype, "dvi1152x864", 11))
  172 + return set_dvi_preset(preset_dvi_1152X864, 1152, 864);
  173 + else if (!strncmp(displaytype, "dvi1280x960", 11))
  174 + return set_dvi_preset(preset_dvi_1280X960, 1280, 960);
  175 + else if (!strncmp(displaytype, "dvi1280x1024", 12))
  176 + return set_dvi_preset(preset_dvi_1280X1024, 1280, 1024);
  177 +
  178 + return NONE;
  179 +}
  180 +
  181 +int lcd_line_length;
  182 +int lcd_color_fg;
  183 +int lcd_color_bg;
  184 +void *lcd_base;
  185 +short console_col;
  186 +short console_row;
  187 +void *lcd_console_address;
  188 +
  189 +void lcd_ctrl_init(void *lcdbase)
  190 +{
  191 + struct prcm *prcm = (struct prcm *)PRCM_BASE;
  192 + char *displaytype = getenv("displaytype");
  193 +
  194 + if (displaytype == NULL)
  195 + return;
  196 +
  197 + lcd_def = env_parse_displaytype(displaytype);
  198 + if (lcd_def == NONE)
  199 + return;
  200 +
  201 + panel_cfg.frame_buffer = lcdbase;
  202 + omap3_dss_panel_config(&panel_cfg);
  203 + /*
  204 + * Pixel clock is defined with many divisions and only few
  205 + * multiplications of the system clock. Since DSS FCLK divisor is set
  206 + * to 16 by default, we need to set it to a smaller value, like 3
  207 + * (chosen via trial and error).
  208 + */
  209 + clrsetbits_le32(&prcm->clksel_dss, 0xF, 3);
  210 +}
  211 +
  212 +void lcd_enable(void)
  213 +{
  214 + if (lcd_def == DVI) {
  215 + gpio_direction_output(54, 0); /* Turn on DVI */
  216 + omap3_dss_enable();
  217 + }
  218 +}
  219 +
  220 +void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) {}
include/configs/cm_t35.h
... ... @@ -336,5 +336,12 @@
336 336 #define CONFIG_OMAP3_GPIO_6 /* GPIO186 is in GPIO bank 6 */
337 337 #endif
338 338  
  339 +/* Display Configuration */
  340 +#define CONFIG_OMAP3_GPIO_2
  341 +#define CONFIG_VIDEO_OMAP3
  342 +#define LCD_BPP LCD_COLOR16
  343 +
  344 +#define CONFIG_LCD
  345 +
339 346 #endif /* __CONFIG_H */