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> 99c7dea60SBin Meng #include <asm/irq.h> 10adfe3b24SBin Meng #include <asm/pci.h> 11b2e02d28SBin Meng #include <asm/post.h> 12afbf1404SBin Meng #include <asm/arch/device.h> 139c7dea60SBin 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 26*1f124ebaSBin Meng static void __maybe_unused disable_igd(void) 27*1f124ebaSBin Meng { 28*1f124ebaSBin Meng u32 gc; 29*1f124ebaSBin Meng 30*1f124ebaSBin Meng gc = x86_pci_read_config32(TNC_IGD, IGD_GC); 31*1f124ebaSBin Meng gc &= ~GMS_MASK; 32*1f124ebaSBin Meng gc |= VGA_DISABLE; 33*1f124ebaSBin Meng x86_pci_write_config32(TNC_IGD, IGD_GC, gc); 34*1f124ebaSBin Meng } 35*1f124ebaSBin Meng 36b2e02d28SBin Meng int arch_cpu_init(void) 37b2e02d28SBin Meng { 38adfe3b24SBin Meng int ret; 39adfe3b24SBin Meng 40b2e02d28SBin Meng post_code(POST_CPU_INIT); 41b2e02d28SBin Meng #ifdef CONFIG_SYS_X86_TSC_TIMER 42b2e02d28SBin Meng timer_set_base(rdtsc()); 43b2e02d28SBin Meng #endif 44b2e02d28SBin Meng 45adfe3b24SBin Meng ret = x86_cpu_init_f(); 46adfe3b24SBin Meng if (ret) 47adfe3b24SBin Meng return ret; 48adfe3b24SBin Meng 49adfe3b24SBin Meng return 0; 50b2e02d28SBin Meng } 51afbf1404SBin Meng 52*1f124ebaSBin Meng int arch_early_init_r(void) 53*1f124ebaSBin Meng { 54*1f124ebaSBin Meng #ifdef CONFIG_DISABLE_IGD 55*1f124ebaSBin Meng disable_igd(); 56*1f124ebaSBin Meng #endif 57*1f124ebaSBin Meng 58*1f124ebaSBin Meng return 0; 59*1f124ebaSBin Meng } 60*1f124ebaSBin Meng 619c7dea60SBin Meng void cpu_irq_init(void) 629c7dea60SBin Meng { 639c7dea60SBin Meng struct tnc_rcba *rcba; 649c7dea60SBin Meng u32 base; 659c7dea60SBin Meng 669c7dea60SBin Meng base = x86_pci_read_config32(TNC_LPC, LPC_RCBA); 679c7dea60SBin Meng base &= ~MEM_BAR_EN; 689c7dea60SBin Meng rcba = (struct tnc_rcba *)base; 699c7dea60SBin Meng 709c7dea60SBin Meng /* Make sure all internal PCI devices are using INTA */ 719c7dea60SBin Meng writel(INTA, &rcba->d02ip); 729c7dea60SBin Meng writel(INTA, &rcba->d03ip); 739c7dea60SBin Meng writel(INTA, &rcba->d27ip); 749c7dea60SBin Meng writel(INTA, &rcba->d31ip); 759c7dea60SBin Meng writel(INTA, &rcba->d23ip); 769c7dea60SBin Meng writel(INTA, &rcba->d24ip); 779c7dea60SBin Meng writel(INTA, &rcba->d25ip); 789c7dea60SBin Meng writel(INTA, &rcba->d26ip); 799c7dea60SBin Meng 809c7dea60SBin Meng /* 819c7dea60SBin Meng * Route TunnelCreek PCI device interrupt pin to PIRQ 829c7dea60SBin Meng * 839c7dea60SBin Meng * Since PCIe downstream ports received INTx are routed to PIRQ 84cdb6babeSBin Meng * A/B/C/D directly and not configurable, we have to route PCIe 85cdb6babeSBin Meng * root ports' INTx to PIRQ A/B/C/D as well. For other devices 86cdb6babeSBin Meng * on TunneCreek, route them to PIRQ E/F/G/H. 879c7dea60SBin Meng */ 889c7dea60SBin Meng writew(PIRQE, &rcba->d02ir); 899c7dea60SBin Meng writew(PIRQF, &rcba->d03ir); 909c7dea60SBin Meng writew(PIRQG, &rcba->d27ir); 919c7dea60SBin Meng writew(PIRQH, &rcba->d31ir); 92cdb6babeSBin Meng writew(PIRQA, &rcba->d23ir); 93cdb6babeSBin Meng writew(PIRQB, &rcba->d24ir); 94cdb6babeSBin Meng writew(PIRQC, &rcba->d25ir); 95cdb6babeSBin Meng writew(PIRQD, &rcba->d26ir); 969c7dea60SBin Meng } 979c7dea60SBin Meng 98afbf1404SBin Meng int arch_misc_init(void) 99afbf1404SBin Meng { 100090290f9SBin Meng unprotect_spi_flash(); 101090290f9SBin Meng 1027e4be120SSimon Glass return pirq_init(); 103afbf1404SBin Meng } 104