1327def50SWang Huan /* 2327def50SWang Huan * Copyright 2014 Freescale Semiconductor, Inc. 3327def50SWang Huan * 4327def50SWang Huan * FSL DCU Framebuffer driver 5327def50SWang Huan * 6327def50SWang Huan * SPDX-License-Identifier: GPL-2.0+ 7327def50SWang Huan */ 8327def50SWang Huan 9327def50SWang Huan #include <asm/io.h> 10327def50SWang Huan #include <common.h> 11*77810e63SStefan Agner #include <fdt_support.h> 12327def50SWang Huan #include <fsl_dcu_fb.h> 13327def50SWang Huan #include <linux/fb.h> 14327def50SWang Huan #include <malloc.h> 15327def50SWang Huan #include <video_fb.h> 16327def50SWang Huan #include "videomodes.h" 17327def50SWang Huan 18327def50SWang Huan /* Convert the X,Y resolution pair into a single number */ 19327def50SWang Huan #define RESOLUTION(x, y) (((u32)(x) << 16) | (y)) 20327def50SWang Huan 21327def50SWang Huan #ifdef CONFIG_SYS_FSL_DCU_LE 22327def50SWang Huan #define dcu_read32 in_le32 23327def50SWang Huan #define dcu_write32 out_le32 24327def50SWang Huan #elif defined(CONFIG_SYS_FSL_DCU_BE) 25327def50SWang Huan #define dcu_read32 in_be32 26327def50SWang Huan #define dcu_write32 out_be32 27327def50SWang Huan #endif 28327def50SWang Huan 29327def50SWang Huan #define DCU_MODE_BLEND_ITER(x) ((x) << 20) 30327def50SWang Huan #define DCU_MODE_RASTER_EN (1 << 14) 31327def50SWang Huan #define DCU_MODE_NORMAL 1 32327def50SWang Huan #define DCU_MODE_COLORBAR 3 33327def50SWang Huan #define DCU_BGND_R(x) ((x) << 16) 34327def50SWang Huan #define DCU_BGND_G(x) ((x) << 8) 35327def50SWang Huan #define DCU_BGND_B(x) (x) 36327def50SWang Huan #define DCU_DISP_SIZE_DELTA_Y(x) ((x) << 16) 37327def50SWang Huan #define DCU_DISP_SIZE_DELTA_X(x) (x) 38327def50SWang Huan #define DCU_HSYN_PARA_BP(x) ((x) << 22) 39327def50SWang Huan #define DCU_HSYN_PARA_PW(x) ((x) << 11) 40327def50SWang Huan #define DCU_HSYN_PARA_FP(x) (x) 41327def50SWang Huan #define DCU_VSYN_PARA_BP(x) ((x) << 22) 42327def50SWang Huan #define DCU_VSYN_PARA_PW(x) ((x) << 11) 43327def50SWang Huan #define DCU_VSYN_PARA_FP(x) (x) 44327def50SWang Huan #define DCU_SYN_POL_INV_PXCK_FALL (0 << 6) 45327def50SWang Huan #define DCU_SYN_POL_NEG_REMAIN (0 << 5) 46327def50SWang Huan #define DCU_SYN_POL_INV_VS_LOW (1 << 1) 47327def50SWang Huan #define DCU_SYN_POL_INV_HS_LOW (1) 48327def50SWang Huan #define DCU_THRESHOLD_LS_BF_VS(x) ((x) << 16) 49327def50SWang Huan #define DCU_THRESHOLD_OUT_BUF_HIGH(x) ((x) << 8) 50327def50SWang Huan #define DCU_THRESHOLD_OUT_BUF_LOW(x) (x) 51327def50SWang Huan #define DCU_UPDATE_MODE_MODE (1 << 31) 52327def50SWang Huan #define DCU_UPDATE_MODE_READREG (1 << 30) 53327def50SWang Huan 54327def50SWang Huan #define DCU_CTRLDESCLN_1_HEIGHT(x) ((x) << 16) 55327def50SWang Huan #define DCU_CTRLDESCLN_1_WIDTH(x) (x) 56327def50SWang Huan #define DCU_CTRLDESCLN_2_POSY(x) ((x) << 16) 57327def50SWang Huan #define DCU_CTRLDESCLN_2_POSX(x) (x) 58327def50SWang Huan #define DCU_CTRLDESCLN_4_EN (1 << 31) 59327def50SWang Huan #define DCU_CTRLDESCLN_4_TILE_EN (1 << 30) 60327def50SWang Huan #define DCU_CTRLDESCLN_4_DATA_SEL_CLUT (1 << 29) 61327def50SWang Huan #define DCU_CTRLDESCLN_4_SAFETY_EN (1 << 28) 62327def50SWang Huan #define DCU_CTRLDESCLN_4_TRANS(x) ((x) << 20) 63327def50SWang Huan #define DCU_CTRLDESCLN_4_BPP(x) ((x) << 16) 64327def50SWang Huan #define DCU_CTRLDESCLN_4_RLE_EN (1 << 15) 65327def50SWang Huan #define DCU_CTRLDESCLN_4_LUOFFS(x) ((x) << 4) 66327def50SWang Huan #define DCU_CTRLDESCLN_4_BB_ON (1 << 2) 67327def50SWang Huan #define DCU_CTRLDESCLN_4_AB(x) (x) 68327def50SWang Huan #define DCU_CTRLDESCLN_5_CKMAX_R(x) ((x) << 16) 69327def50SWang Huan #define DCU_CTRLDESCLN_5_CKMAX_G(x) ((x) << 8) 70327def50SWang Huan #define DCU_CTRLDESCLN_5_CKMAX_B(x) (x) 71327def50SWang Huan #define DCU_CTRLDESCLN_6_CKMIN_R(x) ((x) << 16) 72327def50SWang Huan #define DCU_CTRLDESCLN_6_CKMIN_G(x) ((x) << 8) 73327def50SWang Huan #define DCU_CTRLDESCLN_6_CKMIN_B(x) (x) 74327def50SWang Huan #define DCU_CTRLDESCLN_7_TILE_VER(x) ((x) << 16) 75327def50SWang Huan #define DCU_CTRLDESCLN_7_TILE_HOR(x) (x) 76327def50SWang Huan #define DCU_CTRLDESCLN_8_FG_FCOLOR(x) (x) 77327def50SWang Huan #define DCU_CTRLDESCLN_9_BG_BCOLOR(x) (x) 78327def50SWang Huan 79327def50SWang Huan #define BPP_16_RGB565 4 80327def50SWang Huan #define BPP_24_RGB888 5 81327def50SWang Huan #define BPP_32_ARGB8888 6 82327def50SWang Huan 83*77810e63SStefan Agner DECLARE_GLOBAL_DATA_PTR; 84*77810e63SStefan Agner 85327def50SWang Huan /* 86327def50SWang Huan * This setting is used for the TWR_LCD_RGB card 87327def50SWang Huan */ 88327def50SWang Huan static struct fb_videomode fsl_dcu_mode_480_272 = { 89327def50SWang Huan .name = "480x272-60", 90327def50SWang Huan .refresh = 60, 91327def50SWang Huan .xres = 480, 92327def50SWang Huan .yres = 272, 93327def50SWang Huan .pixclock = 91996, 94327def50SWang Huan .left_margin = 2, 95327def50SWang Huan .right_margin = 2, 96327def50SWang Huan .upper_margin = 1, 97327def50SWang Huan .lower_margin = 1, 98327def50SWang Huan .hsync_len = 41, 99327def50SWang Huan .vsync_len = 2, 100327def50SWang Huan .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 101327def50SWang Huan .vmode = FB_VMODE_NONINTERLACED 102327def50SWang Huan }; 103327def50SWang Huan 104327def50SWang Huan /* 105327def50SWang Huan * This setting is used for Siliconimage SiI9022A HDMI 106327def50SWang Huan */ 107327def50SWang Huan static struct fb_videomode fsl_dcu_mode_640_480 = { 108327def50SWang Huan .name = "640x480-60", 109327def50SWang Huan .refresh = 60, 110327def50SWang Huan .xres = 640, 111327def50SWang Huan .yres = 480, 112327def50SWang Huan .pixclock = 39722, 113327def50SWang Huan .left_margin = 48, 114327def50SWang Huan .right_margin = 16, 115327def50SWang Huan .upper_margin = 33, 116327def50SWang Huan .lower_margin = 10, 117327def50SWang Huan .hsync_len = 96, 118327def50SWang Huan .vsync_len = 2, 119327def50SWang Huan .sync = 0, 120327def50SWang Huan .vmode = FB_VMODE_NONINTERLACED, 121327def50SWang Huan }; 122327def50SWang Huan 123327def50SWang Huan /* 124327def50SWang Huan * DCU register map 125327def50SWang Huan */ 126327def50SWang Huan struct dcu_reg { 127327def50SWang Huan u32 desc_cursor[4]; 128327def50SWang Huan u32 mode; 129327def50SWang Huan u32 bgnd; 130327def50SWang Huan u32 disp_size; 131327def50SWang Huan u32 hsyn_para; 132327def50SWang Huan u32 vsyn_para; 133327def50SWang Huan u32 synpol; 134327def50SWang Huan u32 threshold; 135327def50SWang Huan u32 int_status; 136327def50SWang Huan u32 int_mask; 137327def50SWang Huan u32 colbar[8]; 138327def50SWang Huan u32 div_ratio; 139327def50SWang Huan u32 sign_calc[2]; 140327def50SWang Huan u32 crc_val; 141327def50SWang Huan u8 res_064[0x6c-0x64]; 142327def50SWang Huan u32 parr_err_status1; 143327def50SWang Huan u8 res_070[0x7c-0x70]; 144327def50SWang Huan u32 parr_err_status3; 145327def50SWang Huan u32 mparr_err_status1; 146327def50SWang Huan u8 res_084[0x90-0x84]; 147327def50SWang Huan u32 mparr_err_status3; 148327def50SWang Huan u32 threshold_inp_buf[2]; 149327def50SWang Huan u8 res_09c[0xa0-0x9c]; 150327def50SWang Huan u32 luma_comp; 151327def50SWang Huan u32 chroma_red; 152327def50SWang Huan u32 chroma_green; 153327def50SWang Huan u32 chroma_blue; 154327def50SWang Huan u32 crc_pos; 155327def50SWang Huan u32 lyr_intpol_en; 156327def50SWang Huan u32 lyr_luma_comp; 157327def50SWang Huan u32 lyr_chrm_red; 158327def50SWang Huan u32 lyr_chrm_grn; 159327def50SWang Huan u32 lyr_chrm_blue; 160327def50SWang Huan u8 res_0c4[0xcc-0xc8]; 161327def50SWang Huan u32 update_mode; 162327def50SWang Huan u32 underrun; 163327def50SWang Huan u8 res_0d4[0x100-0xd4]; 164327def50SWang Huan u32 gpr; 165327def50SWang Huan u32 slr_l[2]; 166327def50SWang Huan u32 slr_disp_size; 167327def50SWang Huan u32 slr_hvsync_para; 168327def50SWang Huan u32 slr_pol; 169327def50SWang Huan u32 slr_l_transp[2]; 170327def50SWang Huan u8 res_120[0x200-0x120]; 171327def50SWang Huan u32 ctrldescl[DCU_LAYER_MAX_NUM][16]; 172327def50SWang Huan }; 173327def50SWang Huan 174327def50SWang Huan static struct fb_info info; 175327def50SWang Huan 176327def50SWang Huan static void reset_total_layers(void) 177327def50SWang Huan { 178327def50SWang Huan struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR; 179327def50SWang Huan int i; 180327def50SWang Huan 181327def50SWang Huan for (i = 0; i < DCU_LAYER_MAX_NUM; i++) { 182327def50SWang Huan dcu_write32(®s->ctrldescl[i][0], 0); 183327def50SWang Huan dcu_write32(®s->ctrldescl[i][1], 0); 184327def50SWang Huan dcu_write32(®s->ctrldescl[i][2], 0); 185327def50SWang Huan dcu_write32(®s->ctrldescl[i][3], 0); 186327def50SWang Huan dcu_write32(®s->ctrldescl[i][4], 0); 187327def50SWang Huan dcu_write32(®s->ctrldescl[i][5], 0); 188327def50SWang Huan dcu_write32(®s->ctrldescl[i][6], 0); 189327def50SWang Huan dcu_write32(®s->ctrldescl[i][7], 0); 190327def50SWang Huan dcu_write32(®s->ctrldescl[i][8], 0); 191327def50SWang Huan dcu_write32(®s->ctrldescl[i][9], 0); 192327def50SWang Huan dcu_write32(®s->ctrldescl[i][10], 0); 193327def50SWang Huan } 194327def50SWang Huan 195327def50SWang Huan dcu_write32(®s->update_mode, DCU_UPDATE_MODE_READREG); 196327def50SWang Huan } 197327def50SWang Huan 198327def50SWang Huan static int layer_ctrldesc_init(int index, u32 pixel_format) 199327def50SWang Huan { 200327def50SWang Huan struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR; 201327def50SWang Huan unsigned int bpp = BPP_24_RGB888; 202327def50SWang Huan 203327def50SWang Huan dcu_write32(®s->ctrldescl[index][0], 204327def50SWang Huan DCU_CTRLDESCLN_1_HEIGHT(info.var.yres) | 205327def50SWang Huan DCU_CTRLDESCLN_1_WIDTH(info.var.xres)); 206327def50SWang Huan 207327def50SWang Huan dcu_write32(®s->ctrldescl[index][1], 208327def50SWang Huan DCU_CTRLDESCLN_2_POSY(0) | 209327def50SWang Huan DCU_CTRLDESCLN_2_POSX(0)); 210327def50SWang Huan 211327def50SWang Huan dcu_write32(®s->ctrldescl[index][2], (unsigned int)info.screen_base); 212327def50SWang Huan 213327def50SWang Huan switch (pixel_format) { 214327def50SWang Huan case 16: 215327def50SWang Huan bpp = BPP_16_RGB565; 216327def50SWang Huan break; 217327def50SWang Huan case 24: 218327def50SWang Huan bpp = BPP_24_RGB888; 219327def50SWang Huan break; 220327def50SWang Huan case 32: 221327def50SWang Huan bpp = BPP_32_ARGB8888; 222327def50SWang Huan break; 223327def50SWang Huan default: 224327def50SWang Huan printf("unsupported color depth: %u\n", pixel_format); 225327def50SWang Huan } 226327def50SWang Huan 227327def50SWang Huan dcu_write32(®s->ctrldescl[index][3], 228327def50SWang Huan DCU_CTRLDESCLN_4_EN | 229327def50SWang Huan DCU_CTRLDESCLN_4_TRANS(0xff) | 230327def50SWang Huan DCU_CTRLDESCLN_4_BPP(bpp) | 231327def50SWang Huan DCU_CTRLDESCLN_4_AB(0)); 232327def50SWang Huan 233327def50SWang Huan dcu_write32(®s->ctrldescl[index][4], 234327def50SWang Huan DCU_CTRLDESCLN_5_CKMAX_R(0xff) | 235327def50SWang Huan DCU_CTRLDESCLN_5_CKMAX_G(0xff) | 236327def50SWang Huan DCU_CTRLDESCLN_5_CKMAX_B(0xff)); 237327def50SWang Huan dcu_write32(®s->ctrldescl[index][5], 238327def50SWang Huan DCU_CTRLDESCLN_6_CKMIN_R(0) | 239327def50SWang Huan DCU_CTRLDESCLN_6_CKMIN_G(0) | 240327def50SWang Huan DCU_CTRLDESCLN_6_CKMIN_B(0)); 241327def50SWang Huan 242327def50SWang Huan dcu_write32(®s->ctrldescl[index][6], 243327def50SWang Huan DCU_CTRLDESCLN_7_TILE_VER(0) | 244327def50SWang Huan DCU_CTRLDESCLN_7_TILE_HOR(0)); 245327def50SWang Huan 246327def50SWang Huan dcu_write32(®s->ctrldescl[index][7], DCU_CTRLDESCLN_8_FG_FCOLOR(0)); 247327def50SWang Huan dcu_write32(®s->ctrldescl[index][8], DCU_CTRLDESCLN_9_BG_BCOLOR(0)); 248327def50SWang Huan 249327def50SWang Huan dcu_write32(®s->update_mode, DCU_UPDATE_MODE_READREG); 250327def50SWang Huan 251327def50SWang Huan return 0; 252327def50SWang Huan } 253327def50SWang Huan 254327def50SWang Huan int fsl_dcu_init(unsigned int xres, unsigned int yres, 255327def50SWang Huan unsigned int pixel_format) 256327def50SWang Huan { 257327def50SWang Huan struct dcu_reg *regs = (struct dcu_reg *)CONFIG_SYS_DCU_ADDR; 258327def50SWang Huan unsigned int div, mode; 259327def50SWang Huan 260327def50SWang Huan info.screen_size = 261327def50SWang Huan info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8); 262*77810e63SStefan Agner 263*77810e63SStefan Agner if (info.screen_size > CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB) { 264*77810e63SStefan Agner info.screen_size = 0; 265*77810e63SStefan Agner return -ENOMEM; 266*77810e63SStefan Agner } 267*77810e63SStefan Agner 268*77810e63SStefan Agner /* Reserve framebuffer at the end of memory */ 269*77810e63SStefan Agner gd->fb_base = gd->bd->bi_dram[0].start + 270*77810e63SStefan Agner gd->bd->bi_dram[0].size - info.screen_size; 271*77810e63SStefan Agner info.screen_base = (char *)gd->fb_base; 272*77810e63SStefan Agner 273327def50SWang Huan memset(info.screen_base, 0, info.screen_size); 274327def50SWang Huan 275327def50SWang Huan reset_total_layers(); 276327def50SWang Huan div = dcu_set_pixel_clock(info.var.pixclock); 277327def50SWang Huan dcu_write32(®s->div_ratio, (div - 1)); 278327def50SWang Huan 279327def50SWang Huan dcu_write32(®s->disp_size, 280327def50SWang Huan DCU_DISP_SIZE_DELTA_Y(info.var.yres) | 281327def50SWang Huan DCU_DISP_SIZE_DELTA_X(info.var.xres / 16)); 282327def50SWang Huan 283327def50SWang Huan dcu_write32(®s->hsyn_para, 284327def50SWang Huan DCU_HSYN_PARA_BP(info.var.left_margin) | 285327def50SWang Huan DCU_HSYN_PARA_PW(info.var.hsync_len) | 286327def50SWang Huan DCU_HSYN_PARA_FP(info.var.right_margin)); 287327def50SWang Huan 288327def50SWang Huan dcu_write32(®s->vsyn_para, 289327def50SWang Huan DCU_VSYN_PARA_BP(info.var.upper_margin) | 290327def50SWang Huan DCU_VSYN_PARA_PW(info.var.vsync_len) | 291327def50SWang Huan DCU_VSYN_PARA_FP(info.var.lower_margin)); 292327def50SWang Huan 293327def50SWang Huan dcu_write32(®s->synpol, 294327def50SWang Huan DCU_SYN_POL_INV_PXCK_FALL | 295327def50SWang Huan DCU_SYN_POL_NEG_REMAIN | 296327def50SWang Huan DCU_SYN_POL_INV_VS_LOW | 297327def50SWang Huan DCU_SYN_POL_INV_HS_LOW); 298327def50SWang Huan 299327def50SWang Huan dcu_write32(®s->bgnd, 300327def50SWang Huan DCU_BGND_R(0) | DCU_BGND_G(0) | DCU_BGND_B(0)); 301327def50SWang Huan 302327def50SWang Huan dcu_write32(®s->mode, 303327def50SWang Huan DCU_MODE_BLEND_ITER(DCU_LAYER_MAX_NUM) | 304327def50SWang Huan DCU_MODE_RASTER_EN); 305327def50SWang Huan 306327def50SWang Huan dcu_write32(®s->threshold, 307327def50SWang Huan DCU_THRESHOLD_LS_BF_VS(0x3) | 308327def50SWang Huan DCU_THRESHOLD_OUT_BUF_HIGH(0x78) | 309327def50SWang Huan DCU_THRESHOLD_OUT_BUF_LOW(0)); 310327def50SWang Huan 311327def50SWang Huan mode = dcu_read32(®s->mode); 312327def50SWang Huan dcu_write32(®s->mode, mode | DCU_MODE_NORMAL); 313327def50SWang Huan 314327def50SWang Huan layer_ctrldesc_init(0, pixel_format); 315327def50SWang Huan 316327def50SWang Huan return 0; 317327def50SWang Huan } 318327def50SWang Huan 319*77810e63SStefan Agner ulong board_get_usable_ram_top(ulong total_size) 320*77810e63SStefan Agner { 321*77810e63SStefan Agner return gd->ram_top - CONFIG_VIDEO_FSL_DCU_MAX_FB_SIZE_MB; 322*77810e63SStefan Agner } 323*77810e63SStefan Agner 324327def50SWang Huan void *video_hw_init(void) 325327def50SWang Huan { 326327def50SWang Huan static GraphicDevice ctfb; 327327def50SWang Huan const char *options; 328327def50SWang Huan unsigned int depth = 0, freq = 0; 329327def50SWang Huan struct fb_videomode *fsl_dcu_mode_db = &fsl_dcu_mode_480_272; 330327def50SWang Huan 331327def50SWang Huan if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq, 332327def50SWang Huan &options)) 333327def50SWang Huan return NULL; 334327def50SWang Huan 335327def50SWang Huan /* Find the monitor port, which is a required option */ 336327def50SWang Huan if (!options) 337327def50SWang Huan return NULL; 338327def50SWang Huan if (strncmp(options, "monitor=", 8) != 0) 339327def50SWang Huan return NULL; 340327def50SWang Huan 341327def50SWang Huan switch (RESOLUTION(ctfb.winSizeX, ctfb.winSizeY)) { 342327def50SWang Huan case RESOLUTION(480, 272): 343327def50SWang Huan fsl_dcu_mode_db = &fsl_dcu_mode_480_272; 344327def50SWang Huan break; 345327def50SWang Huan case RESOLUTION(640, 480): 346327def50SWang Huan fsl_dcu_mode_db = &fsl_dcu_mode_640_480; 347327def50SWang Huan break; 348327def50SWang Huan default: 349327def50SWang Huan printf("unsupported resolution %ux%u\n", 350327def50SWang Huan ctfb.winSizeX, ctfb.winSizeY); 351327def50SWang Huan } 352327def50SWang Huan 353327def50SWang Huan info.var.xres = fsl_dcu_mode_db->xres; 354327def50SWang Huan info.var.yres = fsl_dcu_mode_db->yres; 355327def50SWang Huan info.var.bits_per_pixel = 32; 356327def50SWang Huan info.var.pixclock = fsl_dcu_mode_db->pixclock; 357327def50SWang Huan info.var.left_margin = fsl_dcu_mode_db->left_margin; 358327def50SWang Huan info.var.right_margin = fsl_dcu_mode_db->right_margin; 359327def50SWang Huan info.var.upper_margin = fsl_dcu_mode_db->upper_margin; 360327def50SWang Huan info.var.lower_margin = fsl_dcu_mode_db->lower_margin; 361327def50SWang Huan info.var.hsync_len = fsl_dcu_mode_db->hsync_len; 362327def50SWang Huan info.var.vsync_len = fsl_dcu_mode_db->vsync_len; 363327def50SWang Huan info.var.sync = fsl_dcu_mode_db->sync; 364327def50SWang Huan info.var.vmode = fsl_dcu_mode_db->vmode; 365327def50SWang Huan info.fix.line_length = info.var.xres * info.var.bits_per_pixel / 8; 366327def50SWang Huan 367327def50SWang Huan if (platform_dcu_init(ctfb.winSizeX, ctfb.winSizeY, 368327def50SWang Huan options + 8, fsl_dcu_mode_db) < 0) 369327def50SWang Huan return NULL; 370327def50SWang Huan 371327def50SWang Huan ctfb.frameAdrs = (unsigned int)info.screen_base; 372327def50SWang Huan ctfb.plnSizeX = ctfb.winSizeX; 373327def50SWang Huan ctfb.plnSizeY = ctfb.winSizeY; 374327def50SWang Huan 375327def50SWang Huan ctfb.gdfBytesPP = 4; 376327def50SWang Huan ctfb.gdfIndex = GDF_32BIT_X888RGB; 377327def50SWang Huan 378327def50SWang Huan ctfb.memSize = info.screen_size; 379327def50SWang Huan 380327def50SWang Huan return &ctfb; 381327def50SWang Huan } 382*77810e63SStefan Agner 383*77810e63SStefan Agner #if defined(CONFIG_OF_BOARD_SETUP) 384*77810e63SStefan Agner int fsl_dcu_fixedfb_setup(void *blob) 385*77810e63SStefan Agner { 386*77810e63SStefan Agner u64 start, size; 387*77810e63SStefan Agner int ret; 388*77810e63SStefan Agner 389*77810e63SStefan Agner start = gd->bd->bi_dram[0].start; 390*77810e63SStefan Agner size = gd->bd->bi_dram[0].size - info.screen_size; 391*77810e63SStefan Agner 392*77810e63SStefan Agner /* 393*77810e63SStefan Agner * Align size on section size (1 MiB). 394*77810e63SStefan Agner */ 395*77810e63SStefan Agner size &= 0xfff00000; 396*77810e63SStefan Agner ret = fdt_fixup_memory_banks(blob, &start, &size, 1); 397*77810e63SStefan Agner if (ret) { 398*77810e63SStefan Agner eprintf("Cannot setup fb: Error reserving memory\n"); 399*77810e63SStefan Agner return ret; 400*77810e63SStefan Agner } 401*77810e63SStefan Agner 402*77810e63SStefan Agner return 0; 403*77810e63SStefan Agner } 404*77810e63SStefan Agner #endif 405