Commit ba8e76bd49a0575a2442025507882b499856af2b

Authored by Timur Tabi
Committed by Anatolij Gustschin
1 parent a5dbdc81ea

powerpc: use 'video-mode' environment variable to configure DIU

Use the 'video-mode' environment variable (for Freescale chips that have a
DIU display controller) to designate the full video configuration.  Previously,
the DIU driver used the 'monitor' variable, and it was used only to determine
the output video port.

The old definition of the "monitor" environment variable only determines
which video port to use for output.  This variable was set to a number (0,
1, or sometimes 2) to specify a DVI, LVDS, or Dual-LVDS port.  The
resolution was hard-coded into board-specific code.  The Linux command-line
arguments needed to be hard-coded to the proper video definition string.

Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Anatolij Gustschin <agust@denx.de>

Showing 10 changed files with 294 additions and 428 deletions Side-by-side Diff

... ... @@ -1096,13 +1096,10 @@
1096 1096 CONFIG_VIDEO_LOGO
1097 1097 CONFIG_VIDEO_BMP_LOGO
1098 1098  
1099   - The DIU driver will look for the 'monitor' environment variable,
1100   - and if defined, enable the DIU as a console during boot. This
1101   - variable should be set to one of these values:
1102   -
1103   - '0' Output video to the DVI connector
1104   - '1' Output video to the LVDS connector
1105   - '2' Output video to the Dual-Link LVDS connector
  1099 + The DIU driver will look for the 'video-mode' environment
  1100 + variable, and if defined, enable the DIU as a console during
  1101 + boot. See the documentation file README.video for a
  1102 + description of this variable.
1106 1103  
1107 1104 - Keyboard Support:
1108 1105 CONFIG_KEYBOARD
arch/powerpc/cpu/mpc512x/diu.c
... ... @@ -51,21 +51,11 @@
51 51 debug("DIU: Modified value of CLKDVDR = 0x%08x\n", in_be32(clkdvdr));
52 52 }
53 53  
54   -int platform_diu_init(unsigned int *xres, unsigned int *yres)
  54 +int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
55 55 {
56   - unsigned int pixel_format;
  56 + unsigned int pixel_format = 0x88883316;
57 57  
58   -#if defined(CONFIG_VIDEO_XRES) & defined(CONFIG_VIDEO_YRES)
59   - *xres = CONFIG_VIDEO_XRES;
60   - *yres = CONFIG_VIDEO_YRES;
61   -#else
62   - *xres = 1024;
63   - *yres = 768;
64   -#endif
65   - pixel_format = 0x88883316;
66   -
67 58 debug("mpc5121_diu_init\n");
68   -
69   - return fsl_diu_init(*xres, pixel_format, 0);
  59 + return fsl_diu_init(xres, pixel_format, 0);
70 60 }
board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c
1 1 /*
2   - * Copyright 2007 Freescale Semiconductor, Inc.
3   - * York Sun <yorksun@freescale.com>
  2 + * Copyright 2007-2011 Freescale Semiconductor, Inc.
  3 + * Authors: York Sun <yorksun@freescale.com>
  4 + * Timur Tabi <timur@freescale.com>
4 5 *
5 6 * FSL DIU Framebuffer driver
6 7 *
7 8  
... ... @@ -27,7 +28,11 @@
27 28 #include <command.h>
28 29 #include <asm/io.h>
29 30 #include <fsl_diu_fb.h>
  31 +#include "../common/pixis.h"
30 32  
  33 +#define PX_BRDCFG0_DLINK 0x10
  34 +#define PX_BRDCFG0_DVISEL 0x08
  35 +
31 36 void diu_set_pixel_clock(unsigned int pixclock)
32 37 {
33 38 volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
34 39  
35 40  
36 41  
37 42  
38 43  
... ... @@ -49,51 +54,35 @@
49 54 debug("DIU: Modified value of CLKDVDR = 0x%08x\n", *guts_clkdvdr);
50 55 }
51 56  
52   -int platform_diu_init(unsigned int *xres, unsigned int *yres)
  57 +int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
53 58 {
54   - char *monitor_port;
55   - int gamma_fix;
56   - unsigned int pixel_format;
57   - unsigned char tmp_val;
58   - unsigned char pixis_arch;
59   - u8 *pixis_base = (u8 *)PIXIS_BASE;
  59 + const char *name;
  60 + int gamma_fix = 0;
  61 + u32 pixel_format = 0x88883316;
  62 + u8 temp;
60 63  
61   - tmp_val = in_8(pixis_base + PIXIS_BRDCFG0);
62   - pixis_arch = in_8(pixis_base + PIXIS_VER);
  64 + temp = in_8(&pixis->brdcfg0);
63 65  
64   - monitor_port = getenv("monitor");
65   - if (!strncmp(monitor_port, "0", 1)) { /* 0 - DVI */
66   - *xres = 1280;
67   - *yres = 1024;
68   - if (pixis_arch == 0x01)
69   - pixel_format = 0x88882317;
70   - else
71   - pixel_format = 0x88883316;
72   - gamma_fix = 0;
73   - out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08);
74   -
75   - } else if (!strncmp(monitor_port, "1", 1)) { /* 1 - Single link LVDS */
76   - *xres = 1024;
77   - *yres = 768;
78   - pixel_format = 0x88883316;
79   - gamma_fix = 0;
80   - out_8(pixis_base + PIXIS_BRDCFG0, (tmp_val & 0xf7) | 0x10);
81   -
82   - } else if (!strncmp(monitor_port, "2", 1)) { /* 2 - Double link LVDS */
83   - *xres = 1280;
84   - *yres = 1024;
85   - pixel_format = 0x88883316;
  66 + if (strncmp(port, "dlvds", 5) == 0) {
  67 + /* Dual link LVDS */
86 68 gamma_fix = 1;
87   - out_8(pixis_base + PIXIS_BRDCFG0, tmp_val & 0xe7);
88   -
89   - } else { /* DVI */
90   - *xres = 1280;
91   - *yres = 1024;
92   - pixel_format = 0x88882317;
93   - gamma_fix = 0;
94   - out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08);
  69 + temp &= ~(PX_BRDCFG0_DLINK | PX_BRDCFG0_DVISEL);
  70 + name = "Dual-Link LVDS";
  71 + } else if (strncmp(port, "lvds", 4) == 0) {
  72 + /* Single link LVDS */
  73 + temp = (temp & ~PX_BRDCFG0_DVISEL) | PX_BRDCFG0_DLINK;
  74 + name = "Single-Link LVDS";
  75 + } else {
  76 + /* DVI */
  77 + if (in_8(&pixis->ver) == 1) /* Board version */
  78 + pixel_format = 0x88882317;
  79 + temp |= PX_BRDCFG0_DVISEL;
  80 + name = "DVI";
95 81 }
96 82  
97   - return fsl_diu_init(*xres, pixel_format, gamma_fix);
  83 + printf("DIU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
  84 + out_8(&pixis->brdcfg0, temp);
  85 +
  86 + return fsl_diu_init(xres, pixel_format, gamma_fix);
98 87 }
board/freescale/p1022ds/diu.c
... ... @@ -12,6 +12,7 @@
12 12  
13 13 #include <common.h>
14 14 #include <command.h>
  15 +#include <linux/ctype.h>
