[U-Boot-Users] [PATCH] Extend ATI Radeon driver to support more video modes

Adds ATI Radeon 9200 support for 1280x1024, 1024x768, 800x600, 640x480 at 24, 16 and 8 bpp. Hope this patch won't screw up X300 and X700 support.
Signed-off-by: Anatolij Gustschin agust@denx.de --- drivers/video/ati_radeon_fb.c | 401 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 386 insertions(+), 15 deletions(-)
diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c index 0bdaa1c..740a360 100644 --- a/drivers/video/ati_radeon_fb.c +++ b/drivers/video/ati_radeon_fb.c @@ -44,6 +44,7 @@ #include <asm/io.h> #include <malloc.h> #include <video_fb.h> +#include "videomodes.h"
#include <radeon.h> #include "ati_ids.h" @@ -70,6 +71,7 @@ #define PCI_CHIP_RV280_5961 0x5961 #define PCI_CHIP_RV280_5962 0x5962 #define PCI_CHIP_RV280_5964 0x5964 +#define PCI_CHIP_RV280_5C63 0x5C63 #define PCI_CHIP_RV370_5B60 0x5B60 #define PCI_CHIP_RV380_5657 0x5657 #define PCI_CHIP_R420_554d 0x554d @@ -79,6 +81,7 @@ static struct pci_device_id ati_radeon_pci_ids[] = { {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964}, + {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5C63}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657}, {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d}, @@ -90,12 +93,115 @@ static u16 ati_radeon_id_family_table[][2] = { {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280}, {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280}, {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280}, + {PCI_CHIP_RV280_5C63, CHIP_FAMILY_RV280}, {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380}, {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380}, {PCI_CHIP_R420_554d, CHIP_FAMILY_R420}, {0, 0} };
+static struct { + unsigned char idx; + unsigned int val; +} pal_16[] = { + {0x00, 0x00000000}, + {0x00, 0x00000400}, + {0x04, 0x00000400}, + {0x08, 0x00080c08}, + {0x08, 0x00080808}, + {0x10, 0x00101410}, + {0x0c, 0x00080c08}, + {0x18, 0x00181c18}, + {0x10, 0x00101010}, + {0x20, 0x00202420}, + {0x14, 0x00101410}, + {0x28, 0x00292c29}, + {0x18, 0x00181818}, + {0x30, 0x00313431}, + {0x1c, 0x00181c18}, + {0x38, 0x00393c39}, + {0x20, 0x00202020}, + {0x40, 0x00414441}, + {0x24, 0x00202420}, + {0x48, 0x004a4c4a}, + {0x28, 0x00292829}, + {0x50, 0x00525552}, + {0x2c, 0x00292c29}, + {0x58, 0x005a5d5a}, + {0x30, 0x00313031}, + {0x60, 0x00626562}, + {0x34, 0x00313431}, + {0x68, 0x006a6d6a}, + {0x38, 0x00393839}, + {0x70, 0x00737573}, + {0x3c, 0x00393c39}, + {0x78, 0x007b7d7b}, + {0x40, 0x00414041}, + {0x80, 0x00838583}, + {0x44, 0x00414441}, + {0x88, 0x008b8d8b}, + {0x48, 0x004a484a}, + {0x90, 0x00949594}, + {0x4c, 0x004a4c4a}, + {0x98, 0x009c9d9c}, + {0x50, 0x00525052}, + {0xa0, 0x00a4a5a4}, + {0x54, 0x00525552}, + {0xa8, 0x00acaeac}, + {0x58, 0x005a595a}, + {0xb0, 0x00b4b6b4}, + {0x5c, 0x005a5d5a}, + {0xb8, 0x00bdbebd}, + {0x60, 0x00626162}, + {0xc0, 0x00c5c6c5}, + {0x64, 0x00626562}, + {0xc8, 0x00cdcecd}, + {0x68, 0x006a696a}, + {0xd0, 0x00d5d6d5}, + {0x6c, 0x006a6d6a}, + {0xd8, 0x00dedede}, + {0x70, 0x00737173}, + {0xe0, 0x00e6e6e6}, + {0x74, 0x00737573}, + {0xe8, 0x00eeeeee}, + {0x78, 0x007b797b}, + {0xf0, 0x00f6f6f6}, + {0x7c, 0x007b7d7b}, + {0xf8, 0x00ffffff}, + {0x80, 0x00838183}, + {0x84, 0x00838583}, + {0x88, 0x008b898b}, + {0x8c, 0x008b8d8b}, + {0x90, 0x00949194}, + {0x94, 0x00949594}, + {0x98, 0x009c999c}, + {0x9c, 0x009c9d9c}, + {0xa0, 0x00a4a1a4}, + {0xa4, 0x00a4a5a4}, + {0xa8, 0x00acaaac}, + {0xac, 0x00acaeac}, + {0xb0, 0x00b4b2b4}, + {0xb4, 0x00b4b6b4}, + {0xb8, 0x00bdbabd}, + {0xbc, 0x00bdbebd}, + {0xc0, 0x00c5c2c5}, + {0xc4, 0x00c5c6c5}, + {0xc8, 0x00cdcacd}, + {0xcc, 0x00cdcecd}, + {0xd0, 0x00d5d2d5}, + {0xd4, 0x00d5d6d5}, + {0xd8, 0x00dedade}, + {0xdc, 0x00dedede}, + {0xe0, 0x00e6e2e6}, + {0xe4, 0x00e6e6e6}, + {0xe8, 0x00eeeaee}, + {0xec, 0x00eeeeee}, + {0xf0, 0x00f6f2f6}, + {0xf4, 0x00f6f6f6}, + {0xf8, 0x00fffaff}, + {0xfc, 0x00ffffff}, +}; + u16 get_radeon_id_family(u16 device) { int i; @@ -350,6 +456,196 @@ void radeon_setmode(void) radeon_write_pll_regs(rinfo, mode); }
+static void set_pal_16(void) +{ + int i; + + for (i = 0; i < 96; i++) { + OUTREG8(PALETTE_INDEX, pal_16[i].idx); + OUTREG(PALETTE_DATA, pal_16[i].val); + } +} + +static void set_pal_24(void) +{ + int idx, val = 0; + + for (idx = 0; idx < 256; idx++) { + OUTREG8(PALETTE_INDEX, idx); + OUTREG(PALETTE_DATA, val); + val += 0x00010101; + } +} + +void radeon_setmode_9200(int vesa_idx, int bpp) +{ + struct radeon_regs *mode = malloc(sizeof(struct radeon_regs)); + unsigned long dp_gm_cntl; + + mode->crtc_gen_cntl = 0x03000600; + mode->surface_cntl = 0x00a00000; + dp_gm_cntl = 0x100036d2; + mode->crtc_ext_cntl = 0x00008048; + mode->dac_cntl = 0xff002102; + mode->crtc_offset_cntl = 0x00008000; + + if (bpp == 16) { + mode->crtc_gen_cntl = 0x03000400; + dp_gm_cntl = 0x100034d2; + mode->surface_cntl = 0x00500000; + } else if (bpp == 8) { + mode->crtc_gen_cntl = 0x03000200; + dp_gm_cntl = 0x100032d2; + mode->surface_cntl = 0x00000000; + } + + if (vesa_idx == RES_MODE_640x480 && bpp == 8) { + mode->dac_cntl = 0xff002100; + mode->crtc_offset_cntl = 0x00000000; + } + + switch (vesa_idx) { + case RES_MODE_1280x1024: +#if 1 /* @ 60 Hz */ + mode->crtc_h_total_disp = 0x009f00d2; + mode->crtc_h_sync_strt_wid = 0x000e0528; + mode->crtc_v_total_disp = 0x03ff0429; + mode->crtc_v_sync_strt_wid = 0x00030400; + mode->crtc_pitch = 0x00a000a0; + mode->ppll_div_3 = 0x00010060; +#else /* @ 75 Hz */ + mode->crtc_h_total_disp = 0x009f00d2; + mode->crtc_h_sync_strt_wid = 0x00120508; + mode->crtc_v_total_disp = 0x03ff0429; + mode->crtc_v_sync_strt_wid = 0x00030400; + mode->crtc_pitch = 0x00a000a0; + mode->ppll_div_3 = 0x00010078; +#endif + switch (bpp) { + case 24: + mode->surf_info[0] = 0x00a10140; + mode->surf_upper_bound[0] = 0x004fffff; + break; + case 16: + mode->surf_info[0] = 0x005100a0; + mode->surf_upper_bound[0] = 0x0027ffff; + break; + default: /* 8 bpp */ + mode->surf_info[0] = 0x00010050; + mode->surf_upper_bound[0] = 0x0013ffff; + break; + } + break; + case RES_MODE_1024x768: +#if 1 /* @ 60 Hz */ + mode->crtc_h_total_disp = 0x007f00a7; + mode->crtc_h_sync_strt_wid = 0x00910410; + mode->crtc_v_total_disp = 0x02ff0325; + mode->crtc_v_sync_strt_wid = 0x00860302; + mode->crtc_pitch = 0x00800080; + mode->ppll_div_3 = 0x00020074; +#else /* @ 75 Hz */ + mode->crtc_h_total_disp = 0x007f00a3; + mode->crtc_h_sync_strt_wid = 0x000c0408; + mode->crtc_v_total_disp = 0x02ff031f; + mode->crtc_v_sync_strt_wid = 0x00030300; + mode->crtc_pitch = 0x00800080; + mode->ppll_div_3 = 0x0002008c; +#endif + switch (bpp) { + case 24: + mode->surf_info[0] = 0x00a10100; + mode->surf_upper_bound[0] = 0x002fffff; + break; + case 16: + mode->surf_info[0] = 0x00510080; + mode->surf_upper_bound[0] = 0x0017ffff; + break; + default: /* 8 bpp */ + mode->surf_info[0] = 0x00010040; + mode->surf_upper_bound[0] = 0x000bffff; + break; + } + break; + case RES_MODE_800x600: + mode->crtc_h_total_disp = 0x00630083; + mode->crtc_h_sync_strt_wid = 0x00100340; + mode->crtc_v_total_disp = 0x02570273; + mode->crtc_v_sync_strt_wid = 0x00040258; + mode->ppll_div_3 = 0x0003008e; + switch (bpp) { + case 24: + mode->crtc_pitch = 0x00680068; + mode->surf_info[0] = 0x00a100d0; + mode->surf_upper_bound[0] = 0x001edfff; + break; + case 16: + mode->crtc_pitch = 0x00700070; + mode->surf_info[0] = 0x00510070; + mode->surf_upper_bound[0] = 0x00109fff; + break; + default: /* 8 bpp */ + mode->crtc_pitch = 0x00800080; + mode->surf_info[0] = 0x00010040; + mode->surf_upper_bound[0] = 0x00097fff; + break; + } + break; + default: /* RES_MODE_640x480 */ + mode->crtc_h_total_disp = 0x4f0063; + mode->crtc_h_sync_strt_wid = 0x8c02a2; + mode->crtc_v_total_disp = 0x01df020c; + mode->crtc_v_sync_strt_wid = 0x8201ea; + mode->crtc_pitch = 0x00500050; + mode->ppll_div_3 = 0x00030059; + switch (bpp) { + case 24: + mode->surf_info[0] = 0x00a100a0; + mode->surf_upper_bound[0] = 0x0012bfff; + break; + case 16: + mode->surf_info[0] = 0x00510050; + mode->surf_upper_bound[0] = 0x00095fff; + break; + default: /* 8 bpp */ + break; + } + break; + } + + OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); + OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, + ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); + OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); + OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); + OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); + OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); + OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); + OUTREG(CRTC_OFFSET, 0); + OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl); + OUTREG(CRTC_PITCH, mode->crtc_pitch); + + mode->clk_cntl_index = 0x300; + mode->ppll_ref_div = 0xc; + + radeon_write_pll_regs(rinfo, mode); + + OUTREG(SURFACE0_INFO, mode->surf_info[0]); + OUTREG(SURFACE0_LOWER_BOUND, 0); + OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]); + OUTREG(SURFACE_CNTL, mode->surface_cntl); + + OUTREG(DP_GUI_MASTER_CNTL, dp_gm_cntl); + OUTREG(0x0000325c, 0x0000000f); + + if (bpp == 24) + set_pal_24(); + else if (bpp == 16) + set_pal_16(); + + free(mode); +} + #include "../bios_emulator/include/biosemu.h" extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
@@ -421,29 +717,101 @@ GraphicDevice ctfb; void *video_hw_init(void) { GraphicDevice *pGD = (GraphicDevice *) & ctfb; - int i; u32 *vm; + char *penv; + unsigned long t1, hsynch, vsynch; + int bits_per_pixel, i, tmp, vesa_idx = 0, videomode; + struct ctfb_res_modes *res_mode; + struct ctfb_res_modes var_mode;
rinfo = malloc(sizeof(struct radeonfb_info));
+ printf("Video: "); if(radeon_probe(rinfo)) { printf("No radeon video card found!\n"); return NULL; }
- /* fill in Graphic device struct */ - sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640, - 480, 16, (1000 / 1000), - (2000 / 1000)); - printf ("%s\n", pGD->modeIdent); + tmp = 0; + + videomode = CFG_DEFAULT_VIDEO_MODE; + /* get video mode via environment */ + if ((penv = getenv ("videomode")) != NULL) { + /* deceide if it is a string */ + if (penv[0] <= '9') { + videomode = (int) simple_strtoul (penv, NULL, 16); + tmp = 1; + } + } else { + tmp = 1; + } + if (tmp) { + /* parameter are vesa modes */ + /* search params */ + for (i = 0; i < VESA_MODES_COUNT; i++) { + if (vesa_modes[i].vesanr == videomode) + break; + } + if (i == VESA_MODES_COUNT) { + printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE); + i = 0; + } + res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex]; + bits_per_pixel = vesa_modes[i].bits_per_pixel; + vesa_idx = vesa_modes[i].resindex; + } else { + res_mode = (struct ctfb_res_modes *) &var_mode; + bits_per_pixel = video_get_params (res_mode, penv); + }
- pGD->winSizeX = 640; - pGD->winSizeY = 480; - pGD->plnSizeX = 640; - pGD->plnSizeY = 480; + /* calculate hsynch and vsynch freq (info only) */ + t1 = (res_mode->left_margin + res_mode->xres + + res_mode->right_margin + res_mode->hsync_len) / 8; + t1 *= 8; + t1 *= res_mode->pixclock; + t1 /= 1000; + hsynch = 1000000000L / t1; + t1 *= (res_mode->upper_margin + res_mode->yres + + res_mode->lower_margin + res_mode->vsync_len); + t1 /= 1000; + vsynch = 1000000000L / t1;
- pGD->gdfBytesPP = 1; - pGD->gdfIndex = GDF__8BIT_INDEX; + /* fill in Graphic device struct */ + sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres, + res_mode->yres, bits_per_pixel, (hsynch / 1000), + (vsynch / 1000)); + printf ("%s\n", pGD->modeIdent); + pGD->winSizeX = res_mode->xres; + pGD->winSizeY = res_mode->yres; + pGD->plnSizeX = res_mode->xres; + pGD->plnSizeY = res_mode->yres; + + switch (bits_per_pixel) { + case 24: + pGD->gdfBytesPP = 4; + pGD->gdfIndex = GDF_32BIT_X888RGB; + if (res_mode->xres == 800) { + pGD->winSizeX = 832; + pGD->plnSizeX = 832; + } + break; + case 16: + pGD->gdfBytesPP = 2; + pGD->gdfIndex = GDF_16BIT_565RGB; + if (res_mode->xres == 800) { + pGD->winSizeX = 896; + pGD->plnSizeX = 896; + } + break; + default: + if (res_mode->xres == 800) { + pGD->winSizeX = 1024; + pGD->plnSizeX = 1024; + } + pGD->gdfBytesPP = 1; + pGD->gdfIndex = GDF__8BIT_INDEX; + break; + }
pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS; pGD->pciBase = rinfo->fb_base_phys; @@ -464,14 +832,17 @@ void *video_hw_init(void) pGD->cprBase = rinfo->fb_base_phys; /* Dummy */ /* set up Hardware */
- /* Clear video memory */ - i = pGD->memSize / 4; + /* Clear video memory (only visible screen area) */ + i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4; vm = (unsigned int *) pGD->pciBase; while (i--) *vm++ = 0; /*SetDrawingEngine (bits_per_pixel);*/
- radeon_setmode(); + if (rinfo->family == CHIP_FAMILY_RV280) + radeon_setmode_9200(vesa_idx, bits_per_pixel); + else + radeon_setmode();
return ((void *) pGD); }

