void pch_uart_init(void) { device_t dev; u32 tmp, legacy; u8 *base = (u8 *)CONFIG_TTYS0_BASE; switch (CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER) { case 0: dev = PCH_DEV_UART0; legacy = SIO_PCH_LEGACY_UART0; break; case 1: dev = PCH_DEV_UART1; legacy = SIO_PCH_LEGACY_UART1; break; case 2: dev = PCH_DEV_UART2; legacy = SIO_PCH_LEGACY_UART2; break; default: return; } /* Set configured UART base address */ pci_write_config32(dev, PCI_BASE_ADDRESS_0, (u32)base); /* Enable memory access and bus master */ tmp = pci_read_config32(dev, PCI_COMMAND); tmp |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config32(dev, PCI_COMMAND, tmp); /* Take UART out of reset */ tmp = read32(base + SIO_REG_PPR_RESETS); tmp |= SIO_REG_PPR_RESETS_FUNC | SIO_REG_PPR_RESETS_APB | SIO_REG_PPR_RESETS_IDMA; write32(base + SIO_REG_PPR_RESETS, tmp); /* Set M and N divisor inputs and enable clock */ tmp = read32(base + SIO_REG_PPR_CLOCK); tmp |= SIO_REG_PPR_CLOCK_EN | SIO_REG_PPR_CLOCK_UPDATE | (SIO_REG_PPR_CLOCK_N_DIV << 16) | (SIO_REG_PPR_CLOCK_M_DIV << 1); write32(base + SIO_REG_PPR_CLOCK, tmp); /* Put UART in byte access mode for 16550 compatibility */ pcr_andthenor32(PID_SERIALIO, R_PCH_PCR_SERIAL_IO_GPPRVRW7, 0, legacy); }
/* Copy SPD data for on-board memory */ void mainboard_fill_spd_data(struct pei_data *pei_data) { char *spd_file; size_t spd_file_len; int spd_index; int spd_gpio[4]; /************************************************************* * FIXME: Remove when real GPIO support is ready. */ GPIO_PAD gpio_set[4] = { GPIO_LP_GPP_C12, /* PCH_MEM_CONFIG[0] */ GPIO_LP_GPP_C13, /* PCH_MEM_CONFIG[1] */ GPIO_LP_GPP_C14, /* PCH_MEM_CONFIG[2] */ GPIO_LP_GPP_C15, /* PCH_MEM_CONFIG[3] */ }; int index; for (index = 0; index < ARRAY_SIZE(gpio_set); index++) { u32 number = GPIO_GET_PAD_NUMBER(gpio_set[index]); u32 cfgreg = 8 * number + R_PCH_PCR_GPIO_GPP_C_PADCFG_OFFSET; /* * Set GPIO mode and enable input * Clear PMODE0 | PMODE1 | GPIORXDIS */ u32 dw0mask = (1 << 10) | (1 << 11) | (1 << 9); u32 dw0reg = 0; pcr_andthenor32(PID_GPIOCOM1, cfgreg, ~dw0mask, dw0reg); /* Read current input value */ pcr_read32(PID_GPIOCOM1, cfgreg, &dw0reg); spd_gpio[index] = !!(dw0reg & (1 << 1)); } /*************************************************************/ spd_index = (spd_gpio[3] << 3) | (spd_gpio[2] << 2) | (spd_gpio[1] << 1) | spd_gpio[0]; printk(BIOS_DEBUG, "SPD: index %d (GPP_C15=%d GPP_C14=%d GPP_C13=%d GPP_C12=%d)\n", spd_index, spd_gpio[3], spd_gpio[2], spd_gpio[1], spd_gpio[0]); /* Load SPD data from CBFS */ spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, &spd_file_len); if (!spd_file) die("SPD data not found."); /* make sure we have at least one SPD in the file. */ if (spd_file_len < SPD_LEN) die("Missing SPD data."); /* Make sure we did not overrun the buffer */ if (spd_file_len < ((spd_index + 1) * SPD_LEN)) { printk(BIOS_ERR, "SPD index override to 1 - old hardware?\n"); spd_index = 1; } /* Assume same memory in both channels */ spd_index *= SPD_LEN; memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN); memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN); /* Make sure a valid SPD was found */ if (pei_data->spd_data[0][0][0] == 0) die("Invalid SPD data."); mainboard_print_spd_info(pei_data->spd_data[0][0]); }