1b2e02d28SBin Meng /* 2b2e02d28SBin Meng * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> 3b2e02d28SBin Meng * 4b2e02d28SBin Meng * SPDX-License-Identifier: GPL-2.0+ 5b2e02d28SBin Meng */ 6b2e02d28SBin Meng 7b2e02d28SBin Meng #include <common.h> 8b2e02d28SBin Meng #include <asm/io.h> 9*9c7dea60SBin Meng #include <asm/irq.h> 10adfe3b24SBin Meng #include <asm/pci.h> 11b2e02d28SBin Meng #include <asm/post.h> 12afbf1404SBin Meng #include <asm/arch/device.h> 13*9c7dea60SBin Meng #include <asm/arch/tnc.h> 141021af4dSSimon Glass #include <asm/fsp/fsp_support.h> 15b2e02d28SBin Meng #include <asm/processor.h> 16b2e02d28SBin Meng 17adfe3b24SBin Meng static void unprotect_spi_flash(void) 18adfe3b24SBin Meng { 19adfe3b24SBin Meng u32 bc; 20adfe3b24SBin Meng 219704f23bSBin Meng bc = x86_pci_read_config32(TNC_LPC, 0xd8); 22adfe3b24SBin Meng bc |= 0x1; /* unprotect the flash */ 239704f23bSBin Meng x86_pci_write_config32(TNC_LPC, 0xd8, bc); 24adfe3b24SBin Meng } 25adfe3b24SBin Meng 26b2e02d28SBin Meng int arch_cpu_init(void) 27b2e02d28SBin Meng { 28adfe3b24SBin Meng struct pci_controller *hose; 29adfe3b24SBin Meng int ret; 30adfe3b24SBin Meng 31b2e02d28SBin Meng post_code(POST_CPU_INIT); 32b2e02d28SBin Meng #ifdef CONFIG_SYS_X86_TSC_TIMER 33b2e02d28SBin Meng timer_set_base(rdtsc()); 34b2e02d28SBin Meng #endif 35b2e02d28SBin Meng 36adfe3b24SBin Meng ret = x86_cpu_init_f(); 37adfe3b24SBin Meng if (ret) 38adfe3b24SBin Meng return ret; 39adfe3b24SBin Meng 40adfe3b24SBin Meng ret = pci_early_init_hose(&hose); 41adfe3b24SBin Meng if (ret) 42adfe3b24SBin Meng return ret; 43adfe3b24SBin Meng 44adfe3b24SBin Meng unprotect_spi_flash(); 45adfe3b24SBin Meng 46adfe3b24SBin Meng return 0; 47b2e02d28SBin Meng } 48afbf1404SBin Meng 49*9c7dea60SBin Meng void cpu_irq_init(void) 50*9c7dea60SBin Meng { 51*9c7dea60SBin Meng struct tnc_rcba *rcba; 52*9c7dea60SBin Meng u32 base; 53*9c7dea60SBin Meng 54*9c7dea60SBin Meng base = x86_pci_read_config32(TNC_LPC, LPC_RCBA); 55*9c7dea60SBin Meng base &= ~MEM_BAR_EN; 56*9c7dea60SBin Meng rcba = (struct tnc_rcba *)base; 57*9c7dea60SBin Meng 58*9c7dea60SBin Meng /* Make sure all internal PCI devices are using INTA */ 59*9c7dea60SBin Meng writel(INTA, &rcba->d02ip); 60*9c7dea60SBin Meng writel(INTA, &rcba->d03ip); 61*9c7dea60SBin Meng writel(INTA, &rcba->d27ip); 62*9c7dea60SBin Meng writel(INTA, &rcba->d31ip); 63*9c7dea60SBin Meng writel(INTA, &rcba->d23ip); 64*9c7dea60SBin Meng writel(INTA, &rcba->d24ip); 65*9c7dea60SBin Meng writel(INTA, &rcba->d25ip); 66*9c7dea60SBin Meng writel(INTA, &rcba->d26ip); 67*9c7dea60SBin Meng 68*9c7dea60SBin Meng /* 69*9c7dea60SBin Meng * Route TunnelCreek PCI device interrupt pin to PIRQ 70*9c7dea60SBin Meng * 71*9c7dea60SBin Meng * Since PCIe downstream ports received INTx are routed to PIRQ 72*9c7dea60SBin Meng * A/B/C/D directly and not configurable, we route internal PCI 73*9c7dea60SBin Meng * device's INTx to PIRQ E/F/G/H. 74*9c7dea60SBin Meng */ 75*9c7dea60SBin Meng writew(PIRQE, &rcba->d02ir); 76*9c7dea60SBin Meng writew(PIRQF, &rcba->d03ir); 77*9c7dea60SBin Meng writew(PIRQG, &rcba->d27ir); 78*9c7dea60SBin Meng writew(PIRQH, &rcba->d31ir); 79*9c7dea60SBin Meng writew(PIRQE, &rcba->d23ir); 80*9c7dea60SBin Meng writew(PIRQF, &rcba->d24ir); 81*9c7dea60SBin Meng writew(PIRQG, &rcba->d25ir); 82*9c7dea60SBin Meng writew(PIRQH, &rcba->d26ir); 83*9c7dea60SBin Meng } 84*9c7dea60SBin Meng 85afbf1404SBin Meng int arch_misc_init(void) 86afbf1404SBin Meng { 87afbf1404SBin Meng pirq_init(); 88afbf1404SBin Meng 89afbf1404SBin Meng return 0; 90afbf1404SBin Meng } 91