You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
7.1 KiB
245 lines
7.1 KiB
//Created by lxf for Display Controller pmon for 2g1a
|
|
//Oct 14th,2009
|
|
#include <pmon.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
typedef unsigned long u32;
|
|
typedef unsigned short u16;
|
|
typedef unsigned char u8;
|
|
typedef signed long s32;
|
|
typedef signed short s16;
|
|
typedef signed char s8;
|
|
typedef int bool;
|
|
typedef unsigned long dma_addr_t;
|
|
|
|
#define DC_FB1 1
|
|
#define DC_FB0 1
|
|
|
|
#define writeb(val, addr) (*(volatile u8*)(addr) = (val))
|
|
#define writew(val, addr) (*(volatile u16*)(addr) = (val))
|
|
#define writel(val, addr) (*(volatile u32*)(addr) = (val))
|
|
#define readb(addr) (*(volatile u8*)(addr))
|
|
#define readw(addr) (*(volatile u16*)(addr))
|
|
#define readl(addr) (*(volatile u32*)(addr))
|
|
|
|
#define write_reg(addr,val) writel(val,addr)
|
|
|
|
#define EXTRA_PIXEL 0
|
|
#define DC_BASE_ADDR 0xb0301240
|
|
#define DC_BASE_ADDR_1 0xb0301250
|
|
#define GPUPLL_IN_25M_OUT_150M 0x1218
|
|
#define RANDOM_HEIGHT_Z 37
|
|
|
|
static char *ADDR_CURSOR = 0xb6000000;
|
|
//static char *MEM_ptr = 0xA2000000;
|
|
static char *MEM_ptr = 0xb4000000;
|
|
static int MEM_ADDR =0;
|
|
|
|
struct vga_struc{
|
|
long pclk;
|
|
int hr,hss,hse,hfl;
|
|
int vr,vss,vse,vfl;
|
|
}
|
|
vgamode[] =
|
|
{
|
|
{/*"320x240_60.00"*/ 5260, 320, 304, 336, 352, 240, 241, 244, 249 },
|
|
{/*"640x480_70.00"*/ 28560, 640, 664, 728, 816, 480, 481, 484, 500 },
|
|
{/*"640x640_60.00"*/ 33100, 640, 672, 736, 832, 640, 641, 644, 663 },
|
|
{/*"640x768_60.00"*/ 39690, 640, 672, 736, 832, 768, 769, 772, 795 },
|
|
{/*"640x800_60.00"*/ 42130, 640, 680, 744, 848, 800, 801, 804, 828 },
|
|
{/*"800x480_70.00"*/ 35840, 800, 832, 912, 1024, 480, 481, 484, 500 },
|
|
{/*"800x600_60.00"*/ 38220, 800, 832, 912, 1024, 600, 601, 604, 622 },
|
|
{/*"800x640_60.00"*/ 40730, 800, 832, 912, 1024, 640, 641, 644, 663 },
|
|
{/*"832x600_60.00"*/ 40010, 832, 864, 952, 1072, 600, 601, 604, 622 },
|
|
{/*"832x608_60.00"*/ 40520, 832, 864, 952, 1072, 608, 609, 612, 630 },
|
|
{/*"1024x480_60.00"*/ 38170, 1024, 1048, 1152, 1280, 480, 481, 484, 497 },
|
|
{/*"1024x600_60.00"*/ 48960, 1024, 1064, 1168, 1312, 600, 601, 604, 622 },
|
|
{/*"1024x640_60.00"*/ 52830, 1024, 1072, 1176, 1328, 640, 641, 644, 663 },
|
|
{/*"1024x768_60.00"*/ 64110, 1024, 1080, 1184, 1344, 768, 769, 772, 795 },
|
|
{/*"1152x764_60.00"*/ 71380, 1152, 1208, 1328, 1504, 764, 765, 768, 791 },
|
|
{/*"1280x800_60.00"*/ 83460, 1280, 1344, 1480, 1680, 800, 801, 804, 828 },
|
|
{/*"1280x1024_60.00"*/ 10888, 1280, 1360, 1496, 1712, 1024, 1025, 1028, 1060 },
|
|
{/*"1368x768_60.00"*/ 85860, 1368, 1440, 1584, 1800, 768, 769, 772, 795 },
|
|
{/*"1440x800_60.00"*/ 93800, 1440, 1512, 1664, 1888, 800, 801, 804, 828 },
|
|
{/*"1440x900_67.00"*/ 120280, 1440, 1528, 1680, 1920, 900, 901, 904, 935 },
|
|
};
|
|
|
|
enum{
|
|
OF_BUF_CONFIG=0,
|
|
OF_BUF_ADDR=0x20,
|
|
OF_BUF_STRIDE=0x40,
|
|
OF_BUF_ORIG=0x60,
|
|
OF_DITHER_CONFIG=0x120,
|
|
OF_DITHER_TABLE_LOW=0x140,
|
|
OF_DITHER_TABLE_HIGH=0x160,
|
|
OF_PAN_CONFIG=0x180,
|
|
OF_PAN_TIMING=0x1a0,
|
|
OF_HDISPLAY=0x1c0,
|
|
OF_HSYNC=0x1e0,
|
|
OF_VDISPLAY=0x240,
|
|
OF_VSYNC=0x260,
|
|
OF_DBLBUF=0x340,
|
|
};
|
|
|
|
int caclulatefreq(long long XIN,long long PCLK)
|
|
{
|
|
long N=4,NO=4,OD=2,M,FRAC;
|
|
int flag=0;
|
|
long out;
|
|
long long MF;
|
|
printf("PCLK=%lld\n",PCLK);
|
|
|
|
while(flag==0){
|
|
flag=1;
|
|
printf("N=%lld\n",N);
|
|
if(XIN/N<5000) {N--;flag=0;}
|
|
if(XIN/N>50000) {N++;flag=0;}
|
|
}
|
|
flag=0;
|
|
while(flag==0){
|
|
flag=1;
|
|
if(PCLK*NO<200000) {NO*=2;OD++;flag=0;}
|
|
if(PCLK*NO>700000) {NO/=2;OD--;flag=0;}
|
|
}
|
|
MF=PCLK*N*NO*262144/XIN;
|
|
MF %= 262144;
|
|
M=PCLK*N*NO/XIN;
|
|
FRAC=(int)(MF);
|
|
out = (FRAC<<14)+(OD<<12)+(N<<8)+M;
|
|
|
|
printf("in this case, M=%llx ,N=%llx, OD=%llx, FRAC=%llx\n",M,N,OD,FRAC);
|
|
return out;
|
|
}
|
|
|
|
int config_cursor()
|
|
{
|
|
printf("framebuffer Cursor Configuration\n");
|
|
write_reg((0xb0301520 +0x00),0x00020200);
|
|
printf("framebuffer Cursor Address\n");
|
|
write_reg((0xb0301530 +0x00),ADDR_CURSOR);
|
|
printf("framebuffer Cursor Location\n");
|
|
write_reg((0xb0301540 +0x00),0x00060122);
|
|
printf("framebuffer Cursor Background\n");
|
|
write_reg((0xb0301550 +0x00),0x00eeeeee);
|
|
printf("what hell is this register for ?\n");
|
|
write_reg((0xb0301560 +0x00),0x00aaaaaa);
|
|
}
|
|
|
|
static int fb_xsize, fb_ysize;
|
|
|
|
int config_fb(unsigned long base)
|
|
{
|
|
int i,mode=-1;
|
|
|
|
for(i=0;i<sizeof(vgamode)/sizeof(struct vga_struc);i++)
|
|
{
|
|
int out;
|
|
if(vgamode[i].hr == fb_xsize && vgamode[i].vr == fb_ysize){
|
|
mode=i;
|
|
out = caclulatefreq(APB_CLK/1000,vgamode[i].pclk);
|
|
printf("out=%x\n",out);
|
|
/*inner gpu dc logic fifo pll ctrl,must large then outclk*/
|
|
*(volatile int *)0xb2d00414 = GPUPLL_IN_25M_OUT_150M;
|
|
/*output pix1 clock pll ctrl*/
|
|
// *(volatile int *)0xb2d00410 = out;
|
|
/*output pix2 clock pll ctrl */
|
|
*(volatile int *)0xb2d00424 = out;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(mode<0)
|
|
{
|
|
printf("\n\n\nunsupported framebuffer resolution,choose from bellow:\n");
|
|
for(i=0;i<sizeof(vgamode)/sizeof(struct vga_struc);i++)
|
|
printf("%dx%d, ",vgamode[i].hr,vgamode[i].vr);
|
|
printf("\n");
|
|
return;
|
|
}
|
|
|
|
|
|
// Disable the panel 0
|
|
write_reg((base+OF_BUF_CONFIG),0x00000000);
|
|
// framebuffer configuration RGB565
|
|
write_reg((base+OF_BUF_CONFIG),0x00000003);
|
|
write_reg((base+OF_BUF_ADDR),MEM_ADDR );
|
|
write_reg(base+OF_DBLBUF,MEM_ADDR );
|
|
write_reg((base+OF_DITHER_CONFIG),0x00000000);
|
|
write_reg((base+OF_DITHER_TABLE_LOW),0x00000000);
|
|
write_reg((base+OF_DITHER_TABLE_HIGH),0x00000000);
|
|
write_reg((base+OF_PAN_CONFIG),0x80001311);
|
|
write_reg((base+OF_PAN_TIMING),0x00000000);
|
|
|
|
write_reg((base+OF_HDISPLAY),(vgamode[mode].hfl<<16)|vgamode[mode].hr);
|
|
write_reg((base+OF_HSYNC),0x40000000|(vgamode[mode].hse<<16)|vgamode[mode].hss);
|
|
write_reg((base+OF_VDISPLAY),(vgamode[mode].vfl<<16)|vgamode[mode].vr);
|
|
write_reg((base+OF_VSYNC),0x40000000|(vgamode[mode].vse<<16)|vgamode[mode].vss);
|
|
|
|
#if defined(CONFIG_VIDEO_32BPP)
|
|
write_reg((base+OF_BUF_CONFIG),0x00100104);
|
|
write_reg((base+OF_BUF_STRIDE),fb_xsize*4); //1024
|
|
#elif defined(CONFIG_VIDEO_16BPP)
|
|
write_reg((base+OF_BUF_CONFIG),0x00100103);
|
|
write_reg((base+OF_BUF_STRIDE),(fb_xsize*2+255)&~255); //1024
|
|
#elif defined(CONFIG_VIDEO_15BPP)
|
|
write_reg((base+OF_BUF_CONFIG),0x00100102);
|
|
write_reg((base+OF_BUF_STRIDE),fb_xsize*2); //1024
|
|
#elif defined(CONFIG_VIDEO_12BPP)
|
|
write_reg((base+OF_BUF_CONFIG),0x00100101);
|
|
write_reg((base+OF_BUF_STRIDE),fb_xsize*2); //1024
|
|
#else //640x480-32Bits
|
|
write_reg((base+OF_BUF_CONFIG),0x00100104);
|
|
write_reg((base+OF_BUF_STRIDE),fb_xsize*4); //640
|
|
#endif //32Bits
|
|
|
|
}
|
|
|
|
int dc_init()
|
|
{
|
|
int print_count;
|
|
int i;
|
|
int init_R = 0;
|
|
int init_G = 0;
|
|
int init_B = 0;
|
|
int j;
|
|
int ii=0,tmp=0;
|
|
|
|
|
|
int print_addr;
|
|
int print_data;
|
|
printf("enter dc_init...\n");
|
|
|
|
fb_xsize = getenv("xres")? strtoul(getenv("xres"),0,0):FB_XSIZE;
|
|
fb_ysize = getenv("yres")? strtoul(getenv("yres"),0,0):FB_YSIZE;
|
|
|
|
MEM_ADDR = (long)MEM_ptr&0x03ffffff;
|
|
|
|
|
|
if(MEM_ptr == NULL)
|
|
{
|
|
printf("frame buffer memory malloc failed!\n ");
|
|
exit(0);
|
|
}
|
|
|
|
for(ii=0;ii<0x1000; ii+=4)
|
|
*(volatile unsigned int *)(ADDR_CURSOR + ii) = 0x88f31f4f;
|
|
|
|
ADDR_CURSOR = (long)ADDR_CURSOR & 0x03ffffff;
|
|
|
|
printf("frame buffer addr: %x \n",MEM_ADDR);
|
|
|
|
#ifdef DC_FB0
|
|
config_fb(DC_BASE_ADDR);
|
|
#endif
|
|
#ifdef DC_FB1
|
|
config_fb(DC_BASE_ADDR_1);
|
|
#endif
|
|
config_cursor();
|
|
|
|
|
|
printf("display controller reg config complete!\n");
|
|
|
|
|
|
return MEM_ptr;
|
|
}
|
|
|
|
|