On Mon, Feb 11, 2008 at 08:42:08PM +0100, Anatolij Gustschin wrote:
Adds ATI Radeon 9200 support for 1280x1024, 1024x768, 800x600, 640x480 at 24, 16 and 8 bpp. Hope this patch won't screw up X300 and X700 support.
Can someone test/check this issue? :)
Signed-off-by: Anatolij Gustschin agust@denx.de
drivers/video/ati_radeon_fb.c | 401 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 386 insertions(+), 15 deletions(-)
diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c index 0bdaa1c..740a360 100644 --- a/drivers/video/ati_radeon_fb.c +++ b/drivers/video/ati_radeon_fb.c @@ -44,6 +44,7 @@ #include <asm/io.h> #include <malloc.h> #include <video_fb.h> +#include "videomodes.h"
#include <radeon.h> #include "ati_ids.h" @@ -70,6 +71,7 @@ #define PCI_CHIP_RV280_5961 0x5961 #define PCI_CHIP_RV280_5962 0x5962 #define PCI_CHIP_RV280_5964 0x5964 +#define PCI_CHIP_RV280_5C63 0x5C63 #define PCI_CHIP_RV370_5B60 0x5B60 #define PCI_CHIP_RV380_5657 0x5657 #define PCI_CHIP_R420_554d 0x554d @@ -79,6 +81,7 @@ static struct pci_device_id ati_radeon_pci_ids[] = { {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
- {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5C63}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60}, {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657}, {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
@@ -90,12 +93,115 @@ static u16 ati_radeon_id_family_table[][2] = { {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280}, {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280}, {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
- {PCI_CHIP_RV280_5C63, CHIP_FAMILY_RV280}, {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380}, {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380}, {PCI_CHIP_R420_554d, CHIP_FAMILY_R420}, {0, 0}
};
Are you adding a new board here? If so, please provide a separate patch.
+static struct {
- unsigned char idx;
- unsigned int val;
+} pal_16[] = {
- {0x00, 0x00000000},
- {0x00, 0x00000400},
- {0x04, 0x00000400},
- {0x08, 0x00080c08},
- {0x08, 0x00080808},
- {0x10, 0x00101410},
- {0x0c, 0x00080c08},
- {0x18, 0x00181c18},
- {0x10, 0x00101010},
- {0x20, 0x00202420},
- {0x14, 0x00101410},
- {0x28, 0x00292c29},
- {0x18, 0x00181818},
- {0x30, 0x00313431},
- {0x1c, 0x00181c18},
- {0x38, 0x00393c39},
- {0x20, 0x00202020},
- {0x40, 0x00414441},
- {0x24, 0x00202420},
- {0x48, 0x004a4c4a},
- {0x28, 0x00292829},
- {0x50, 0x00525552},
- {0x2c, 0x00292c29},
- {0x58, 0x005a5d5a},
- {0x30, 0x00313031},
- {0x60, 0x00626562},
- {0x34, 0x00313431},
- {0x68, 0x006a6d6a},
- {0x38, 0x00393839},
- {0x70, 0x00737573},
- {0x3c, 0x00393c39},
- {0x78, 0x007b7d7b},
- {0x40, 0x00414041},
- {0x80, 0x00838583},
- {0x44, 0x00414441},
- {0x88, 0x008b8d8b},
- {0x48, 0x004a484a},
- {0x90, 0x00949594},
- {0x4c, 0x004a4c4a},
- {0x98, 0x009c9d9c},
- {0x50, 0x00525052},
- {0xa0, 0x00a4a5a4},
- {0x54, 0x00525552},
- {0xa8, 0x00acaeac},
- {0x58, 0x005a595a},
- {0xb0, 0x00b4b6b4},
- {0x5c, 0x005a5d5a},
- {0xb8, 0x00bdbebd},
- {0x60, 0x00626162},
- {0xc0, 0x00c5c6c5},
- {0x64, 0x00626562},
- {0xc8, 0x00cdcecd},
- {0x68, 0x006a696a},
- {0xd0, 0x00d5d6d5},
- {0x6c, 0x006a6d6a},
- {0xd8, 0x00dedede},
- {0x70, 0x00737173},
- {0xe0, 0x00e6e6e6},
- {0x74, 0x00737573},
- {0xe8, 0x00eeeeee},
- {0x78, 0x007b797b},
- {0xf0, 0x00f6f6f6},
- {0x7c, 0x007b7d7b},
- {0xf8, 0x00ffffff},
- {0x80, 0x00838183},
- {0x84, 0x00838583},
- {0x88, 0x008b898b},
- {0x8c, 0x008b8d8b},
- {0x90, 0x00949194},
- {0x94, 0x00949594},
- {0x98, 0x009c999c},
- {0x9c, 0x009c9d9c},
- {0xa0, 0x00a4a1a4},
- {0xa4, 0x00a4a5a4},
- {0xa8, 0x00acaaac},
- {0xac, 0x00acaeac},
- {0xb0, 0x00b4b2b4},
- {0xb4, 0x00b4b6b4},
- {0xb8, 0x00bdbabd},
- {0xbc, 0x00bdbebd},
- {0xc0, 0x00c5c2c5},
- {0xc4, 0x00c5c6c5},
- {0xc8, 0x00cdcacd},
- {0xcc, 0x00cdcecd},
- {0xd0, 0x00d5d2d5},
- {0xd4, 0x00d5d6d5},
- {0xd8, 0x00dedade},
- {0xdc, 0x00dedede},
- {0xe0, 0x00e6e2e6},
- {0xe4, 0x00e6e6e6},
- {0xe8, 0x00eeeaee},
- {0xec, 0x00eeeeee},
- {0xf0, 0x00f6f2f6},
- {0xf4, 0x00f6f6f6},
- {0xf8, 0x00fffaff},
- {0xfc, 0x00ffffff},
+};
u16 get_radeon_id_family(u16 device) { int i; @@ -350,6 +456,196 @@ void radeon_setmode(void) radeon_write_pll_regs(rinfo, mode); }
+static void set_pal_16(void) +{
- int i;
- for (i = 0; i < 96; i++) {
OUTREG8(PALETTE_INDEX, pal_16[i].idx);
OUTREG(PALETTE_DATA, pal_16[i].val);
- }
+}
+static void set_pal_24(void) +{
- int idx, val = 0;
- for (idx = 0; idx < 256; idx++) {
OUTREG8(PALETTE_INDEX, idx);
OUTREG(PALETTE_DATA, val);
val += 0x00010101;
- }
+}
+void radeon_setmode_9200(int vesa_idx, int bpp) +{
- struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
- unsigned long dp_gm_cntl;
- mode->crtc_gen_cntl = 0x03000600;
- mode->surface_cntl = 0x00a00000;
- dp_gm_cntl = 0x100036d2;
- mode->crtc_ext_cntl = 0x00008048;
- mode->dac_cntl = 0xff002102;
- mode->crtc_offset_cntl = 0x00008000;
- if (bpp == 16) {
mode->crtc_gen_cntl = 0x03000400;
dp_gm_cntl = 0x100034d2;
mode->surface_cntl = 0x00500000;
- } else if (bpp == 8) {
mode->crtc_gen_cntl = 0x03000200;
dp_gm_cntl = 0x100032d2;
mode->surface_cntl = 0x00000000;
- }
- if (vesa_idx == RES_MODE_640x480 && bpp == 8) {
mode->dac_cntl = 0xff002100;
mode->crtc_offset_cntl = 0x00000000;
- }
- switch (vesa_idx) {
- case RES_MODE_1280x1024:
+#if 1 /* @ 60 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x000e0528;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010060;
+#else /* @ 75 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x00120508;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010078;
+#endif
Mmm... better adding a configuration define here or just remove the unused code.
switch (bpp) {
case 24:
mode->surf_info[0] = 0x00a10140;
mode->surf_upper_bound[0] = 0x004fffff;
break;
case 16:
mode->surf_info[0] = 0x005100a0;
mode->surf_upper_bound[0] = 0x0027ffff;
break;
default: /* 8 bpp */
mode->surf_info[0] = 0x00010050;
mode->surf_upper_bound[0] = 0x0013ffff;
break;
}
break;
- case RES_MODE_1024x768:
+#if 1 /* @ 60 Hz */
mode->crtc_h_total_disp = 0x007f00a7;
mode->crtc_h_sync_strt_wid = 0x00910410;
mode->crtc_v_total_disp = 0x02ff0325;
mode->crtc_v_sync_strt_wid = 0x00860302;
mode->crtc_pitch = 0x00800080;
mode->ppll_div_3 = 0x00020074;
+#else /* @ 75 Hz */
mode->crtc_h_total_disp = 0x007f00a3;
mode->crtc_h_sync_strt_wid = 0x000c0408;
mode->crtc_v_total_disp = 0x02ff031f;
mode->crtc_v_sync_strt_wid = 0x00030300;
mode->crtc_pitch = 0x00800080;
mode->ppll_div_3 = 0x0002008c;
+#endif
Ditto.
switch (bpp) {
case 24:
mode->surf_info[0] = 0x00a10100;
mode->surf_upper_bound[0] = 0x002fffff;
break;
case 16:
mode->surf_info[0] = 0x00510080;
mode->surf_upper_bound[0] = 0x0017ffff;
break;
default: /* 8 bpp */
mode->surf_info[0] = 0x00010040;
mode->surf_upper_bound[0] = 0x000bffff;
break;
}
break;
- case RES_MODE_800x600:
mode->crtc_h_total_disp = 0x00630083;
mode->crtc_h_sync_strt_wid = 0x00100340;
mode->crtc_v_total_disp = 0x02570273;
mode->crtc_v_sync_strt_wid = 0x00040258;
mode->ppll_div_3 = 0x0003008e;
switch (bpp) {
case 24:
mode->crtc_pitch = 0x00680068;
mode->surf_info[0] = 0x00a100d0;
mode->surf_upper_bound[0] = 0x001edfff;
break;
case 16:
mode->crtc_pitch = 0x00700070;
mode->surf_info[0] = 0x00510070;
mode->surf_upper_bound[0] = 0x00109fff;
break;
default: /* 8 bpp */
mode->crtc_pitch = 0x00800080;
mode->surf_info[0] = 0x00010040;
mode->surf_upper_bound[0] = 0x00097fff;
break;
}
break;
- default: /* RES_MODE_640x480 */
mode->crtc_h_total_disp = 0x4f0063;
mode->crtc_h_sync_strt_wid = 0x8c02a2;
mode->crtc_v_total_disp = 0x01df020c;
mode->crtc_v_sync_strt_wid = 0x8201ea;
mode->crtc_pitch = 0x00500050;
mode->ppll_div_3 = 0x00030059;
switch (bpp) {
case 24:
mode->surf_info[0] = 0x00a100a0;
mode->surf_upper_bound[0] = 0x0012bfff;
break;
case 16:
mode->surf_info[0] = 0x00510050;
mode->surf_upper_bound[0] = 0x00095fff;
break;
default: /* 8 bpp */
break;
}
break;
- }
- OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
- OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
- OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
- OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
- OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
- OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
- OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
- OUTREG(CRTC_OFFSET, 0);
- OUTREG(CRTC_OFFSET_CNTL, mode->crtc_offset_cntl);
- OUTREG(CRTC_PITCH, mode->crtc_pitch);
- mode->clk_cntl_index = 0x300;
- mode->ppll_ref_div = 0xc;
- radeon_write_pll_regs(rinfo, mode);
- OUTREG(SURFACE0_INFO, mode->surf_info[0]);
- OUTREG(SURFACE0_LOWER_BOUND, 0);
- OUTREG(SURFACE0_UPPER_BOUND, mode->surf_upper_bound[0]);
- OUTREG(SURFACE_CNTL, mode->surface_cntl);
- OUTREG(DP_GUI_MASTER_CNTL, dp_gm_cntl);
- OUTREG(0x0000325c, 0x0000000f);
- if (bpp == 24)
set_pal_24();
- else if (bpp == 16)
set_pal_16();
- free(mode);
+}
#include "../bios_emulator/include/biosemu.h" extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
@@ -421,29 +717,101 @@ GraphicDevice ctfb; void *video_hw_init(void) { GraphicDevice *pGD = (GraphicDevice *) & ctfb;
- int i; u32 *vm;
char *penv;
unsigned long t1, hsynch, vsynch;
int bits_per_pixel, i, tmp, vesa_idx = 0, videomode;
struct ctfb_res_modes *res_mode;
struct ctfb_res_modes var_mode;
rinfo = malloc(sizeof(struct radeonfb_info));
printf("Video: "); if(radeon_probe(rinfo)) { printf("No radeon video card found!\n"); return NULL; }
- /* fill in Graphic device struct */
- sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640,
480, 16, (1000 / 1000),
(2000 / 1000));
- printf ("%s\n", pGD->modeIdent);
- tmp = 0;
- videomode = CFG_DEFAULT_VIDEO_MODE;
- /* get video mode via environment */
- if ((penv = getenv ("videomode")) != NULL) {
/* deceide if it is a string */
if (penv[0] <= '9') {
videomode = (int) simple_strtoul (penv, NULL, 16);
tmp = 1;
}
- } else {
tmp = 1;
- }
- if (tmp) {
/* parameter are vesa modes */
/* search params */
for (i = 0; i < VESA_MODES_COUNT; i++) {
if (vesa_modes[i].vesanr == videomode)
break;
}
if (i == VESA_MODES_COUNT) {
printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
i = 0;
}
res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex];
bits_per_pixel = vesa_modes[i].bits_per_pixel;
vesa_idx = vesa_modes[i].resindex;
- } else {
res_mode = (struct ctfb_res_modes *) &var_mode;
bits_per_pixel = video_get_params (res_mode, penv);
- }
- pGD->winSizeX = 640;
- pGD->winSizeY = 480;
- pGD->plnSizeX = 640;
- pGD->plnSizeY = 480;
- /* calculate hsynch and vsynch freq (info only) */
- t1 = (res_mode->left_margin + res_mode->xres +
res_mode->right_margin + res_mode->hsync_len) / 8;
- t1 *= 8;
- t1 *= res_mode->pixclock;
- t1 /= 1000;
- hsynch = 1000000000L / t1;
- t1 *= (res_mode->upper_margin + res_mode->yres +
res_mode->lower_margin + res_mode->vsync_len);
- t1 /= 1000;
- vsynch = 1000000000L / t1;
- pGD->gdfBytesPP = 1;
- pGD->gdfIndex = GDF__8BIT_INDEX;
/* fill in Graphic device struct */
sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
res_mode->yres, bits_per_pixel, (hsynch / 1000),
(vsynch / 1000));
printf ("%s\n", pGD->modeIdent);
pGD->winSizeX = res_mode->xres;
pGD->winSizeY = res_mode->yres;
pGD->plnSizeX = res_mode->xres;
pGD->plnSizeY = res_mode->yres;
switch (bits_per_pixel) {
case 24:
pGD->gdfBytesPP = 4;
pGD->gdfIndex = GDF_32BIT_X888RGB;
if (res_mode->xres == 800) {
pGD->winSizeX = 832;
pGD->plnSizeX = 832;
}
break;
case 16:
pGD->gdfBytesPP = 2;
pGD->gdfIndex = GDF_16BIT_565RGB;
if (res_mode->xres == 800) {
pGD->winSizeX = 896;
pGD->plnSizeX = 896;
}
break;
default:
if (res_mode->xres == 800) {
pGD->winSizeX = 1024;
pGD->plnSizeX = 1024;
}
pGD->gdfBytesPP = 1;
pGD->gdfIndex = GDF__8BIT_INDEX;
break;
}
pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS; pGD->pciBase = rinfo->fb_base_phys;
@@ -464,14 +832,17 @@ void *video_hw_init(void) pGD->cprBase = rinfo->fb_base_phys; /* Dummy */ /* set up Hardware */
- /* Clear video memory */
- i = pGD->memSize / 4;
- /* Clear video memory (only visible screen area) */
- i = pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP / 4; vm = (unsigned int *) pGD->pciBase; while (i--) *vm++ = 0; /*SetDrawingEngine (bits_per_pixel);*/
- radeon_setmode();
if (rinfo->family == CHIP_FAMILY_RV280)
radeon_setmode_9200(vesa_idx, bits_per_pixel);
else
radeon_setmode();
return ((void *) pGD);
}
1.5.3.3
Suggestion: your patch is filled by several magic numbers, maybe adding some defines can improve its readability. :)
Ciao,
Rodolfo

