soc/intel/apollolake: Enable LPC bus interface
This adds early LPC setup in bootblock (for Chrome EC) as well as late (ramstage) IO decode/sirq enable. Change-Id: Ic270e66dbf07240229d4783f80e2ec02007c36c2 Signed-off-by: Divya Sasidharan <divya.s.sasidharan@intel.com> Signed-off-by: Freddy Paul <freddy.paul@intel.com> Signed-off-by: Andrey Petrov <andrey.petrov@intel.com> Reviewed-on: https://review.coreboot.org/14469 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
		
				
					committed by
					
						 Aaron Durbin
						Aaron Durbin
					
				
			
			
				
	
			
			
			
						parent
						
							f748f83ecb
						
					
				
				
					commit
					e976bd4469
				
			| @@ -20,6 +20,7 @@ | ||||
| #include <soc/bootblock.h> | ||||
| #include <soc/cpu.h> | ||||
| #include <soc/gpio.h> | ||||
| #include <soc/lpc.h> | ||||
| #include <soc/northbridge.h> | ||||
| #include <soc/pci_devs.h> | ||||
| #include <soc/uart.h> | ||||
| @@ -28,12 +29,36 @@ static const struct pad_config tpm_spi_configs[] = { | ||||
| 	PAD_CFG_NF(GPIO_106, NATIVE, DEEP, NF3),	/* FST_SPI_CS2_N */ | ||||
| }; | ||||
|  | ||||
| static const struct pad_config lpc_gpio_configs[] = { | ||||
| 	PAD_CFG_NF(LPC_AD0, NATIVE, DEEP, NF1), | ||||
| 	PAD_CFG_NF(LPC_AD1, NATIVE, DEEP, NF1), | ||||
| 	PAD_CFG_NF(LPC_AD2, NATIVE, DEEP, NF1), | ||||
| 	PAD_CFG_NF(LPC_AD3, NATIVE, DEEP, NF1), | ||||
| 	PAD_CFG_NF(LPC_FRAMEB, NATIVE, DEEP, NF1), | ||||
| 	PAD_CFG_NF(LPC_CLKOUT0, UP_20K, DEEP, NF1), | ||||
| 	PAD_CFG_NF(LPC_CLKOUT1, UP_20K, DEEP, NF1) | ||||
| }; | ||||
|  | ||||
| static void tpm_enable(void) | ||||
| { | ||||
| 	/* Configure gpios */ | ||||
| 	gpio_configure_pads(tpm_spi_configs, ARRAY_SIZE(tpm_spi_configs)); | ||||
| } | ||||
|  | ||||
| static void early_lpc_enable(void) | ||||
| { | ||||
| 	/* Enable requested fixed IO decode ranges */ | ||||
| 	pci_write_config16(LPC_DEV, LPC_EN, LPC_EN_MC1 | LPC_EN_KB | LPC_EN_LGAME); | ||||
|  | ||||
| 	/* Enable generic IO decode ranges for 0x800-0x9ff */ | ||||
| 	/* FIXME: remove range hardcoding and/or calculate based on EC definitions */ | ||||
| 	pci_write_config32(LPC_DEV, LPC_GEN1_DEC, ((0xff & ~3 ) << 8) | 0x800 | 1); | ||||
| 	pci_write_config32(LPC_DEV, LPC_GEN2_DEC, ((0xff & ~3 ) << 8) | 0x900 | 1); | ||||
|  | ||||
| 	/* GPIO pins need to be configured to specific native function */ | ||||
| 	gpio_configure_pads(lpc_gpio_configs, ARRAY_SIZE(lpc_gpio_configs)); | ||||
| } | ||||
|  | ||||
| void asmlinkage bootblock_c_entry(void) | ||||
| { | ||||
| 	device_t dev = NB_DEV_ROOT; | ||||
| @@ -59,4 +84,8 @@ void bootblock_soc_early_init(void) | ||||
|  | ||||
| 	if (IS_ENABLED(CONFIG_LPC_TPM)) | ||||
| 		tpm_enable(); | ||||
|  | ||||
| 	if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC_LPC)) | ||||
| 		early_lpc_enable(); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -32,6 +32,15 @@ struct soc_intel_apollolake_config { | ||||
| 	uint8_t pcie_rp3_clkreq_pin; | ||||
| 	uint8_t pcie_rp4_clkreq_pin; | ||||
| 	uint8_t pcie_rp5_clkreq_pin; | ||||
|  | ||||
| 	/* Generic IO decode ranges */ | ||||
| 	uint32_t gen1_dec; | ||||
| 	uint32_t gen2_dec; | ||||
| 	uint32_t gen3_dec; | ||||
| 	uint32_t gen4_dec; | ||||
|  | ||||
| 	/* LPC port ranges */ | ||||
| 	uint16_t lpc_dec; | ||||
| }; | ||||
|  | ||||
| #endif	/* _SOC_APOLLOLAKE_CHIP_H_ */ | ||||
|   | ||||
							
								
								
									
										40
									
								
								src/soc/intel/apollolake/include/soc/lpc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/soc/intel/apollolake/include/soc/lpc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| /* | ||||
|  * This file is part of the coreboot project. | ||||
|  * | ||||
|  * Copyright (C) 2016 Intel Corp. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
|  | ||||
| #ifndef _SOC_APOLLOLAKE_LPC_H | ||||
| #define _SOC_APOLLOLAKE_LPC_H | ||||
|  | ||||
| /* PCI Configuration Space (D31:F0): LPC */ | ||||
| #define SERIRQ_CNTL		0x64 /* Serial IRQ Control Register */ | ||||
| #define LPC_IO_DEC		0x80 /* IO Decode Ranges Register */ | ||||
| #define LPC_EN			0x82 /* LPC IF Enables Register */ | ||||
| #define  LPC_EN_COMA		(1 << 0) /* COM port A */ | ||||
| #define  LPC_EN_COMB		(1 << 1) /* COM port B */ | ||||
| #define  LPC_EN_PARP		(1 << 2) /* Parallel port */ | ||||
| #define  LPC_EN_FLP		(1 << 3) /* Floppy */ | ||||
| #define  LPC_EN_LGAME		(1 << 8) /* Low Gameport, 0x200-0x207 */ | ||||
| #define  LPC_EN_HGAME		(1 << 9) /* High Gameport, 0x208-0x20f */ | ||||
| #define  LPC_EN_KB		(1 << 10) /* Keyboard, 0x60, 0x64 */ | ||||
| #define  LPC_EN_MC1		(1 << 11) /* Microcontroller #1, 0x62, 0x66 */ | ||||
| #define  LPC_EN_MC2		(1 << 13) /* Microcontroller #2, 0x4e, 0x4f */ | ||||
| #define  LPC_EN_SIO		(1 << 12) /* Super IO, 0x2e, 0x2f */ | ||||
|  | ||||
| #define LPC_GEN1_DEC		0x84 /* LPC IF Generic Decode Range 1 */ | ||||
| #define LPC_GEN2_DEC		0x88 /* LPC IF Generic Decode Range 2 */ | ||||
| #define LPC_GEN3_DEC		0x8C /* LPC IF Generic Decode Range 3 */ | ||||
| #define LPC_GEN4_DEC		0x90 /* LPC IF Generic Decode Range 4 */ | ||||
|  | ||||
| #endif //_SOC_APOLLOLAKE_LPC_H | ||||
| @@ -48,8 +48,11 @@ | ||||
| #define  LPSS_DEV_UART2		_LPSS_PCI_DEV(UART, 2) | ||||
| #define  LPSS_DEV_UART3		_LPSS_PCI_DEV(UART, 3) | ||||
|  | ||||
| #define LPC_SLOT		0x1f | ||||
|  | ||||
| #define P2SB_DEV		PCI_DEV(0, 0xd, 0) | ||||
| #define PMC_DEV			PCI_DEV(0, 0xd, 1) | ||||
| #define SPI_DEV			PCI_DEV(0, 0xd, 2) | ||||
| #define LPC_DEV			PCI_DEV(0, LPC_SLOT, 0) | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* | ||||
|  * This file is part of the coreboot project. | ||||
|  * | ||||
|  * Copyright (C) 2016 Intel Corp. | ||||
|  * Copyright (C) 2015-2016 Intel Corp. | ||||
|  * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.) | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
| @@ -20,6 +20,46 @@ | ||||
| #include <device/pci_ids.h> | ||||
| #include <soc/acpi.h> | ||||
| #include <soc/pci_ids.h> | ||||
| #include <reg_script.h> | ||||
| #include <vendorcode/google/chromeos/chromeos.h> | ||||
| #include <soc/lpc.h> | ||||
| #include "chip.h" | ||||
|  | ||||
| static const struct reg_script lpc_serirq_enable[] = { | ||||
| 	/* Setup SERIRQ, enable continuous mode */ | ||||
| 	REG_PCI_OR8(SERIRQ_CNTL, (1 << 7) | (1 << 6)), | ||||
| #if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE) | ||||
| 	REG_PCI_RMW8(SERIRQ_CNTL, ~(1 << 6), 0), | ||||
| #endif | ||||
| 	REG_SCRIPT_END | ||||
| }; | ||||
|  | ||||
| static void enable_lpc_decode(struct device *lpc) | ||||
| { | ||||
| 	const struct soc_intel_apollolake_config *config; | ||||
|  | ||||
| 	if (!lpc || !lpc->chip_info) | ||||
| 		return; | ||||
|  | ||||
| 	config = lpc->chip_info; | ||||
|  | ||||
| 	/* Enable requested fixed IO decode ranges */ | ||||
| 	pci_write_config16(lpc, LPC_EN, config->lpc_dec); | ||||
|  | ||||
| 	/* Enable generic IO decode ranges */ | ||||
| 	pci_write_config32(lpc, LPC_GEN1_DEC, config->gen1_dec); | ||||
| 	pci_write_config32(lpc, LPC_GEN2_DEC, config->gen2_dec); | ||||
| 	pci_write_config32(lpc, LPC_GEN3_DEC, config->gen3_dec); | ||||
| 	pci_write_config32(lpc, LPC_GEN4_DEC, config->gen4_dec); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void lpc_init(struct device *dev) | ||||
| { | ||||
| 	enable_lpc_decode(dev); | ||||
| 	reg_script_run_on_dev(dev, lpc_serirq_enable); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void soc_lpc_add_io_resources(device_t dev) | ||||
| { | ||||
| @@ -46,6 +86,7 @@ static struct device_operations device_ops = { | ||||
| 	.set_resources = &pci_dev_set_resources, | ||||
| 	.enable_resources = &pci_dev_enable_resources, | ||||
| 	.write_acpi_tables = southbridge_write_acpi_tables, | ||||
| 	.init = &lpc_init | ||||
| }; | ||||
|  | ||||
| static const struct pci_driver soc_lpc __pci_driver = { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user