15 16 #include <asm/io.h>
16 17 #include <stdio_dev.h>
17 18 #include <video_fb.h>
18 19  
... ... @@ -81,10 +82,10 @@
81 82 out_be32(&gur->clkdvdr, temp | 0x80000000 | ((pixval & 0x1F) << 16));
82 83 }
83 84  
84   -int platform_diu_init(unsigned int *xres, unsigned int *yres)
  85 +int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
85 86 {
86 87 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
87   - char *monitor_port;
  88 + const char *name;
88 89 u32 pixel_format;
89 90 u8 temp;
90 91  
91 92  
92 93  
93 94  
... ... @@ -100,21 +101,23 @@
100 101  
101 102 temp = in_8(&pixis->brdcfg1);
102 103  
103   - monitor_port = getenv("monitor");
104   - if (!strncmp(monitor_port, "1", 1)) { /* 1 - Single link LVDS */
105   - *xres = 1024;
106   - *yres = 768;
107   - /* Enable the DFP port, disable the DVI and the backlight */
108   - temp &= ~(PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT);
109   - temp |= PX_BRDCFG1_DFPEN;
  104 + if (strncmp(port, "lvds", 4) == 0) {
  105 + /* Single link LVDS */
  106 + temp &= ~PX_BRDCFG1_DVIEN;
  107 + /*
  108 + * LVDS also needs backlight enabled, otherwise the display
  109 + * will be blank.
  110 + */
  111 + temp |= (PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
  112 + name = "Single-Link LVDS";
110 113 } else { /* DVI */
111   - *xres = 1280;
112   - *yres = 1024;
113 114 /* Enable the DVI port, disable the DFP and the backlight */
114 115 temp &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
115 116 temp |= PX_BRDCFG1_DVIEN;
  117 + name = "DVI";
116 118 }
117 119  
  120 + printf("DIU: Switching to %s monitor @ %ux%u\n", name, xres, yres);
118 121 out_8(&pixis->brdcfg1, temp);
119 122  
120 123 /*
... ... @@ -136,7 +139,7 @@
136 139 clrsetbits_be32(&gur->pmuxcr, PMUXCR_ELBCDIU_MASK, PMUXCR_ELBCDIU_DIU);
137 140 pmuxcr = in_be32(&gur->pmuxcr);
138 141  
139   - return fsl_diu_init(*xres, pixel_format, 0);
  142 + return fsl_diu_init(xres, pixel_format, 0);
140 143 }
141 144  
142 145 /*
drivers/video/Makefile
... ... @@ -28,7 +28,7 @@
28 28 COBJS-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
29 29 COBJS-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
30 30 COBJS-$(CONFIG_CFB_CONSOLE) += cfb_console.o
31   -COBJS-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o
  31 +COBJS-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
32 32 COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
33 33 COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
34 34 COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
drivers/video/fsl_diu_fb.c
1 1 /*
2   - * Copyright 2007, 2010 Freescale Semiconductor, Inc.
3   - * York Sun <yorksun@freescale.com>
  2 + * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc.
  3 + * Authors: York Sun <yorksun@freescale.com>
  4 + * Timur Tabi <timur@freescale.com>
4 5 *
5 6 * FSL DIU Framebuffer driver
6 7 *
7 8  
8 9  
... ... @@ -24,12 +25,42 @@
24 25 */
25 26  
26 27 #include <common.h>
27   -#include <i2c.h>
28 28 #include <malloc.h>
29 29 #include <asm/io.h>
30 30  
  31 +#include "videomodes.h"
  32 +#include <video_fb.h>
31 33 #include <fsl_diu_fb.h>
32 34  
  35 +struct fb_var_screeninfo {
  36 + unsigned int xres; /* visible resolution */
  37 + unsigned int yres;
  38 +
  39 + unsigned int bits_per_pixel; /* guess what */
  40 +
  41 + /* Timing: All values in pixclocks, except pixclock (of course) */
  42 + unsigned int pixclock; /* pixel clock in ps (pico seconds) */
  43 + unsigned int left_margin; /* time from sync to picture */
  44 + unsigned int right_margin; /* time from picture to sync */
  45 + unsigned int upper_margin; /* time from sync to picture */
  46 + unsigned int lower_margin;
  47 + unsigned int hsync_len; /* length of horizontal sync */
  48 + unsigned int vsync_len; /* length of vertical sync */
  49 + unsigned int sync; /* see FB_SYNC_* */
  50 + unsigned int vmode; /* see FB_VMODE_* */
  51 + unsigned int rotate; /* angle we rotate counter clockwise */
  52 +};
  53 +
  54 +struct fb_info {
  55 + struct fb_var_screeninfo var; /* Current var */
  56 + unsigned int smem_len; /* Length of frame buffer mem */
  57 + unsigned int type; /* see FB_TYPE_* */
  58 + unsigned int line_length; /* length of a line in bytes */
  59 +
  60 + void *screen_base;
  61 + unsigned long screen_size;
  62 +};
  63 +
33 64 struct fb_videomode {
34 65 const char *name; /* optional */
35 66 unsigned int refresh; /* optional */
... ... @@ -53,6 +84,7 @@
53 84  
54 85 /* This setting is used for the ifm pdm360ng with PRIMEVIEW PM070WL3 */
55 86 static struct fb_videomode fsl_diu_mode_800 = {
  87 + .name = "800x600-60",
56 88 .refresh = 60,
57 89 .xres = 800,
58 90 .yres = 480,
... ... @@ -74,6 +106,7 @@
74 106 * hsync 31.5kHz, vsync 60Hz
75 107 */
76 108 static struct fb_videomode fsl_diu_mode_1024 = {
  109 + .name = "1024x768-60",
77 110 .refresh = 60,
78 111 .xres = 1024,
79 112 .yres = 768,
80 113  
81 114  
82 115  
83 116  
84 117  
85 118  
86 119  
87 120  
88 121  
89 122  
90 123  
91 124  
92 125  
93 126  
94 127  
95 128  
96 129  
97 130  
98 131  
99 132  
100 133  
101 134  
102 135  
... ... @@ -109,121 +142,138 @@
109 142 */
110 143 struct diu_ad {
111 144 /* Word 0(32-bit) in DDR memory */
112   - unsigned int pix_fmt; /* hard coding pixel format */
  145 + __le32 pix_fmt; /* hard coding pixel format */
113 146 /* Word 1(32-bit) in DDR memory */
114   - unsigned int addr;
  147 + __le32 addr;
115 148 /* Word 2(32-bit) in DDR memory */
116   - unsigned int src_size_g_alpha;
  149 + __le32 src_size_g_alpha;
117 150 /* Word 3(32-bit) in DDR memory */
118   - unsigned int aoi_size;
  151 + __le32 aoi_size;
119 152 /* Word 4(32-bit) in DDR memory */
120   - unsigned int offset_xyi;
  153 + __le32 offset_xyi;
121 154 /* Word 5(32-bit) in DDR memory */
122   - unsigned int offset_xyd;
  155 + __le32 offset_xyd;
123 156 /* Word 6(32-bit) in DDR memory */
124   - unsigned int ckmax_r:8;
125   - unsigned int ckmax_g:8;
126   - unsigned int ckmax_b:8;
127   - unsigned int res9:8;
  157 + __le32 ckmax_r:8;
  158 + __le32 ckmax_g:8;
  159 + __le32 ckmax_b:8;
  160 + __le32 res9:8;
128 161 /* Word 7(32-bit) in DDR memory */
129   - unsigned int ckmin_r:8;
130   - unsigned int ckmin_g:8;
131   - unsigned int ckmin_b:8;
132   - unsigned int res10:8;
  162 + __le32 ckmin_r:8;
  163 + __le32 ckmin_g:8;
  164 + __le32 ckmin_b:8;
  165 + __le32 res10:8;
133 166 /* Word 8(32-bit) in DDR memory */
134   - unsigned int next_ad;
  167 + __le32 next_ad;
135 168 /* Word 9(32-bit) in DDR memory, just for 64-bit aligned */
136   - unsigned int res1;
137   - unsigned int res2;
138   - unsigned int res3;
139   -}__attribute__ ((packed));
  169 + __le32 res[3];
  170 +} __attribute__ ((packed));
140 171  
141 172 /*
142 173 * DIU register map
143 174 */
144 175 struct diu {
145   - unsigned int desc[3];
146   - unsigned int gamma;
147   - unsigned int pallete;
148   - unsigned int cursor;
149   - unsigned int curs_pos;
150   - unsigned int diu_mode;
151   - unsigned int bgnd;
152   - unsigned int bgnd_wb;
153   - unsigned int disp_size;
154   - unsigned int wb_size;
155   - unsigned int wb_mem_addr;
156   - unsigned int hsyn_para;
157   - unsigned int vsyn_para;
158   - unsigned int syn_pol;
159   - unsigned int thresholds;
160   - unsigned int int_status;
161   - unsigned int int_mask;
162   - unsigned int colorbar[8];
163   - unsigned int filling;
164   - unsigned int plut;
  176 + __be32 desc[3];
  177 + __be32 gamma;
  178 + __be32 pallete;
  179 + __be32 cursor;
  180 + __be32 curs_pos;
  181 + __be32 diu_mode;
  182 + __be32 bgnd;
  183 + __be32 bgnd_wb;
  184 + __be32 disp_size;
  185 + __be32 wb_size;
  186 + __be32 wb_mem_addr;
  187 + __be32 hsyn_para;
  188 + __be32 vsyn_para;
  189 + __be32 syn_pol;
  190 + __be32 thresholds;
  191 + __be32 int_status;
  192 + __be32 int_mask;
  193 + __be32 colorbar[8];
  194 + __be32 filling;
  195 + __be32 plut;
165 196 } __attribute__ ((packed));
166 197  
167   -struct diu_hw {
168   - struct diu *diu_reg;
169   - volatile unsigned int mode; /* DIU operation mode */
170   -};
171   -
172 198 struct diu_addr {
173   - unsigned char * paddr; /* Virtual address */
174   - unsigned int offset;
  199 + void *vaddr; /* Virtual address */
  200 + u32 paddr; /* 32-bit physical address */
  201 + unsigned int offset; /* Alignment offset */
175 202 };
176 203  
  204 +static struct fb_info info;
  205 +
177 206 /*
178   - * Modes of operation of DIU
  207 + * Align to 64-bit(8-byte), 32-byte, etc.
179 208 */
180   -#define MFB_MODE0 0 /* DIU off */
181   -#define MFB_MODE1 1 /* All three planes output to display */
182   -#define MFB_MODE2 2 /* Plane 1 to display,
183   - * planes 2+3 written back to memory */
184   -#define MFB_MODE3 3 /* All three planes written back to memory */
185   -#define MFB_MODE4 4 /* Color bar generation */
  209 +static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
  210 +{
  211 + u32 offset, ssize;
  212 + u32 mask;
186 213  
187   -#define MAX_CURS 32
  214 + ssize = size + bytes_align;
  215 + buf->vaddr = malloc(ssize);
  216 + if (!buf->vaddr)
  217 + return -1;
188 218  
189   -static struct fb_info fsl_fb_info;
190   -static struct diu_addr gamma, cursor;
191   -static struct diu_ad fsl_diu_fb_ad __attribute__ ((aligned(32)));
192   -static struct diu_ad dummy_ad __attribute__ ((aligned(32)));
193   -static unsigned char *dummy_fb;
194   -static struct diu_hw dr = {
195   - .mode = MFB_MODE1,
196   -};
  219 + memset(buf->vaddr, 0, ssize);
  220 + mask = bytes_align - 1;
  221 + offset = (u32)buf->vaddr & mask;
  222 + if (offset) {
  223 + buf->offset = bytes_align - offset;
  224 + buf->vaddr += offset;
  225 + } else
  226 + buf->offset = 0;
197 227  
198   -int fb_enabled = 0;
199   -int fb_initialized = 0;
200   -const int default_xres = 1280;
201   -const int default_pixel_format = 0x88882317;
  228 + buf->paddr = virt_to_phys(buf->vaddr);
  229 + return 0;
  230 +}
202 231  
203   -static int map_video_memory(struct fb_info *info, unsigned long bytes_align);
204   -static void enable_lcdc(void);
205   -static void disable_lcdc(void);
206   -static int fsl_diu_enable_panel(struct fb_info *info);
207   -static int fsl_diu_disable_panel(struct fb_info *info);
208   -static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align);
209   -void diu_set_pixel_clock(unsigned int pixclock);
  232 +/*
  233 + * Allocate a framebuffer and an Area Descriptor that points to it. Both
  234 + * are created in the same memory block. The Area Descriptor is updated to
  235 + * point to the framebuffer memory. Memory is aligned as needed.
  236 + */
  237 +static struct diu_ad *allocate_fb(unsigned int xres, unsigned int yres,
  238 + unsigned int depth, void **fb)
  239 +{
  240 + unsigned long size = xres * yres * depth;
  241 + struct diu_addr addr;
  242 + struct diu_ad *ad;
  243 + size_t ad_size = roundup(sizeof(struct diu_ad), 32);
210 244  
211   -int fsl_diu_init(int xres, unsigned int pixel_format, int gamma_fix)
  245 + /*
  246 + * Allocate a memory block that holds the Area Descriptor and the
  247 + * frame buffer right behind it. To keep the code simple, everything
  248 + * is aligned on a 32-byte address.
  249 + */
  250 + if (allocate_buf(&addr, ad_size + size, 32) < 0)
  251 + return NULL;
  252 +
  253 + ad = addr.vaddr;
  254 + ad->addr = cpu_to_le32(addr.paddr + ad_size);
  255 + ad->aoi_size = cpu_to_le32((yres << 16) | xres);
  256 + ad->src_size_g_alpha = cpu_to_le32((yres << 12) | xres);
  257 + ad->offset_xyi = 0;
  258 + ad->offset_xyd = 0;
  259 +
  260 + if (fb)
  261 + *fb = addr.vaddr + ad_size;
  262 +
  263 + return ad;
  264 +}
  265 +
  266 +int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix)
212 267 {
213 268 struct fb_videomode *fsl_diu_mode_db;
214   - struct diu_ad *ad = &fsl_diu_fb_ad;
215   - struct diu *hw;
216   - struct fb_info *info = &fsl_fb_info;
217   - struct fb_var_screeninfo *var = &info->var;
218   - unsigned char *gamma_table_base;
  269 + struct diu_ad *ad;
  270 + struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR;
  271 + u8 *gamma_table_base;
219 272 unsigned int i, j;
  273 + struct diu_ad *dummy_ad;
  274 + struct diu_addr gamma;
  275 + struct diu_addr cursor;
220 276  
221   - debug("Enter fsl_diu_init\n");
222   - dr.diu_reg = (struct diu *) (CONFIG_SYS_DIU_ADDR);
223   - hw = (struct diu *) dr.diu_reg;
224   -
225   - disable_lcdc();
226   -
227 277 switch (xres) {
228 278 case 800:
229 279 fsl_diu_mode_db = &fsl_diu_mode_800;
230 280  
231 281  
232 282  
233 283  
234 284  
... ... @@ -235,65 +285,40 @@
235 285 fsl_diu_mode_db = &fsl_diu_mode_1024;
236 286 }
237 287  
238   - if (0 == fb_initialized) {
239   - allocate_buf(&gamma, 768, 32);
240   - debug("gamma is allocated @ 0x%x\n",
241   - (unsigned int)gamma.paddr);
242   - allocate_buf(&cursor, MAX_CURS * MAX_CURS * 2, 32);
243   - debug("curosr is allocated @ 0x%x\n",
244   - (unsigned int)cursor.paddr);
245   -
246   - /* create a dummy fb and dummy ad */
247   - dummy_fb = malloc(64);
248   - if (NULL == dummy_fb) {
249   - printf("Cannot allocate dummy fb\n");
250   - return -1;
251   - }
252   - dummy_ad.addr = cpu_to_le32((unsigned int)dummy_fb);
253   - dummy_ad.pix_fmt = 0x88882317;
254   - dummy_ad.src_size_g_alpha = 0x04400000; /* alpha = 0 */
255   - dummy_ad.aoi_size = 0x02000400;
256   - dummy_ad.offset_xyi = 0;
257   - dummy_ad.offset_xyd = 0;
258   - dummy_ad.next_ad = 0;
259   - /* Memory allocation for framebuffer */
260   - if (map_video_memory(info, 32)) {
261   - printf("Unable to allocate fb memory 1\n");
262   - return -1;
263   - }
  288 + /* The AD struct for the dummy framebuffer and the FB itself */
  289 + dummy_ad = allocate_fb(2, 4, 4, NULL);
  290 + if (!dummy_ad) {
  291 + printf("DIU: Out of memory\n");
  292 + return -1;
264 293 }
  294 + dummy_ad->pix_fmt = 0x88883316;
265 295  
266   - memset(info->screen_base, 0, info->smem_len);
267   -
268   - out_be32(&dr.diu_reg->desc[0], (int)&dummy_ad);
269   - out_be32(&dr.diu_reg->desc[1], (int)&dummy_ad);
270   - out_be32(&dr.diu_reg->desc[2], (int)&dummy_ad);
271   - debug("dummy dr.diu_reg->desc[0] = 0x%x\n", dr.diu_reg->desc[0]);
272   - debug("dummy desc[0] = 0x%x\n", hw->desc[0]);
273   -
274 296 /* read mode info */
275   - var->xres = fsl_diu_mode_db->xres;
276   - var->yres = fsl_diu_mode_db->yres;
277   - var->bits_per_pixel = 32;
278   - var->pixclock = fsl_diu_mode_db->pixclock;
279   - var->left_margin = fsl_diu_mode_db->left_margin;
280   - var->right_margin = fsl_diu_mode_db->right_margin;
281   - var->upper_margin = fsl_diu_mode_db->upper_margin;
282   - var->lower_margin = fsl_diu_mode_db->lower_margin;
283   - var->hsync_len = fsl_diu_mode_db->hsync_len;
284   - var->vsync_len = fsl_diu_mode_db->vsync_len;
285   - var->sync = fsl_diu_mode_db->sync;
286   - var->vmode = fsl_diu_mode_db->vmode;
287   - info->line_length = var->xres * var->bits_per_pixel / 8;
  297 + info.var.xres = fsl_diu_mode_db->xres;
  298 + info.var.yres = fsl_diu_mode_db->yres;
  299 + info.var.bits_per_pixel = 32;
  300 + info.var.pixclock = fsl_diu_mode_db->pixclock;
  301 + info.var.left_margin = fsl_diu_mode_db->left_margin;
  302 + info.var.right_margin = fsl_diu_mode_db->right_margin;
  303 + info.var.upper_margin = fsl_diu_mode_db->upper_margin;
  304 + info.var.lower_margin = fsl_diu_mode_db->lower_margin;
  305 + info.var.hsync_len = fsl_diu_mode_db->hsync_len;
  306 + info.var.vsync_len = fsl_diu_mode_db->vsync_len;
  307 + info.var.sync = fsl_diu_mode_db->sync;
  308 + info.var.vmode = fsl_diu_mode_db->vmode;
  309 + info.line_length = info.var.xres * info.var.bits_per_pixel / 8;
288 310  
  311 + /* Memory allocation for framebuffer */
  312 + info.smem_len =
  313 + info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
  314 + ad = allocate_fb(info.var.xres, info.var.yres,
  315 + info.var.bits_per_pixel / 8, &info.screen_base);
  316 + if (!ad) {
  317 + printf("DIU: Out of memory\n");
  318 + return -1;
  319 + }
  320 +
289 321 ad->pix_fmt = pixel_format;
290   - ad->addr = cpu_to_le32((unsigned int)info->screen_base);
291   - ad->src_size_g_alpha
292   - = cpu_to_le32((var->yres << 12) | var->xres);
293   - /* fix me. AOI should not be greater than display size */
294   - ad->aoi_size = cpu_to_le32(( var->yres << 16) | var->xres);
295   - ad->offset_xyi = 0;
296   - ad->offset_xyd = 0;
297 322  
298 323 /* Disable chroma keying function */
299 324 ad->ckmax_r = 0;
300 325  
301 326  
302 327  
303 328  
304 329  
305 330  
306 331  
307 332  
308 333  
309 334  
310 335  
311 336  
312 337  
313 338  
314 339  
315 340  
316 341  
317 342  
... ... @@ -304,195 +329,91 @@
304 329 ad->ckmin_g = 255;
305 330 ad->ckmin_b = 255;
306 331  
307   - gamma_table_base = gamma.paddr;
308   - debug("gamma_table_base is allocated @ 0x%x\n",
309   - (unsigned int)gamma_table_base);
310   -
311   - /* Prep for DIU init - gamma table */
312   -
  332 + /* Initialize the gamma table */
  333 + if (allocate_buf(&gamma, 256 * 3, 32) < 0) {
  334 + printf("DIU: Out of memory\n");
  335 + return -1;
  336 + }
  337 + gamma_table_base = gamma.vaddr;
313 338 for (i = 0; i <= 2; i++)
314   - for (j = 0; j <= 255; j++)
  339 + for (j = 0; j < 256; j++)
315 340 *gamma_table_base++ = j;
316 341  
317 342 if (gamma_fix == 1) { /* fix the gamma */
318   - debug("Fix gamma table\n");
319   - gamma_table_base = gamma.paddr;
320   - for (i = 0; i < 256*3; i++) {
  343 + gamma_table_base = gamma.vaddr;
  344 + for (i = 0; i < 256 * 3; i++) {
321 345 gamma_table_base[i] = (gamma_table_base[i] << 2)
322 346 | ((gamma_table_base[i] >> 6) & 0x03);
323 347 }
324 348 }
325 349  
326   - debug("update-lcdc: HW - %p\n Disabling DIU\n", hw);
  350 + /* Initialize the cursor */
  351 + if (allocate_buf(&cursor, 32 * 32 * 2, 32) < 0) {
  352 + printf("DIU: Can't alloc cursor data\n");
  353 + return -1;
  354 + }
327 355  
328 356 /* Program DIU registers */
  357 + out_be32(&hw->diu_mode, 0); /* Temporarily disable the DIU */
329 358  
330   - out_be32(&hw->gamma, (int)gamma.paddr);
331   - out_be32(&hw->cursor, (int)cursor.paddr);
  359 + out_be32(&hw->gamma, gamma.paddr);
  360 + out_be32(&hw->cursor, cursor.paddr);
332 361 out_be32(&hw->bgnd, 0x007F7F7F);
333   - out_be32(&hw->bgnd_wb, 0); /* BGND_WB */
334   - out_be32(&hw->disp_size, var->yres << 16 | var->xres); /* DISP SIZE */
335   - out_be32(&hw->wb_size, 0); /* WB SIZE */
336   - out_be32(&hw->wb_mem_addr, 0); /* WB MEM ADDR */
337   - out_be32(&hw->hsyn_para, var->left_margin << 22 | /* BP_H */
338   - var->hsync_len << 11 | /* PW_H */
339   - var->right_margin); /* FP_H */
  362 + out_be32(&hw->bgnd_wb, 0);
  363 + out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres);
  364 + out_be32(&hw->wb_size, 0);
  365 + out_be32(&hw->wb_mem_addr, 0);
  366 + out_be32(&hw->hsyn_para, info.var.left_margin << 22 |
  367 + info.var.hsync_len << 11 |
  368 + info.var.right_margin);
340 369  
341   - out_be32(&hw->vsyn_para, var->upper_margin << 22 | /* BP_V */
342   - var->vsync_len << 11 | /* PW_V */
343   - var->lower_margin); /* FP_V */
  370 + out_be32(&hw->vsyn_para, info.var.upper_margin << 22 |
  371 + info.var.vsync_len << 11 |
  372 + info.var.lower_margin);
344 373  
345   - out_be32(&hw->syn_pol, 0); /* SYNC SIGNALS POLARITY */
346   - out_be32(&hw->thresholds, 0x00037800); /* The Thresholds */
347   - out_be32(&hw->int_status, 0); /* INTERRUPT STATUS */
348   - out_be32(&hw->int_mask, 0); /* INT MASK */
  374 + out_be32(&hw->syn_pol, 0);
  375 + out_be32(&hw->thresholds, 0x00037800);
  376 + out_be32(&hw->int_status, 0);
  377 + out_be32(&hw->int_mask, 0);
349 378 out_be32(&hw->plut, 0x01F5F666);
350 379 /* Pixel Clock configuration */
351   - debug("DIU pixclock in ps - %d\n", var->pixclock);
352   - diu_set_pixel_clock(var->pixclock);
  380 + diu_set_pixel_clock(info.var.pixclock);
353 381  
354   - fb_initialized = 1;
  382 + /* Set the frame buffers */
  383 + out_be32(&hw->desc[0], virt_to_phys(ad));
  384 + out_be32(&hw->desc[1], virt_to_phys(dummy_ad));
  385 + out_be32(&hw->desc[2], virt_to_phys(dummy_ad));
355 386  
356   - /* Enable the DIU */
357   - fsl_diu_enable_panel(info);
358   - enable_lcdc();
  387 + /* Enable the DIU, set display to all three planes */
  388 + out_be32(&hw->diu_mode, 1);
359 389  
360 390 return 0;
361 391 }
362 392  
363   -char *fsl_fb_open(struct fb_info **info)
  393 +void *video_hw_init(void)
364 394 {
365   - *info = &fsl_fb_info;
366   - return fsl_fb_info.screen_base;
367   -}
  395 + static GraphicDevice ctfb;
  396 + const char *options;
  397 + unsigned int depth = 0, freq = 0;
368 398  
369   -void fsl_diu_close(void)
370   -{
371   - struct fb_info *info = &fsl_fb_info;
372   - fsl_diu_disable_panel(info);
373   -}
  399 + if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq,
  400 + &options))
  401 + return NULL;
374 402  
375   -static int fsl_diu_enable_panel(struct fb_info *info)
376   -{
377   - struct diu *hw = dr.diu_reg;
378   - struct diu_ad *ad = &fsl_diu_fb_ad;
  403 + /* Find the monitor port, which is a required option */
  404 + if (!options)
  405 + return NULL;
  406 + if (strncmp(options, "monitor=", 8) != 0)
  407 + return NULL;
379 408  
380   - debug("Entered: enable_panel\n");
381   - if (in_be32(&hw->desc[0]) != (unsigned)ad)
382   - out_be32(&hw->desc[0], (unsigned)ad);
383   - debug("desc[0] = 0x%x\n", hw->desc[0]);
384   - return 0;
385   -}
386   -
387   -static int fsl_diu_disable_panel(struct fb_info *info)
388   -{
389   - struct diu *hw = dr.diu_reg;
390   -
391   - debug("Entered: disable_panel\n");
392   - if (in_be32(&hw->desc[0]) != (unsigned)&dummy_ad)
393   - out_be32(&hw->desc[0], (unsigned)&dummy_ad);
394   - return 0;
395   -}
396   -
397   -static int map_video_memory(struct fb_info *info, unsigned long bytes_align)
398   -{
399   - unsigned long offset;
400   - unsigned long mask;
401   -
402   - debug("Entered: map_video_memory\n");
403   - /* allocate maximum 1280*1024 with 32bpp */
404   - info->smem_len = 1280 * 4 *1024 + bytes_align;
405   - debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->smem_len);
406   - info->screen_base = malloc(info->smem_len);
407   - if (info->screen_base == NULL) {
408   - printf("Unable to allocate fb memory\n");
409   - return -1;
410   - }
411   - info->smem_start = (unsigned int) info->screen_base;
412   - mask = bytes_align - 1;
413   - offset = (unsigned long)info->screen_base & mask;
414   - if (offset) {
415   - info->screen_base += (bytes_align - offset);
416   - info->smem_len = info->smem_len - (bytes_align - offset);
417   - } else
418   - info->smem_len = info->smem_len - bytes_align;
419   -
420   - info->screen_size = info->smem_len;
421   -
422   - debug("Allocated fb @ 0x%08lx, size=%d.\n",
423   - info->smem_start, info->smem_len);
424   -
425   - return 0;
426   -}
427   -
428   -static void enable_lcdc(void)
429   -{
430   - struct diu *hw = dr.diu_reg;
431   -
432   - debug("Entered: enable_lcdc, fb_enabled = %d\n", fb_enabled);
433   - if (!fb_enabled) {
434   - out_be32(&hw->diu_mode, dr.mode);
435   - fb_enabled++;
436   - }
437   - debug("diu_mode = %d\n", hw->diu_mode);
438   -}
439   -
440   -static void disable_lcdc(void)
441   -{
442   - struct diu *hw = dr.diu_reg;
443   -
444   - debug("Entered: disable_lcdc, fb_enabled = %d\n", fb_enabled);
445   - if (fb_enabled) {
446   - out_be32(&hw->diu_mode, 0);
447   - fb_enabled = 0;
448   - }
449   -}
450   -
451   -/*
452   - * Align to 64-bit(8-byte), 32-byte, etc.
453   - */
454   -static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
455   -{
456   - u32 offset, ssize;
457   - u32 mask;
458   -
459   - debug("Entered: allocate_buf\n");
460   - ssize = size + bytes_align;
461   - buf->paddr = malloc(ssize);
462   - if (!buf->paddr)
463   - return -1;
464   -
465   - memset(buf->paddr, 0, ssize);
466   - mask = bytes_align - 1;
467   - offset = (u32)buf->paddr & mask;
468   - if (offset) {
469   - buf->offset = bytes_align - offset;
470   - buf->paddr = (unsigned char *) ((u32)buf->paddr + offset);
471   - } else
472   - buf->offset = 0;
473   - return 0;
474   -}
475   -
476   -#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
477   -#include <stdio_dev.h>
478   -#include <video_fb.h>
479   -/*
480   - * The Graphic Device
481   - */
482   -static GraphicDevice ctfb;
483   -
484   -void *video_hw_init(void)
485   -{
486   - struct fb_info *info;
487   -
488   - if (platform_diu_init(&ctfb.winSizeX, &ctfb.winSizeY) < 0)
  409 + if (platform_diu_init(ctfb.winSizeX, ctfb.winSizeY, options + 8) < 0)
489 410 return NULL;
490 411  
491 412 /* fill in Graphic device struct */
492 413 sprintf(ctfb.modeIdent, "%ix%ix%i %ikHz %iHz",
493   - ctfb.winSizeX, ctfb.winSizeY, 32, 64, 60);
  414 + ctfb.winSizeX, ctfb.winSizeY, depth, 64, freq);
494 415  
495   - ctfb.frameAdrs = (unsigned int)fsl_fb_open(&info);
  416 + ctfb.frameAdrs = (unsigned int)info.screen_base;
496 417 ctfb.plnSizeX = ctfb.winSizeX;
497 418 ctfb.plnSizeY = ctfb.winSizeY;
498 419  
... ... @@ -501,7 +422,7 @@
501 422  
502 423 ctfb.isaBase = 0;
503 424 ctfb.pciBase = 0;
504   - ctfb.memSize = info->screen_size;
  425 + ctfb.memSize = info.screen_size;
505 426  
506 427 /* Cursor Start Address */
507 428 ctfb.dprBase = 0;
... ... @@ -510,5 +431,4 @@
510 431  
511 432 return &ctfb;
512 433 }
513   -#endif /* defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) */
include/configs/MPC8610HPCD.h
1 1 /*
2   - * Copyright 2007, 2010 Freescale Semiconductor, Inc.
  2 + * Copyright 2007-2011 Freescale Semiconductor, Inc.
3 3 *
4 4 * This program is free software; you can redistribute it and/or
5 5 * modify it under the terms of the GNU General Public License
... ... @@ -23,6 +23,8 @@
23 23  
24 24  
25 25 /* video */
  26 +#define CONFIG_FSL_DIU_FB
  27 +
