Fuloong video init support.

* include/grub/vga.h (grub_vga_write_arx): inb monochrome address as
	well.
	(grub_vga_read_arx): New function.
	* grub-core/video/sis315pro.c (GRUB_SIS315PRO_MMIO_SPACE): New
	definition.
	(framebuffer): New members io, mmioptr and mmiobase.
	(read_sis_cmd): New function.
	(write_sis_cmd): Likewise.
	(grub_video_sis315pro_setup): Do the initialisation. Use 640x480
	rather than 640x400.
	* grub-core/video/sis315_init.c: New file.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-05-16 02:34:58 +02:00
parent c3fc520c0d
commit 736e0ade54
3 changed files with 377 additions and 4 deletions

View File

@ -0,0 +1,158 @@
static const struct { grub_uint8_t reg; grub_uint8_t val; } sr_dump [] =
{
{ 0x28, 0x81 },
{ 0x2a, 0x00 },
{ 0x29, 0xe1 },
{ 0x2b, 0x81 },
{ 0x2d, 0x00 },
{ 0x2c, 0xe1 },
{ 0x2e, 0x81 },
{ 0x30, 0x00 },
{ 0x2f, 0xe1 },
{ 0x28, 0x01 },
{ 0x29, 0x22 },
{ 0x28, 0x3b },
{ 0x29, 0x22 },
{ 0x2a, 0x01 },
{ 0x2e, 0x01 },
{ 0x2f, 0x22 },
{ 0x2e, 0x3b },
{ 0x2f, 0x22 },
{ 0x30, 0x01 },
{ 0x15, 0x00 },
{ 0x1b, 0x30 },
{ 0x16, 0x0f },
{ 0x16, 0x8f },
{ 0x17, 0xba },
{ 0x16, 0x0f },
{ 0x16, 0x8f },
{ 0x1f, 0x00 },
{ 0x20, 0x20 },
{ 0x23, 0xf6 },
{ 0x24, 0x0d },
{ 0x25, 0x33 },
{ 0x21, 0x84 },
{ 0x22, 0x00 },
{ 0x27, 0x1f },
{ 0x31, 0x00 },
{ 0x33, 0x00 },
{ 0x32, 0x11 },
{ 0x25, 0x33 },
{ 0x05, 0x86 },
{ 0x01, 0x20 },
{ 0x32, 0x11 },
{ 0x1e, 0x00 },
{ 0x1d, 0x00 },
{ 0x00, 0x03 },
{ 0x01, 0x21 },
{ 0x02, 0x0f },
{ 0x03, 0x00 },
{ 0x04, 0x0e },
{ 0x0a, 0x00 },
{ 0x0b, 0x00 },
{ 0x0c, 0x00 },
{ 0x0d, 0x00 },
{ 0x0e, 0x00 },
{ 0x37, 0x00 },
{ 0x0a, 0x00 },
{ 0x0b, 0x00 },
{ 0x0c, 0x05 },
{ 0x0e, 0x00 },
{ 0x0e, 0x00 },
{ 0x10, 0x0b },
{ 0x31, 0x00 },
{ 0x2b, 0x01 },
{ 0x2c, 0xe1 },
{ 0x2b, 0x1b },
{ 0x2c, 0xe1 },
{ 0x2d, 0x01 },
{ 0x3d, 0x00 },
{ 0x08, 0x84 },
{ 0x09, 0x00 },
{ 0x3d, 0x01 },
{ 0x1f, 0x00 },
{ 0x06, 0x02 },
{ 0x0f, 0x00 },
{ 0x17, 0xba },
{ 0x21, 0xa4 },
{ 0x32, 0x11 },
{ 0x07, 0x18 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x01, 0x01 },
{ 0x21, 0x84 },
{ 0x01, 0x21 },
{ 0x16, 0x8f },
{ 0x18, 0xa9 },
{ 0x19, 0xa0 },
{ 0x1b, 0x30 },
{ 0x17, 0xb8 },
{ 0x19, 0xa3 },
{ 0x13, 0x00 },
{ 0x14, 0x00 },
{ 0x14, 0x02 },
{ 0x15, 0x00 },
{ 0x16, 0x0f },
{ 0x16, 0x8f },
{ 0x1d, 0x00 },
{ 0x14, 0x00 },
{ 0x14, 0x01 },
{ 0x15, 0x00 },
{ 0x16, 0x0f },
{ 0x16, 0x8f },
{ 0x1d, 0x00 },
{ 0x14, 0x01 },
{ 0x14, 0x01 },
{ 0x15, 0x10 },
{ 0x13, 0x35 },
{ 0x14, 0x51 },
{ 0x16, 0x0f },
{ 0x16, 0x8f },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x11 },
{ 0x1d, 0x11 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x1d, 0x00 },
{ 0x17, 0xba },
{ 0x19, 0xa0 },
{ 0x19, 0xa0 },
{ 0x01, 0x01 },
{ 0x16, 0x0f },
{ 0x18, 0xa9 },
{ 0x19, 0xa0 },
{ 0x1b, 0x30 },
{ 0x21, 0xa4 },
{ 0x05, 0x86 },
};
static const grub_uint8_t gr[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@ -30,6 +30,7 @@
#define GRUB_SIS315PRO_PCIID 0x03251039
#define GRUB_SIS315PRO_TOTAL_MEMORY_SPACE 0x800000
#define GRUB_SIS315PRO_MMIO_SPACE 0x1000
static struct
{
@ -39,9 +40,26 @@ static struct
grub_uint8_t *ptr;
int mapped;
grub_uint32_t base;
grub_uint32_t mmiobase;
volatile grub_uint32_t *mmioptr;
grub_pci_device_t dev;
grub_port_t io;
} framebuffer;
static grub_uint8_t
read_sis_cmd (grub_uint8_t addr)
{
grub_outb (addr, framebuffer.io + 0x44);
return grub_inb (framebuffer.io + 0x45);
}
static void
write_sis_cmd (grub_uint8_t val, grub_uint8_t addr)
{
grub_outb (addr, framebuffer.io + 0x44);
grub_outb (val, framebuffer.io + 0x45);
}
#ifndef TEST
static grub_err_t
grub_video_sis315pro_video_init (void)
@ -63,6 +81,8 @@ grub_video_sis315pro_video_fini (void)
}
#endif
#include "sis315_init.c"
static grub_err_t
grub_video_sis315pro_setup (unsigned int width, unsigned int height,
unsigned int mode_type,
@ -71,6 +91,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
int depth;
grub_err_t err;
int found = 0;
unsigned i;
#ifndef TEST
auto int NESTED_FUNC_ATTR find_card (grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)));
@ -89,7 +110,12 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
found = 1;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
framebuffer.base = grub_pci_read (addr);
framebuffer.base = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
framebuffer.mmiobase = grub_pci_read (addr) & GRUB_PCI_ADDR_MEM_MASK;
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG2);
framebuffer.io = (grub_pci_read (addr) & GRUB_PCI_ADDR_IO_MASK)
+ GRUB_MACHINE_PCI_IO_BASE;
framebuffer.dev = dev;
return 1;
@ -99,7 +125,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
depth = (mode_type & GRUB_VIDEO_MODE_TYPE_DEPTH_MASK)
>> GRUB_VIDEO_MODE_TYPE_DEPTH_POS;
if ((width != 640 && width != 0) || (height != 400 && height != 0)
if ((width != 640 && width != 0) || (height != 480 && height != 0)
|| (depth != 8 && depth != 0))
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Only 640x400x8 is supported");
@ -110,7 +136,7 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
#endif
/* Fill mode info details. */
framebuffer.mode_info.width = 640;
framebuffer.mode_info.height = 400;
framebuffer.mode_info.height = 480;
framebuffer.mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
framebuffer.mode_info.bpp = 8;
framebuffer.mode_info.bytes_per_pixel = 1;
@ -129,12 +155,49 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
= grub_video_get_blit_format (&framebuffer.mode_info);
#endif
#ifndef TEST
if (found && (framebuffer.base == 0 || framebuffer.mmiobase == 0))
{
grub_pci_address_t addr;
/* FIXME: choose address dynamically if needed. */
framebuffer.base = 0x40000000;
framebuffer.mmiobase = 0x04000000;
framebuffer.io = 0xb300;
addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG0);
grub_pci_write (addr, framebuffer.base | GRUB_PCI_ADDR_MEM_PREFETCH);
addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG1);
grub_pci_write (addr, framebuffer.mmiobase);
addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_ADDRESS_REG2);
grub_pci_write (addr, framebuffer.io | GRUB_PCI_ADDR_SPACE_IO);
/* Set latency. */
addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_CACHELINE);
grub_pci_write (addr, 0x80004700);
/* Enable address spaces. */
addr = grub_pci_make_address (framebuffer.dev, GRUB_PCI_REG_COMMAND);
grub_pci_write (addr, 0x7);
addr = grub_pci_make_address (framebuffer.dev, 0x30);
grub_pci_write (addr, 0x04060001);
framebuffer.io += GRUB_MACHINE_PCI_IO_BASE;
}
#endif
/* We can safely discard volatile attribute. */
#ifndef TEST
framebuffer.ptr
= (void *) grub_pci_device_map_range (framebuffer.dev,
framebuffer.base,
GRUB_SIS315PRO_TOTAL_MEMORY_SPACE);
framebuffer.mmioptr = grub_pci_device_map_range (framebuffer.dev,
framebuffer.mmiobase,
GRUB_SIS315PRO_MMIO_SPACE);
#endif
framebuffer.mapped = 1;
@ -144,6 +207,145 @@ grub_video_sis315pro_setup (unsigned int width, unsigned int height,
framebuffer.mode_info.height * framebuffer.mode_info.pitch);
#endif
grub_outb (GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY
| GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY
| GRUB_VGA_IO_MISC_UPPER_64K
| GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0
| GRUB_VGA_IO_MISC_28MHZ
| GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS
| GRUB_VGA_IO_MISC_COLOR,
GRUB_VGA_IO_MISC_WRITE + GRUB_MACHINE_PCI_IO_BASE);
grub_vga_sr_write (0x86, 5);
for (i = 6; i <= 0x27; i++)
grub_vga_sr_write (0, i);
for (i = 0x31; i <= 0x3d; i++)
grub_vga_sr_write (0, i);
for (i = 0; i < ARRAY_SIZE (sr_dump); i++)
grub_vga_sr_write (sr_dump[i].val, sr_dump[i].reg);
for (i = 0x30; i < 0x40; i++)
grub_vga_cr_write (0, i);
grub_vga_cr_write (0x77, 0x40);
grub_vga_cr_write (0x77, 0x41);
grub_vga_cr_write (0x00, 0x42);
grub_vga_cr_write (0x5b, 0x43);
grub_vga_cr_write (0x00, 0x44);
grub_vga_cr_write (0x23, 0x48);
grub_vga_cr_write (0xaa, 0x49);
grub_vga_cr_write (0x02, 0x37);
grub_vga_cr_write (0x20, 0x5b);
grub_vga_cr_write (0x00, 0x83);
grub_vga_cr_write (0x80, 0x63);
grub_vga_cr_write (0x0c, GRUB_VGA_CR_VSYNC_END);
grub_vga_cr_write (0x5f, GRUB_VGA_CR_HTOTAL);
grub_vga_cr_write (0x4f, GRUB_VGA_CR_HORIZ_END);
grub_vga_cr_write (0x50, GRUB_VGA_CR_HBLANK_START);
grub_vga_cr_write (0x82, GRUB_VGA_CR_HBLANK_END);
grub_vga_cr_write (0x54, GRUB_VGA_CR_HORIZ_SYNC_PULSE_START);
grub_vga_cr_write (0x80, GRUB_VGA_CR_HORIZ_SYNC_PULSE_END);
grub_vga_cr_write (0x0b, GRUB_VGA_CR_VERT_TOTAL);
grub_vga_cr_write (0x3e, GRUB_VGA_CR_OVERFLOW);
grub_vga_cr_write (0x00, GRUB_VGA_CR_BYTE_PANNING);
grub_vga_cr_write (0x40, GRUB_VGA_CR_CELL_HEIGHT);
grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_START);
grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_END);
grub_vga_cr_write (0x00, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER);
grub_vga_cr_write (0x00, GRUB_VGA_CR_START_ADDR_LOW_REGISTER);
grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_ADDR_HIGH);
grub_vga_cr_write (0x00, GRUB_VGA_CR_CURSOR_ADDR_LOW);
grub_vga_cr_write (0xea, GRUB_VGA_CR_VSYNC_START);
grub_vga_cr_write (0x8c, GRUB_VGA_CR_VSYNC_END);
grub_vga_cr_write (0xdf, GRUB_VGA_CR_VDISPLAY_END);
grub_vga_cr_write (0x28, GRUB_VGA_CR_PITCH);
grub_vga_cr_write (0x40, GRUB_VGA_CR_UNDERLINE_LOCATION);
grub_vga_cr_write (0xe7, GRUB_VGA_CR_VERTICAL_BLANK_START);
grub_vga_cr_write (0x04, GRUB_VGA_CR_VERTICAL_BLANK_END);
grub_vga_cr_write (0xa3, GRUB_VGA_CR_MODE);
grub_vga_cr_write (0xff, GRUB_VGA_CR_LINE_COMPARE);
grub_vga_cr_write (0x0c, GRUB_VGA_CR_VSYNC_END);
grub_vga_cr_write (0x5f, GRUB_VGA_CR_HTOTAL);
grub_vga_cr_write (0x4f, GRUB_VGA_CR_HORIZ_END);
grub_vga_cr_write (0x50, GRUB_VGA_CR_HBLANK_START);
grub_vga_cr_write (0x82, GRUB_VGA_CR_HBLANK_END);
grub_vga_cr_write (0x55, GRUB_VGA_CR_HORIZ_SYNC_PULSE_START);
grub_vga_cr_write (0x81, GRUB_VGA_CR_HORIZ_SYNC_PULSE_END);
grub_vga_cr_write (0x0b, GRUB_VGA_CR_VERT_TOTAL);
grub_vga_cr_write (0x3e, GRUB_VGA_CR_OVERFLOW);
grub_vga_cr_write (0xe9, GRUB_VGA_CR_VSYNC_START);
grub_vga_cr_write (0x8b, GRUB_VGA_CR_VSYNC_END);
grub_vga_cr_write (0xdf, GRUB_VGA_CR_VDISPLAY_END);
grub_vga_cr_write (0xe7, GRUB_VGA_CR_VERTICAL_BLANK_START);
grub_vga_cr_write (0x04, GRUB_VGA_CR_VERTICAL_BLANK_END);
grub_vga_cr_write (0x40, GRUB_VGA_CR_CELL_HEIGHT);
grub_vga_cr_write (0x50, GRUB_VGA_CR_PITCH);
grub_vga_cr_write (0x00, 0x19);
grub_vga_cr_write (0x00, 0x1a);
grub_vga_cr_write (0x6c, 0x52);
grub_vga_cr_write (0x2e, 0x34);
grub_vga_cr_write (0x00, 0x31);
grub_vga_cr_write (0, GRUB_VGA_CR_START_ADDR_HIGH_REGISTER);
grub_vga_cr_write (0, GRUB_VGA_CR_START_ADDR_LOW_REGISTER);
for (i = 0; i < 16; i++)
grub_vga_write_arx (i, i);
grub_vga_write_arx (1, GRUB_VGA_ARX_MODE);
grub_vga_write_arx (0, GRUB_VGA_ARX_OVERSCAN);
grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_PLANE_ENABLE);
grub_vga_write_arx (0, GRUB_VGA_ARX_HORIZONTAL_PANNING);
grub_vga_write_arx (0, GRUB_VGA_ARX_COLOR_SELECT);
grub_outb (0xff, GRUB_VGA_IO_PIXEL_MASK + GRUB_MACHINE_PCI_IO_BASE);
for (i = 0; i < ARRAY_SIZE (gr); i++)
grub_vga_gr_write (gr[i], i);
for (i = 0; i < GRUB_VIDEO_FBSTD_NUMCOLORS; i++)
grub_vga_palette_write (i, grub_video_fbstd_colors[i].r,
grub_video_fbstd_colors[i].g,
grub_video_fbstd_colors[i].b);
#if 1
{
if (read_sis_cmd (0x5) != 0xa1)
write_sis_cmd (0x86, 0x5);
write_sis_cmd (read_sis_cmd (0x20) | 0xa1, 0x20);
write_sis_cmd (read_sis_cmd (0x1e) | 0xda, 0x1e);
#define IND_SIS_CMDQUEUE_SET 0x26
#define IND_SIS_CMDQUEUE_THRESHOLD 0x27
#define COMMAND_QUEUE_THRESHOLD 0x1F
#define SIS_CMD_QUEUE_RESET 0x01
#define SIS_AGP_CMDQUEUE_ENABLE 0x80 /* 315/330/340 series SR26 */
#define SIS_VRAM_CMDQUEUE_ENABLE 0x40
#define SIS_MMIO_CMD_ENABLE 0x20
#define SIS_CMD_QUEUE_SIZE_512k 0x00
#define SIS_CMD_QUEUE_SIZE_1M 0x04
#define SIS_CMD_QUEUE_SIZE_2M 0x08
#define SIS_CMD_QUEUE_SIZE_4M 0x0C
#define SIS_CMD_QUEUE_RESET 0x01
#define SIS_CMD_AUTO_CORR 0x02
write_sis_cmd (COMMAND_QUEUE_THRESHOLD, IND_SIS_CMDQUEUE_THRESHOLD);
write_sis_cmd (SIS_CMD_QUEUE_RESET, IND_SIS_CMDQUEUE_SET);
framebuffer.mmioptr[0x85C4 / 4] = framebuffer.mmioptr[0x85C8 / 4];
write_sis_cmd (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR, IND_SIS_CMDQUEUE_SET);
framebuffer.mmioptr[0x85C0 / 4] = (0x1000000 - (512 * 1024));
}
#endif
#ifndef TEST
err = grub_video_fb_create_render_target_from_pointer (&framebuffer
.render_target,

View File

@ -84,8 +84,8 @@ enum
{
GRUB_VGA_IO_MISC_COLOR = 0x01,
GRUB_VGA_IO_MISC_ENABLE_VRAM_ACCESS = 0x02,
GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 = 0x08,
GRUB_VGA_IO_MISC_28MHZ = 0x04,
GRUB_VGA_IO_MISC_EXTERNAL_CLOCK_0 = 0x08,
GRUB_VGA_IO_MISC_UPPER_64K = 0x20,
GRUB_VGA_IO_MISC_NEGATIVE_HORIZ_POLARITY = 0x40,
GRUB_VGA_IO_MISC_NEGATIVE_VERT_POLARITY = 0x80,
@ -290,11 +290,24 @@ static inline void
grub_vga_write_arx (grub_uint8_t val, grub_uint8_t addr)
{
grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER);
grub_inb (GRUB_MACHINE_PCI_IO_BASE + 0x3ba);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX);
grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ);
grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX);
}
static inline grub_uint8_t
grub_vga_read_arx (grub_uint8_t addr)
{
grub_uint8_t val;
grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_INPUT_STATUS1_REGISTER);
grub_outb (addr, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX);
val = grub_inb (GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX_READ);
grub_outb (val, GRUB_MACHINE_PCI_IO_BASE + GRUB_VGA_IO_ARX);
return val;
}
struct grub_video_hw_config
{
unsigned vertical_total;