114f88c43SAnatolij Gustschin /* 2ba8e76bdSTimur Tabi * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc. 3ba8e76bdSTimur Tabi * Authors: York Sun <yorksun@freescale.com> 4ba8e76bdSTimur Tabi * Timur Tabi <timur@freescale.com> 514f88c43SAnatolij Gustschin * 614f88c43SAnatolij Gustschin * FSL DIU Framebuffer driver 714f88c43SAnatolij Gustschin * 814f88c43SAnatolij Gustschin * See file CREDITS for list of people who contributed to this 914f88c43SAnatolij Gustschin * project. 1014f88c43SAnatolij Gustschin * 1114f88c43SAnatolij Gustschin * This program is free software; you can redistribute it and/or 1214f88c43SAnatolij Gustschin * modify it under the terms of the GNU General Public License as 1314f88c43SAnatolij Gustschin * published by the Free Software Foundation; either version 2 of 1414f88c43SAnatolij Gustschin * the License, or (at your option) any later version. 1514f88c43SAnatolij Gustschin * 1614f88c43SAnatolij Gustschin * This program is distributed in the hope that it will be useful, 1714f88c43SAnatolij Gustschin * but WITHOUT ANY WARRANTY; without even the implied warranty of 1814f88c43SAnatolij Gustschin * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1914f88c43SAnatolij Gustschin * GNU General Public License for more details. 2014f88c43SAnatolij Gustschin * 2114f88c43SAnatolij Gustschin * You should have received a copy of the GNU General Public License 2214f88c43SAnatolij Gustschin * along with this program; if not, write to the Free Software 2314f88c43SAnatolij Gustschin * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 2414f88c43SAnatolij Gustschin * MA 02111-1307 USA 2514f88c43SAnatolij Gustschin */ 2614f88c43SAnatolij Gustschin 2714f88c43SAnatolij Gustschin #include <common.h> 2814f88c43SAnatolij Gustschin #include <malloc.h> 2914f88c43SAnatolij Gustschin #include <asm/io.h> 3014f88c43SAnatolij Gustschin 31ba8e76bdSTimur Tabi #include "videomodes.h" 32ba8e76bdSTimur Tabi #include <video_fb.h> 3314f88c43SAnatolij Gustschin #include <fsl_diu_fb.h> 348c6b2504STimur Tabi #include <linux/list.h> 358c6b2504STimur Tabi #include <linux/fb.h> 3614f88c43SAnatolij Gustschin 3714f88c43SAnatolij Gustschin /* This setting is used for the ifm pdm360ng with PRIMEVIEW PM070WL3 */ 383b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_800_480 = { 393b4a2263STimur Tabi .name = "800x480-60", 4014f88c43SAnatolij Gustschin .refresh = 60, 4114f88c43SAnatolij Gustschin .xres = 800, 4214f88c43SAnatolij Gustschin .yres = 480, 4314f88c43SAnatolij Gustschin .pixclock = 31250, 4414f88c43SAnatolij Gustschin .left_margin = 86, 4514f88c43SAnatolij Gustschin .right_margin = 42, 4614f88c43SAnatolij Gustschin .upper_margin = 33, 4714f88c43SAnatolij Gustschin .lower_margin = 10, 4814f88c43SAnatolij Gustschin .hsync_len = 128, 4914f88c43SAnatolij Gustschin .vsync_len = 2, 5014f88c43SAnatolij Gustschin .sync = 0, 5114f88c43SAnatolij Gustschin .vmode = FB_VMODE_NONINTERLACED 5214f88c43SAnatolij Gustschin }; 5314f88c43SAnatolij Gustschin 543b4a2263STimur Tabi /* For the SHARP LQ084S3LG01, used on the P1022DS board */ 553b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_800_600 = { 563b4a2263STimur Tabi .name = "800x600-60", 573b4a2263STimur Tabi .refresh = 60, 583b4a2263STimur Tabi .xres = 800, 593b4a2263STimur Tabi .yres = 600, 603b4a2263STimur Tabi .pixclock = 25000, 613b4a2263STimur Tabi .left_margin = 88, 623b4a2263STimur Tabi .right_margin = 40, 633b4a2263STimur Tabi .upper_margin = 23, 643b4a2263STimur Tabi .lower_margin = 1, 653b4a2263STimur Tabi .hsync_len = 128, 663b4a2263STimur Tabi .vsync_len = 4, 673b4a2263STimur Tabi .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 683b4a2263STimur Tabi .vmode = FB_VMODE_NONINTERLACED 693b4a2263STimur Tabi }; 703b4a2263STimur Tabi 7114f88c43SAnatolij Gustschin /* 7214f88c43SAnatolij Gustschin * These parameters give default parameters 7314f88c43SAnatolij Gustschin * for video output 1024x768, 7414f88c43SAnatolij Gustschin * FIXME - change timing to proper amounts 7514f88c43SAnatolij Gustschin * hsync 31.5kHz, vsync 60Hz 7614f88c43SAnatolij Gustschin */ 773b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_1024_768 = { 78ba8e76bdSTimur Tabi .name = "1024x768-60", 7914f88c43SAnatolij Gustschin .refresh = 60, 8014f88c43SAnatolij Gustschin .xres = 1024, 8114f88c43SAnatolij Gustschin .yres = 768, 8214f88c43SAnatolij Gustschin .pixclock = 15385, 8314f88c43SAnatolij Gustschin .left_margin = 160, 8414f88c43SAnatolij Gustschin .right_margin = 24, 8514f88c43SAnatolij Gustschin .upper_margin = 29, 8614f88c43SAnatolij Gustschin .lower_margin = 3, 8714f88c43SAnatolij Gustschin .hsync_len = 136, 8814f88c43SAnatolij Gustschin .vsync_len = 6, 8914f88c43SAnatolij Gustschin .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 9014f88c43SAnatolij Gustschin .vmode = FB_VMODE_NONINTERLACED 9114f88c43SAnatolij Gustschin }; 9214f88c43SAnatolij Gustschin 933b4a2263STimur Tabi static struct fb_videomode fsl_diu_mode_1280_1024 = { 9414f88c43SAnatolij Gustschin .name = "1280x1024-60", 9514f88c43SAnatolij Gustschin .refresh = 60, 9614f88c43SAnatolij Gustschin .xres = 1280, 9714f88c43SAnatolij Gustschin .yres = 1024, 9814f88c43SAnatolij Gustschin .pixclock = 9375, 9914f88c43SAnatolij Gustschin .left_margin = 38, 10014f88c43SAnatolij Gustschin .right_margin = 128, 10114f88c43SAnatolij Gustschin .upper_margin = 2, 10214f88c43SAnatolij Gustschin .lower_margin = 7, 10314f88c43SAnatolij Gustschin .hsync_len = 216, 10414f88c43SAnatolij Gustschin .vsync_len = 37, 10514f88c43SAnatolij Gustschin .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 10614f88c43SAnatolij Gustschin .vmode = FB_VMODE_NONINTERLACED 10714f88c43SAnatolij Gustschin }; 10814f88c43SAnatolij Gustschin 109*debef5cdSJerry Huang static struct fb_videomode fsl_diu_mode_1280_720 = { 110*debef5cdSJerry Huang .name = "1280x720-60", 111*debef5cdSJerry Huang .refresh = 60, 112*debef5cdSJerry Huang .xres = 1280, 113*debef5cdSJerry Huang .yres = 720, 114*debef5cdSJerry Huang .pixclock = 13426, 115*debef5cdSJerry Huang .left_margin = 192, 116*debef5cdSJerry Huang .right_margin = 64, 117*debef5cdSJerry Huang .upper_margin = 22, 118*debef5cdSJerry Huang .lower_margin = 1, 119*debef5cdSJerry Huang .hsync_len = 136, 120*debef5cdSJerry Huang .vsync_len = 3, 121*debef5cdSJerry Huang .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 122*debef5cdSJerry Huang .vmode = FB_VMODE_NONINTERLACED 123*debef5cdSJerry Huang }; 124*debef5cdSJerry Huang 125*debef5cdSJerry Huang static struct fb_videomode fsl_diu_mode_1920_1080 = { 126*debef5cdSJerry Huang .name = "1920x1080-60", 127*debef5cdSJerry Huang .refresh = 60, 128*debef5cdSJerry Huang .xres = 1920, 129*debef5cdSJerry Huang .yres = 1080, 130*debef5cdSJerry Huang .pixclock = 5787, 131*debef5cdSJerry Huang .left_margin = 328, 132*debef5cdSJerry Huang .right_margin = 120, 133*debef5cdSJerry Huang .upper_margin = 34, 134*debef5cdSJerry Huang .lower_margin = 1, 135*debef5cdSJerry Huang .hsync_len = 208, 136*debef5cdSJerry Huang .vsync_len = 3, 137*debef5cdSJerry Huang .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 138*debef5cdSJerry Huang .vmode = FB_VMODE_NONINTERLACED 139*debef5cdSJerry Huang }; 140*debef5cdSJerry Huang 14114f88c43SAnatolij Gustschin /* 14214f88c43SAnatolij Gustschin * These are the fields of area descriptor(in DDR memory) for every plane 14314f88c43SAnatolij Gustschin */ 14414f88c43SAnatolij Gustschin struct diu_ad { 14514f88c43SAnatolij Gustschin /* Word 0(32-bit) in DDR memory */ 146ba8e76bdSTimur Tabi __le32 pix_fmt; /* hard coding pixel format */ 14714f88c43SAnatolij Gustschin /* Word 1(32-bit) in DDR memory */ 148ba8e76bdSTimur Tabi __le32 addr; 14914f88c43SAnatolij Gustschin /* Word 2(32-bit) in DDR memory */ 150ba8e76bdSTimur Tabi __le32 src_size_g_alpha; 15114f88c43SAnatolij Gustschin /* Word 3(32-bit) in DDR memory */ 152ba8e76bdSTimur Tabi __le32 aoi_size; 15314f88c43SAnatolij Gustschin /* Word 4(32-bit) in DDR memory */ 154ba8e76bdSTimur Tabi __le32 offset_xyi; 15514f88c43SAnatolij Gustschin /* Word 5(32-bit) in DDR memory */ 156ba8e76bdSTimur Tabi __le32 offset_xyd; 15714f88c43SAnatolij Gustschin /* Word 6(32-bit) in DDR memory */ 158ba8e76bdSTimur Tabi __le32 ckmax_r:8; 159ba8e76bdSTimur Tabi __le32 ckmax_g:8; 160ba8e76bdSTimur Tabi __le32 ckmax_b:8; 161ba8e76bdSTimur Tabi __le32 res9:8; 16214f88c43SAnatolij Gustschin /* Word 7(32-bit) in DDR memory */ 163ba8e76bdSTimur Tabi __le32 ckmin_r:8; 164ba8e76bdSTimur Tabi __le32 ckmin_g:8; 165ba8e76bdSTimur Tabi __le32 ckmin_b:8; 166ba8e76bdSTimur Tabi __le32 res10:8; 16714f88c43SAnatolij Gustschin /* Word 8(32-bit) in DDR memory */ 168ba8e76bdSTimur Tabi __le32 next_ad; 16914f88c43SAnatolij Gustschin /* Word 9(32-bit) in DDR memory, just for 64-bit aligned */ 170ba8e76bdSTimur Tabi __le32 res[3]; 17114f88c43SAnatolij Gustschin } __attribute__ ((packed)); 17214f88c43SAnatolij Gustschin 17314f88c43SAnatolij Gustschin /* 17414f88c43SAnatolij Gustschin * DIU register map 17514f88c43SAnatolij Gustschin */ 17614f88c43SAnatolij Gustschin struct diu { 177ba8e76bdSTimur Tabi __be32 desc[3]; 178ba8e76bdSTimur Tabi __be32 gamma; 179ba8e76bdSTimur Tabi __be32 pallete; 180ba8e76bdSTimur Tabi __be32 cursor; 181ba8e76bdSTimur Tabi __be32 curs_pos; 182ba8e76bdSTimur Tabi __be32 diu_mode; 183ba8e76bdSTimur Tabi __be32 bgnd; 184ba8e76bdSTimur Tabi __be32 bgnd_wb; 185ba8e76bdSTimur Tabi __be32 disp_size; 186ba8e76bdSTimur Tabi __be32 wb_size; 187ba8e76bdSTimur Tabi __be32 wb_mem_addr; 188ba8e76bdSTimur Tabi __be32 hsyn_para; 189ba8e76bdSTimur Tabi __be32 vsyn_para; 190ba8e76bdSTimur Tabi __be32 syn_pol; 191ba8e76bdSTimur Tabi __be32 thresholds; 192ba8e76bdSTimur Tabi __be32 int_status; 193ba8e76bdSTimur Tabi __be32 int_mask; 194ba8e76bdSTimur Tabi __be32 colorbar[8]; 195ba8e76bdSTimur Tabi __be32 filling; 196ba8e76bdSTimur Tabi __be32 plut; 19714f88c43SAnatolij Gustschin } __attribute__ ((packed)); 19814f88c43SAnatolij Gustschin 199ba8e76bdSTimur Tabi struct diu_addr { 200ba8e76bdSTimur Tabi void *vaddr; /* Virtual address */ 201ba8e76bdSTimur Tabi u32 paddr; /* 32-bit physical address */ 202ba8e76bdSTimur Tabi unsigned int offset; /* Alignment offset */ 20314f88c43SAnatolij Gustschin }; 20414f88c43SAnatolij Gustschin 205ba8e76bdSTimur Tabi static struct fb_info info; 20614f88c43SAnatolij Gustschin 20714f88c43SAnatolij Gustschin /* 208ba8e76bdSTimur Tabi * Align to 64-bit(8-byte), 32-byte, etc. 20914f88c43SAnatolij Gustschin */ 210ba8e76bdSTimur Tabi static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align) 211ba8e76bdSTimur Tabi { 212ba8e76bdSTimur Tabi u32 offset, ssize; 213ba8e76bdSTimur Tabi u32 mask; 21414f88c43SAnatolij Gustschin 215ba8e76bdSTimur Tabi ssize = size + bytes_align; 216ba8e76bdSTimur Tabi buf->vaddr = malloc(ssize); 217ba8e76bdSTimur Tabi if (!buf->vaddr) 218ba8e76bdSTimur Tabi return -1; 21914f88c43SAnatolij Gustschin 220ba8e76bdSTimur Tabi memset(buf->vaddr, 0, ssize); 221ba8e76bdSTimur Tabi mask = bytes_align - 1; 222ba8e76bdSTimur Tabi offset = (u32)buf->vaddr & mask; 223ba8e76bdSTimur Tabi if (offset) { 224ba8e76bdSTimur Tabi buf->offset = bytes_align - offset; 225ba8e76bdSTimur Tabi buf->vaddr += offset; 226ba8e76bdSTimur Tabi } else 227ba8e76bdSTimur Tabi buf->offset = 0; 22814f88c43SAnatolij Gustschin 229ba8e76bdSTimur Tabi buf->paddr = virt_to_phys(buf->vaddr); 230ba8e76bdSTimur Tabi return 0; 231ba8e76bdSTimur Tabi } 23214f88c43SAnatolij Gustschin 233ba8e76bdSTimur Tabi /* 234ba8e76bdSTimur Tabi * Allocate a framebuffer and an Area Descriptor that points to it. Both 235ba8e76bdSTimur Tabi * are created in the same memory block. The Area Descriptor is updated to 236ba8e76bdSTimur Tabi * point to the framebuffer memory. Memory is aligned as needed. 237ba8e76bdSTimur Tabi */ 238ba8e76bdSTimur Tabi static struct diu_ad *allocate_fb(unsigned int xres, unsigned int yres, 2398c6b2504STimur Tabi unsigned int depth, char **fb) 240ba8e76bdSTimur Tabi { 241ba8e76bdSTimur Tabi unsigned long size = xres * yres * depth; 242ba8e76bdSTimur Tabi struct diu_addr addr; 243ba8e76bdSTimur Tabi struct diu_ad *ad; 244ba8e76bdSTimur Tabi size_t ad_size = roundup(sizeof(struct diu_ad), 32); 24514f88c43SAnatolij Gustschin 246ba8e76bdSTimur Tabi /* 247ba8e76bdSTimur Tabi * Allocate a memory block that holds the Area Descriptor and the 248ba8e76bdSTimur Tabi * frame buffer right behind it. To keep the code simple, everything 249ba8e76bdSTimur Tabi * is aligned on a 32-byte address. 250ba8e76bdSTimur Tabi */ 251ba8e76bdSTimur Tabi if (allocate_buf(&addr, ad_size + size, 32) < 0) 252ba8e76bdSTimur Tabi return NULL; 253ba8e76bdSTimur Tabi 254ba8e76bdSTimur Tabi ad = addr.vaddr; 255ba8e76bdSTimur Tabi ad->addr = cpu_to_le32(addr.paddr + ad_size); 256ba8e76bdSTimur Tabi ad->aoi_size = cpu_to_le32((yres << 16) | xres); 257ba8e76bdSTimur Tabi ad->src_size_g_alpha = cpu_to_le32((yres << 12) | xres); 258ba8e76bdSTimur Tabi ad->offset_xyi = 0; 259ba8e76bdSTimur Tabi ad->offset_xyd = 0; 260ba8e76bdSTimur Tabi 261ba8e76bdSTimur Tabi if (fb) 262ba8e76bdSTimur Tabi *fb = addr.vaddr + ad_size; 263ba8e76bdSTimur Tabi 264ba8e76bdSTimur Tabi return ad; 265ba8e76bdSTimur Tabi } 266ba8e76bdSTimur Tabi 2673b4a2263STimur Tabi int fsl_diu_init(u16 xres, u16 yres, u32 pixel_format, int gamma_fix) 26814f88c43SAnatolij Gustschin { 26914f88c43SAnatolij Gustschin struct fb_videomode *fsl_diu_mode_db; 270ba8e76bdSTimur Tabi struct diu_ad *ad; 271ba8e76bdSTimur Tabi struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR; 272ba8e76bdSTimur Tabi u8 *gamma_table_base; 27314f88c43SAnatolij Gustschin unsigned int i, j; 274ba8e76bdSTimur Tabi struct diu_ad *dummy_ad; 275ba8e76bdSTimur Tabi struct diu_addr gamma; 276ba8e76bdSTimur Tabi struct diu_addr cursor; 27714f88c43SAnatolij Gustschin 2783b4a2263STimur Tabi /* Convert the X,Y resolution pair into a single number */ 2793b4a2263STimur Tabi #define RESOLUTION(x, y) (((u32)(x) << 16) | (y)) 2803b4a2263STimur Tabi 2813b4a2263STimur Tabi switch (RESOLUTION(xres, yres)) { 2823b4a2263STimur Tabi case RESOLUTION(800, 480): 2833b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_800_480; 28414f88c43SAnatolij Gustschin break; 2853b4a2263STimur Tabi case RESOLUTION(800, 600): 2863b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_800_600; 28715006cb7SJerry Huang break; 2883b4a2263STimur Tabi case RESOLUTION(1024, 768): 2893b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_1024_768; 29015006cb7SJerry Huang break; 2913b4a2263STimur Tabi case RESOLUTION(1280, 1024): 2923b4a2263STimur Tabi fsl_diu_mode_db = &fsl_diu_mode_1280_1024; 29314f88c43SAnatolij Gustschin break; 294*debef5cdSJerry Huang case RESOLUTION(1280, 720): 295*debef5cdSJerry Huang fsl_diu_mode_db = &fsl_diu_mode_1280_720; 296*debef5cdSJerry Huang break; 297*debef5cdSJerry Huang case RESOLUTION(1920, 1080): 298*debef5cdSJerry Huang fsl_diu_mode_db = &fsl_diu_mode_1920_1080; 299*debef5cdSJerry Huang break; 30014f88c43SAnatolij Gustschin default: 3013b4a2263STimur Tabi printf("DIU: Unsupported resolution %ux%u\n", xres, yres); 3023b4a2263STimur Tabi return -1; 30314f88c43SAnatolij Gustschin } 30414f88c43SAnatolij Gustschin 305ba8e76bdSTimur Tabi /* The AD struct for the dummy framebuffer and the FB itself */ 306ba8e76bdSTimur Tabi dummy_ad = allocate_fb(2, 4, 4, NULL); 307ba8e76bdSTimur Tabi if (!dummy_ad) { 308ba8e76bdSTimur Tabi printf("DIU: Out of memory\n"); 30914f88c43SAnatolij Gustschin return -1; 31014f88c43SAnatolij Gustschin } 311ba8e76bdSTimur Tabi dummy_ad->pix_fmt = 0x88883316; 31214f88c43SAnatolij Gustschin 31314f88c43SAnatolij Gustschin /* read mode info */ 314ba8e76bdSTimur Tabi info.var.xres = fsl_diu_mode_db->xres; 315ba8e76bdSTimur Tabi info.var.yres = fsl_diu_mode_db->yres; 316ba8e76bdSTimur Tabi info.var.bits_per_pixel = 32; 317ba8e76bdSTimur Tabi info.var.pixclock = fsl_diu_mode_db->pixclock; 318ba8e76bdSTimur Tabi info.var.left_margin = fsl_diu_mode_db->left_margin; 319ba8e76bdSTimur Tabi info.var.right_margin = fsl_diu_mode_db->right_margin; 320ba8e76bdSTimur Tabi info.var.upper_margin = fsl_diu_mode_db->upper_margin; 321ba8e76bdSTimur Tabi info.var.lower_margin = fsl_diu_mode_db->lower_margin; 322ba8e76bdSTimur Tabi info.var.hsync_len = fsl_diu_mode_db->hsync_len; 323ba8e76bdSTimur Tabi info.var.vsync_len = fsl_diu_mode_db->vsync_len; 324ba8e76bdSTimur Tabi info.var.sync = fsl_diu_mode_db->sync; 325ba8e76bdSTimur Tabi info.var.vmode = fsl_diu_mode_db->vmode; 3268c6b2504STimur Tabi info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8; 327ba8e76bdSTimur Tabi 328ba8e76bdSTimur Tabi /* Memory allocation for framebuffer */ 3298c6b2504STimur Tabi info.screen_size = 330ba8e76bdSTimur Tabi info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8); 331ba8e76bdSTimur Tabi ad = allocate_fb(info.var.xres, info.var.yres, 332ba8e76bdSTimur Tabi info.var.bits_per_pixel / 8, &info.screen_base); 333ba8e76bdSTimur Tabi if (!ad) { 334ba8e76bdSTimur Tabi printf("DIU: Out of memory\n"); 335ba8e76bdSTimur Tabi return -1; 336ba8e76bdSTimur Tabi } 33714f88c43SAnatolij Gustschin 33814f88c43SAnatolij Gustschin ad->pix_fmt = pixel_format; 33914f88c43SAnatolij Gustschin 34014f88c43SAnatolij Gustschin /* Disable chroma keying function */ 34114f88c43SAnatolij Gustschin ad->ckmax_r = 0; 34214f88c43SAnatolij Gustschin ad->ckmax_g = 0; 34314f88c43SAnatolij Gustschin ad->ckmax_b = 0; 34414f88c43SAnatolij Gustschin 34514f88c43SAnatolij Gustschin ad->ckmin_r = 255; 34614f88c43SAnatolij Gustschin ad->ckmin_g = 255; 34714f88c43SAnatolij Gustschin ad->ckmin_b = 255; 34814f88c43SAnatolij Gustschin 349ba8e76bdSTimur Tabi /* Initialize the gamma table */ 350ba8e76bdSTimur Tabi if (allocate_buf(&gamma, 256 * 3, 32) < 0) { 351ba8e76bdSTimur Tabi printf("DIU: Out of memory\n"); 352ba8e76bdSTimur Tabi return -1; 353ba8e76bdSTimur Tabi } 354ba8e76bdSTimur Tabi gamma_table_base = gamma.vaddr; 35514f88c43SAnatolij Gustschin for (i = 0; i <= 2; i++) 356ba8e76bdSTimur Tabi for (j = 0; j < 256; j++) 35714f88c43SAnatolij Gustschin *gamma_table_base++ = j; 35814f88c43SAnatolij Gustschin 35914f88c43SAnatolij Gustschin if (gamma_fix == 1) { /* fix the gamma */ 360ba8e76bdSTimur Tabi gamma_table_base = gamma.vaddr; 36114f88c43SAnatolij Gustschin for (i = 0; i < 256 * 3; i++) { 36214f88c43SAnatolij Gustschin gamma_table_base[i] = (gamma_table_base[i] << 2) 36314f88c43SAnatolij Gustschin | ((gamma_table_base[i] >> 6) & 0x03); 36414f88c43SAnatolij Gustschin } 36514f88c43SAnatolij Gustschin } 36614f88c43SAnatolij Gustschin 367ba8e76bdSTimur Tabi /* Initialize the cursor */ 368ba8e76bdSTimur Tabi if (allocate_buf(&cursor, 32 * 32 * 2, 32) < 0) { 369ba8e76bdSTimur Tabi printf("DIU: Can't alloc cursor data\n"); 370ba8e76bdSTimur Tabi return -1; 371ba8e76bdSTimur Tabi } 37214f88c43SAnatolij Gustschin 37314f88c43SAnatolij Gustschin /* Program DIU registers */ 374ba8e76bdSTimur Tabi out_be32(&hw->diu_mode, 0); /* Temporarily disable the DIU */ 37514f88c43SAnatolij Gustschin 376ba8e76bdSTimur Tabi out_be32(&hw->gamma, gamma.paddr); 377ba8e76bdSTimur Tabi out_be32(&hw->cursor, cursor.paddr); 37814f88c43SAnatolij Gustschin out_be32(&hw->bgnd, 0x007F7F7F); 379ba8e76bdSTimur Tabi out_be32(&hw->bgnd_wb, 0); 380ba8e76bdSTimur Tabi out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres); 381ba8e76bdSTimur Tabi out_be32(&hw->wb_size, 0); 382ba8e76bdSTimur Tabi out_be32(&hw->wb_mem_addr, 0); 383ba8e76bdSTimur Tabi out_be32(&hw->hsyn_para, info.var.left_margin << 22 | 384ba8e76bdSTimur Tabi info.var.hsync_len << 11 | 385ba8e76bdSTimur Tabi info.var.right_margin); 38614f88c43SAnatolij Gustschin 387ba8e76bdSTimur Tabi out_be32(&hw->vsyn_para, info.var.upper_margin << 22 | 388ba8e76bdSTimur Tabi info.var.vsync_len << 11 | 389ba8e76bdSTimur Tabi info.var.lower_margin); 39014f88c43SAnatolij Gustschin 391ba8e76bdSTimur Tabi out_be32(&hw->syn_pol, 0); 392ba8e76bdSTimur Tabi out_be32(&hw->thresholds, 0x00037800); 393ba8e76bdSTimur Tabi out_be32(&hw->int_status, 0); 394ba8e76bdSTimur Tabi out_be32(&hw->int_mask, 0); 39514f88c43SAnatolij Gustschin out_be32(&hw->plut, 0x01F5F666); 39614f88c43SAnatolij Gustschin /* Pixel Clock configuration */ 397ba8e76bdSTimur Tabi diu_set_pixel_clock(info.var.pixclock); 39814f88c43SAnatolij Gustschin 399ba8e76bdSTimur Tabi /* Set the frame buffers */ 400ba8e76bdSTimur Tabi out_be32(&hw->desc[0], virt_to_phys(ad)); 401ba8e76bdSTimur Tabi out_be32(&hw->desc[1], virt_to_phys(dummy_ad)); 402ba8e76bdSTimur Tabi out_be32(&hw->desc[2], virt_to_phys(dummy_ad)); 40314f88c43SAnatolij Gustschin 404ba8e76bdSTimur Tabi /* Enable the DIU, set display to all three planes */ 405ba8e76bdSTimur Tabi out_be32(&hw->diu_mode, 1); 40614f88c43SAnatolij Gustschin 40714f88c43SAnatolij Gustschin return 0; 40814f88c43SAnatolij Gustschin } 40914f88c43SAnatolij Gustschin 41014f88c43SAnatolij Gustschin void *video_hw_init(void) 41114f88c43SAnatolij Gustschin { 412ba8e76bdSTimur Tabi static GraphicDevice ctfb; 413ba8e76bdSTimur Tabi const char *options; 414ba8e76bdSTimur Tabi unsigned int depth = 0, freq = 0; 41514f88c43SAnatolij Gustschin 416ba8e76bdSTimur Tabi if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq, 417ba8e76bdSTimur Tabi &options)) 418ba8e76bdSTimur Tabi return NULL; 419ba8e76bdSTimur Tabi 420ba8e76bdSTimur Tabi /* Find the monitor port, which is a required option */ 421ba8e76bdSTimur Tabi if (!options) 422ba8e76bdSTimur Tabi return NULL; 423ba8e76bdSTimur Tabi if (strncmp(options, "monitor=", 8) != 0) 424ba8e76bdSTimur Tabi return NULL; 425ba8e76bdSTimur Tabi 426ba8e76bdSTimur Tabi if (platform_diu_init(ctfb.winSizeX, ctfb.winSizeY, options + 8) < 0) 42714f88c43SAnatolij Gustschin return NULL; 42814f88c43SAnatolij Gustschin 42914f88c43SAnatolij Gustschin /* fill in Graphic device struct */ 43014f88c43SAnatolij Gustschin sprintf(ctfb.modeIdent, "%ix%ix%i %ikHz %iHz", 431ba8e76bdSTimur Tabi ctfb.winSizeX, ctfb.winSizeY, depth, 64, freq); 43214f88c43SAnatolij Gustschin 433ba8e76bdSTimur Tabi ctfb.frameAdrs = (unsigned int)info.screen_base; 43414f88c43SAnatolij Gustschin ctfb.plnSizeX = ctfb.winSizeX; 43514f88c43SAnatolij Gustschin ctfb.plnSizeY = ctfb.winSizeY; 43614f88c43SAnatolij Gustschin 43714f88c43SAnatolij Gustschin ctfb.gdfBytesPP = 4; 43814f88c43SAnatolij Gustschin ctfb.gdfIndex = GDF_32BIT_X888RGB; 43914f88c43SAnatolij Gustschin 44014f88c43SAnatolij Gustschin ctfb.isaBase = 0; 44114f88c43SAnatolij Gustschin ctfb.pciBase = 0; 442ba8e76bdSTimur Tabi ctfb.memSize = info.screen_size; 44314f88c43SAnatolij Gustschin 44414f88c43SAnatolij Gustschin /* Cursor Start Address */ 44514f88c43SAnatolij Gustschin ctfb.dprBase = 0; 44614f88c43SAnatolij Gustschin ctfb.vprBase = 0; 44714f88c43SAnatolij Gustschin ctfb.cprBase = 0; 44814f88c43SAnatolij Gustschin 44914f88c43SAnatolij Gustschin return &ctfb; 45014f88c43SAnatolij Gustschin } 451