26 28 #ifdef CONFIG_FSL_DIU_FB
27 29 #define CONFIG_SYS_DIU_ADDR (CONFIG_SYS_CCSRBAR + 0x2c000)
28 30 #define CONFIG_VIDEO
... ... @@ -625,8 +627,6 @@
625 627 "diuregs=md e002c000 1d\0" \
626 628 "dium=mw e002c01c\0" \
627 629 "diuerr=md e002c014 1\0" \
628   - "othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0 debug\0" \
629   - "monitor=0-DVI\0" \
630 630 "pmregs=md e00e1000 2b\0" \
631 631 "lawregs=md e0000c08 4b\0" \
632 632 "lbcregs=md e0005000 36\0" \
... ... @@ -646,9 +646,7 @@
646 646 "ramdiskfile=8610hpcd/ramdisk.uboot\0" \
647 647 "fdtaddr=c00000\0" \
648 648 "fdtfile=8610hpcd/mpc8610_hpcd.dtb\0" \
649   - "bdev=sda3\0" \
650   - "othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0\0"\
651   - "monitor=0-DVI\0"
  649 + "bdev=sda3\0"
652 650 #endif
653 651  
654 652 #define CONFIG_NFSBOOTCOMMAND \
include/configs/P1022DS.h
... ... @@ -202,6 +202,8 @@
202 202 #define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
203 203  
204 204 /* Video */
  205 +#define CONFIG_FSL_DIU_FB
  206 +
