From bdc88d4eb31e2bc84afb427c216c79e87a4233ef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:24 -0700 Subject: x86: Support ROMs on other archs We shouldn't assume that the VGA ROM can always be loaded at c0000. This is only true on x86 machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- include/pci_rom.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/pci_rom.h b/include/pci_rom.h index 8b2674cf879..4ba36eb1b7b 100644 --- a/include/pci_rom.h +++ b/include/pci_rom.h @@ -8,7 +8,6 @@ #define _PCI_ROM_H #define PCI_ROM_HDR 0xaa55 -#define PCI_VGA_RAM_IMAGE_START 0xc0000 struct pci_rom_header { uint16_t signature; -- cgit v1.3.1 From 222f25f85503f19acb9cb7ff138d3fe5215c3ad9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:26 -0700 Subject: bios_emulator: Add some VESA interface debugging Allow the supported modes to be listed when in debug mode. Signed-off-by: Simon Glass --- drivers/bios_emulator/atibios.c | 161 +++++++++++++++++++++++++++++++++++----- include/vbe.h | 9 ++- 2 files changed, 148 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c index 93b815ccb49..7ea5fa62247 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, ®s, vesa_mode, mode_info); if (vesa_mode != -1) atibios_set_vesa_mode(®s, vesa_mode, mode_info); } diff --git a/include/vbe.h b/include/vbe.h index d4056914c4e..c5deee9eca9 100644 --- a/include/vbe.h +++ b/include/vbe.h @@ -35,10 +35,14 @@ struct __packed screen_info_input { struct __packed vbe_info { char signature[4]; u16 version; - u8 *oem_string_ptr; + u32 oem_string_ptr; u32 capabilities; - u16 video_mode_list[256]; + u32 modes_ptr; u16 total_memory; + u16 oem_version; + u32 vendor_name_ptr; + u32 product_name_ptr; + u32 product_rev_ptr; }; struct __packed vesa_mode_info { @@ -96,6 +100,7 @@ struct vbe_ddc_info { #define VESA_GET_INFO 0x4f00 #define VESA_GET_MODE_INFO 0x4f01 #define VESA_SET_MODE 0x4f02 +#define VESA_GET_CUR_MODE 0x4f03 struct graphic_device; int vbe_get_video_info(struct graphic_device *gdev); -- cgit v1.3.1 From 4a2708a097eacd7aa3d10ccf26a70a467fa69217 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 14 Jan 2015 21:37:04 -0700 Subject: x86: Access the VGA ROM when needed Add code to the generic pci_rom file to access the VGA ROM in PCI space when needed. Signed-off-by: Simon Glass --- drivers/pci/pci_auto.c | 28 +++++++++++++++++++++++++++- drivers/pci/pci_rom.c | 7 ++++++- include/pci.h | 9 +++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 44470fa812b..ed928574061 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -11,7 +11,7 @@ */ #include - +#include #include #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 a16e99f1dad..eb7659177b4 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -81,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); diff --git a/include/pci.h b/include/pci.h index 7f67ca65426..4fbb8f6729f 100644 --- a/include/pci.h +++ b/include/pci.h @@ -697,5 +697,14 @@ void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum, * */ u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum); +/** + * pciauto_setup_rom() - Set up access to a device ROM + * + * @hose: PCI hose to use + * @dev: PCI device to adjust + * @return 0 if done, -ve on error + */ +int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev); + #endif /* __ASSEMBLY__ */ #endif /* _PCI_H */ -- cgit v1.3.1 From d1a5d3c133a07d6035b9f97a6315afed7d73514a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 1 Jan 2015 16:17:58 -0700 Subject: x86: config: Always scroll the display by 5 lines, for speed Scrolling a line at a time is very slow for reasons that I don't understand. It seems to take about 100ms to copy 4MB of RAM in the frame buffer. To cope with this, scroll 5 lines each time. Signed-off-by: Simon Glass --- include/configs/x86-common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index f16ae329132..4f0a3c59289 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -179,6 +179,7 @@ #define VIDEO_FB_16BPP_WORD_SWAP #define CONFIG_I8042_KBD #define CONFIG_CFB_CONSOLE +#define CONFIG_CONSOLE_SCROLL_LINES 5 /*----------------------------------------------------------------------- * CPU Features -- cgit v1.3.1 From 5da38086bd6c39efd09e57900702b99541844339 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:06 -0700 Subject: x86: dts: Add compatible string for Intel ICH9 SPI controller Add this to the enum so that we can use the various fdtdec functions. A later commit will move this driver to driver model. Signed-off-by: Simon Glass --- include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/fdtdec.h b/include/fdtdec.h index 75af750ee57..8c2bd21b2d2 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -173,6 +173,7 @@ enum fdt_compat_id { COMPAT_INTEL_MODEL_206AX, /* Intel Model 206AX CPU */ COMPAT_INTEL_GMA, /* Intel Graphics Media Accelerator */ COMPAT_AMS_AS3722, /* AMS AS3722 PMIC */ + COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */ COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 487122eebcf..e989241b709 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -83,6 +83,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(INTEL_MODEL_206AX, "intel,model-206ax"), COMPAT(INTEL_GMA, "intel,gma"), COMPAT(AMS_AS3722, "ams,as3722"), + COMPAT(INTEL_ICH_SPI, "intel,ich-spi"), }; const char *fdtdec_get_compatible(enum fdt_compat_id id) -- cgit v1.3.1 From 9b0e35cb4889eb04a7ea5dd648d73df0bf37cc68 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:07 -0700 Subject: net: Add a separate file for IP checksumming Move the checksum code out into its own file so it can be used elsewhere. Also use a new version which supports a length which is not a multiple of 2 and add a new function to add two checksums. Signed-off-by: Simon Glass --- include/net.h | 30 +++++++++++++++++++++++++++++ net/Makefile | 1 + net/checksum.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 net/checksum.c (limited to 'include') diff --git a/include/net.h b/include/net.h index 3da35fe9818..73ea88b42d7 100644 --- a/include/net.h +++ b/include/net.h @@ -482,6 +482,36 @@ extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source); extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport, int len); +/** + * compute_ip_checksum() - Compute IP checksum + * + * @addr: Address to check (must be 16-bit aligned) + * @nbytes: Number of bytes to check (normally a multiple of 2) + * @return 16-bit IP checksum + */ +unsigned compute_ip_checksum(const void *addr, unsigned nbytes); + +/** + * add_ip_checksums() - add two IP checksums + * + * @offset: Offset of first sum (if odd we do a byte-swap) + * @sum: First checksum + * @new_sum: New checksum to add + * @return updated 16-bit IP checksum + */ +unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum); + +/** + * ip_checksum_ok() - check if a checksum is correct + * + * This works by making sure the checksum sums to 0 + * + * @addr: Address to check (must be 16-bit aligned) + * @nbytes: Number of bytes to check (normally a multiple of 2) + * @return true if the checksum matches, false if not + */ +int ip_checksum_ok(const void *addr, unsigned nbytes); + /* Checksum */ extern int NetCksumOk(uchar *, int); /* Return true if cksum OK */ extern uint NetCksum(uchar *, int); /* Calculate the checksum */ diff --git a/net/Makefile b/net/Makefile index 942595021da..e9cc8ada96a 100644 --- a/net/Makefile +++ b/net/Makefile @@ -7,6 +7,7 @@ #ccflags-y += -DDEBUG +obj-y += checksum.o obj-$(CONFIG_CMD_NET) += arp.o obj-$(CONFIG_CMD_NET) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o diff --git a/net/checksum.c b/net/checksum.c new file mode 100644 index 00000000000..a8c9ff5ea45 --- /dev/null +++ b/net/checksum.c @@ -0,0 +1,60 @@ +/* + * This file was originally taken from the FreeBSD project. + * + * Copyright (c) 2001 Charles Mott + * Copyright (c) 2008 coresystems GmbH + * All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +unsigned compute_ip_checksum(const void *vptr, unsigned nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *)ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + sum = ~sum & 0xffff; + + return sum; +} + +unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new) +{ + unsigned long checksum; + + sum = ~sum & 0xffff; + new = ~new & 0xffff; + if (offset & 1) { + /* + * byte-swap the sum if it came from an odd offset; since the + * computation is endian independant this works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xffff) + checksum -= 0xffff; + + return (~checksum) & 0xffff; +} + +int ip_checksum_ok(const void *addr, unsigned nbytes) +{ + return !(compute_ip_checksum(addr, nbytes) & 0xfffe); +} -- cgit v1.3.1 From fc4860c089a6b6603e1ae4f9c1f8bd1b3aadfc8b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:10 -0700 Subject: x86: rtc: mc146818: Add helpers to read/write CMOS RAM On x86 we use CMOS RAM to read and write some settings. Add basic support for this, including access to registers 128-255. Signed-off-by: Simon Glass --- drivers/rtc/mc146818.c | 121 +++++++++++++++++++++++++++++-------------------- include/rtc.h | 32 +++++++++++++ 2 files changed, 105 insertions(+), 48 deletions(-) (limited to 'include') diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index 39e6041be36..c9d318c0a7e 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/include/rtc.h b/include/rtc.h index d11aa8baf91..54e361ea5e8 100644 --- a/include/rtc.h +++ b/include/rtc.h @@ -50,6 +50,38 @@ void to_tm (int, struct rtc_time *); unsigned long mktime (unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); +/** + * rtc_read8() - Read an 8-bit register + * + * @reg: Register to read + * @return value read + */ +int rtc_read8(int reg); + +/** + * rtc_write8() - Write an 8-bit register + * + * @reg: Register to write + * @value: Value to write + */ +void rtc_write8(int reg, uchar val); + +/** + * rtc_read32() - Read a 32-bit value from the RTC + * + * @reg: Offset to start reading from + * @return value read + */ +u32 rtc_read32(int reg); + +/** + * rtc_write32() - Write a 32-bit value to the RTC + * + * @reg: Register to start writing to + * @value: Value to write + */ +void rtc_write32(int reg, u32 value); + /** * rtc_init() - Set up the real time clock ready for use */ -- cgit v1.3.1 From 8e899af0597a43d70752654b227f308dd0d0039c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:11 -0700 Subject: x86: spi: Add device tree support As a temporary measure before the ICH driver moves over to driver model, add device tree support to the driver. Signed-off-by: Simon Glass --- drivers/spi/ich.c | 7 +++++++ include/configs/x86-common.h | 1 + 2 files changed, 8 insertions(+) (limited to 'include') diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 0379444872e..fdff158637d 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/include/configs/x86-common.h b/include/configs/x86-common.h index 4f0a3c59289..ecedfc3ab16 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -211,6 +211,7 @@ #define CONFIG_CMD_SF_TEST #define CONFIG_CMD_SPI #define CONFIG_SPI +#define CONFIG_OF_SPI_FLASH /*----------------------------------------------------------------------- * Environment configuration -- cgit v1.3.1 From 069f5481ba19b819ef11ba23181a264fc566b180 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:15 -0700 Subject: x86: config: Enable hook for saving MRC configuration Add a hook to ensure that this information is saved. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- arch/x86/cpu/coreboot/coreboot.c | 5 +++++ include/configs/chromebook_link.h | 1 + 2 files changed, 6 insertions(+) (limited to 'include') diff --git a/arch/x86/cpu/coreboot/coreboot.c b/arch/x86/cpu/coreboot/coreboot.c index 6d06d5af19e..4cdd0d40353 100644 --- a/arch/x86/cpu/coreboot/coreboot.c +++ b/arch/x86/cpu/coreboot/coreboot.c @@ -99,3 +99,8 @@ void panic_puts(const char *str) while (*str) NS16550_putc(port, *str++); } + +int misc_init_r(void) +{ + return 0; +} diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index 7e6d239d13d..6e8b9efb458 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -20,6 +20,7 @@ #define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000 #define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_MISC_INIT_R #define CONFIG_NR_DRAM_BANKS 8 #define CONFIG_X86_MRC_ADDR 0xfffa0000 -- cgit v1.3.1 From e43ade3749ff10bc313f33bf23705465e4163896 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 19 Jan 2015 22:16:17 -0700 Subject: x86: config: chromebook_link: Enable environment Enable an environment area. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- include/configs/chromebook_link.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h index 6e8b9efb458..7b460e83c45 100644 --- a/include/configs/chromebook_link.h +++ b/include/configs/chromebook_link.h @@ -64,6 +64,13 @@ #define CONFIG_CMD_CROS_EC #define CONFIG_ARCH_EARLY_INIT_R +#undef CONFIG_ENV_IS_NOWHERE +#undef CONFIG_ENV_SIZE +#define CONFIG_ENV_SIZE 0x1000 +#define CONFIG_ENV_SECT_SIZE 0x1000 +#define CONFIG_ENV_IS_IN_SPI_FLASH +#define CONFIG_ENV_OFFSET 0x003f8000 + #define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ "stdout=vga,serial\0" \ "stderr=vga,serial\0" -- cgit v1.3.1