diff options
Diffstat (limited to 'src/southbridge/amd/cs5530/vga.c')
-rw-r--r-- | src/southbridge/amd/cs5530/vga.c | 495 |
1 files changed, 0 insertions, 495 deletions
diff --git a/src/southbridge/amd/cs5530/vga.c b/src/southbridge/amd/cs5530/vga.c deleted file mode 100644 index 66ab239efc..0000000000 --- a/src/southbridge/amd/cs5530/vga.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Juergen Beisert <juergen@kreuzholzen.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -/** - * @brief Activate the VGA feature in a Geode GX1 based system with one - * of five possible VESA modes: VGA, SVGA, XGA, 4:3 SXGA and 5:4 SXGA. - * Also it is prepared to display a splash screen. - * - * In a Geode GX1 environment the companion CS5530 is the VGA - * interface only. It contains a PLL for pixel clock generation, - * DACs to generate the analogue RGB signals, drivers for HSYNC - * and VSYNC and drivers for a digital flatpanel. - * The graphic feature itself (framebuffer, acceleration unit) - * is not part of this device. It is part of the CPU device. - * But both depend on each other, we cannot divide them into - * different drivers. So this driver is not only a CS5530 driver, - * it is also a Geode GX1 chipset graphic driver. - */ -#include <arch/io.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ops.h> -#include <device/pci_ids.h> -#include <console/console.h> -#include <cpu/amd/gx1def.h> -#include <delay.h> - -#if CONFIG_GX1_VIDEO -/* - * Some register descriptions that are no listed in cpu/amd/gx1def.h - */ -#define CS5530_DOT_CLK_CONFIG 0x0024 -#define CS5530_DISPLAY_CONFIG 0x0004 - -#define DC_FB_ST_OFFSET 0x8310 /* framebuffer start offset */ -#define DC_CB_ST_OFFSET 0x8314 /* compression start offset */ -#define DC_CURS_ST_OFFSET 0x8318 /* cursor start offset */ -#define DC_VID_ST_OFFSET 0x8320 /* video start offset */ -#define DC_LINE_DELTA 0x8324 /* fb and cb skip counts */ -#define DC_BUF_SIZE 0x8328 /* fb and cb line size */ -#define DC_H_TIMING_1 0x8330 /* horizontal timing... */ -#define DC_H_TIMING_2 0x8334 -#define DC_H_TIMING_3 0x8338 -#define DC_FP_H_TIMING 0x833C -#define DC_V_TIMING_1 0x8340 /* vertical timing... */ -#define DC_V_TIMING_2 0x8344 -#define DC_V_TIMING_3 0x8348 -#define DC_FP_V_TIMING 0x834C -#define DC_TIMING_CFG 0x8308 -#define DC_OUTPUT_CFG 0x830C - -/** - * what colour depth should be used as default (in bpp) - * Note: Currently no other value than 16 is supported - */ -#define COLOUR_DEPTH 16 - -/** - * Support for a few basic video modes - * Note: all modes only for CRT. The flatpanel feature is - * not supported here (due to the lack of hardware to test) - */ -struct video_mode { - int pixel_clock; /*<< pixel clock in Hz */ - unsigned long pll_value; /*<< pll register value for this clock */ - - int visible_pixel; /*<< visible pixels in one line */ - int hsync_start; /*<< start of hsync behind visible pixels */ - int hsync_end; /*<< end of hsync behind its start */ - int line_length; /*<< whole line length */ - - int visible_lines; /*<< visible lines on screen */ - int vsync_start; /*<< vsync start behind last visible line */ - int vsync_end; /*<< end of vsync behind its start */ - int picture_length; /*<< whole screen length */ - - int sync_pol; /*<< 0: low, 1: high, bit 0 hsync, bit 1 vsync */ -}; - -/* - * values for .sync_pol in struct video_mode - */ -#define HSYNC_HIGH_POL 0 -#define HSYNC_LOW_POL 1 -#define VSYNC_HIGH_POL 0 -#define VSYNC_LOW_POL 2 - -/** - * 640x480 @ 72Hz hsync: 37.9kHz - * VESA standard mode for classic 4:3 monitors - * Copied from X11: - * ModeLine "640x480" 31.5 640 664 704 832 480 489 491 520 -hsync -vsync - */ -static const struct video_mode mode_640x480 = { - .pixel_clock = 31500000, - .pll_value = 0x33915801, - - .visible_pixel = 640, - .hsync_start = 664, - .hsync_end = 704, /* 1.27 us sync length */ - .line_length = 832, /* 26.39us */ - - .visible_lines = 480, - .vsync_start = 489, - .vsync_end = 491, - .picture_length = 520, /* 13.89ms */ - - .sync_pol = HSYNC_LOW_POL | VSYNC_LOW_POL, -}; - -/** - * 800x600 @ 72Hz hsync: 48.1kHz - * VESA standard mode for classic 4:3 monitors - * Copied from X11: - * ModeLine "800x600" 50.0 800 856 976 1040 600 637 643 666 +hsync +vsync - */ -static const struct video_mode mode_800x600 = { - .pixel_clock = 50000000, - .pll_value = 0x23088801, - - .visible_pixel = 800, - .hsync_start = 856, - .hsync_end = 976, - .line_length = 1040, /* 20.8us */ - - .visible_lines = 600, - .vsync_start = 637, - .vsync_end = 643, - .picture_length = 666, /* 13.89ms */ - - .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL, -}; - -/** - * 1024x768 @ 70Hz (VESA) hsync: 56.5kHz - * Standard mode for classic 4:3 monitors - * Copied from X11: - * ModeLine "1024x768" 75.0 1024 1048 1184 1328 768 771 777 806 -hsync -vsync - */ -static const struct video_mode mode_1024x768 = { - .pixel_clock = 75000000, - .pll_value = 0x37E22801, - - .visible_pixel = 1024, - .hsync_start = 1048, - .hsync_end = 1184, - .line_length = 1328, /* 17.7us */ - - .visible_lines = 768, - .vsync_start = 771, - .vsync_end = 777, - .picture_length = 806, /* 14.3us */ - - .sync_pol = HSYNC_LOW_POL | VSYNC_LOW_POL, -}; - -/** - * 1280x960 @ 60Hz (VESA) hsync: 60.0kHz - * Mode for classic 4:3 monitors - * Copied from X11: - * ModeLine "1280x960" 108.0 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync - */ -static const struct video_mode mode_1280x960 = { - .pixel_clock = 108000000, - .pll_value = 0x2710C805, - - .visible_pixel = 1280, - .hsync_start = 1376, - .hsync_end = 1488, - .line_length = 1800, /* 16.67us */ - - .visible_lines = 960, - .vsync_start = 961, - .vsync_end = 964, - .picture_length = 1000, /* 16.67ms */ - - .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL, -}; - -/** - * 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz - * Mode for modern 5:4 flat screens - * Copied from X11: - * ModeLine "1280x1024" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync - */ -static const struct video_mode mode_1280x1024 = { - .pixel_clock = 108000000, - .pll_value = 0x2710C805, - - .visible_pixel = 1280, - .hsync_start = 1328, - .hsync_end = 1440, - .line_length = 1688, /* 15.6us */ - - .visible_lines = 1024, - .vsync_start = 1025, - .vsync_end = 1028, - .picture_length = 1066, - - .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL, -}; - -/** - * List of supported common modes - */ -static const struct video_mode *modes[] = { - &mode_640x480, /* CONFIG_GX1_VIDEOMODE = 0 */ - &mode_800x600, /* CONFIG_GX1_VIDEOMODE = 1 */ - &mode_1024x768, /* CONFIG_GX1_VIDEOMODE = 2 */ - &mode_1280x960, /* CONFIG_GX1_VIDEOMODE = 3 */ - &mode_1280x1024 /* CONFIG_GX1_VIDEOMODE = 4 */ -}; - -/* make a sanity check at buildtime */ -#if CONFIG_GX1_VIDEOMODE > 4 -# error Requested video mode is unknown! -#endif - -/** - * Setup the pixel PLL in the companion chip - * @param[in] base register's base address - * @param[in] pll_val pll register value to be set - * - * The PLL to program here is located in the CS5530 - */ -static void cs5530_set_clock_frequency(u32 io_base, unsigned long pll_val) -{ - unsigned long reg; - - /* disable the PLL first, reset and power it down */ - reg = read32(io_base+CS5530_DOT_CLK_CONFIG) & ~0x20; - reg |= 0x80000100; - write32(io_base+CS5530_DOT_CLK_CONFIG, reg); - - /* write the new PLL setting */ - reg |= (pll_val & ~0x80000920); - write32(io_base+CS5530_DOT_CLK_CONFIG, reg); - - mdelay(1); /* wait for control voltage to be 0V */ - - /* enable the PLL */ - reg |= 0x00000800; - write32(io_base+CS5530_DOT_CLK_CONFIG, reg); - - /* clear reset */ - reg &= ~0x80000000; - write32(io_base+CS5530_DOT_CLK_CONFIG, reg); - - /* clear bypass */ - reg &= ~0x00000100; - write32(io_base+CS5530_DOT_CLK_CONFIG, reg); -} - -/** - * Setup memory layout - * @param[in] gx_base GX register area - * @param[in] mode Data about the video mode to setup - * - * Memory layout must be setup in Geode GX1's chipset. - * Note: This routine assumes unlocked DC registers. - * Note: Using compressed buffer is not supported yet! - * (makes more sense later, but not while booting) - * - * At this point a check is missed if the requested video - * mode is possible with the provided video memory. - * Check if symbol CONFIG_VIDEO_MB is at least: - * - 1 (=1MiB) for VGA and SVGA - * - 2 (=2MiB) for XGA - * - 4 (=4MiB) for SXGA - */ -static void dc_setup_layout(u32 gx_base, const struct video_mode *mode) -{ - u32 base = 0x00000000; - - write32(gx_base + DC_FB_ST_OFFSET, base); - - base += (COLOUR_DEPTH>>3) * mode->visible_pixel * mode->visible_lines; - - write32(gx_base + DC_CB_ST_OFFSET, base); - write32(gx_base + DC_CURS_ST_OFFSET, base); - write32(gx_base + DC_VID_ST_OFFSET, base); - write32(gx_base + DC_LINE_DELTA, ((COLOUR_DEPTH>>3) * mode->visible_pixel) >> 2); - write32(gx_base + DC_BUF_SIZE, ((COLOUR_DEPTH>>3) * mode->visible_pixel) >> 3); -} - -/** - * Setup the HSYNC/VSYNC, active video timing - * @param[in] gx_base GX register area - * @param[in] mode Data about the video mode to setup - * - * Sync signal generation is done in Geode GX1's chipset. - * Note: This routine assumes unlocked DC registers - * - * |<------------------------- htotal ----------------------------->| - * |<------------ hactive -------------->| | - * | hblankstart-->| | - * | hblankend-->| - * | hsyncstart-->| | - * | hsyncend-->| | - * |#####################################___________________________| RGB data - * |______________________________________________---------_________| HSYNC - * - * |<------------------------- vtotal ----------------------------->| - * |<------------ vactive -------------->| | - * | vblankstart-->| | - * | vblankend-->| - * | vsyncstart-->| | - * | vsyncend-->| | - * |#####################################___________________________| line data - * |______________________________________________---------_________| YSYNC - */ -static void dc_setup_timing(u32 gx_base, const struct video_mode *mode) -{ - u32 hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal; - u32 vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal; - - hactive = mode->visible_pixel & 0x7FF; - hblankstart = hactive; - hsyncstart = mode->hsync_start & 0x7FF; - hsyncend = mode->hsync_end & 0x7FF; - hblankend = mode->line_length & 0x7FF; - htotal = hblankend; - - vactive = mode->visible_lines & 0x7FF; - vblankstart = vactive; - vsyncstart = mode->vsync_start & 0x7FF; - vsyncend = mode->vsync_end & 0x7FF; - vblankend = mode->picture_length & 0x7FF; - vtotal = vblankend; - - /* row description */ - write32(gx_base + DC_H_TIMING_1, (hactive - 1) | ((htotal - 1) << 16)); - /* horizontal blank description */ - write32(gx_base + DC_H_TIMING_2, (hblankstart - 1) | ((hblankend - 1) << 16)); - /* horizontal sync description */ - write32(gx_base + DC_H_TIMING_3, (hsyncstart - 1) | ((hsyncend - 1) << 16)); - write32(gx_base + DC_FP_H_TIMING, (hsyncstart - 1) | ((hsyncend - 1) << 16)); - - /* line description */ - write32(gx_base + DC_V_TIMING_1, (vactive - 1) | ((vtotal - 1) << 16)); - /* vertical blank description */ - write32(gx_base + DC_V_TIMING_2, (vblankstart - 1) | ((vblankend - 1) << 16)); - /* vertical sync description */ - write32(gx_base + DC_V_TIMING_3, (vsyncstart - 1) | ((vsyncend - 1) << 16)); - write32(gx_base + DC_FP_V_TIMING, (vsyncstart - 2) | ((vsyncend - 2) << 16)); -} - -/** - * Setup required internals to bring the mode up and running - * @param[in] gx_base GX register area - * @param[in] mode Data about the video mode to setup - * - * Must be setup in Geode GX1's chipset. - * Note: This routine assumes unlocked DC registers. - */ -static void cs5530_activate_mode(u32 gx_base, const struct video_mode *mode) -{ - write32(gx_base + DC_GENERAL_CFG, 0x00000080); - mdelay(1); - dc_setup_layout(gx_base,mode); - dc_setup_timing(gx_base,mode); - - write32(gx_base + DC_GENERAL_CFG, 0x2000C581); - write32(gx_base + DC_TIMING_CFG, 0x0000002F); - write32(gx_base + DC_OUTPUT_CFG, 0x00003004); -} - -/** - * Activate the current mode to be "visible" outside - * @param[in] gx_base GX register area - * @param[in] mode Data about the video mode to setup - * - * As we now activate the interface this must be done - * in the CS5530 - */ -static void cs5530_activate_video(u32 io_base, const struct video_mode *mode) -{ - u32 val; - - val = (u32)mode->sync_pol << 8; - write32(io_base + CS5530_DISPLAY_CONFIG, val | 0x0020002F); -} - -#if CONFIG_SPLASH_GRAPHIC - -/* - * This bitmap file must provide: - * int width: pixel count in one line - * int height: line count - * int colours: ount of used colour - * unsigned long colour_map[]: RGB 565 colours to be used - * unsigned char bitmap[]: index per pixel into colour_map[], width*height pixels - */ -#include "bitmap.c" - -/* - * show a boot splash screen in the right lower corner of the screen - * swidth: screen width in pixel - * sheight: screen height in lines - * pitch: line pitch in bytes - * base: screen base address - * - * This routine assumes we are using a 16 bit colour depth! - */ -static void show_boot_splash_16(u32 swidth, u32 sheight, u32 pitch,void *base) -{ - int word_count,i; - unsigned short *adr; - u32 xstart,ystart,x,y; - /* - * fill the screen with the colour of the - * left top pixel in the graphic - */ - word_count = pitch * sheight; - adr = (unsigned short*)base; - for (i = 0; i < word_count; i++, adr++) - *adr = colour_map[bitmap[0]]; - - /* - * paint the splash - */ - xstart = swidth-width; - ystart = sheight-height; - for (y = 0; y < height; y++) { - adr=(unsigned short*)(base + pitch*(y+ystart) + 2 * xstart); - for (x = 0; x < width; x++) { - *adr=(unsigned short)colour_map[(int)bitmap[x + y * width]]; - adr++; - } - } -} -#else -# define show_boot_splash_16(w, x, y , z) -#endif - -/** - * coreboot management part - * @param[in] dev Info about the PCI device to initialise - */ -static void cs5530_vga_init(device_t dev) -{ - const struct video_mode *mode; - u32 io_base, gx_base; - - io_base = pci_read_config32(dev, 0x10); - gx_base = GX_BASE; - mode = modes[CONFIG_GX1_VIDEOMODE]; - - printk(BIOS_DEBUG, "Setting up video mode %dx%d with %d Hz clock\n", - mode->visible_pixel, mode->visible_lines, mode->pixel_clock); - - cs5530_set_clock_frequency(io_base, mode->pll_value); - - write32(gx_base + DC_UNLOCK, DC_UNLOCK_MAGIC); - - show_boot_splash_16(mode->visible_pixel, mode->visible_lines, - mode->visible_pixel * (COLOUR_DEPTH>>3), (void*)(GX_BASE + 0x800000)); - - cs5530_activate_mode(gx_base, mode); - - cs5530_activate_video(io_base, mode); - write32(gx_base + DC_UNLOCK, 0x00000000); -} - -static struct device_operations vga_ops = { - .read_resources = pci_dev_read_resources, - .set_resources = pci_dev_set_resources, - .enable_resources = pci_dev_enable_resources, - .init = cs5530_vga_init, - .enable = NULL, /* not required */ -}; - -static const struct pci_driver vga_pci_driver __pci_driver = { - .ops = &vga_ops, - .vendor = PCI_VENDOR_ID_CYRIX, - .device = PCI_DEVICE_ID_CYRIX_5530_VIDEO, -}; - -#endif /* #if CONFIG_GX1_VIDEO */ |