205 207 #ifdef CONFIG_FSL_DIU_FB
206 208 #define CONFIG_SYS_DIU_ADDR (CONFIG_SYS_CCSRBAR + 0x10000)
207 209 #define CONFIG_VIDEO
... ... @@ -219,7 +221,7 @@
219 221 #undef CONFIG_SYS_FLASH_EMPTY_INFO
220 222 #endif
221 223  
222   -#ifndef CONFIG_DIU
  224 +#ifndef CONFIG_FSL_DIU_FB
223 225 #define CONFIG_ATI
224 226 #endif
225 227  
... ... @@ -507,9 +509,7 @@
507 509 "diuregs=md e002c000 1d\0" \
508 510 "dium=mw e002c01c\0" \
509 511 "diuerr=md e002c014 1\0" \
510   - "othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0 tty0\0" \
511   - "hwconfig=esdhc;audclk:12\0" \
512   - "monitor=0-DVI\0"
  512 + "hwconfig=esdhc;audclk:12\0"
513 513  
514 514 #define CONFIG_HDBOOT \
515 515 "setenv bootargs root=/dev/$bdev rw " \
include/configs/pdm360ng.h
... ... @@ -64,8 +64,6 @@
64 64 #define CONFIG_SPLASH_SCREEN
65 65 #define CONFIG_VIDEO_LOGO
66 66 #define CONFIG_VIDEO_BMP_RLE8
67   -#define CONFIG_VIDEO_XRES 800
68   -#define CONFIG_VIDEO_YRES 480
69 67 #endif
70 68  
71 69 #define CONFIG_SYS_MPC512X_CLKIN 33333333 /* in Hz */
include/fsl_diu_fb.h
1 1 /*
2   - * Copyright 2007 Freescale Semiconductor, Inc.
3   - * York Sun <yorksun@freescale.com>
  2 + * Copyright 2007, 2011 Freescale Semiconductor, Inc.
  3 + * Authors: York Sun <yorksun@freescale.com>
  4 + * Timur Tabi <timur@freescale.com>
4 5 *
5 6 * FSL DIU Framebuffer driver
6 7 *
7 8  
... ... @@ -23,39 +24,9 @@
23 24 * MA 02111-1307 USA
24 25 */
25 26  
26   -struct fb_var_screeninfo {
27   - unsigned int xres; /* visible resolution */
28   - unsigned int yres;
  27 +int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix);