Hello,
Rodolfo Giometti wrote:
On Mon, Feb 11, 2008 at 08:42:08PM +0100, Anatolij Gustschin wrote:
Adds ATI Radeon 9200 support for 1280x1024, 1024x768, 800x600, 640x480 at 24, 16 and 8 bpp. Hope this patch won't screw up X300 and X700 support.
Can someone test/check this issue? :)
Signed-off-by: Anatolij Gustschin agust@denx.de
drivers/video/ati_radeon_fb.c | 401 +++++++++++++++++++++++++++++++++++++++-- 1 files changed, 386 insertions(+), 15 deletions(-)
<snip>
@@ -90,12 +93,115 @@ static u16 ati_radeon_id_family_table[][2] = { {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280}, {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280}, {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
- {PCI_CHIP_RV280_5C63, CHIP_FAMILY_RV280}, {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380}, {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380}, {PCI_CHIP_R420_554d, CHIP_FAMILY_R420}, {0, 0}
};
Are you adding a new board here? If so, please provide a separate patch.
Yes. This is a Radeon Mobility 9200 board, which is RV280 based. Ok.
<snip>
+#if 1 /* @ 60 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x000e0528;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010060;
+#else /* @ 75 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x00120508;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010078;
+#endif
Mmm... better adding a configuration define here or just remove the unused code.
Ok, I'm going to drop the unused code then.
<snip>
- radeon_setmode();
if (rinfo->family == CHIP_FAMILY_RV280)
radeon_setmode_9200(vesa_idx, bits_per_pixel);
else
radeon_setmode();
return ((void *) pGD);
}
1.5.3.3
Suggestion: your patch is filled by several magic numbers, maybe adding some defines can improve its readability. :)
Ok, I will try it and resubmit separated patches.
Best regards,
Anatolij

