static int bd82x6x_northbridge_early_init(struct udevice *dev) { const int chipset_type = SANDYBRIDGE_MOBILE; u32 capid0_a; u8 reg8; /* Device ID Override Enable should be done very early */ dm_pci_read_config32(dev, 0xe4, &capid0_a); if (capid0_a & (1 << 10)) { dm_pci_read_config8(dev, 0xf3, ®8); reg8 &= ~7; /* Clear 2:0 */ if (chipset_type == SANDYBRIDGE_MOBILE) reg8 |= 1; /* Set bit 0 */ dm_pci_write_config8(dev, 0xf3, reg8); } sandybridge_setup_northbridge_bars(dev); /* Device Enable */ dm_pci_write_config32(dev, DEVEN, DEVEN_HOST | DEVEN_IGD); return 0; }
static int broadwell_pch_early_init(struct udevice *dev) { struct gpio_desc desc; struct udevice *bus; pci_dev_t bdf; int ret; dm_pci_write_config32(dev, PCH_RCBA, RCB_BASE_ADDRESS | 1); dm_pci_write_config32(dev, PMBASE, ACPI_BASE_ADDRESS | 1); dm_pci_write_config8(dev, ACPI_CNTL, ACPI_EN); dm_pci_write_config32(dev, GPIO_BASE, GPIO_BASE_ADDRESS | 1); dm_pci_write_config8(dev, GPIO_CNTL, GPIO_EN); /* Enable IOAPIC */ writew(0x1000, RCB_REG(OIC)); /* Read back for posted write */ readw(RCB_REG(OIC)); /* Set HPET address and enable it */ clrsetbits_le32(RCB_REG(HPTC), 3, 1 << 7); /* Read back for posted write */ readl(RCB_REG(HPTC)); /* Enable HPET to start counter */ setbits_le32(HPET_BASE_ADDRESS + 0x10, 1 << 0); setbits_le32(RCB_REG(GCS), 1 << 5); /* * Enable PP3300_AUTOBAHN_EN after initial GPIO setup * to prevent possible brownout. This will cause the GPIOs to be set * up if it has not been done already. */ ret = gpio_request_by_name(dev, "power-enable-gpio", 0, &desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); if (ret) return ret; /* 8.14 Additional PCI Express Programming Steps, step #1 */ bdf = PCI_BDF(0, 0x1c, 0); bus = pci_get_controller(dev); pci_bus_clrset_config32(bus, bdf, 0xf4, 0x60, 0); pci_bus_clrset_config32(bus, bdf, 0xf4, 0x80, 0x80); pci_bus_clrset_config32(bus, bdf, 0xe2, 0x30, 0x30); return 0; }
static inline u32 sir_read(struct udevice *dev, int idx) { u32 data; dm_pci_write_config32(dev, SATA_SIRI, idx); dm_pci_read_config32(dev, SATA_SIRD, &data); return data; }
static int bd82x6x_lpc_early_init(struct udevice *dev) { /* Setting up Southbridge. In the northbridge code. */ debug("Setting up static southbridge registers\n"); dm_pci_write_config32(dev->parent, PCH_RCBA_BASE, DEFAULT_RCBA | 1); dm_pci_write_config32(dev->parent, PMBASE, DEFAULT_PMBASE | 1); /* Enable ACPI BAR */ dm_pci_write_config8(dev->parent, ACPI_CNTL, 0x80); debug("Disabling watchdog reboot\n"); setbits_le32(RCB_REG(GCS), 1 >> 5); /* No reset */ outw(1 << 11, DEFAULT_PMBASE | 0x60 | 0x08); /* halt timer */ dm_pci_write_config32(dev->parent, GPIO_BASE, DEFAULT_GPIOBASE | 1); dm_pci_write_config32(dev->parent, GPIO_CNTL, 0x10); return 0; }
static void common_sata_init(struct udevice *dev, unsigned int port_map) { u32 reg32; u16 reg16; /* Set IDE I/O Configuration */ reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0; dm_pci_write_config32(dev, IDE_CONFIG, reg32); /* Port enable */ dm_pci_read_config16(dev, 0x92, ®16); reg16 &= ~0x3f; reg16 |= port_map; dm_pci_write_config16(dev, 0x92, reg16); /* SATA Initialization register */ port_map &= 0xff; dm_pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183); }
static int broadwell_northbridge_early_init(struct udevice *dev) { /* Move earlier? */ dm_pci_write_config32(dev, PCIEXBAR + 4, 0); /* 64MiB - 0-63 buses */ dm_pci_write_config32(dev, PCIEXBAR, MCFG_BASE_ADDRESS | 4 | 1); dm_pci_write_config32(dev, MCHBAR, MCH_BASE_ADDRESS | 1); dm_pci_write_config32(dev, DMIBAR, DMI_BASE_ADDRESS | 1); dm_pci_write_config32(dev, EPBAR, EP_BASE_ADDRESS | 1); writel(EDRAM_BASE_ADDRESS | 1, MCH_BASE_ADDRESS + EDRAMBAR); writel(GDXC_BASE_ADDRESS | 1, MCH_BASE_ADDRESS + GDXCBAR); /* Set C0000-FFFFF to access RAM on both reads and writes */ dm_pci_write_config8(dev, PAM0, 0x30); dm_pci_write_config8(dev, PAM1, 0x33); dm_pci_write_config8(dev, PAM2, 0x33); dm_pci_write_config8(dev, PAM3, 0x33); dm_pci_write_config8(dev, PAM4, 0x33); dm_pci_write_config8(dev, PAM5, 0x33); dm_pci_write_config8(dev, PAM6, 0x33); /* Device enable: IGD and Mini-HD */ dm_pci_write_config32(dev, DEVEN, DEVEN_D0EN | DEVEN_D2EN | DEVEN_D3EN); return 0; }
int intel_me_hsio_version(struct udevice *dev, uint16_t *versionp, uint16_t *checksump) { int count; u32 hsiover; struct me_hfs hfs; /* Query for HSIO version, overloads H_GS and HFS */ dm_pci_write_config32(dev, PCI_ME_H_GS, ME_HSIO_MESSAGE | ME_HSIO_CMD_GETHSIOVER); /* Must wait for ME acknowledgement */ for (count = ME_RETRY; count > 0; --count) { me_read_dword_ptr(dev, &hfs, PCI_ME_HFS); if (hfs.bios_msg_ack) break; udelay(ME_DELAY); } if (!count) { debug("ERROR: ME failed to respond\n"); return -ETIMEDOUT; } /* HSIO version should be in HFS_5 */ dm_pci_read_config32(dev, PCI_ME_HFS5, &hsiover); *versionp = hsiover >> 16; *checksump = hsiover & 0xffff; debug("ME: HSIO Version : %d (CRC 0x%04x)\n", *versionp, *checksump); /* Reset registers to normal behavior */ dm_pci_write_config32(dev, PCI_ME_H_GS, ME_HSIO_MESSAGE | ME_HSIO_CMD_GETHSIOVER); return 0; }
static void sandybridge_setup_northbridge_bars(struct udevice *dev) { /* Set up all hardcoded northbridge BARs */ debug("Setting up static registers\n"); dm_pci_write_config32(dev, EPBAR, DEFAULT_EPBAR | 1); dm_pci_write_config32(dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32); dm_pci_write_config32(dev, MCHBAR, DEFAULT_MCHBAR | 1); dm_pci_write_config32(dev, MCHBAR + 4, (0LL + DEFAULT_MCHBAR) >> 32); /* 64MB - busses 0-63 */ dm_pci_write_config32(dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5); dm_pci_write_config32(dev, PCIEXBAR + 4, (0LL + DEFAULT_PCIEXBAR) >> 32); dm_pci_write_config32(dev, DMIBAR, DEFAULT_DMIBAR | 1); dm_pci_write_config32(dev, DMIBAR + 4, (0LL + DEFAULT_DMIBAR) >> 32); /* Set C0000-FFFFF to access RAM on both reads and writes */ dm_pci_write_config8(dev, PAM0, 0x30); dm_pci_write_config8(dev, PAM1, 0x33); dm_pci_write_config8(dev, PAM2, 0x33); dm_pci_write_config8(dev, PAM3, 0x33); dm_pci_write_config8(dev, PAM4, 0x33); dm_pci_write_config8(dev, PAM5, 0x33); dm_pci_write_config8(dev, PAM6, 0x33); }
int board_early_init_f(void) { struct udevice *pch; int ret; ret = uclass_first_device(UCLASS_PCH, &pch); if (ret) return ret; if (!pch) return -ENODEV; /* Initialize LPC interface to turn on superio chipset decode range */ dm_pci_write_config16(pch, LPC_IO_DEC, COMA_DEC_RANGE | COMB_DEC_RANGE); dm_pci_write_config16(pch, LPC_EN, KBC_LPC_EN | COMA_LPC_EN); dm_pci_write_config32(pch, LPC_GEN1_DEC, GEN_DEC_RANGE_256B | (SIO1007_IOPORT3 & 0xff00) | GEN_DEC_RANGE_EN); dm_pci_write_config32(pch, LPC_GEN2_DEC, GEN_DEC_RANGE_16B | SIO1007_RUNTIME_IOPORT | GEN_DEC_RANGE_EN); /* Enable legacy serial port at 0x3f8 */ sio1007_enable_serial(SIO1007_IOPORT3, 0, UART0_BASE, UART0_IRQ); /* Enable SIO1007 runtime I/O port at 0x180 */ sio1007_enable_runtime(SIO1007_IOPORT3, SIO1007_RUNTIME_IOPORT); /* * On Cougar Canyon 2 board, the RS232 transiver connected to serial * port 0 (0x3f8) is controlled by a GPIO pin (GPIO10) on the SIO1007. * Set the pin value to 1 to enable the RS232 transiver. */ sio1007_gpio_config(SIO1007_IOPORT3, 0, GPIO_DIR_OUTPUT, GPIO_POL_NO_INVERT, GPIO_TYPE_PUSH_PULL); sio1007_gpio_set_value(SIO1007_RUNTIME_IOPORT, 0, 1); return 0; }
static void irq_enable_sci(struct udevice *dev) { struct irq_router *priv = dev_get_priv(dev); if (priv->actl_8bit) { /* Bit7 must be turned on to enable ACPI */ dm_pci_write_config8(dev->parent, priv->actl_addr, 0x80); } else { /* Write 0 to enable SCI on IRQ9 */ if (priv->config == PIRQ_VIA_PCI) dm_pci_write_config32(dev->parent, priv->actl_addr, 0); else writel(0, priv->ibase + priv->actl_addr); } }
static int pch_gpi_routing(struct udevice *pch) { u8 route[16]; u32 reg; int gpi; if (fdtdec_get_byte_array(gd->fdt_blob, pch->of_offset, "intel,gpi-routing", route, sizeof(route))) return -EINVAL; for (reg = 0, gpi = 0; gpi < ARRAY_SIZE(route); gpi++) reg |= route[gpi] << (gpi * 2); dm_pci_write_config32(pch, 0xb8, reg); return 0; }
/** * lpc_early_init() - set up LPC serial ports and other early things * * @dev: LPC device * @return 0 if OK, -ve on error */ static int lpc_early_init(struct udevice *dev) { struct reg_info { u32 base; u32 size; } values[4], *ptr; int count; int i; count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset, "intel,gen-dec", (u32 *)values, sizeof(values) / sizeof(u32)); if (count < 0) return -EINVAL; /* Set COM1/COM2 decode range */ dm_pci_write_config16(dev->parent, LPC_IO_DEC, 0x0010); /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */ dm_pci_write_config16(dev->parent, LPC_EN, KBC_LPC_EN | MC_LPC_EN | GAMEL_LPC_EN | COMA_LPC_EN); /* Write all registers but use 0 if we run out of data */ count = count * sizeof(u32) / sizeof(values[0]); for (i = 0, ptr = values; i < ARRAY_SIZE(values); i++, ptr++) { u32 reg = 0; if (i < count) reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16); dm_pci_write_config32(dev->parent, LPC_GENX_DEC(i), reg); } enable_spi_prefetch(dev->parent); /* This is already done in start.S, but let's do it in C */ enable_port80_on_lpc(dev->parent); set_spi_speed(); return 0; }
static void xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr, struct xhci_hcor **ret_hcor) { struct xhci_hccr *hccr; struct xhci_hcor *hcor; u32 cmd; hccr = (struct xhci_hccr *)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); hcor = (struct xhci_hcor *)((uintptr_t) hccr + HC_LENGTH(xhci_readl(&hccr->cr_capbase))); debug("XHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", (u32)hccr, (u32)hcor, (u32)HC_LENGTH(xhci_readl(&hccr->cr_capbase))); *ret_hccr = hccr; *ret_hcor = hcor; /* enable busmaster */ dm_pci_read_config32(dev, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_MASTER; dm_pci_write_config32(dev, PCI_COMMAND, cmd); }
int pci_bar_show(struct udevice *dev) { u8 header_type; int bar_cnt, bar_id, mem_type; bool is_64, is_io; u32 base_low, base_high; u32 size_low, size_high; u64 base, size; u32 reg_addr; int prefetchable; dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type); if (header_type == PCI_HEADER_TYPE_CARDBUS) { printf("CardBus doesn't support BARs\n"); return -ENOSYS; } bar_cnt = (header_type == PCI_HEADER_TYPE_NORMAL) ? 6 : 2; printf("ID Base Size Width Type\n"); printf("----------------------------------------------------------\n"); bar_id = 0; reg_addr = PCI_BASE_ADDRESS_0; while (bar_cnt) { dm_pci_read_config32(dev, reg_addr, &base_low); dm_pci_write_config32(dev, reg_addr, 0xffffffff); dm_pci_read_config32(dev, reg_addr, &size_low); dm_pci_write_config32(dev, reg_addr, base_low); reg_addr += 4; base = base_low & ~0xf; size = size_low & ~0xf; base_high = 0x0; size_high = 0xffffffff; is_64 = 0; prefetchable = base_low & PCI_BASE_ADDRESS_MEM_PREFETCH; is_io = base_low & PCI_BASE_ADDRESS_SPACE_IO; mem_type = base_low & PCI_BASE_ADDRESS_MEM_TYPE_MASK; if (mem_type == PCI_BASE_ADDRESS_MEM_TYPE_64) { dm_pci_read_config32(dev, reg_addr, &base_high); dm_pci_write_config32(dev, reg_addr, 0xffffffff); dm_pci_read_config32(dev, reg_addr, &size_high); dm_pci_write_config32(dev, reg_addr, base_high); bar_cnt--; reg_addr += 4; is_64 = 1; } base = base | ((u64)base_high << 32); size = size | ((u64)size_high << 32); if ((!is_64 && size_low) || (is_64 && size)) { size = ~size + 1; printf(" %d %#016llx %#016llx %d %s %s\n", bar_id, (unsigned long long)base, (unsigned long long)size, is_64 ? 64 : 32, is_io ? "I/O" : "MEM", prefetchable ? "Prefetchable" : ""); } bar_id++; bar_cnt--; } return 0; }
static inline void sir_write(struct udevice *dev, int idx, u32 value) { dm_pci_write_config32(dev, SATA_SIRI, idx); dm_pci_write_config32(dev, SATA_SIRD, value); }
static void enable_port80_on_lpc(struct udevice *pch) { /* Enable port 80 POST on LPC */ dm_pci_write_config32(pch, PCH_RCBA_BASE, DEFAULT_RCBA | 1); clrbits_le32(RCB_REG(GCS), 4); }
void dm_pciauto_setup_device(struct udevice *dev, int bars_num, struct pci_region *mem, struct pci_region *prefetch, struct pci_region *io, bool enum_only) { u32 bar_response; pci_size_t bar_size; u16 cmdstat = 0; int bar, bar_nr = 0; u8 header_type; int rom_addr; pci_addr_t bar_value; struct pci_region *bar_res; int found_mem64 = 0; u16 class; dm_pci_read_config16(dev, PCI_COMMAND, &cmdstat); cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; for (bar = PCI_BASE_ADDRESS_0; bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { /* Tickle the BAR and get the response */ if (!enum_only) dm_pci_write_config32(dev, bar, 0xffffffff); dm_pci_read_config32(dev, bar, &bar_response); /* If BAR is not implemented go to the next BAR */ if (!bar_response) continue; found_mem64 = 0; /* Check the BAR type and set our address mask */ if (bar_response & PCI_BASE_ADDRESS_SPACE) { bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK)) & 0xffff) + 1; if (!enum_only) bar_res = io; debug("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (unsigned long long)bar_size); } else { if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { u32 bar_response_upper; u64 bar64; if (!enum_only) { dm_pci_write_config32(dev, bar + 4, 0xffffffff); } dm_pci_read_config32(dev, bar + 4, &bar_response_upper); bar64 = ((u64)bar_response_upper << 32) | bar_response; bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; if (!enum_only) found_mem64 = 1; } else { bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1); } if (!enum_only) { if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH)) { bar_res = prefetch; } else { bar_res = mem; } } debug("PCI Autoconfig: BAR %d, %s, size=0x%llx, ", bar_nr, bar_res == prefetch ? "Prf" : "Mem", (unsigned long long)bar_size); } if (!enum_only && pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) { /* Write it out and update our limit */ dm_pci_write_config32(dev, bar, (u32)bar_value); if (found_mem64) { bar += 4; #ifdef CONFIG_SYS_PCI_64BIT dm_pci_write_config32(dev, bar, (u32)(bar_value >> 32)); #else /* * If we are a 64-bit decoder then increment to * the upper 32 bits of the bar and force it to * locate in the lower 4GB of memory. */ dm_pci_write_config32(dev, bar, 0x00000000); #endif } } cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? PCI_COMMAND_IO : PCI_COMMAND_MEMORY; debug("\n"); bar_nr++; }