29 28  
30   - unsigned int bits_per_pixel; /* guess what */
31   -
32   - /* Timing: All values in pixclocks, except pixclock (of course) */
33   - unsigned int pixclock; /* pixel clock in ps (pico seconds) */
34   - unsigned int left_margin; /* time from sync to picture */
35   - unsigned int right_margin; /* time from picture to sync */
36   - unsigned int upper_margin; /* time from sync to picture */
37   - unsigned int lower_margin;
38   - unsigned int hsync_len; /* length of horizontal sync */
39   - unsigned int vsync_len; /* length of vertical sync */
40   - unsigned int sync; /* see FB_SYNC_* */
41   - unsigned int vmode; /* see FB_VMODE_* */
42   - unsigned int rotate; /* angle we rotate counter clockwise */
43   -};
44   -
45   -struct fb_info {
46   - struct fb_var_screeninfo var; /* Current var */
47   - unsigned long smem_start; /* Start of frame buffer mem */
48   - /* (physical address) */
49   - unsigned int smem_len; /* Length of frame buffer mem */
50   - unsigned int type; /* see FB_TYPE_* */
51   - unsigned int line_length; /* length of a line in bytes */
52   -
53   - char *screen_base;
54   - unsigned long screen_size;
55   -};
56   -
57   -
58   -extern char *fsl_fb_open(struct fb_info **info);
59   -int fsl_diu_init(int xres, unsigned int pixel_format, int gamma_fix);
60   -int platform_diu_init(unsigned int *xres, unsigned int *yres);
  29 +/* Prototypes for external board-specific functions */
  30 +int platform_diu_init(unsigned int xres, unsigned int yres, const char *port);
  31 +void diu_set_pixel_clock(unsigned int pixclock);