summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@ti.com>2015-01-26 17:44:49 -0500
committerTom Rini <trini@ti.com>2015-01-26 17:44:49 -0500
commitab92da9f47d51d363c7de42e2a7bd807e2c1bd54 (patch)
treedfabc29929e39a1ecc47edf5a4cf839ead062acd /drivers
parentaed03faa064cca56847571b13cbd4c849c6116aa (diff)
parente43ade3749ff10bc313f33bf23705465e4163896 (diff)
downloadblackbird-obmc-uboot-ab92da9f47d51d363c7de42e2a7bd807e2c1bd54.tar.gz
blackbird-obmc-uboot-ab92da9f47d51d363c7de42e2a7bd807e2c1bd54.zip
Merge branch 'master' of git://git.denx.de/u-boot-x86
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bios_emulator/atibios.c161
-rw-r--r--drivers/bios_emulator/include/x86emu/debug.h2
-rw-r--r--drivers/bios_emulator/x86emu/ops.c2
-rw-r--r--drivers/block/ahci.c20
-rw-r--r--drivers/pci/pci_auto.c28
-rw-r--r--drivers/pci/pci_rom.c40
-rw-r--r--drivers/pci/pci_tegra.c5
-rw-r--r--drivers/rtc/mc146818.c121
-rw-r--r--drivers/spi/ich.c7
-rw-r--r--drivers/video/Kconfig7
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/cfb_console.c26
-rw-r--r--drivers/video/vesa_fb.c64
-rw-r--r--drivers/video/x86_fb.c38
14 files changed, 384 insertions, 139 deletions
diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c
index 93b815ccb4..7ea5fa6224 100644
--- a/drivers/bios_emulator/atibios.c
+++ b/drivers/bios_emulator/atibios.c
@@ -62,40 +62,158 @@ static u32 saveBaseAddress14;
static u32 saveBaseAddress18;
static u32 saveBaseAddress20;
-static void atibios_set_vesa_mode(RMREGS *regs, int vesa_mode,
- struct vbe_mode_info *mode_info)
+/* Addres im memory of VBE region */
+const int vbe_offset = 0x2000;
+
+static const void *bios_ptr(const void *buf, BE_VGAInfo *vga_info,
+ u32 x86_dword_ptr)
+{
+ u32 seg_ofs, flat;
+
+ seg_ofs = le32_to_cpu(x86_dword_ptr);
+ flat = ((seg_ofs & 0xffff0000) >> 12) | (seg_ofs & 0xffff);
+ if (flat >= 0xc0000)
+ return vga_info->BIOSImage + flat - 0xc0000;
+ else
+ return buf + (flat - vbe_offset);
+}
+
+static int atibios_debug_mode(BE_VGAInfo *vga_info, RMREGS *regs,
+ int vesa_mode, struct vbe_mode_info *mode_info)
+{
+ void *buffer = (void *)(M.mem_base + vbe_offset);
+ u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00;
+ u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff;
+ struct vesa_mode_info *vm;
+ struct vbe_info *info;
+ const u16 *modes_bios, *ptr;
+ u16 *modes;
+ int size;
+
+ debug("VBE: Getting information\n");
+ regs->e.eax = VESA_GET_INFO;
+ regs->e.esi = buffer_seg;
+ regs->e.edi = buffer_adr;
+ info = buffer;
+ memset(info, '\0', sizeof(*info));
+ strcpy(info->signature, "VBE2");
+ BE_int86(0x10, regs, regs);
+ if (regs->e.eax != 0x4f) {
+ debug("VESA_GET_INFO: error %x\n", regs->e.eax);
+ return -ENOSYS;
+ }
+ debug("version %x\n", le16_to_cpu(info->version));
+ debug("oem '%s'\n", (char *)bios_ptr(buffer, vga_info,
+ info->oem_string_ptr));
+ debug("vendor '%s'\n", (char *)bios_ptr(buffer, vga_info,
+ info->vendor_name_ptr));
+ debug("product '%s'\n", (char *)bios_ptr(buffer, vga_info,
+ info->product_name_ptr));
+ debug("rev '%s'\n", (char *)bios_ptr(buffer, vga_info,
+ info->product_rev_ptr));
+ modes_bios = bios_ptr(buffer, vga_info, info->modes_ptr);
+ debug("Modes: ");
+ for (ptr = modes_bios; *ptr != 0xffff; ptr++)
+ debug("%x ", le16_to_cpu(*ptr));
+ debug("\nmemory %dMB\n", le16_to_cpu(info->total_memory) >> 4);
+ size = (ptr - modes_bios) * sizeof(u16) + 2;
+ modes = malloc(size);
+ if (!modes)
+ return -ENOMEM;
+ memcpy(modes, modes_bios, size);
+
+ regs->e.eax = VESA_GET_CUR_MODE;
+ BE_int86(0x10, regs, regs);
+ if (regs->e.eax != 0x4f) {
+ debug("VESA_GET_CUR_MODE: error %x\n", regs->e.eax);
+ return -ENOSYS;
+ }
+ debug("Current mode %x\n", regs->e.ebx);
+
+ for (ptr = modes; *ptr != 0xffff; ptr++) {
+ int mode = le16_to_cpu(*ptr);
+ bool linear_ok;
+ int attr;
+
+ break;
+ debug("Mode %x: ", mode);
+ memset(buffer, '\0', sizeof(struct vbe_mode_info));
+ regs->e.eax = VESA_GET_MODE_INFO;
+ regs->e.ebx = 0;
+ regs->e.ecx = mode;
+ regs->e.edx = 0;
+ regs->e.esi = buffer_seg;
+ regs->e.edi = buffer_adr;
+ BE_int86(0x10, regs, regs);
+ if (regs->e.eax != 0x4f) {
+ debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax);
+ continue;
+ }
+ memcpy(mode_info->mode_info_block, buffer,
+ sizeof(struct vesa_mode_info));
+ mode_info->valid = true;
+ vm = &mode_info->vesa;
+ attr = le16_to_cpu(vm->mode_attributes);
+ linear_ok = attr & 0x80;
+ debug("res %d x %d, %d bpp, mm %d, (Linear %s, attr %02x)\n",
+ le16_to_cpu(vm->x_resolution),
+ le16_to_cpu(vm->y_resolution),
+ vm->bits_per_pixel, vm->memory_model,
+ linear_ok ? "OK" : "not available",
+ attr);
+ debug("\tRGB pos=%d,%d,%d, size=%d,%d,%d\n",
+ vm->red_mask_pos, vm->green_mask_pos, vm->blue_mask_pos,
+ vm->red_mask_size, vm->green_mask_size,
+ vm->blue_mask_size);
+ }
+
+ return 0;
+}
+
+static int atibios_set_vesa_mode(RMREGS *regs, int vesa_mode,
+ struct vbe_mode_info *mode_info)
{
+ void *buffer = (void *)(M.mem_base + vbe_offset);
+ u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00;
+ u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff;
+ struct vesa_mode_info *vm;
+
debug("VBE: Setting VESA mode %#04x\n", vesa_mode);
- /* request linear framebuffer mode */
- vesa_mode |= (1 << 14);
- /* request clearing of framebuffer */
- vesa_mode &= ~(1 << 15);
regs->e.eax = VESA_SET_MODE;
regs->e.ebx = vesa_mode;
+ /* request linear framebuffer mode and don't clear display */
+ regs->e.ebx |= (1 << 14) | (1 << 15);
BE_int86(0x10, regs, regs);
+ if (regs->e.eax != 0x4f) {
+ debug("VESA_SET_MODE: error %x\n", regs->e.eax);
+ return -ENOSYS;
+ }
- int offset = 0x2000;
- void *buffer = (void *)(M.mem_base + offset);
-
- u16 buffer_seg = (((unsigned long)offset) >> 4) & 0xff00;
- u16 buffer_adr = ((unsigned long)offset) & 0xffff;
+ memset(buffer, '\0', sizeof(struct vbe_mode_info));
+ debug("VBE: Geting info for VESA mode %#04x\n", vesa_mode);
regs->e.eax = VESA_GET_MODE_INFO;
- regs->e.ebx = 0;
regs->e.ecx = vesa_mode;
- regs->e.edx = 0;
regs->e.esi = buffer_seg;
regs->e.edi = buffer_adr;
BE_int86(0x10, regs, regs);
+ if (regs->e.eax != 0x4f) {
+ debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax);
+ return -ENOSYS;
+ }
+
memcpy(mode_info->mode_info_block, buffer,
- sizeof(struct vbe_mode_info));
+ sizeof(struct vesa_mode_info));
mode_info->valid = true;
+ mode_info->video_mode = vesa_mode;
+ vm = &mode_info->vesa;
+ vm->x_resolution = le16_to_cpu(vm->x_resolution);
+ vm->y_resolution = le16_to_cpu(vm->y_resolution);
+ vm->bytes_per_scanline = le16_to_cpu(vm->bytes_per_scanline);
+ vm->phys_base_ptr = le32_to_cpu(vm->phys_base_ptr);
+ vm->mode_attributes = le16_to_cpu(vm->mode_attributes);
+ debug("VBE: Init complete\n");
- vesa_mode |= (1 << 14);
- /* request clearing of framebuffer */
- vesa_mode &= ~(1 << 15);
- regs->e.eax = VESA_SET_MODE;
- regs->e.ebx = vesa_mode;
- BE_int86(0x10, regs, regs);
+ return 0;
}
/****************************************************************************
@@ -132,6 +250,9 @@ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info,
/*Cleanup and exit*/
BE_getVGA(vga_info);
+ /* Useful for debugging */
+ if (0)
+ atibios_debug_mode(vga_info, &regs, vesa_mode, mode_info);
if (vesa_mode != -1)
atibios_set_vesa_mode(&regs, vesa_mode, mode_info);
}
diff --git a/drivers/bios_emulator/include/x86emu/debug.h b/drivers/bios_emulator/include/x86emu/debug.h
index 304b2bf007..4962a2acaf 100644
--- a/drivers/bios_emulator/include/x86emu/debug.h
+++ b/drivers/bios_emulator/include/x86emu/debug.h
@@ -102,7 +102,7 @@
# define ERR_PRINTF(x) printf(x)
# define ERR_PRINTF2(x, y) printf(x, y)
-#ifdef CONFIG_X86EMU_DEBUG103
+#ifdef CONFIG_X86EMU_DEBUG
# define DECODE_PRINTF(x) if (DEBUG_DECODE()) \
diff --git a/drivers/bios_emulator/x86emu/ops.c b/drivers/bios_emulator/x86emu/ops.c
index 2bb5e2d9d5..5752fee1cd 100644
--- a/drivers/bios_emulator/x86emu/ops.c
+++ b/drivers/bios_emulator/x86emu/ops.c
@@ -179,7 +179,7 @@ void x86emuOp_illegal_op(
{
START_OF_INSTR();
if (M.x86.R_SP != 0) {
- ERR_PRINTF("ILLEGAL X86 OPCODE\n");
+ DB(printf("ILLEGAL X86 OPCODE\n"));
TRACE_REGS();
DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
M.x86.R_CS, M.x86.R_IP-1,op1));
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index 37d2d2a28e..c908fab450 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -513,6 +513,20 @@ static void ahci_set_feature(u8 port)
}
#endif
+static int wait_spinup(volatile u8 *port_mmio)
+{
+ ulong start;
+ u32 tf_data;
+
+ start = get_timer(0);
+ do {
+ tf_data = readl(port_mmio + PORT_TFDATA);
+ if (!(tf_data & ATA_BUSY))
+ return 0;
+ } while (get_timer(start) < WAIT_MS_SPINUP);
+
+ return -ETIMEDOUT;
+}
static int ahci_port_start(u8 port)
{
@@ -579,7 +593,11 @@ static int ahci_port_start(u8 port)
debug("Exit start port %d\n", port);
- return 0;
+ /*
+ * Make sure interface is not busy based on error and status
+ * information from task file data register before proceeding
+ */
+ return wait_spinup(port_mmio);
}
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index 44470fa812..ed92857406 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -11,7 +11,7 @@
*/
#include <common.h>
-
+#include <errno.h>
#include <pci.h>
#undef DEBUG
@@ -191,6 +191,32 @@ void pciauto_setup_device(struct pci_controller *hose,
pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
}
+int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev)
+{
+ pci_addr_t bar_value;
+ pci_size_t bar_size;
+ u32 bar_response;
+ u16 cmdstat = 0;
+
+ pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS, 0xfffffffe);
+ pci_hose_read_config_dword(hose, dev, PCI_ROM_ADDRESS, &bar_response);
+ if (!bar_response)
+ return -ENOENT;
+
+ bar_size = -(bar_response & ~1);
+ DEBUGF("PCI Autoconfig: ROM, size=%#x, ", bar_size);
+ if (pciauto_region_allocate(hose->pci_mem, bar_size, &bar_value) == 0) {
+ pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS,
+ bar_value);
+ }
+ DEBUGF("\n");
+ pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
+ cmdstat |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+ pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat);
+
+ return 0;
+}
+
void pciauto_prescan_setup_bridge(struct pci_controller *hose,
pci_dev_t dev, int sub_bus)
{
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index 7d25cc9f2f..eb7659177b 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -66,6 +66,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
struct pci_rom_header *rom_header;
struct pci_rom_data *rom_data;
u16 vendor, device;
+ u16 rom_vendor, rom_device;
u32 vendev;
u32 mapped_vendev;
u32 rom_address;
@@ -80,7 +81,12 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
#ifdef CONFIG_X86_OPTION_ROM_ADDR
rom_address = CONFIG_X86_OPTION_ROM_ADDR;
#else
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, (u32)PCI_ROM_ADDRESS_MASK);
+
+ if (pciauto_setup_rom(pci_bus_to_hose(PCI_BUS(dev)), dev)) {
+ debug("Cannot find option ROM\n");
+ return -ENOENT;
+ }
+
pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address);
if (rom_address == 0x00000000 || rom_address == 0xffffffff) {
debug("%s: rom_address=%x\n", __func__, rom_address);
@@ -95,26 +101,28 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
rom_header = (struct pci_rom_header *)rom_address;
debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n",
- le32_to_cpu(rom_header->signature),
- rom_header->size * 512, le32_to_cpu(rom_header->data));
+ le16_to_cpu(rom_header->signature),
+ rom_header->size * 512, le16_to_cpu(rom_header->data));
- if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
+ if (le16_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
printf("Incorrect expansion ROM header signature %04x\n",
- le32_to_cpu(rom_header->signature));
+ le16_to_cpu(rom_header->signature));
return -EINVAL;
}
- rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data));
+ rom_data = (((void *)rom_header) + le16_to_cpu(rom_header->data));
+ rom_vendor = le16_to_cpu(rom_data->vendor);
+ rom_device = le16_to_cpu(rom_data->device);
debug("PCI ROM image, vendor ID %04x, device ID %04x,\n",
- rom_data->vendor, rom_data->device);
+ rom_vendor, rom_device);
/* If the device id is mapped, a mismatch is expected */
- if ((vendor != rom_data->vendor || device != rom_data->device) &&
+ if ((vendor != rom_vendor || device != rom_device) &&
(vendev == mapped_vendev)) {
printf("ID mismatch: vendor ID %04x, device ID %04x\n",
- rom_data->vendor, rom_data->device);
- return -EPERM;
+ rom_vendor, rom_device);
+ /* Continue anyway */
}
debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n",
@@ -144,17 +152,23 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header,
image_size);
rom_data = (struct pci_rom_data *)((void *)rom_header +
- le32_to_cpu(rom_header->data));
+ le16_to_cpu(rom_header->data));
- image_size = le32_to_cpu(rom_data->ilen) * 512;
- } while ((rom_data->type != 0) && (rom_data->indicator != 0));
+ image_size = le16_to_cpu(rom_data->ilen) * 512;
+ } while ((rom_data->type != 0) && (rom_data->indicator == 0));
if (rom_data->type != 0)
return -EACCES;
rom_size = rom_header->size * 512;
+#ifdef PCI_VGA_RAM_IMAGE_START
target = (void *)PCI_VGA_RAM_IMAGE_START;
+#else
+ target = (void *)malloc(rom_size);
+ if (!target)
+ return -ENOMEM;
+#endif
if (target != rom_header) {
ulong start = get_timer(0);
diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c
index f9e05add19..67b5fdf07c 100644
--- a/drivers/pci/pci_tegra.c
+++ b/drivers/pci/pci_tegra.c
@@ -459,7 +459,6 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node,
unsigned int *lanes)
{
struct fdt_pci_addr addr;
- pci_dev_t bdf;
int err;
err = fdtdec_get_int(fdt, node, "nvidia,num-lanes", 0);
@@ -470,13 +469,13 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node,
*lanes = err;
- err = fdtdec_get_pci_bdf(fdt, node, &addr, &bdf);
+ err = fdtdec_get_pci_addr(fdt, node, 0, "reg", &addr);
if (err < 0) {
error("failed to parse \"reg\" property");
return err;
}
- *index = PCI_DEV(bdf) - 1;
+ *index = PCI_DEV(addr.phys_hi) - 1;
return 0;
}
diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c
index 39e6041be3..c9d318c0a7 100644
--- a/drivers/rtc/mc146818.c
+++ b/drivers/rtc/mc146818.c
@@ -27,9 +27,6 @@
/* Set this to 1 to clear the CMOS RAM */
#define CLEAR_CMOS 0
-static uchar rtc_read (uchar reg);
-static void rtc_write (uchar reg, uchar val);
-
#define RTC_PORT_MC146818 CONFIG_SYS_ISA_IO_BASE_ADDRESS + 0x70
#define RTC_SECONDS 0x00
#define RTC_SECONDS_ALARM 0x01
@@ -60,24 +57,24 @@ int rtc_get (struct rtc_time *tmp)
{
uchar sec, min, hour, mday, wday, mon, year;
/* here check if rtc can be accessed */
- while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
- sec = rtc_read (RTC_SECONDS);
- min = rtc_read (RTC_MINUTES);
- hour = rtc_read (RTC_HOURS);
- mday = rtc_read (RTC_DATE_OF_MONTH);
- wday = rtc_read (RTC_DAY_OF_WEEK);
- mon = rtc_read (RTC_MONTH);
- year = rtc_read (RTC_YEAR);
+ while ((rtc_read8(RTC_CONFIG_A) & 0x80) == 0x80);
+ sec = rtc_read8(RTC_SECONDS);
+ min = rtc_read8(RTC_MINUTES);
+ hour = rtc_read8(RTC_HOURS);
+ mday = rtc_read8(RTC_DATE_OF_MONTH);
+ wday = rtc_read8(RTC_DAY_OF_WEEK);
+ mon = rtc_read8(RTC_MONTH);
+ year = rtc_read8(RTC_YEAR);
#ifdef RTC_DEBUG
printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
"hr: %02x min: %02x sec: %02x\n",
year, mon, mday, wday,
hour, min, sec );
printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
- rtc_read (RTC_CONFIG_D) & 0x3F,
- rtc_read (RTC_HOURS_ALARM),
- rtc_read (RTC_MINUTES_ALARM),
- rtc_read (RTC_SECONDS_ALARM) );
+ rtc_read8(RTC_CONFIG_D) & 0x3F,
+ rtc_read8(RTC_HOURS_ALARM),
+ rtc_read8(RTC_MINUTES_ALARM),
+ rtc_read8(RTC_SECONDS_ALARM));
#endif
tmp->tm_sec = bcd2bin (sec & 0x7F);
tmp->tm_min = bcd2bin (min & 0x7F);
@@ -108,80 +105,108 @@ int rtc_set (struct rtc_time *tmp)
tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
#endif
- rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+ rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */
- rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
- rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
- rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
- rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
- rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
- rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
- rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
- rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+ rtc_write8(RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+ rtc_write8(RTC_MONTH, bin2bcd(tmp->tm_mon));
+ rtc_write8(RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+ rtc_write8(RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
+ rtc_write8(RTC_HOURS, bin2bcd(tmp->tm_hour));
+ rtc_write8(RTC_MINUTES, bin2bcd(tmp->tm_min));
+ rtc_write8(RTC_SECONDS, bin2bcd(tmp->tm_sec));
+ rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */
return 0;
}
void rtc_reset (void)
{
- rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
- rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */
- rtc_write(RTC_CONFIG_B,0x00);
- rtc_write(RTC_CONFIG_B,0x00);
- rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+ rtc_write8(RTC_CONFIG_B, 0x82); /* disable the RTC to update the regs */
+ rtc_write8(RTC_CONFIG_A, 0x20); /* Normal OP */
+ rtc_write8(RTC_CONFIG_B, 0x00);
+ rtc_write8(RTC_CONFIG_B, 0x00);
+ rtc_write8(RTC_CONFIG_B, 0x02); /* enable the RTC to update the regs */
}
/* ------------------------------------------------------------------------- */
-#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR
/*
* use direct memory access
*/
-static uchar rtc_read (uchar reg)
+int rtc_read8(int reg)
{
+#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR
return in8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg);
+#else
+ int ofs = 0;
+
+ if (reg >= 128) {
+ ofs = 2;
+ reg -= 128;
+ }
+ out8(RTC_PORT_MC146818 + ofs, reg);
+
+ return in8(RTC_PORT_MC146818 + ofs + 1);
+#endif
}
-static void rtc_write (uchar reg, uchar val)
+void rtc_write8(int reg, uchar val)
{
+#ifdef CONFIG_SYS_RTC_REG_BASE_ADDR
out8(CONFIG_SYS_RTC_REG_BASE_ADDR + reg, val);
-}
#else
-static uchar rtc_read (uchar reg)
+ int ofs = 0;
+
+ if (reg >= 128) {
+ ofs = 2;
+ reg -= 128;
+ }
+ out8(RTC_PORT_MC146818 + ofs, reg);
+ out8(RTC_PORT_MC146818 + ofs + 1, val);
+#endif
+}
+
+u32 rtc_read32(int reg)
{
- out8(RTC_PORT_MC146818,reg);
- return in8(RTC_PORT_MC146818 + 1);
+ u32 value = 0;
+ int i;
+
+ for (i = 0; i < sizeof(value); i++)
+ value |= rtc_read8(reg + i) << (i << 3);
+
+ return value;
}
-static void rtc_write (uchar reg, uchar val)
+void rtc_write32(int reg, u32 value)
{
- out8(RTC_PORT_MC146818,reg);
- out8(RTC_PORT_MC146818+1, val);
+ int i;
+
+ for (i = 0; i < sizeof(value); i++)
+ rtc_write8(reg + i, (value >> (i << 3)) & 0xff);
}
-#endif
void rtc_init(void)
{
#if CLEAR_CMOS
int i;
- rtc_write(RTC_SECONDS_ALARM, 0);
- rtc_write(RTC_MINUTES_ALARM, 0);
- rtc_write(RTC_HOURS_ALARM, 0);
+ rtc_write8(RTC_SECONDS_ALARM, 0);
+ rtc_write8(RTC_MINUTES_ALARM, 0);
+ rtc_write8(RTC_HOURS_ALARM, 0);
for (i = RTC_CONFIG_A; i < RTC_REG_SIZE; i++)
- rtc_write(i, 0);
+ rtc_write8(i, 0);
printf("RTC: zeroing CMOS RAM\n");
#endif
/* Setup the real time clock */
- rtc_write(RTC_CONFIG_B, RTC_CONFIG_B_24H);
+ rtc_write8(RTC_CONFIG_B, RTC_CONFIG_B_24H);
/* Setup the frequency it operates at */
- rtc_write(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ |
+ rtc_write8(RTC_CONFIG_A, RTC_CONFIG_A_REF_CLCK_32KHZ |
RTC_CONFIG_A_RATE_1024HZ);
/* Ensure all reserved bits are 0 in register D */
- rtc_write(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME);
+ rtc_write8(RTC_CONFIG_D, RTC_CONFIG_D_VALID_RAM_AND_TIME);
/* Clear any pending interrupts */
- rtc_read(RTC_CONFIG_C);
+ rtc_read8(RTC_CONFIG_C);
}
#endif
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 0379444872..fdff158637 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -153,6 +153,13 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
return &ich->slave;
}
+struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
+ int spi_node)
+{
+ /* We only support a single SPI at present */
+ return spi_setup_slave(0, 0, 20000000, 0);
+}
+
void spi_free_slave(struct spi_slave *slave)
{
struct ich_spi_slave *ich = to_ich_spi(slave);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index ccbd7e295d..51728b366f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1,11 +1,12 @@
-config VIDEO_X86
- bool "Enable x86 video driver support"
+config VIDEO_VESA
+ bool "Enable VESA video driver support"
depends on X86
default n
help
Turn on this option to enable a very simple driver which uses vesa
to discover the video mode and then provides a frame buffer for use
- by U-Boot.
+ by U-Boot. This can in principle be used with any platform that
+ supports PCI and video cards that support VESA BIOS Extension (VBE).
config VIDEO_LCD_SSD2828
bool "SSD2828 bridge chip"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index c3fcf455d2..af2d47bd75 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -44,7 +44,7 @@ obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o
obj-$(CONFIG_VIDEO_TEGRA) += tegra.o
obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
-obj-$(CONFIG_VIDEO_X86) += x86_fb.o
+obj-$(CONFIG_VIDEO_VESA) += vesa_fb.o
obj-$(CONFIG_FORMIKE) += formike.o
obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
obj-$(CONFIG_VIDEO_PARADE) += parade.o
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index d4226e3eb6..a81affa333 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -299,7 +299,11 @@ void console_cursor(int state);
#define CONSOLE_ROW_SECOND (video_console_address + CONSOLE_ROW_SIZE)
#define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
-#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+
+/* By default we scroll by a single line */
+#ifndef CONFIG_CONSOLE_SCROLL_LINES
+#define CONFIG_CONSOLE_SCROLL_LINES 1
+#endif
/* Macros */
#ifdef VIDEO_FB_LITTLE_ENDIAN
@@ -740,26 +744,33 @@ static void console_clear_line(int line, int begin, int end)
static void console_scrollup(void)
{
+ const int rows = CONFIG_CONSOLE_SCROLL_LINES;
+ int i;
+
/* copy up rows ignoring the first one */
#ifdef VIDEO_HW_BITBLT
video_hw_bitblt(VIDEO_PIXEL_SIZE, /* bytes per pixel */
0, /* source pos x */
video_logo_height +
- VIDEO_FONT_HEIGHT, /* source pos y */
+ VIDEO_FONT_HEIGHT * rows, /* source pos y */
0, /* dest pos x */
video_logo_height, /* dest pos y */
VIDEO_VISIBLE_COLS, /* frame width */
VIDEO_VISIBLE_ROWS
- video_logo_height
- - VIDEO_FONT_HEIGHT /* frame height */
+ - VIDEO_FONT_HEIGHT * rows /* frame height */
);
#else
- memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
- CONSOLE_SCROLL_SIZE >> 2);
+ memcpyl(CONSOLE_ROW_FIRST, CONSOLE_ROW_FIRST + rows * CONSOLE_ROW_SIZE,
+ (CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows) >> 2);
#endif
/* clear the last one */
- console_clear_line(CONSOLE_ROWS - 1, 0, CONSOLE_COLS - 1);
+ for (i = 1; i <= rows; i++)
+ console_clear_line(CONSOLE_ROWS - i, 0, CONSOLE_COLS - 1);
+
+ /* Decrement row number */
+ console_row -= rows;
}
static void console_back(void)
@@ -871,9 +882,6 @@ static void console_newline(int n)
if (console_row >= CONSOLE_ROWS) {
/* Scroll everything up */
console_scrollup();
-
- /* Decrement row number */
- console_row = CONSOLE_ROWS - 1;
}
}
diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c
new file mode 100644
index 0000000000..3dacafd6bf
--- /dev/null
+++ b/drivers/video/vesa_fb.c
@@ -0,0 +1,64 @@
+/*
+ *
+ * Vesa frame buffer driver for x86
+ *
+ * Copyright (C) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <pci_rom.h>
+#include <video_fb.h>
+#include <vbe.h>
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+/* Devices to allow - only the last one works fully */
+struct pci_device_id vesa_video_ids[] = {
+ { .vendor = 0x102b, .device = 0x0525 },
+ { .vendor = 0x1002, .device = 0x5159 },
+ { .vendor = 0x1002, .device = 0x4752 },
+ { .vendor = 0x1002, .device = 0x5452 },
+ {},
+};
+
+void *video_hw_init(void)
+{
+ GraphicDevice *gdev = &ctfb;
+ int bits_per_pixel;
+ pci_dev_t dev;
+ int ret;
+
+ printf("Video: ");
+ if (vbe_get_video_info(gdev)) {
+ /* TODO: Should we look these up by class? */
+ dev = pci_find_devices(vesa_video_ids, 0);
+ if (dev == -1) {
+ printf("no card detected\n");
+ return NULL;
+ }
+ printf("bdf %x\n", dev);
+ ret = pci_run_vga_bios(dev, NULL, true);
+ if (ret) {
+ printf("failed to run video BIOS: %d\n", ret);
+ return NULL;
+ }
+ }
+
+ if (vbe_get_video_info(gdev)) {
+ printf("No video mode configured\n");
+ return NULL;
+ }
+
+ bits_per_pixel = gdev->gdfBytesPP * 8;
+ sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY,
+ bits_per_pixel);
+ printf("%s\n", gdev->modeIdent);
+ debug("Framex buffer at %x\n", gdev->pciBase);
+
+ return (void *)gdev;
+}
diff --git a/drivers/video/x86_fb.c b/drivers/video/x86_fb.c
deleted file mode 100644
index 6641033a5d..0000000000
--- a/drivers/video/x86_fb.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *
- * Vesa frame buffer driver for x86
- *
- * Copyright (C) 2014 Google, Inc
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <video_fb.h>
-#include <vbe.h>
-#include "videomodes.h"
-
-/*
- * The Graphic Device
- */
-GraphicDevice ctfb;
-
-void *video_hw_init(void)
-{
- GraphicDevice *gdev = &ctfb;
- int bits_per_pixel;
-
- printf("Video: ");
- if (vbe_get_video_info(gdev)) {
- printf("No video mode configured\n");
- return NULL;
- }
-
- bits_per_pixel = gdev->gdfBytesPP * 8;
- sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY,
- bits_per_pixel);
- printf("%s\n", gdev->modeIdent);
- debug("Frame buffer at %x\n", gdev->frameAdrs);
-
- return (void *)gdev;
-}
OpenPOWER on IntegriCloud