14e7a6acaSSimon Glass /* 24e7a6acaSSimon Glass * Copyright (C) 2014 Google, Inc 34e7a6acaSSimon Glass * 44e7a6acaSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 54e7a6acaSSimon Glass */ 64e7a6acaSSimon Glass 74e7a6acaSSimon Glass #include <common.h> 84e7a6acaSSimon Glass #include <errno.h> 94e7a6acaSSimon Glass #include <fdtdec.h> 104e7a6acaSSimon Glass #include <malloc.h> 114e7a6acaSSimon Glass #include <asm/lapic.h> 124e7a6acaSSimon Glass #include <asm/pci.h> 134e7a6acaSSimon Glass #include <asm/arch/bd82x6x.h> 144e7a6acaSSimon Glass #include <asm/arch/model_206ax.h> 154e7a6acaSSimon Glass #include <asm/arch/pch.h> 164e7a6acaSSimon Glass #include <asm/arch/sandybridge.h> 174e7a6acaSSimon Glass 184e7a6acaSSimon Glass void bd82x6x_pci_init(pci_dev_t dev) 194e7a6acaSSimon Glass { 204e7a6acaSSimon Glass u16 reg16; 214e7a6acaSSimon Glass u8 reg8; 224e7a6acaSSimon Glass 234e7a6acaSSimon Glass debug("bd82x6x PCI init.\n"); 244e7a6acaSSimon Glass /* Enable Bus Master */ 254e7a6acaSSimon Glass reg16 = pci_read_config16(dev, PCI_COMMAND); 264e7a6acaSSimon Glass reg16 |= PCI_COMMAND_MASTER; 274e7a6acaSSimon Glass pci_write_config16(dev, PCI_COMMAND, reg16); 284e7a6acaSSimon Glass 294e7a6acaSSimon Glass /* This device has no interrupt */ 304e7a6acaSSimon Glass pci_write_config8(dev, INTR, 0xff); 314e7a6acaSSimon Glass 324e7a6acaSSimon Glass /* disable parity error response and SERR */ 334e7a6acaSSimon Glass reg16 = pci_read_config16(dev, BCTRL); 344e7a6acaSSimon Glass reg16 &= ~(1 << 0); 354e7a6acaSSimon Glass reg16 &= ~(1 << 1); 364e7a6acaSSimon Glass pci_write_config16(dev, BCTRL, reg16); 374e7a6acaSSimon Glass 384e7a6acaSSimon Glass /* Master Latency Count must be set to 0x04! */ 394e7a6acaSSimon Glass reg8 = pci_read_config8(dev, SMLT); 404e7a6acaSSimon Glass reg8 &= 0x07; 414e7a6acaSSimon Glass reg8 |= (0x04 << 3); 424e7a6acaSSimon Glass pci_write_config8(dev, SMLT, reg8); 434e7a6acaSSimon Glass 444e7a6acaSSimon Glass /* Will this improve throughput of bus masters? */ 454e7a6acaSSimon Glass pci_write_config8(dev, PCI_MIN_GNT, 0x06); 464e7a6acaSSimon Glass 474e7a6acaSSimon Glass /* Clear errors in status registers */ 484e7a6acaSSimon Glass reg16 = pci_read_config16(dev, PSTS); 494e7a6acaSSimon Glass /* reg16 |= 0xf900; */ 504e7a6acaSSimon Glass pci_write_config16(dev, PSTS, reg16); 514e7a6acaSSimon Glass 524e7a6acaSSimon Glass reg16 = pci_read_config16(dev, SECSTS); 534e7a6acaSSimon Glass /* reg16 |= 0xf900; */ 544e7a6acaSSimon Glass pci_write_config16(dev, SECSTS, reg16); 554e7a6acaSSimon Glass } 564e7a6acaSSimon Glass 574e7a6acaSSimon Glass #define PCI_BRIDGE_UPDATE_COMMAND 584e7a6acaSSimon Glass void bd82x6x_pci_dev_enable_resources(pci_dev_t dev) 594e7a6acaSSimon Glass { 604e7a6acaSSimon Glass uint16_t command; 614e7a6acaSSimon Glass 624e7a6acaSSimon Glass command = pci_read_config16(dev, PCI_COMMAND); 634e7a6acaSSimon Glass command |= PCI_COMMAND_IO; 644e7a6acaSSimon Glass #ifdef PCI_BRIDGE_UPDATE_COMMAND 654e7a6acaSSimon Glass /* 664e7a6acaSSimon Glass * If we write to PCI_COMMAND, on some systems this will cause the 674e7a6acaSSimon Glass * ROM and APICs to become invisible. 684e7a6acaSSimon Glass */ 694e7a6acaSSimon Glass debug("%x cmd <- %02x\n", dev, command); 704e7a6acaSSimon Glass pci_write_config16(dev, PCI_COMMAND, command); 714e7a6acaSSimon Glass #else 724e7a6acaSSimon Glass printf("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command); 734e7a6acaSSimon Glass #endif 744e7a6acaSSimon Glass } 754e7a6acaSSimon Glass 764e7a6acaSSimon Glass void bd82x6x_pci_bus_enable_resources(pci_dev_t dev) 774e7a6acaSSimon Glass { 784e7a6acaSSimon Glass uint16_t ctrl; 794e7a6acaSSimon Glass 804e7a6acaSSimon Glass ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL); 814e7a6acaSSimon Glass ctrl |= PCI_COMMAND_IO; 824e7a6acaSSimon Glass ctrl |= PCI_BRIDGE_CTL_VGA; 834e7a6acaSSimon Glass debug("%x bridge ctrl <- %04x\n", dev, ctrl); 844e7a6acaSSimon Glass pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl); 854e7a6acaSSimon Glass 864e7a6acaSSimon Glass bd82x6x_pci_dev_enable_resources(dev); 874e7a6acaSSimon Glass } 884e7a6acaSSimon Glass 894e7a6acaSSimon Glass int bd82x6x_init_pci_devices(void) 904e7a6acaSSimon Glass { 91*72cd085aSSimon Glass struct pci_controller *hose; 92*72cd085aSSimon Glass 93*72cd085aSSimon Glass hose = pci_bus_to_hose(0); 94*72cd085aSSimon Glass lpc_enable(PCH_LPC_DEV); 95*72cd085aSSimon Glass lpc_init(hose, PCH_LPC_DEV); 96*72cd085aSSimon Glass 974e7a6acaSSimon Glass return 0; 984e7a6acaSSimon Glass } 994e7a6acaSSimon Glass 1004e7a6acaSSimon Glass int bd82x6x_init(void) 1014e7a6acaSSimon Glass { 1024e7a6acaSSimon Glass bd82x6x_pci_init(PCH_DEV); 1034e7a6acaSSimon Glass 1044e7a6acaSSimon Glass return 0; 1054e7a6acaSSimon Glass } 106