1.1 --- a/stage2/jzlcd.c Sun Jul 09 00:36:42 2017 +0200
1.2 +++ b/stage2/jzlcd.c Sun Jul 09 01:47:02 2017 +0200
1.3 @@ -1,5 +1,5 @@
1.4 /*
1.5 - * JzRISC LCD controller
1.6 + * jz4740 LCD controller configuration.
1.7 *
1.8 * Copyright (C) Xiangfu Liu <xiangfu@sharism.cc>
1.9 * Copyright (C) 2015, 2016, 2017 Paul Boddie <paul@boddie.org.uk>
1.10 @@ -64,7 +64,7 @@
1.11
1.12 /* Return the number of panels available. */
1.13
1.14 -static uint16_t lcd_get_panels(vidinfo_t *vid)
1.15 +static uint8_t lcd_get_panels(vidinfo_t *vid)
1.16 {
1.17 struct jzfb_info *jzfb = vid->jz_fb;
1.18 return ((jzfb->cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||
1.19 @@ -73,7 +73,7 @@
1.20
1.21 /* Calculate and return the pixel clock frequency. */
1.22
1.23 -static uint32_t jz_lcd_get_pixel_clock(vidinfo_t *vid)
1.24 +static uint32_t lcd_get_pixel_clock(vidinfo_t *vid)
1.25 {
1.26 struct jzfb_info *jzfb = vid->jz_fb;
1.27 uint32_t pclk, width_cycles, mode = jzfb->cfg & MODE_MASK;
1.28 @@ -139,6 +139,8 @@
1.29
1.30 static uint32_t lcd_get_palette_size(vidinfo_t *vid)
1.31 {
1.32 + /* Get a collection of two-byte entries, one per colour. */
1.33 +
1.34 if (vid->jz_fb->bpp < 12)
1.35 return (1 << (vid->jz_fb->bpp)) * sizeof(uint16_t);
1.36 else
1.37 @@ -169,78 +171,31 @@
1.38
1.39 /* Functions returning addresses of each data region. */
1.40
1.41 -static uint32_t lcd_get_palette(uint32_t addr, vidinfo_t *vid)
1.42 +static uint32_t lcd_get_palette(vidinfo_t *vid)
1.43 {
1.44 - /* Allocate memory at the end of the region for the palette. */
1.45 - return addr - lcd_get_aligned_palette_size(vid);
1.46 + /* Use memory at the end of the allocated region for the palette. */
1.47 +
1.48 + return get_memory_size() - lcd_get_aligned_palette_size(vid);
1.49 }
1.50
1.51 -static uint32_t lcd_get_descriptors(uint32_t addr, vidinfo_t *vid)
1.52 +static uint32_t lcd_get_descriptors(vidinfo_t *vid)
1.53 {
1.54 - /* Allocate memory before the palette for the descriptor array. */
1.55 - return lcd_get_palette(addr, vid) - lcd_get_descriptors_size();
1.56 + /* Use memory before the palette for the descriptor array. */
1.57 +
1.58 + return lcd_get_palette(vid) - lcd_get_descriptors_size();
1.59 }
1.60
1.61 -static uint32_t lcd_get_framebuffer(uint32_t addr, uint16_t panel, vidinfo_t *vid)
1.62 +static uint32_t lcd_get_framebuffer(uint16_t panel, vidinfo_t *vid)
1.63 {
1.64 - /* Allocate pages for the frame buffer and palette. */
1.65 - return addr - lcd_get_total_size(vid) + (panel * lcd_get_aligned_size(vid));
1.66 + /* Framebuffers for panels are allocated at the start of the region. */
1.67 +
1.68 + return get_memory_size() - lcd_get_total_size(vid) + (panel * lcd_get_aligned_size(vid));
1.69 }
1.70
1.71
1.72
1.73 /* Initialisation functions. */
1.74
1.75 -static void jz_lcd_desc_init(vidinfo_t *vid)
1.76 -{
1.77 - struct jz_fb_dma_descriptor *descriptors;
1.78 - struct jz_mem_info * fbi;
1.79 -
1.80 - fbi = &vid->jz_mem;
1.81 -
1.82 - /* Allocate space for descriptors before the palette entries. */
1.83 -
1.84 - descriptors = (struct jz_fb_dma_descriptor *) lcd_get_descriptors(get_memory_size(), vid);
1.85 - fbi->dmadesc_fblow = (struct jz_fb_dma_descriptor *) &descriptors[0];
1.86 - fbi->dmadesc_fbhigh = (struct jz_fb_dma_descriptor *) &descriptors[1];
1.87 - fbi->dmadesc_palette = (struct jz_fb_dma_descriptor *) &descriptors[2];
1.88 -
1.89 - /* Populate descriptors. */
1.90 -
1.91 - if (lcd_get_panels(vid) == 2)
1.92 - {
1.93 - fbi->dmadesc_fblow->fdadr = fbi->dmadesc_fblow;
1.94 - fbi->dmadesc_fblow->fsadr = lcd_get_framebuffer(get_memory_size(), 1, vid);
1.95 - fbi->dmadesc_fblow->fidr = 0;
1.96 - fbi->dmadesc_fblow->ldcmd = lcd_get_size(vid) / 4 ;
1.97 -
1.98 - fbi->fdadr1 = fbi->dmadesc_fblow; /* only used in dual-panel mode */
1.99 - }
1.100 -
1.101 - fbi->dmadesc_fbhigh->fsadr = fbi->screen;
1.102 - fbi->dmadesc_fbhigh->fidr = 0;
1.103 - fbi->dmadesc_fbhigh->ldcmd = lcd_get_size(vid) / 4; /* length in words */
1.104 -
1.105 - if (vid->jz_fb->bpp < 12)
1.106 - {
1.107 - fbi->dmadesc_palette->fsadr = fbi->palette;
1.108 - fbi->dmadesc_palette->fidr = 0;
1.109 - fbi->dmadesc_palette->ldcmd = (lcd_get_palette_size(vid) / 4) | (1<<28);
1.110 -
1.111 - /* assume any mode with <12 bpp is palette driven */
1.112 - fbi->dmadesc_palette->fdadr = fbi->dmadesc_fbhigh;
1.113 - fbi->dmadesc_fbhigh->fdadr = fbi->dmadesc_palette;
1.114 - /* flips back and forth between pal and fbhigh */
1.115 - fbi->fdadr0 = fbi->dmadesc_palette;
1.116 - } else {
1.117 - /* palette shouldn't be loaded in true-color mode */
1.118 - fbi->dmadesc_fbhigh->fdadr = fbi->dmadesc_fbhigh;
1.119 - fbi->fdadr0 = fbi->dmadesc_fbhigh; /* no pal just fbhigh */
1.120 - }
1.121 -
1.122 - flush_cache_all();
1.123 -}
1.124 -
1.125 static uint32_t jz_lcd_stn_init(uint32_t stnH, vidinfo_t *vid)
1.126 {
1.127 struct jzfb_info *jzfb = vid->jz_fb;
1.128 @@ -288,7 +243,7 @@
1.129 }
1.130
1.131 lcd_ctrl_set(vid, LCD_VSYNC, jzfb->vsw);
1.132 - lcd_ctrl_set(vid, LCD_HSYNC, ((jzfb->blw+jzfb->w) << 16) | (jzfb->blw+jzfb->w+jzfb->hsw));
1.133 + lcd_ctrl_set(vid, LCD_HSYNC, ((jzfb->blw + jzfb->w) << 16) | (jzfb->blw + jzfb->w + jzfb->hsw));
1.134
1.135 /* Screen setting */
1.136 lcd_ctrl_set(vid, LCD_VAT, ((jzfb->blw + jzfb->w + jzfb->hsw + jzfb->elw) << 16) | (stnH + jzfb->vsw + jzfb->bfw + jzfb->efw));
1.137 @@ -304,9 +259,10 @@
1.138 static void jz_lcd_tft_init(vidinfo_t *vid)
1.139 {
1.140 struct jzfb_info *jzfb = vid->jz_fb;
1.141 +
1.142 lcd_ctrl_set(vid, LCD_VSYNC, jzfb->vsw);
1.143 lcd_ctrl_set(vid, LCD_HSYNC, jzfb->hsw);
1.144 - lcd_ctrl_set(vid, LCD_DAV, ((jzfb->vsw+jzfb->bfw) << 16) | (jzfb->vsw +jzfb->bfw+jzfb->h));
1.145 + lcd_ctrl_set(vid, LCD_DAV, ((jzfb->vsw + jzfb->bfw) << 16) | (jzfb->vsw + jzfb->bfw + jzfb->h));
1.146 lcd_ctrl_set(vid, LCD_DAH, ((jzfb->hsw + jzfb->blw) << 16) | (jzfb->hsw + jzfb->blw + jzfb->w));
1.147 lcd_ctrl_set(vid, LCD_VAT, (((jzfb->blw + jzfb->w + jzfb->elw + jzfb->hsw)) << 16) |
1.148 (jzfb->vsw + jzfb->bfw + jzfb->h + jzfb->efw));
1.149 @@ -315,7 +271,7 @@
1.150 static void jz_lcd_samsung_init(vidinfo_t *vid)
1.151 {
1.152 struct jzfb_info *jzfb = vid->jz_fb;
1.153 - uint32_t pclk = jz_lcd_get_pixel_clock(vid);
1.154 + uint32_t pclk = lcd_get_pixel_clock(vid);
1.155 uint32_t total, tp_s, tp_e, ckv_s, ckv_e;
1.156 uint32_t rev_s, rev_e, inv_s, inv_e;
1.157
1.158 @@ -405,7 +361,7 @@
1.159
1.160 static void jz_lcd_set_timing(vidinfo_t *vid)
1.161 {
1.162 - uint32_t pclk = jz_lcd_get_pixel_clock(vid);
1.163 + uint32_t pclk = lcd_get_pixel_clock(vid);
1.164 uint32_t val;
1.165
1.166 #ifdef CONFIG_CPU_JZ4730
1.167 @@ -445,6 +401,89 @@
1.168 lcd_ctrl_set(vid, CPM_CPCCR, lcd_ctrl_get(vid, CPM_CPCCR) | CPM_CPCCR_CE); /* update divide */
1.169 }
1.170
1.171 +/* Initialise the LCD controller with the memory, panel and framebuffer details.
1.172 + Return the pixel clock frequency. */
1.173 +
1.174 +static void jz_lcd_ctrl_init(void *lcd_base, void *fb_vaddr, vidinfo_t *vid)
1.175 +{
1.176 + struct jz_mem_info *fbi = &vid->jz_mem;
1.177 + struct jz_fb_dma_descriptor *descriptors = (struct jz_fb_dma_descriptor *) lcd_get_descriptors(vid);
1.178 +
1.179 + /* Set the LCD controller address. */
1.180 +
1.181 + vid->lcd = lcd_base;
1.182 +
1.183 + /* Position framebuffer regions at the given address. */
1.184 +
1.185 + fbi->screen = (uint32_t) fb_vaddr;
1.186 +
1.187 + /* Obtain the palette address. */
1.188 +
1.189 + fbi->palette = lcd_get_palette(vid);
1.190 +
1.191 + /* Initialise a palette for lower colour depths. */
1.192 +
1.193 + if (vid->jz_fb->bpp < 12)
1.194 + lcd_init_palette(vid);
1.195 +
1.196 + /* Reference the descriptors in memory. */
1.197 +
1.198 + fbi->dmadesc_fb0 = &descriptors[0];
1.199 + fbi->dmadesc_fb1 = &descriptors[1];
1.200 + fbi->dmadesc_palette = &descriptors[2];
1.201 +
1.202 + /* Populate descriptors. */
1.203 +
1.204 + /* Provide the first framebuffer descriptor in single and dual modes. */
1.205 +
1.206 + fbi->dmadesc_fb0->fsadr = lcd_get_framebuffer(0, vid);
1.207 + fbi->dmadesc_fb0->fidr = 0;
1.208 + fbi->dmadesc_fb0->ldcmd = lcd_get_size(vid) / 4; /* length in words */
1.209 +
1.210 + /* Provide the second framebuffer descriptor only in dual-panel mode. */
1.211 +
1.212 + if (lcd_get_panels(vid) == 2)
1.213 + {
1.214 + fbi->dmadesc_fb1->fdadr = fbi->dmadesc_fb1;
1.215 + fbi->dmadesc_fb1->fsadr = lcd_get_framebuffer(1, vid);
1.216 + fbi->dmadesc_fb1->fidr = 0;
1.217 + fbi->dmadesc_fb1->ldcmd = lcd_get_size(vid) / 4;
1.218 +
1.219 + /* Note the address to be provided for the second channel. */
1.220 +
1.221 + fbi->fdadr1 = fbi->dmadesc_fb1;
1.222 + }
1.223 +
1.224 + /* Initialise palette descriptor details if a palette is to be used. */
1.225 +
1.226 + /* Assume any mode with <12 bpp is palette driven. */
1.227 +
1.228 + if (vid->jz_fb->bpp < 12)
1.229 + {
1.230 + fbi->dmadesc_palette->fsadr = fbi->palette;
1.231 + fbi->dmadesc_palette->fidr = 0;
1.232 + fbi->dmadesc_palette->ldcmd = (lcd_get_palette_size(vid) / 4) | LCD_CMD_PAL;
1.233 +
1.234 + /* Flip back and forth between the palette and framebuffer. */
1.235 +
1.236 + fbi->dmadesc_palette->fdadr = fbi->dmadesc_fb0;
1.237 + fbi->dmadesc_fb0->fdadr = fbi->dmadesc_palette;
1.238 +
1.239 + /* Provide the palette descriptor address first. */
1.240 +
1.241 + fbi->fdadr0 = fbi->dmadesc_palette;
1.242 + }
1.243 + else
1.244 + {
1.245 + /* No palette: always use the framebuffer descriptor. */
1.246 +
1.247 + fbi->dmadesc_fb0->fdadr = fbi->dmadesc_fb0;
1.248 + fbi->fdadr0 = fbi->dmadesc_fb0;
1.249 + }
1.250 +}
1.251 +
1.252 +/* Initialise the LCD registers. */
1.253 +
1.254 static void jz_lcd_hw_init(vidinfo_t *vid)
1.255 {
1.256 struct jzfb_info *jzfb = vid->jz_fb;
1.257 @@ -516,7 +555,7 @@
1.258 break;
1.259 }
1.260
1.261 - /* Further control register and panel configuration. */
1.262 + /* Further control register and panel configuration. */
1.263
1.264 val |= LCD_CTRL_BST_16; /* Burst Length is 16WORD=64Byte */
1.265 val |= LCD_CTRL_OFUP; /* OutFIFO underrun protect */
1.266 @@ -537,10 +576,10 @@
1.267
1.268 static void jz_lcd_dma_init(vidinfo_t *vid)
1.269 {
1.270 - struct jz_mem_info *fbi = &vid->jz_mem;
1.271 - uint32_t mode = vid->jz_fb->cfg & MODE_MASK;
1.272 + struct jz_mem_info *fbi = &vid->jz_mem;
1.273 + uint32_t mode = vid->jz_fb->cfg & MODE_MASK;
1.274
1.275 - /* Configure DMA by setting frame descriptor addresses. */
1.276 + /* Configure DMA by setting frame descriptor addresses. */
1.277
1.278 lcd_ctrl_set(vid, LCD_DA0, (uint32_t) fbi->fdadr0);
1.279
1.280 @@ -548,13 +587,12 @@
1.281 lcd_ctrl_set(vid, LCD_DA1, (uint32_t) fbi->fdadr1);
1.282 }
1.283
1.284 -/* Public operations. */
1.285 +/* Set the colour depth. */
1.286
1.287 void lcd_set_bpp(uint8_t bpp)
1.288 {
1.289 vidinfo_t *vid = &panel_info;
1.290 - struct jzfb_info *jzfb = vid->jz_fb;
1.291 - jzfb->bpp = bpp;
1.292 + vid->jz_fb->bpp = bpp;
1.293 }
1.294
1.295 void lcd_enable()
1.296 @@ -588,16 +626,14 @@
1.297 {
1.298 vidinfo_t *vid = &panel_info;
1.299 struct jz_mem_info *fbi = &vid->jz_mem;
1.300 + void *fb_vaddr;
1.301
1.302 - /* Start from the top of memory and obtain palette and framebuffer regions. */
1.303 + /* Start from the top of memory and obtain the framebuffer region. */
1.304
1.305 - fbi->screen = lcd_get_framebuffer(get_memory_size(), 0, vid);
1.306 - fbi->palette = lcd_get_palette(get_memory_size(), vid);
1.307 + fb_vaddr = (void *) lcd_get_framebuffer(0, vid);
1.308
1.309 - if (vid->jz_fb->bpp < 12)
1.310 - lcd_init_palette(vid);
1.311 -
1.312 - jz_lcd_desc_init(vid);
1.313 + jz_lcd_ctrl_init(0, fb_vaddr, vid);
1.314 + flush_cache_all();
1.315 jz_lcd_hw_init(vid);
1.316 jz_lcd_timing_init(vid);
1.317 jz_lcd_dma_init(vid);