1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
214f88c43SAnatolij Gustschin /*
3ba8e76bdSTimur Tabi * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc.
4ba8e76bdSTimur Tabi * Authors: York Sun <yorksun@freescale.com>
5ba8e76bdSTimur Tabi * Timur Tabi <timur@freescale.com>
614f88c43SAnatolij Gustschin *
714f88c43SAnatolij Gustschin * FSL DIU Framebuffer driver
814f88c43SAnatolij Gustschin */
914f88c43SAnatolij Gustschin
1014f88c43SAnatolij Gustschin #include <common.h>
1114f88c43SAnatolij Gustschin #include <malloc.h>
1214f88c43SAnatolij Gustschin #include <asm/io.h>
1314f88c43SAnatolij Gustschin
14ba8e76bdSTimur Tabi #include "videomodes.h"
15ba8e76bdSTimur Tabi #include <video_fb.h>
1614f88c43SAnatolij Gustschin #include <fsl_diu_fb.h>
178c6b2504STimur Tabi #include <linux/list.h>
188c6b2504STimur Tabi #include <linux/fb.h>
1914f88c43SAnatolij Gustschin
2014f88c43SAnatolij Gustschin /* This setting is used for the ifm pdm360ng with PRIMEVIEW PM070WL3 */
213b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_800_480 = {
223b4a2263STimur Tabi .name = "800x480-60",
2314f88c43SAnatolij Gustschin .refresh = 60,
2414f88c43SAnatolij Gustschin .xres = 800,
2514f88c43SAnatolij Gustschin .yres = 480,
2614f88c43SAnatolij Gustschin .pixclock = 31250,
2714f88c43SAnatolij Gustschin .left_margin = 86,
2814f88c43SAnatolij Gustschin .right_margin = 42,
2914f88c43SAnatolij Gustschin .upper_margin = 33,
3014f88c43SAnatolij Gustschin .lower_margin = 10,
3114f88c43SAnatolij Gustschin .hsync_len = 128,
3214f88c43SAnatolij Gustschin .vsync_len = 2,
3314f88c43SAnatolij Gustschin .sync = 0,
3414f88c43SAnatolij Gustschin .vmode = FB_VMODE_NONINTERLACED
3514f88c43SAnatolij Gustschin };
3614f88c43SAnatolij Gustschin
373b4a2263STimur Tabi /* For the SHARP LQ084S3LG01, used on the P1022DS board */
383b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_800_600 = {
393b4a2263STimur Tabi .name = "800x600-60",
403b4a2263STimur Tabi .refresh = 60,
413b4a2263STimur Tabi .xres = 800,
423b4a2263STimur Tabi .yres = 600,
433b4a2263STimur Tabi .pixclock = 25000,
443b4a2263STimur Tabi .left_margin = 88,
453b4a2263STimur Tabi .right_margin = 40,
463b4a2263STimur Tabi .upper_margin = 23,
473b4a2263STimur Tabi .lower_margin = 1,
483b4a2263STimur Tabi .hsync_len = 128,
493b4a2263STimur Tabi .vsync_len = 4,
503b4a2263STimur Tabi .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
513b4a2263STimur Tabi .vmode = FB_VMODE_NONINTERLACED
523b4a2263STimur Tabi };
533b4a2263STimur Tabi
5414f88c43SAnatolij Gustschin /*
5514f88c43SAnatolij Gustschin * These parameters give default parameters
5614f88c43SAnatolij Gustschin * for video output 1024x768,
5714f88c43SAnatolij Gustschin * FIXME - change timing to proper amounts
5814f88c43SAnatolij Gustschin * hsync 31.5kHz, vsync 60Hz
5914f88c43SAnatolij Gustschin */
603b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_1024_768 = {
61ba8e76bdSTimur Tabi .name = "1024x768-60",
6214f88c43SAnatolij Gustschin .refresh = 60,
6314f88c43SAnatolij Gustschin .xres = 1024,
6414f88c43SAnatolij Gustschin .yres = 768,
6514f88c43SAnatolij Gustschin .pixclock = 15385,
6614f88c43SAnatolij Gustschin .left_margin = 160,
6714f88c43SAnatolij Gustschin .right_margin = 24,
6814f88c43SAnatolij Gustschin .upper_margin = 29,
6914f88c43SAnatolij Gustschin .lower_margin = 3,
7014f88c43SAnatolij Gustschin .hsync_len = 136,
7114f88c43SAnatolij Gustschin .vsync_len = 6,
7214f88c43SAnatolij Gustschin .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
7314f88c43SAnatolij Gustschin .vmode = FB_VMODE_NONINTERLACED
7414f88c43SAnatolij Gustschin };
7514f88c43SAnatolij Gustschin
763b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_1280_1024 = {
7714f88c43SAnatolij Gustschin .name = "1280x1024-60",
7814f88c43SAnatolij Gustschin .refresh = 60,
7914f88c43SAnatolij Gustschin .xres = 1280,
8014f88c43SAnatolij Gustschin .yres = 1024,
8114f88c43SAnatolij Gustschin .pixclock = 9375,
8214f88c43SAnatolij Gustschin .left_margin = 38,
8314f88c43SAnatolij Gustschin .right_margin = 128,
8414f88c43SAnatolij Gustschin .upper_margin = 2,
8514f88c43SAnatolij Gustschin .lower_margin = 7,
8614f88c43SAnatolij Gustschin .hsync_len = 216,
8714f88c43SAnatolij Gustschin .vsync_len = 37,
8814f88c43SAnatolij Gustschin .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
8914f88c43SAnatolij Gustschin .vmode = FB_VMODE_NONINTERLACED
9014f88c43SAnatolij Gustschin };
9114f88c43SAnatolij Gustschin
92debef5cdSJerry Huang static struct fb_videomode fsl_diu_mode_1280_720 = {
93debef5cdSJerry Huang .name = "1280x720-60",
94debef5cdSJerry Huang .refresh = 60,
95debef5cdSJerry Huang .xres = 1280,
96debef5cdSJerry Huang .yres = 720,
97debef5cdSJerry Huang .pixclock = 13426,
98debef5cdSJerry Huang .left_margin = 192,
99debef5cdSJerry Huang .right_margin = 64,
100debef5cdSJerry Huang .upper_margin = 22,
101debef5cdSJerry Huang .lower_margin = 1,
102debef5cdSJerry Huang .hsync_len = 136,
103debef5cdSJerry Huang .vsync_len = 3,
104debef5cdSJerry Huang .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
105debef5cdSJerry Huang .vmode = FB_VMODE_NONINTERLACED
106debef5cdSJerry Huang };
107debef5cdSJerry Huang
108debef5cdSJerry Huang static struct fb_videomode fsl_diu_mode_1920_1080 = {
109debef5cdSJerry Huang .name = "1920x1080-60",
110debef5cdSJerry Huang .refresh = 60,
111debef5cdSJerry Huang .xres = 1920,
112debef5cdSJerry Huang .yres = 1080,
113debef5cdSJerry Huang .pixclock = 5787,
114debef5cdSJerry Huang .left_margin = 328,
115debef5cdSJerry Huang .right_margin = 120,
116debef5cdSJerry Huang .upper_margin = 34,
117debef5cdSJerry Huang .lower_margin = 1,
118debef5cdSJerry Huang .hsync_len = 208,
119debef5cdSJerry Huang .vsync_len = 3,
120debef5cdSJerry Huang .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
121debef5cdSJerry Huang .vmode = FB_VMODE_NONINTERLACED
122debef5cdSJerry Huang };
123debef5cdSJerry Huang
12414f88c43SAnatolij Gustschin /*
12514f88c43SAnatolij Gustschin * These are the fields of area descriptor(in DDR memory) for every plane
12614f88c43SAnatolij Gustschin */
12714f88c43SAnatolij Gustschin struct diu_ad {
12814f88c43SAnatolij Gustschin /* Word 0(32-bit) in DDR memory */
129ba8e76bdSTimur Tabi __le32 pix_fmt; /* hard coding pixel format */
13014f88c43SAnatolij Gustschin /* Word 1(32-bit) in DDR memory */
131ba8e76bdSTimur Tabi __le32 addr;
13214f88c43SAnatolij Gustschin /* Word 2(32-bit) in DDR memory */
133ba8e76bdSTimur Tabi __le32 src_size_g_alpha;
13414f88c43SAnatolij Gustschin /* Word 3(32-bit) in DDR memory */
135ba8e76bdSTimur Tabi __le32 aoi_size;
13614f88c43SAnatolij Gustschin /* Word 4(32-bit) in DDR memory */
137ba8e76bdSTimur Tabi __le32 offset_xyi;
13814f88c43SAnatolij Gustschin /* Word 5(32-bit) in DDR memory */
139ba8e76bdSTimur Tabi __le32 offset_xyd;
14014f88c43SAnatolij Gustschin /* Word 6(32-bit) in DDR memory */
141ba8e76bdSTimur Tabi __le32 ckmax_r:8;
142ba8e76bdSTimur Tabi __le32 ckmax_g:8;
143ba8e76bdSTimur Tabi __le32 ckmax_b:8;
144ba8e76bdSTimur Tabi __le32 res9:8;
14514f88c43SAnatolij Gustschin /* Word 7(32-bit) in DDR memory */
146ba8e76bdSTimur Tabi __le32 ckmin_r:8;
147ba8e76bdSTimur Tabi __le32 ckmin_g:8;
148ba8e76bdSTimur Tabi __le32 ckmin_b:8;
149ba8e76bdSTimur Tabi __le32 res10:8;
15014f88c43SAnatolij Gustschin /* Word 8(32-bit) in DDR memory */
151ba8e76bdSTimur Tabi __le32 next_ad;
15214f88c43SAnatolij Gustschin /* Word 9(32-bit) in DDR memory, just for 64-bit aligned */
153ba8e76bdSTimur Tabi __le32 res[3];
15414f88c43SAnatolij Gustschin } __attribute__ ((packed));
15514f88c43SAnatolij Gustschin
15614f88c43SAnatolij Gustschin /*
15714f88c43SAnatolij Gustschin * DIU register map
15814f88c43SAnatolij Gustschin */
15914f88c43SAnatolij Gustschin struct diu {
160ba8e76bdSTimur Tabi __be32 desc[3];
161ba8e76bdSTimur Tabi __be32 gamma;
162ba8e76bdSTimur Tabi __be32 pallete;
163ba8e76bdSTimur Tabi __be32 cursor;
164ba8e76bdSTimur Tabi __be32 curs_pos;
165ba8e76bdSTimur Tabi __be32 diu_mode;
166ba8e76bdSTimur Tabi __be32 bgnd;
167ba8e76bdSTimur Tabi __be32 bgnd_wb;
168ba8e76bdSTimur Tabi __be32 disp_size;
169ba8e76bdSTimur Tabi __be32 wb_size;
170ba8e76bdSTimur Tabi __be32 wb_mem_addr;
171ba8e76bdSTimur Tabi __be32 hsyn_para;
172ba8e76bdSTimur Tabi __be32 vsyn_para;
173ba8e76bdSTimur Tabi __be32 syn_pol;
174ba8e76bdSTimur Tabi __be32 thresholds;
175ba8e76bdSTimur Tabi __be32 int_status;
176ba8e76bdSTimur Tabi __be32 int_mask;
177ba8e76bdSTimur Tabi __be32 colorbar[8];
178ba8e76bdSTimur Tabi __be32 filling;
179ba8e76bdSTimur Tabi __be32 plut;
18014f88c43SAnatolij Gustschin } __attribute__ ((packed));
18114f88c43SAnatolij Gustschin
182ba8e76bdSTimur Tabi struct diu_addr {
183ba8e76bdSTimur Tabi void *vaddr; /* Virtual address */
184ba8e76bdSTimur Tabi u32 paddr; /* 32-bit physical address */
185ba8e76bdSTimur Tabi unsigned int offset; /* Alignment offset */
18614f88c43SAnatolij Gustschin };
18714f88c43SAnatolij Gustschin
188ba8e76bdSTimur Tabi static struct fb_info info;
18914f88c43SAnatolij Gustschin
19014f88c43SAnatolij Gustschin /*
191ba8e76bdSTimur Tabi * Align to 64-bit(8-byte), 32-byte, etc.
19214f88c43SAnatolij Gustschin */
allocate_buf(struct diu_addr * buf,u32 size,u32 bytes_align)193ba8e76bdSTimur Tabi static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
194ba8e76bdSTimur Tabi {
195ba8e76bdSTimur Tabi u32 offset, ssize;
196ba8e76bdSTimur Tabi u32 mask;
19714f88c43SAnatolij Gustschin
198ba8e76bdSTimur Tabi ssize = size + bytes_align;
199ba8e76bdSTimur Tabi buf->vaddr = malloc(ssize);
200ba8e76bdSTimur Tabi if (!buf->vaddr)
201ba8e76bdSTimur Tabi return -1;
20214f88c43SAnatolij Gustschin
203ba8e76bdSTimur Tabi memset(buf->vaddr, 0, ssize);
204ba8e76bdSTimur Tabi mask = bytes_align - 1;
205ba8e76bdSTimur Tabi offset = (u32)buf->vaddr & mask;
206ba8e76bdSTimur Tabi if (offset) {
207ba8e76bdSTimur Tabi buf->offset = bytes_align - offset;
208ba8e76bdSTimur Tabi buf->vaddr += offset;
209ba8e76bdSTimur Tabi } else
210ba8e76bdSTimur Tabi buf->offset = 0;
21114f88c43SAnatolij Gustschin
212ba8e76bdSTimur Tabi buf->paddr = virt_to_phys(buf->vaddr);
213ba8e76bdSTimur Tabi return 0;
214ba8e76bdSTimur Tabi }
21514f88c43SAnatolij Gustschin
216ba8e76bdSTimur Tabi /*
217ba8e76bdSTimur Tabi * Allocate a framebuffer and an Area Descriptor that points to it. Both
218ba8e76bdSTimur Tabi * are created in the same memory block. The Area Descriptor is updated to
219ba8e76bdSTimur Tabi * point to the framebuffer memory. Memory is aligned as needed.
220ba8e76bdSTimur Tabi */
allocate_fb(unsigned int xres,unsigned int yres,unsigned int depth,char ** fb)221ba8e76bdSTimur Tabi static struct diu_ad *allocate_fb(unsigned int xres, unsigned int yres,
2228c6b2504STimur Tabi unsigned int depth, char **fb)
223ba8e76bdSTimur Tabi {
224ba8e76bdSTimur Tabi unsigned long size = xres * yres * depth;
225ba8e76bdSTimur Tabi struct diu_addr addr;
226ba8e76bdSTimur Tabi struct diu_ad *ad;
227ba8e76bdSTimur Tabi size_t ad_size = roundup(sizeof(struct diu_ad), 32);
22814f88c43SAnatolij Gustschin
229ba8e76bdSTimur Tabi /*
230ba8e76bdSTimur Tabi * Allocate a memory block that holds the Area Descriptor and the
231ba8e76bdSTimur Tabi * frame buffer right behind it. To keep the code simple, everything
232ba8e76bdSTimur Tabi * is aligned on a 32-byte address.
233ba8e76bdSTimur Tabi */
234ba8e76bdSTimur Tabi if (allocate_buf(&addr, ad_size + size, 32) < 0)
235ba8e76bdSTimur Tabi return NULL;
236ba8e76bdSTimur Tabi
237ba8e76bdSTimur Tabi ad = addr.vaddr;
238ba8e76bdSTimur Tabi ad->addr = cpu_to_le32(addr.paddr + ad_size);
239ba8e76bdSTimur Tabi ad->aoi_size = cpu_to_le32((yres << 16) | xres);
240ba8e76bdSTimur Tabi ad->src_size_g_alpha = cpu_to_le32((yres << 12) | xres);
241ba8e76bdSTimur Tabi ad->offset_xyi = 0;
242ba8e76bdSTimur Tabi ad->offset_xyd = 0;
243ba8e76bdSTimur Tabi
244ba8e76bdSTimur Tabi if (fb)
245ba8e76bdSTimur Tabi *fb = addr.vaddr + ad_size;
246ba8e76bdSTimur Tabi
247ba8e76bdSTimur Tabi return ad;
248ba8e76bdSTimur Tabi }
249ba8e76bdSTimur Tabi
fsl_diu_init(u16 xres,u16 yres,u32 pixel_format,int gamma_fix)2503b4a2263STimur Tabi int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix)
25114f88c43SAnatolij Gustschin {
25214f88c43SAnatolij Gustschin struct fb_videomode *fsl_diu_mode_db;
253ba8e76bdSTimur Tabi struct diu_ad *ad;
254ba8e76bdSTimur Tabi struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR;
255ba8e76bdSTimur Tabi u8 *gamma_table_base;
25614f88c43SAnatolij Gustschin unsigned int i, j;
257ba8e76bdSTimur Tabi struct diu_addr gamma;
258ba8e76bdSTimur Tabi struct diu_addr cursor;
25914f88c43SAnatolij Gustschin
2603b4a2263STimur Tabi /* Convert the X,Y resolution pair into a single number */
2613b4a2263STimur Tabi #define RESOLUTION(x, y) (((u32)(x) << 16) | (y))
2623b4a2263STimur Tabi
2633b4a2263STimur Tabi switch (RESOLUTION(xres, yres)) {
2643b4a2263STimur Tabi case RESOLUTION(800, 480):
2653b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_800_480;
26614f88c43SAnatolij Gustschin break;
2673b4a2263STimur Tabi case RESOLUTION(800, 600):
2683b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_800_600;
26915006cb7SJerry Huang break;
2703b4a2263STimur Tabi case RESOLUTION(1024, 768):
2713b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_1024_768;
27215006cb7SJerry Huang break;
2733b4a2263STimur Tabi case RESOLUTION(1280, 1024):
2743b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_1280_1024;
27514f88c43SAnatolij Gustschin break;
276debef5cdSJerry Huang case RESOLUTION(1280, 720):
277debef5cdSJerry Huang fsl_diu_mode_db = &fsl_diu_mode_1280_720;
278debef5cdSJerry Huang break;
279debef5cdSJerry Huang case RESOLUTION(1920, 1080):
280debef5cdSJerry Huang fsl_diu_mode_db = &fsl_diu_mode_1920_1080;
281debef5cdSJerry Huang break;
28214f88c43SAnatolij Gustschin default:
2833b4a2263STimur Tabi printf("DIU: Unsupported resolution %ux%u\n", xres, yres);
2843b4a2263STimur Tabi return -1;
28514f88c43SAnatolij Gustschin }
28614f88c43SAnatolij Gustschin
28714f88c43SAnatolij Gustschin /* read mode info */
288ba8e76bdSTimur Tabi info.var.xres = fsl_diu_mode_db->xres;
289ba8e76bdSTimur Tabi info.var.yres = fsl_diu_mode_db->yres;
290ba8e76bdSTimur Tabi info.var.bits_per_pixel = 32;
291ba8e76bdSTimur Tabi info.var.pixclock = fsl_diu_mode_db->pixclock;
292ba8e76bdSTimur Tabi info.var.left_margin = fsl_diu_mode_db->left_margin;
293ba8e76bdSTimur Tabi info.var.right_margin = fsl_diu_mode_db->right_margin;
294ba8e76bdSTimur Tabi info.var.upper_margin = fsl_diu_mode_db->upper_margin;
295ba8e76bdSTimur Tabi info.var.lower_margin = fsl_diu_mode_db->lower_margin;
296ba8e76bdSTimur Tabi info.var.hsync_len = fsl_diu_mode_db->hsync_len;
297ba8e76bdSTimur Tabi info.var.vsync_len = fsl_diu_mode_db->vsync_len;
298ba8e76bdSTimur Tabi info.var.sync = fsl_diu_mode_db->sync;
299ba8e76bdSTimur Tabi info.var.vmode = fsl_diu_mode_db->vmode;
3008c6b2504STimur Tabi info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8;
301ba8e76bdSTimur Tabi
302ba8e76bdSTimur Tabi /* Memory allocation for framebuffer */
3038c6b2504STimur Tabi info.screen_size =
304ba8e76bdSTimur Tabi info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
305ba8e76bdSTimur Tabi ad = allocate_fb(info.var.xres, info.var.yres,
306ba8e76bdSTimur Tabi info.var.bits_per_pixel / 8, &info.screen_base);
307ba8e76bdSTimur Tabi if (!ad) {
308ba8e76bdSTimur Tabi printf("DIU: Out of memory\n");
309ba8e76bdSTimur Tabi return -1;
310ba8e76bdSTimur Tabi }
31114f88c43SAnatolij Gustschin
31214f88c43SAnatolij Gustschin ad->pix_fmt = pixel_format;
31314f88c43SAnatolij Gustschin
31414f88c43SAnatolij Gustschin /* Disable chroma keying function */
31514f88c43SAnatolij Gustschin ad->ckmax_r = 0;
31614f88c43SAnatolij Gustschin ad->ckmax_g = 0;
31714f88c43SAnatolij Gustschin ad->ckmax_b = 0;
31814f88c43SAnatolij Gustschin
31914f88c43SAnatolij Gustschin ad->ckmin_r = 255;
32014f88c43SAnatolij Gustschin ad->ckmin_g = 255;
32114f88c43SAnatolij Gustschin ad->ckmin_b = 255;
32214f88c43SAnatolij Gustschin
323ba8e76bdSTimur Tabi /* Initialize the gamma table */
324ba8e76bdSTimur Tabi if (allocate_buf(&gamma, 256 * 3, 32) < 0) {
325ba8e76bdSTimur Tabi printf("DIU: Out of memory\n");
326ba8e76bdSTimur Tabi return -1;
327ba8e76bdSTimur Tabi }
328ba8e76bdSTimur Tabi gamma_table_base = gamma.vaddr;
32914f88c43SAnatolij Gustschin for (i = 0; i <= 2; i++)
330ba8e76bdSTimur Tabi for (j = 0; j < 256; j++)
33114f88c43SAnatolij Gustschin *gamma_table_base++ = j;
33214f88c43SAnatolij Gustschin
33314f88c43SAnatolij Gustschin if (gamma_fix == 1) { /* fix the gamma */
334ba8e76bdSTimur Tabi gamma_table_base = gamma.vaddr;
33514f88c43SAnatolij Gustschin for (i = 0; i < 256 * 3; i++) {
33614f88c43SAnatolij Gustschin gamma_table_base[i] = (gamma_table_base[i] << 2)
33714f88c43SAnatolij Gustschin | ((gamma_table_base[i] >> 6) & 0x03);
33814f88c43SAnatolij Gustschin }
33914f88c43SAnatolij Gustschin }
34014f88c43SAnatolij Gustschin
341ba8e76bdSTimur Tabi /* Initialize the cursor */
342ba8e76bdSTimur Tabi if (allocate_buf(&cursor, 32 * 32 * 2, 32) < 0) {
343ba8e76bdSTimur Tabi printf("DIU: Can't alloc cursor data\n");
344ba8e76bdSTimur Tabi return -1;
345ba8e76bdSTimur Tabi }
34614f88c43SAnatolij Gustschin
34714f88c43SAnatolij Gustschin /* Program DIU registers */
348ba8e76bdSTimur Tabi out_be32(&hw->diu_mode, 0); /* Temporarily disable the DIU */
34914f88c43SAnatolij Gustschin
350ba8e76bdSTimur Tabi out_be32(&hw->gamma, gamma.paddr);
351ba8e76bdSTimur Tabi out_be32(&hw->cursor, cursor.paddr);
35214f88c43SAnatolij Gustschin out_be32(&hw->bgnd, 0x007F7F7F);
353ba8e76bdSTimur Tabi out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres);
354ba8e76bdSTimur Tabi out_be32(&hw->hsyn_para, info.var.left_margin << 22 |
355ba8e76bdSTimur Tabi info.var.hsync_len << 11 |
356ba8e76bdSTimur Tabi info.var.right_margin);
35714f88c43SAnatolij Gustschin
358ba8e76bdSTimur Tabi out_be32(&hw->vsyn_para, info.var.upper_margin << 22 |
359ba8e76bdSTimur Tabi info.var.vsync_len << 11 |
360ba8e76bdSTimur Tabi info.var.lower_margin);
36114f88c43SAnatolij Gustschin
36214f88c43SAnatolij Gustschin /* Pixel Clock configuration */
363ba8e76bdSTimur Tabi diu_set_pixel_clock(info.var.pixclock);
36414f88c43SAnatolij Gustschin
365ba8e76bdSTimur Tabi /* Set the frame buffers */
366ba8e76bdSTimur Tabi out_be32(&hw->desc[0], virt_to_phys(ad));
36715b83386STimur Tabi out_be32(&hw->desc[1], 0);
36815b83386STimur Tabi out_be32(&hw->desc[2], 0);
36914f88c43SAnatolij Gustschin
370ba8e76bdSTimur Tabi /* Enable the DIU, set display to all three planes */
371ba8e76bdSTimur Tabi out_be32(&hw->diu_mode, 1);
37214f88c43SAnatolij Gustschin
37314f88c43SAnatolij Gustschin return 0;
37414f88c43SAnatolij Gustschin }
37514f88c43SAnatolij Gustschin
video_hw_init(void)37614f88c43SAnatolij Gustschin void *video_hw_init(void)
37714f88c43SAnatolij Gustschin {
378ba8e76bdSTimur Tabi static GraphicDevice ctfb;
379ba8e76bdSTimur Tabi const char *options;
380ba8e76bdSTimur Tabi unsigned int depth = 0, freq = 0;
38114f88c43SAnatolij Gustschin
382ba8e76bdSTimur Tabi if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq,
383ba8e76bdSTimur Tabi &options))
384ba8e76bdSTimur Tabi return NULL;
385ba8e76bdSTimur Tabi
386ba8e76bdSTimur Tabi /* Find the monitor port, which is a required option */
387ba8e76bdSTimur Tabi if (!options)
388ba8e76bdSTimur Tabi return NULL;
389ba8e76bdSTimur Tabi if (strncmp(options, "monitor=", 8) != 0)
390ba8e76bdSTimur Tabi return NULL;
391ba8e76bdSTimur Tabi
392ba8e76bdSTimur Tabi if (platform_diu_init(ctfb.winSizeX, ctfb.winSizeY, options + 8) < 0)
39314f88c43SAnatolij Gustschin return NULL;
39414f88c43SAnatolij Gustschin
39514f88c43SAnatolij Gustschin /* fill in Graphic device struct */
39614f88c43SAnatolij Gustschin sprintf(ctfb.modeIdent, "%ix%ix%i %ikHz %iHz",
397ba8e76bdSTimur Tabi ctfb.winSizeX, ctfb.winSizeY, depth, 64, freq);
39814f88c43SAnatolij Gustschin
399ba8e76bdSTimur Tabi ctfb.frameAdrs = (unsigned int)info.screen_base;
40014f88c43SAnatolij Gustschin ctfb.plnSizeX = ctfb.winSizeX;
40114f88c43SAnatolij Gustschin ctfb.plnSizeY = ctfb.winSizeY;
40214f88c43SAnatolij Gustschin
40314f88c43SAnatolij Gustschin ctfb.gdfBytesPP = 4;
40414f88c43SAnatolij Gustschin ctfb.gdfIndex = GDF_32BIT_X888RGB;
40514f88c43SAnatolij Gustschin
40614f88c43SAnatolij Gustschin ctfb.isaBase = 0;
40714f88c43SAnatolij Gustschin ctfb.pciBase = 0;
408ba8e76bdSTimur Tabi ctfb.memSize = info.screen_size;
40914f88c43SAnatolij Gustschin
41014f88c43SAnatolij Gustschin /* Cursor Start Address */
41114f88c43SAnatolij Gustschin ctfb.dprBase = 0;
41214f88c43SAnatolij Gustschin ctfb.vprBase = 0;
41314f88c43SAnatolij Gustschin ctfb.cprBase = 0;
41414f88c43SAnatolij Gustschin
41514f88c43SAnatolij Gustschin return &ctfb;
41614f88c43SAnatolij Gustschin }
417