Ejemplo n.º 1
0
static void serialio_init(struct device *dev)
{
	struct southbridge_intel_lynxpoint_config *config = dev->chip_info;
	struct resource *bar0, *bar1;
	int sio_index = -1;
	u32 reg32;

	printk(BIOS_DEBUG, "Initializing Serial IO device\n");

	/* Ensure memory and bus master are enabled */
	reg32 = pci_read_config32(dev, PCI_COMMAND);
	reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
	pci_write_config32(dev, PCI_COMMAND, reg32);

	/* Find BAR0 and BAR1 */
	bar0 = find_resource(dev, PCI_BASE_ADDRESS_0);
	if (!bar0)
		return;
	bar1 = find_resource(dev, PCI_BASE_ADDRESS_1);
	if (!bar1)
		return;

	if (!config->sio_acpi_mode)
		serialio_enable_clock(bar0);

	switch (dev->path.pci.devfn) {
	case PCI_DEVFN(21, 0): /* SDMA */
		sio_index = SIO_ID_SDMA;
		serialio_init_once(config->sio_acpi_mode);
		serialio_d21_mode(sio_index, SIO_PIN_INTB,
				  config->sio_acpi_mode);
		break;
	case PCI_DEVFN(21, 1): /* I2C0 */
		sio_index = SIO_ID_I2C0;
		serialio_d21_ltr(bar0);
		serialio_i2c_voltage_sel(bar0, config->sio_i2c0_voltage);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCI_DEVFN(21, 2): /* I2C1 */
		sio_index = SIO_ID_I2C1;
		serialio_d21_ltr(bar0);
		serialio_i2c_voltage_sel(bar0, config->sio_i2c1_voltage);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCI_DEVFN(21, 3): /* SPI0 */
		sio_index = SIO_ID_SPI0;
		serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCI_DEVFN(21, 4): /* SPI1 */
		sio_index = SIO_ID_SPI1;
		serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCI_DEVFN(21, 5): /* UART0 */
		sio_index = SIO_ID_UART0;
		serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTD,
				  config->sio_acpi_mode);
		break;
	case PCI_DEVFN(21, 6): /* UART1 */
		sio_index = SIO_ID_UART1;
		serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTD,
				  config->sio_acpi_mode);
		break;
	case PCI_DEVFN(23, 0): /* SDIO */
		sio_index = SIO_ID_SDIO;
		serialio_d23_ltr(bar0);
		serialio_d23_mode(config->sio_acpi_mode);
		break;
	default:
		return;
	}

	if (config->sio_acpi_mode) {
		global_nvs_t *gnvs;

		/* Find ACPI NVS to update BARs */
		gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
		if (!gnvs) {
			printk(BIOS_ERR, "Unable to locate Global NVS\n");
			return;
		}

		/* Save BAR0 and BAR1 to ACPI NVS */
		gnvs->s0b[sio_index] = (u32)bar0->base;
		gnvs->s1b[sio_index] = (u32)bar1->base;
	}
}
Ejemplo n.º 2
0
static void serialio_init(struct device *dev)
{
	config_t *config = dev->chip_info;
	struct resource *bar0, *bar1;
	int sio_index = -1;
	u32 reg32;

	printk(BIOS_DEBUG, "Initializing Serial IO device\n");

	/* Ensure memory and bus master are enabled */
	reg32 = pci_read_config32(dev, PCI_COMMAND);
	reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
	pci_write_config32(dev, PCI_COMMAND, reg32);

	/* Find BAR0 and BAR1 */
	bar0 = find_resource(dev, PCI_BASE_ADDRESS_0);
	if (!bar0)
		return;
	bar1 = find_resource(dev, PCI_BASE_ADDRESS_1);
	if (!bar1)
		return;

	if (!config->sio_acpi_mode)
		serialio_enable_clock(bar0);

	switch (dev->path.pci.devfn) {
	case PCH_DEVFN_SDMA: /* SDMA */
		sio_index = SIO_ID_SDMA;
		serialio_init_once(config->sio_acpi_mode);
		serialio_d21_mode(sio_index, SIO_PIN_INTB,
				  config->sio_acpi_mode);
		break;
	case PCH_DEVFN_I2C0: /* I2C0 */
		sio_index = SIO_ID_I2C0;
		serialio_d21_ltr(bar0);
		serialio_i2c_voltage_sel(bar0, config->sio_i2c0_voltage);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCH_DEVFN_I2C1: /* I2C1 */
		sio_index = SIO_ID_I2C1;
		serialio_d21_ltr(bar0);
		serialio_i2c_voltage_sel(bar0, config->sio_i2c1_voltage);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCH_DEVFN_SPI0: /* SPI0 */
		sio_index = SIO_ID_SPI0;
		serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCH_DEVFN_SPI1: /* SPI1 */
		sio_index = SIO_ID_SPI1;
		serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTC,
				  config->sio_acpi_mode);
		break;
	case PCH_DEVFN_UART0: /* UART0 */
		sio_index = SIO_ID_UART0;
		if (!serialio_uart_is_debug(dev))
			serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTD,
				  config->sio_acpi_mode);
		break;
	case PCH_DEVFN_UART1: /* UART1 */
		sio_index = SIO_ID_UART1;
		if (!serialio_uart_is_debug(dev))
			serialio_d21_ltr(bar0);
		serialio_d21_mode(sio_index, SIO_PIN_INTD,
				  config->sio_acpi_mode);
		break;
	case PCH_DEVFN_SDIO: /* SDIO */
		sio_index = SIO_ID_SDIO;
		serialio_d23_ltr(bar0);
		serialio_d23_mode(config->sio_acpi_mode);
		break;
	default:
		return;
	}

	if (config->sio_acpi_mode) {
		global_nvs_t *gnvs;

		/* Find ACPI NVS to update BARs */
		gnvs = (global_nvs_t *)cbmem_find(CBMEM_ID_ACPI_GNVS);
		if (!gnvs) {
			printk(BIOS_ERR, "Unable to locate Global NVS\n");
			return;
		}

		/* Save BAR0 and BAR1 to ACPI NVS */
		gnvs->dev.bar0[sio_index] = (u32)bar0->base;
		gnvs->dev.bar1[sio_index] = (u32)bar1->base;

		/* Do not enable UART if it is used as debug port */
		if (!serialio_uart_is_debug(dev))
			gnvs->dev.enable[sio_index] = 1;

		/* Put device in D3hot state via BAR1 */
		if (dev->path.pci.devfn != PCH_DEVFN_SDMA)
			serialio_enable_d3hot(bar1); /* all but SDMA */
	}
}