diff options
author | Simon Glass <sjg@chromium.org> | 2014-11-14 18:18:32 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2014-11-25 06:34:00 -0700 |
commit | 4e7a6acac7a46cc5ab0ea7986cc9e74351eed165 (patch) | |
tree | 15ac5235dec1c99e93da8444d7070d0b0c2e180c /arch/x86/cpu | |
parent | a0bd851ecec0e04c5e3f224a912b2872618f77ba (diff) | |
download | u-boot-imx-4e7a6acac7a46cc5ab0ea7986cc9e74351eed165.zip u-boot-imx-4e7a6acac7a46cc5ab0ea7986cc9e74351eed165.tar.gz u-boot-imx-4e7a6acac7a46cc5ab0ea7986cc9e74351eed165.tar.bz2 |
x86: ivybridge: Add support for BD82x6x PCH
Add basic setup for the PCH.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'arch/x86/cpu')
-rw-r--r-- | arch/x86/cpu/ivybridge/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/bd82x6x.c | 99 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/pci.c | 40 |
3 files changed, 140 insertions, 0 deletions
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index 721b37e..b37fb8f 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -4,6 +4,7 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-y += bd82x6x.o obj-y += car.o obj-y += cpu.o obj-y += early_init.o diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c new file mode 100644 index 0000000..fab7c53 --- /dev/null +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2014 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <fdtdec.h> +#include <malloc.h> +#include <asm/lapic.h> +#include <asm/pci.h> +#include <asm/arch/bd82x6x.h> +#include <asm/arch/model_206ax.h> +#include <asm/arch/pch.h> +#include <asm/arch/sandybridge.h> + +void bd82x6x_pci_init(pci_dev_t dev) +{ + u16 reg16; + u8 reg8; + + debug("bd82x6x PCI init.\n"); + /* Enable Bus Master */ + reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 |= PCI_COMMAND_MASTER; + pci_write_config16(dev, PCI_COMMAND, reg16); + + /* This device has no interrupt */ + pci_write_config8(dev, INTR, 0xff); + + /* disable parity error response and SERR */ + reg16 = pci_read_config16(dev, BCTRL); + reg16 &= ~(1 << 0); + reg16 &= ~(1 << 1); + pci_write_config16(dev, BCTRL, reg16); + + /* Master Latency Count must be set to 0x04! */ + reg8 = pci_read_config8(dev, SMLT); + reg8 &= 0x07; + reg8 |= (0x04 << 3); + pci_write_config8(dev, SMLT, reg8); + + /* Will this improve throughput of bus masters? */ + pci_write_config8(dev, PCI_MIN_GNT, 0x06); + + /* Clear errors in status registers */ + reg16 = pci_read_config16(dev, PSTS); + /* reg16 |= 0xf900; */ + pci_write_config16(dev, PSTS, reg16); + + reg16 = pci_read_config16(dev, SECSTS); + /* reg16 |= 0xf900; */ + pci_write_config16(dev, SECSTS, reg16); +} + +#define PCI_BRIDGE_UPDATE_COMMAND +void bd82x6x_pci_dev_enable_resources(pci_dev_t dev) +{ + uint16_t command; + + command = pci_read_config16(dev, PCI_COMMAND); + command |= PCI_COMMAND_IO; +#ifdef PCI_BRIDGE_UPDATE_COMMAND + /* + * If we write to PCI_COMMAND, on some systems this will cause the + * ROM and APICs to become invisible. + */ + debug("%x cmd <- %02x\n", dev, command); + pci_write_config16(dev, PCI_COMMAND, command); +#else + printf("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command); +#endif +} + +void bd82x6x_pci_bus_enable_resources(pci_dev_t dev) +{ + uint16_t ctrl; + + ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL); + ctrl |= PCI_COMMAND_IO; + ctrl |= PCI_BRIDGE_CTL_VGA; + debug("%x bridge ctrl <- %04x\n", dev, ctrl); + pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl); + + bd82x6x_pci_dev_enable_resources(dev); +} + +int bd82x6x_init_pci_devices(void) +{ + return 0; +} + +int bd82x6x_init(void) +{ + bd82x6x_pci_init(PCH_DEV); + + return 0; +} diff --git a/arch/x86/cpu/ivybridge/pci.c b/arch/x86/cpu/ivybridge/pci.c index c1ae658..452d1c3 100644 --- a/arch/x86/cpu/ivybridge/pci.c +++ b/arch/x86/cpu/ivybridge/pci.c @@ -12,6 +12,8 @@ #include <common.h> #include <pci.h> #include <asm/pci.h> +#include <asm/arch/bd82x6x.h> +#include <asm/arch/pch.h> static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev, struct pci_config_table *table) @@ -58,3 +60,41 @@ void board_pci_setup_hose(struct pci_controller *hose) hose->region_count = 3; } + +int board_pci_pre_scan(struct pci_controller *hose) +{ + pci_dev_t dev; + u16 reg16; + + bd82x6x_init(); + + reg16 = 0xff; + dev = PCH_DEV; + reg16 = pci_read_config16(dev, PCI_COMMAND); + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config16(dev, PCI_COMMAND, reg16); + + /* + * Clear non-reserved bits in status register. + */ + pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); + pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); + pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08); + + pci_write_bar32(hose, dev, 0, 0xf0000000); + + return 0; +} + +int board_pci_post_scan(struct pci_controller *hose) +{ + int ret; + + ret = bd82x6x_init_pci_devices(); + if (ret) { + printf("bd82x6x_init_pci_devices() failed: %d\n", ret); + return ret; + } + + return 0; +} |