In message 47B38277.6010001@denx.de you wrote:
+#if 1 /* @ 60 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x000e0528;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010060;
+#else /* @ 75 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x00120508;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010078;
+#endif
Mmm... better adding a configuration define here or just remove the unused code.
Ok, I'm going to drop the unused code then.
No, please keep it as reference in case anybody needs this later.
Best regards,
Wolfgang Denk

On Thu, Feb 14, 2008 at 01:39:14AM +0100, Wolfgang Denk wrote:
In message 47B38277.6010001@denx.de you wrote:
+#if 1 /* @ 60 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x000e0528;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010060;
+#else /* @ 75 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x00120508;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010078;
+#endif
Mmm... better adding a configuration define here or just remove the unused code.
Ok, I'm going to drop the unused code then.
No, please keep it as reference in case anybody needs this later.
Uh? =:-o Why did you change your mind? ;)
| Delivery-date: Sun, 01 Apr 2007 15:18:41 +0200 | From: Wolfgang Denk wd@denx.de | To: Rodolfo Giometti giometti@enneenne.com | cc: Markus Klotzb?cher mk@denx.de | Subject: Re: [PATCH] ISP116x HCD (Host Controller Driver) | | [snip] | | Please remove code in "#if 0 ... #endif" blocks. | | [snip] | | Best regards, | | Wolfgang Denk
However I suggested also to add a configuration define, something like:
#if defined(CFG_ATI_RADEON_60HZ) ... #elif defined(CFG_ATI_RADEON_75HZ) ... #else #error "..." #endif
This allow keeping the code in a better style... or we can rewrite it as follow:
/* @ 60 Hz */ mode->crtc_h_total_disp = 0x009f00d2; mode->crtc_h_sync_strt_wid = 0x000e0528; mode->crtc_v_total_disp = 0x03ff0429; mode->crtc_v_sync_strt_wid = 0x00030400; mode->crtc_pitch = 0x00a000a0; mode->ppll_div_3 = 0x00010060;
/* @ 75 Hz * * Still untested. Just use it as reference for future improvemets. * * mode->crtc_h_total_disp = 0x009f00d2; * mode->crtc_h_sync_strt_wid = 0x00120508; * mode->crtc_v_total_disp = 0x03ff0429; * mode->crtc_v_sync_strt_wid = 0x00030400; * mode->crtc_pitch = 0x00a000a0; * mode->ppll_div_3 = 0x00010078; */
Ciao,
Rodolfo

