1.1 --- a/stage2/jzlcd.c Sun Jul 09 16:48:29 2017 +0200
1.2 +++ b/stage2/jzlcd.c Sun Jul 09 17:14:00 2017 +0200
1.3 @@ -22,7 +22,6 @@
1.4
1.5 #include "sdram.h"
1.6 #include "jzlcd.h"
1.7 -#include "cpu.h"
1.8 #include "board.h"
1.9
1.10 extern vidinfo_t panel_info;
1.11 @@ -114,6 +113,7 @@
1.12 static uint32_t lcd_get_size(vidinfo_t *vid)
1.13 {
1.14 /* Lines must be aligned to a word boundary. */
1.15 +
1.16 uint32_t line_length = ALIGN((vid->jz_fb->w * vid->jz_fb->bpp) / 8, sizeof(uint32_t));
1.17 return line_length * vid->jz_fb->h;
1.18 }
1.19 @@ -121,12 +121,14 @@
1.20 static uint32_t lcd_get_aligned_size(vidinfo_t *vid)
1.21 {
1.22 /* LCD_CTRL_BST_16 requires 16-word alignment. */
1.23 +
1.24 return ALIGN(lcd_get_size(vid), 16 * sizeof(uint32_t));
1.25 }
1.26
1.27 static uint32_t lcd_get_min_size(vidinfo_t *vid)
1.28 {
1.29 /* Lines must be aligned to a word boundary. */
1.30 +
1.31 uint32_t line_length = ALIGN((vid->jz_fb->w * 32) / 8, sizeof(uint32_t));
1.32 return line_length * vid->jz_fb->h;
1.33 }
1.34 @@ -134,6 +136,7 @@
1.35 static uint32_t lcd_get_aligned_min_size(vidinfo_t *vid)
1.36 {
1.37 /* LCD_CTRL_BST_16 requires 16-word alignment. */
1.38 +
1.39 return ALIGN(lcd_get_min_size(vid), 16 * sizeof(uint32_t));
1.40 }
1.41
1.42 @@ -158,15 +161,6 @@
1.43 return 3 * sizeof(struct jz_fb_dma_descriptor);
1.44 }
1.45
1.46 -static uint32_t lcd_get_total_size(vidinfo_t *vid)
1.47 -{
1.48 - uint32_t size = lcd_get_aligned_size(vid) * lcd_get_panels(vid);
1.49 - uint32_t min_size = lcd_get_aligned_min_size(vid);
1.50 -
1.51 - /* Round up to nearest full page, or MMU section if defined. */
1.52 - return ALIGN((size >= min_size ? size : min_size) + lcd_get_aligned_palette_size(vid) + lcd_get_descriptors_size(), PAGE_SIZE);
1.53 -}
1.54 -
1.55
1.56
1.57 /* Functions returning addresses of each data region. */
1.58 @@ -175,7 +169,7 @@
1.59 {
1.60 /* Use memory at the end of the allocated region for the palette. */
1.61
1.62 - return get_memory_size() - lcd_get_aligned_palette_size(vid);
1.63 + return vid->jz_mem.screen + vid->jz_mem.total - lcd_get_aligned_palette_size(vid);
1.64 }
1.65
1.66 static uint32_t lcd_get_descriptors(vidinfo_t *vid)
1.67 @@ -185,11 +179,11 @@
1.68 return lcd_get_palette(vid) - lcd_get_descriptors_size();
1.69 }
1.70
1.71 -static uint32_t lcd_get_framebuffer(uint16_t panel, vidinfo_t *vid)
1.72 +static uint32_t lcd_get_framebuffer(uint8_t panel, vidinfo_t *vid)
1.73 {
1.74 /* Framebuffers for panels are allocated at the start of the region. */
1.75
1.76 - return get_memory_size() - lcd_get_total_size(vid) + (panel * lcd_get_aligned_size(vid));
1.77 + return vid->jz_mem.screen + (panel * lcd_get_aligned_size(vid));
1.78 }
1.79
1.80
1.81 @@ -359,60 +353,49 @@
1.82
1.83
1.84
1.85 -static void jz_lcd_set_timing(vidinfo_t *vid)
1.86 -{
1.87 - uint32_t pclk = lcd_get_pixel_clock(vid);
1.88 - uint32_t val;
1.89 +/* Public functions. */
1.90 +
1.91 +/* Return the total size of the required memory. */
1.92
1.93 -#ifdef CONFIG_CPU_JZ4730
1.94 - val = __cpm_get_pllout() / pclk;
1.95 - REG_CPM_CFCR2 = val - 1;
1.96 - val = pclk * 4 ;
1.97 - if ( val > 150000000 ) {
1.98 - val = 150000000;
1.99 - }
1.100 - val = __cpm_get_pllout() / val;
1.101 - val--;
1.102 - if ( val > 0xF )
1.103 - val = 0xF;
1.104 -#else
1.105 - int pll_div;
1.106 +uint32_t jz4740_lcd_get_total_size(vidinfo_t *vid)
1.107 +{
1.108 + uint32_t size = lcd_get_aligned_size(vid) * lcd_get_panels(vid);
1.109 + uint32_t min_size = lcd_get_aligned_min_size(vid);
1.110 +
1.111 + /* Round up to nearest full page, or MMU section if defined. */
1.112
1.113 - pll_div = REG_CPM_CPCCR & CPM_CPCCR_PCS; /* clock source,0:pllout/2 1: pllout */
1.114 - pll_div = pll_div ? 1 : 2 ;
1.115 - val = ( __cpm_get_pllout()/pll_div ) / pclk;
1.116 - val--;
1.117 - if ( val > 0x1ff ) {
1.118 - val = 0x1ff;
1.119 - }
1.120 - __cpm_set_pixdiv(val);
1.121 + return ALIGN((size >= min_size ? size : min_size) +
1.122 + lcd_get_aligned_palette_size(vid) + lcd_get_descriptors_size(),
1.123 + PAGE_SIZE);
1.124 +}
1.125
1.126 - val = pclk * 3 ; /* LCDClock > 2.5*Pixclock */
1.127 - if ( val > 150000000 ) {
1.128 - val = 150000000;
1.129 - }
1.130 - val = ( __cpm_get_pllout()/pll_div ) / val;
1.131 - val--;
1.132 - if ( val > 0x1f ) {
1.133 - val = 0x1f;
1.134 - }
1.135 -#endif
1.136 - __cpm_set_ldiv( val );
1.137 - REG_CPM_CPCCR = REG_CPM_CPCCR | CPM_CPCCR_CE; /* update divide */
1.138 +/* Return the calculated pixel clock frequency for the display. */
1.139 +
1.140 +uint32_t jz4740_lcd_get_pixel_clock(vidinfo_t *vid)
1.141 +{
1.142 + return lcd_get_pixel_clock(vid);
1.143 }
1.144
1.145 /* Initialise the LCD controller with the memory, panel and framebuffer details.
1.146 Return the pixel clock frequency. */
1.147
1.148 -static void jz_lcd_ctrl_init(void *lcd_base, void *fb_vaddr, vidinfo_t *vid)
1.149 +void jz4740_lcd_ctrl_init(void *lcd_base, void *fb_vaddr, vidinfo_t *vid)
1.150 {
1.151 struct jz_mem_info *fbi = &vid->jz_mem;
1.152 - struct jz_fb_dma_descriptor *descriptors = (struct jz_fb_dma_descriptor *) lcd_get_descriptors(vid);
1.153 + struct jz_fb_dma_descriptor *descriptors;
1.154
1.155 /* Set the LCD controller address. */
1.156
1.157 vid->lcd = lcd_base;
1.158
1.159 + /* Initialise the total region size. */
1.160 +
1.161 + fbi->total = jz4740_lcd_get_total_size(vid);
1.162 +
1.163 + /* Obtain a reference to the descriptors. */
1.164 +
1.165 + descriptors = (struct jz_fb_dma_descriptor *) lcd_get_descriptors(vid);
1.166 +
1.167 /* Position framebuffer regions at the given address. */
1.168
1.169 fbi->screen = (uint32_t) fb_vaddr;
1.170 @@ -484,7 +467,7 @@
1.171
1.172 /* Initialise the LCD registers. */
1.173
1.174 -static void jz_lcd_hw_init(vidinfo_t *vid)
1.175 +void jz4740_lcd_hw_init(vidinfo_t *vid)
1.176 {
1.177 struct jzfb_info *jzfb = vid->jz_fb;
1.178 uint32_t val = 0;
1.179 @@ -564,17 +547,9 @@
1.180 lcd_ctrl_set(vid, LCD_CFG, jzfb->cfg);
1.181 }
1.182
1.183 -static void jz_lcd_timing_init(vidinfo_t *vid)
1.184 -{
1.185 - __cpm_stop_lcd();
1.186 - jz_lcd_set_timing(vid);
1.187 - __cpm_start_lcd();
1.188 - udelay(1000);
1.189 -}
1.190 -
1.191 /* Initialise DMA for the driver. */
1.192
1.193 -static void jz_lcd_dma_init(vidinfo_t *vid)
1.194 +void jz4740_lcd_dma_init(vidinfo_t *vid)
1.195 {
1.196 struct jz_mem_info *fbi = &vid->jz_mem;
1.197 uint32_t mode = vid->jz_fb->cfg & MODE_MASK;
1.198 @@ -621,22 +596,3 @@
1.199
1.200 lcd_ctrl_set(vid, LCD_CTRL, lcd_ctrl_get(vid, LCD_CTRL) & ~LCD_CTRL_ENA);
1.201 }
1.202 -
1.203 -uint32_t lcd_ctrl_init()
1.204 -{
1.205 - vidinfo_t *vid = &panel_info;
1.206 - struct jz_mem_info *fbi = &vid->jz_mem;
1.207 - void *fb_vaddr;
1.208 -
1.209 - /* Start from the top of memory and obtain the framebuffer region. */
1.210 -
1.211 - fb_vaddr = (void *) lcd_get_framebuffer(0, vid);
1.212 -
1.213 - jz_lcd_ctrl_init((void *) LCD_BASE_KSEG1, fb_vaddr, vid);
1.214 - flush_cache_all();
1.215 - jz_lcd_hw_init(vid);
1.216 - jz_lcd_timing_init(vid);
1.217 - jz_lcd_dma_init(vid);
1.218 -
1.219 - return fbi->screen;
1.220 -}
2.1 --- a/stage2/jzlcd.h Sun Jul 09 16:48:29 2017 +0200
2.2 +++ b/stage2/jzlcd.h Sun Jul 09 17:14:00 2017 +0200
2.3 @@ -27,11 +27,6 @@
2.4
2.5 #include <stdint.h>
2.6
2.7 -void lcd_set_bpp(uint8_t bpp);
2.8 -uint32_t lcd_ctrl_init();
2.9 -void lcd_enable();
2.10 -void lcd_disable();
2.11 -
2.12 /* Framebuffer characteristics. */
2.13
2.14 struct jzfb_info {
2.15 @@ -85,6 +80,18 @@
2.16 void *lcd; /* address of LCD controller registers */
2.17 } vidinfo_t;
2.18
2.19 +/* Public functions. */
2.20 +
2.21 +uint32_t jz4740_lcd_get_total_size(vidinfo_t *vid);
2.22 +uint32_t jz4740_lcd_get_pixel_clock(vidinfo_t *vid);
2.23 +void jz4740_lcd_ctrl_init(void *lcd_base, void *fb_vaddr, vidinfo_t *vid);
2.24 +void jz4740_lcd_hw_init(vidinfo_t *vid);
2.25 +void jz4740_lcd_dma_init(vidinfo_t *vid);
2.26 +void lcd_set_bpp(uint8_t bpp);
2.27 +uint32_t lcd_ctrl_init();
2.28 +void lcd_enable();
2.29 +void lcd_disable();
2.30 +
2.31 /* Alignment/rounding macros. */
2.32
2.33 #define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1)
3.1 --- a/stage2/lcd.c Sun Jul 09 16:48:29 2017 +0200
3.2 +++ b/stage2/lcd.c Sun Jul 09 17:14:00 2017 +0200
3.3 @@ -22,11 +22,14 @@
3.4
3.5 #include "jzlcd.h"
3.6 #include "sdram.h"
3.7 +#include "cpu.h"
3.8 #include "board.h"
3.9
3.10 extern vidinfo_t panel_info;
3.11 static uint32_t lcd_base;
3.12
3.13 +
3.14 +
3.15 static uint16_t get_line_length()
3.16 {
3.17 return ALIGN((panel_info.jz_fb->w * panel_info.jz_fb->bpp) / 8, sizeof(uint32_t));
3.18 @@ -254,8 +257,101 @@
3.19 }
3.20 }
3.21
3.22 +
3.23 +
3.24 /* LCD initialisation. */
3.25
3.26 +#ifdef CONFIG_CPU_JZ4730
3.27 +void jz4730_set_lcd_frequencies(uint32_t pclk, uint8_t ratio)
3.28 +{
3.29 + uint32_t val;
3.30 +
3.31 + val = __cpm_get_pllout() / pclk;
3.32 + REG_CPM_CFCR2 = val - 1;
3.33 + val = pclk * ratio;
3.34 +
3.35 + if (val > 150000000) {
3.36 + val = 150000000;
3.37 + }
3.38 +
3.39 + val = __cpm_get_pllout() / val;
3.40 + val--;
3.41 +
3.42 + if (val > 0xF)
3.43 + val = 0xF;
3.44 +
3.45 + __cpm_set_ldiv(val);
3.46 + REG_CPM_CPCCR = REG_CPM_CPCCR | CPM_CPCCR_CE; /* update divide */
3.47 +}
3.48 +#else
3.49 +void jz4740_set_lcd_frequencies(uint32_t pclk, uint8_t ratio)
3.50 +{
3.51 + uint32_t val;
3.52 + int pll_div;
3.53 +
3.54 + pll_div = REG_CPM_CPCCR & CPM_CPCCR_PCS; /* clock source,0:pllout/2 1: pllout */
3.55 + pll_div = pll_div ? 1 : 2;
3.56 + val = (__cpm_get_pllout() / pll_div) / pclk;
3.57 + val--;
3.58 +
3.59 + if ( val > 0x1ff ) {
3.60 + val = 0x1ff;
3.61 + }
3.62 +
3.63 + __cpm_set_pixdiv(val);
3.64 +
3.65 + val = pclk * ratio; /* LCDClock > 2.5*Pixclock */
3.66 +
3.67 + if ( val > 150000000 ) {
3.68 + val = 150000000;
3.69 + }
3.70 +
3.71 + val = (__cpm_get_pllout() / pll_div) / val;
3.72 + val--;
3.73 +
3.74 + if (val > 0x1f)
3.75 + val = 0x1f;
3.76 +
3.77 + __cpm_set_ldiv(val);
3.78 + REG_CPM_CPCCR = REG_CPM_CPCCR | CPM_CPCCR_CE; /* update divide */
3.79 +}
3.80 +#endif
3.81 +
3.82 +void lcd_set_timing(vidinfo_t *vid)
3.83 +{
3.84 + uint32_t pclk = jz4740_lcd_get_pixel_clock(vid);
3.85 +
3.86 + __cpm_stop_lcd();
3.87 +
3.88 +#ifdef CONFIG_CPU_JZ4730
3.89 + jz4730_set_lcd_frequencies(pclk, 4);
3.90 +#else
3.91 + jz4740_set_lcd_frequencies(pclk, 3);
3.92 +#endif
3.93 +
3.94 + __cpm_start_lcd();
3.95 + udelay(1000);
3.96 +}
3.97 +
3.98 +uint32_t lcd_ctrl_init()
3.99 +{
3.100 + vidinfo_t *vid = &panel_info;
3.101 + struct jz_mem_info *fbi = &vid->jz_mem;
3.102 + void *fb_vaddr;
3.103 +
3.104 + /* Start from the top of memory and obtain the framebuffer region. */
3.105 +
3.106 + fb_vaddr = (void *) (get_memory_size() - jz4740_lcd_get_total_size(vid));
3.107 +
3.108 + jz4740_lcd_ctrl_init((void *) LCD_BASE_KSEG1, fb_vaddr, vid);
3.109 + flush_cache_all();
3.110 + jz4740_lcd_hw_init(vid);
3.111 + lcd_set_timing(vid);
3.112 + jz4740_lcd_dma_init(vid);
3.113 +
3.114 + return fbi->screen;
3.115 +}
3.116 +
3.117 void lcd_init()
3.118 {
3.119 __lcd_display_pin_init();