On 10:24 Fri 15 Feb , Rodolfo Giometti wrote:
On Thu, Feb 14, 2008 at 01:39:14AM +0100, Wolfgang Denk wrote:
In message 47B38277.6010001@denx.de you wrote:
+#if 1 /* @ 60 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x000e0528;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010060;
+#else /* @ 75 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x00120508;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010078;
+#endif
Mmm... better adding a configuration define here or just remove the unused code.
Ok, I'm going to drop the unused code then.
No, please keep it as reference in case anybody needs this later.
Uh? =:-o Why did you change your mind? ;)
| Delivery-date: Sun, 01 Apr 2007 15:18:41 +0200 | From: Wolfgang Denk wd@denx.de | To: Rodolfo Giometti giometti@enneenne.com | cc: Markus Klotzb?cher mk@denx.de | Subject: Re: [PATCH] ISP116x HCD (Host Controller Driver) | | [snip] | | Please remove code in "#if 0 ... #endif" blocks. | | [snip] | | Best regards, | | Wolfgang Denk
However I suggested also to add a configuration define, something like:
#if defined(CFG_ATI_RADEON_60HZ) ... #elif defined(CFG_ATI_RADEON_75HZ) ... #else #error "..." #endif
Please use CONFIG and not CFG too allow this parameter in Kconfig
Best Regards, J.

Hello,
Jean-Christophe PLAGNIOL-VILLARD wrote:
On 10:24 Fri 15 Feb , Rodolfo Giometti wrote:
On Thu, Feb 14, 2008 at 01:39:14AM +0100, Wolfgang Denk wrote:
In message 47B38277.6010001@denx.de you wrote:
+#if 1 /* @ 60 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x000e0528;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010060;
+#else /* @ 75 Hz */
mode->crtc_h_total_disp = 0x009f00d2;
mode->crtc_h_sync_strt_wid = 0x00120508;
mode->crtc_v_total_disp = 0x03ff0429;
mode->crtc_v_sync_strt_wid = 0x00030400;
mode->crtc_pitch = 0x00a000a0;
mode->ppll_div_3 = 0x00010078;
+#endif
Mmm... better adding a configuration define here or just remove the unused code.
Ok, I'm going to drop the unused code then.
No, please keep it as reference in case anybody needs this later.
Uh? =:-o Why did you change your mind? ;)
| Delivery-date: Sun, 01 Apr 2007 15:18:41 +0200 | From: Wolfgang Denk wd@denx.de | To: Rodolfo Giometti giometti@enneenne.com | cc: Markus Klotzb?cher mk@denx.de | Subject: Re: [PATCH] ISP116x HCD (Host Controller Driver) | | [snip] | | Please remove code in "#if 0 ... #endif" blocks. | | [snip] | | Best regards, | | Wolfgang Denk
However I suggested also to add a configuration define, something like:
#if defined(CFG_ATI_RADEON_60HZ) ... #elif defined(CFG_ATI_RADEON_75HZ) ... #else #error "..." #endif
Please use CONFIG and not CFG too allow this parameter in Kconfig
new and already applied patch uses CONFIG_RADEON_VREFRESH_75HZ and another case (@ 60HZ) is just default case.
Best Regards,
Anatolij
participants (4)
-
Anatolij Gustschin
-
Jean-Christophe PLAGNIOL-VILLARD
-
Rodolfo Giometti
-
Wolfgang Denk