/** * Copyright (C) 2010-2014 Ikanos Communications. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * Info : * This module provides the glue between Linux's PCI subsystem and Fusiv PCIe core hardware. * We basically provide hardware initialization function and glue for accessing configuration space. */ #include #include #include #include #include #include #include #include #include #include #include #define MAX_READ_COUNT 500000 #define SERDES 1 /* PCIE Serdes Register Addresses*/ // RC0 #define PCIE0_SDS_PCSR_CTL_0 0xB90E2000 #define PCIE0_SDS_PCSR_CTL_1 0xB90E2004 #define PCIE0_SDS_PCSR_CTL_2 0xB90E2008 #define PCIE0_SDS_PCSR_CTL_3 0xB90E200C #define PCIE0_SDS_PCSR_CTL_4 0xB90E2010 #define PCIE0_SDS_PCSR_CTL_5 0xB90E2014 //register used for indirect PCIE0 serdes accessing #define PCIE0_SDS_PCSR_CTL_6 0xB90E2018 #define PCIE0_SDS_PCSR_STAT_0 0xB90E201C #define PCIE0_SDS_PCSR_STAT_1 0xB90E2020 // RC1 #define PCIE1_SDS_PCSR_CTL_0 0xB90E4000 #define PCIE1_SDS_PCSR_CTL_1 0xB90E4004 #define PCIE1_SDS_PCSR_CTL_2 0xB90E4008 #define PCIE1_SDS_PCSR_CTL_3 0xB90E400C #define PCIE1_SDS_PCSR_CTL_4 0xB90E4010 #define PCIE1_SDS_PCSR_CTL_5 0xB90E4014 //register used for indirect PCIE1 serdes accessing #define PCIE1_SDS_PCSR_CTL_6 0xB90E4018 #define PCIE1_SDS_PCSR_STAT_0 0xB90E401C #define PCIE1_SDS_PCSR_STAT_1 0xB90E4020 // SCU Serdes Control #define SCU_SERDES_CTL_0 0xB9000070 #define SCU_RST_CTL0 0xB9000204 /*Read/write access functions in config space*/ static int fusiv_pcibios_read_port0( struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { unsigned char busnum = bus->number; u32 data = 0; u32 cfgaddr = CFGADDR(busnum,devfn,where); /* We are assuming that only one Device is attached to the bus */ if(PCI_SLOT(devfn) > 0) { return PCIBIOS_DEVICE_NOT_FOUND; } if ((size == 2) && (where & 1)) return PCIBIOS_BAD_REGISTER_NUMBER; else if ((size == 4) && (where & 3)) return PCIBIOS_BAD_REGISTER_NUMBER; RDCFG32(0, cfgaddr, data); if (size == 1) *val = (data >> ((where & 3) << 3)) & 0xff; else if (size == 2) *val = (data >> ((where & 3) << 3)) & 0xffff; else *val = data; return PCIBIOS_SUCCESSFUL; } static int fusiv_pcibios_write_port0( struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { unsigned char busnum = bus->number; u32 cfgaddr = CFGADDR(busnum,devfn,where); u32 data = 0; if(PCI_SLOT(devfn) > 0) { return PCIBIOS_DEVICE_NOT_FOUND; } if ((size == 2) && (where & 1)) return PCIBIOS_BAD_REGISTER_NUMBER; else if ((size == 4) && (where & 3)) return PCIBIOS_BAD_REGISTER_NUMBER; RDCFG32(0,cfgaddr,data); if (size == 1) data = (data & ~(0xff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); else if (size == 2) data = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); else data = val; WRCFG32(0,cfgaddr,data); return PCIBIOS_SUCCESSFUL; } #ifdef CONFIG_FUSIV_PCIE_RC1 static int fusiv_pcibios_read_port1( struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) { unsigned char busnum = bus->number; u32 data = 0; u32 cfgaddr = CFGADDR(busnum,devfn,where); if(PCI_SLOT(devfn) > 0) { return PCIBIOS_DEVICE_NOT_FOUND; } if ((size == 2) && (where & 1)) return PCIBIOS_BAD_REGISTER_NUMBER; else if ((size == 4) && (where & 3)) return PCIBIOS_BAD_REGISTER_NUMBER; RDCFG32(1,cfgaddr,data); if (size == 1) *val = (data >> ((where & 3) << 3)) & 0xff; else if (size == 2) *val = (data >> ((where & 3) << 3)) & 0xffff; else *val = data; return PCIBIOS_SUCCESSFUL; } static int fusiv_pcibios_write_port1( struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) { unsigned char busnum = bus->number; u32 cfgaddr = CFGADDR(busnum,devfn,where); if(PCI_SLOT(devfn) > 0) { return PCIBIOS_DEVICE_NOT_FOUND; } u32 data = 0; if ((size == 2) && (where & 1)) return PCIBIOS_BAD_REGISTER_NUMBER; else if ((size == 4) && (where & 3)) return PCIBIOS_BAD_REGISTER_NUMBER; RDCFG32(1, cfgaddr, data); if (size == 1) data = (data & ~(0xff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); else if (size == 2) data = (data & ~(0xffff << ((where & 3) << 3))) | (val << ((where & 3) << 3)); else data = val; WRCFG32(1,cfgaddr,data); return PCIBIOS_SUCCESSFUL; } #endif int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_controller *controller; controller = (struct pci_controller *) dev->sysdata; /* Index Field is initialized with RC Port Number during controller init */ switch(controller->index) { case 0: /* Unmask the required INTx pin */ /* pin = 1,2,3 and 4 for INTA,INTB, INTC and INTD respectively */ WRREG32(FUSIV_PCIE_ADDR(0,PCIE_INTERRUPT_MASK),(RDREG32(FUSIV_PCIE_ADDR(0,PCIE_INTERRUPT_MASK)) & ~(1 << (17 - 2*pin)))); WRREG32(FUSIV_PCIE_ADDR(0,PCIE_INTERRUPT_MASK),(RDREG32(FUSIV_PCIE_ADDR(0,PCIE_INTERRUPT_MASK)) & ~(1 << (18 - 2*pin)))); return PCIe0_INT; case 1: WRREG32(FUSIV_PCIE_ADDR(1,PCIE_INTERRUPT_MASK),(RDREG32(FUSIV_PCIE_ADDR(1,PCIE_INTERRUPT_MASK)) & ~(1 << (17 - 2*pin)))); WRREG32(FUSIV_PCIE_ADDR(1,PCIE_INTERRUPT_MASK),(RDREG32(FUSIV_PCIE_ADDR(1,PCIE_INTERRUPT_MASK)) & ~(1 << (18 - 2*pin)))); return PCIe1_INT; default: return -1; /* Illegal */ } } struct pci_ops fusiv_pci_ops_0 = { .read = fusiv_pcibios_read_port0, .write = fusiv_pcibios_write_port0, }; static struct resource fusiv_pci_mem_resource_0 = { .name = "FUSIV PCIE0 MEM", .start = PCIE_MEM_PA_LO_0, .end = PCIE_MEM_PA_HI_0, .flags = IORESOURCE_MEM, }; static struct resource fusiv_pci_io_resource_0 = { .name = "FUSIV PCIE0 IO", .start = 0x00000100, .end = 0x7FFF, .flags = IORESOURCE_DISABLED, }; static struct pci_controller fusiv_pci_controller_0 = { .mem_resource = &fusiv_pci_mem_resource_0, .io_resource = &fusiv_pci_io_resource_0, .pci_ops = &fusiv_pci_ops_0, .index = 0, }; #ifdef CONFIG_FUSIV_PCIE_RC1 static struct pci_ops fusiv_pci_ops_1 = { .read = fusiv_pcibios_read_port1, .write = fusiv_pcibios_write_port1, }; static struct resource fusiv_pci_mem_resource_1 = { .name = "FUSIV PCIE1 MEM", .start = PCIE_MEM_PA_LO_1, .end = PCIE_MEM_PA_HI_1, .flags = IORESOURCE_MEM, }; static struct resource fusiv_pci_io_resource_1 = { .name = "FUSIV PCIE1 IO", .start = 0x000008000, .end = 0xFFFF, .flags = IORESOURCE_DISABLED, }; static struct pci_controller fusiv_pci_controller_1 = { .mem_resource = &fusiv_pci_mem_resource_1, .io_resource = &fusiv_pci_io_resource_1, .pci_ops = &fusiv_pci_ops_1, .index = 1, }; #endif void wait_done_from_serdes_pcie0() { unsigned int tempval; //`PCIE0_SDS_PCSR_CTL_5 Bit[29] == 1 // Wait for Bit[29] to go 1 //`PCIE0_SDS_PCSR_CTL_5 = 32'h2000_0000; ///clearing previous response. while(1) { tempval = RDREG32(PCIE0_SDS_PCSR_CTL_5); if ((tempval & 0x20000000) != 0) { tempval = 0x20000000; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); break; } } } void config_pcie0() { unsigned int tempval; unsigned int read_count, i; #if SERDES tempval = RDREG32(SCU_SERDES_CTL_0); tempval &= 0xFFFFFFF8; WRREG32(SCU_SERDES_CTL_0,tempval); /*dekumar:Minumum delay should be 500us. Keeping 800us*/ udelay(800); //0x1900_0070 |= 32'h0000_0001; // POR of PCIE0 SERDES tempval = RDREG32(SCU_SERDES_CTL_0); tempval |= 0x00000001; WRREG32(SCU_SERDES_CTL_0,tempval); tempval = RDREG32(SCU_SERDES_CTL_0); tempval &= 0xFFFFFFF9; WRREG32(SCU_SERDES_CTL_0,tempval); tempval = RDREG32(PCIE0_SDS_PCSR_CTL_0); tempval |= 0x2000; WRREG32(PCIE0_SDS_PCSR_CTL_0,tempval); //`PCIE0_SDS_PCSR_CTL_4 |= 32'h8000_0002 ; //Enabling mux not taking values from pins. 32'hB5FE_3FFF tempval = RDREG32(PCIE0_SDS_PCSR_CTL_4); tempval |= 0x40000080 ; // For PSTATE and TXELECIDLE WRREG32(PCIE0_SDS_PCSR_CTL_4,tempval); //`PCIE0_SDS_PCSR_CTL_5 = 32'hA0BF_0065; tempval = 0xA0BF0065; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //indirect access response check Function described above //`PCIE0_SDS_PCSR_CTL_5 = 32'h8008_0066; tempval = 0x80080066; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8008_0067; tempval = 0x80080067; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8013_0068; tempval = 0x80130068; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8013_0069; tempval = 0x80130069; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8001_006A; tempval = 0x8001006A; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8011_006B; tempval = 0x8011006B; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h800C_006C; tempval = 0x800C006C; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80AA_806F; tempval = 0x80AA806F; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_8070; tempval = 0x80008070; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8034_8071; tempval = 0x80348071; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80BF_8072; tempval = 0x80BF8072; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8008_8073; tempval = 0x80088073; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //PCIE0_SDS_PCSR_CTL_5 = 32'h8008_8074; tempval = 0x80088074; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //PCIE0_SDS_PCSR_CTL_5 = 32'h8013_8075; tempval = 0x80138075; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8013_8076; tempval = 0x80138076; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8003_8077; tempval = 0x80038077; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8014_8078; tempval = 0x80148078; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8010_8079; tempval = 0x80108079; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_807A; tempval = 0x8000807A; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8010_807B; tempval = 0x8010807B; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_807C; tempval = 0x8000807C; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_807D; tempval = 0x80FF807D; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80CF_807E; tempval = 0x80CF807E; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F7_807F; tempval = 0x80F7807F; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80E1_8080; tempval = 0x80E18080; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_8081; tempval = 0x80F58081; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FD_8082; tempval = 0x80FD8082; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FD_8083; tempval = 0x80FD8083; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_8084; tempval = 0x80FF8084; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_8085; tempval = 0x80FF8085; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_8086; tempval = 0x80FF8086; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_8087; tempval = 0x80FF8087; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80E3_8088; tempval = 0x80E38088; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80E7_8089; tempval = 0x80E78089; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80DB_808A; tempval = 0x80DB808A; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_808B; tempval = 0x80F5808B; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FD_808C; tempval = 0x80FD808C; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FD_808D; tempval = 0x80FD808D; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_808E; tempval = 0x80F5808E; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_808F; tempval = 0x80F5808F; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_8090; tempval = 0x80FF8090; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_8091; tempval = 0x80FF8091; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80E3_8092; tempval = 0x80E38092; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80E7_8093; tempval = 0x80E78093; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80DB_8094; tempval = 0x80DB8094; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_8095; tempval = 0x80F58095; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FD_8096; tempval = 0x80FD8096; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FD_8097; tempval = 0x80FD8097; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_8098; tempval = 0x80F58098; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_8099; tempval = 0x80F58099; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_809A; tempval = 0x80FF809A; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_809B; tempval = 0x80FF809B; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80FF_809C; tempval = 0x80FF809C; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80F5_809D; tempval = 0x80F5809D; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h803F_809E; tempval = 0x803F809E; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_809F; tempval = 0x8000809F; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8032_80A0; tempval = 0x803280A0; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_80A1; tempval = 0x800080A1; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8003_80A2; tempval = 0x800280A2; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8005_80A3; tempval = 0x800580A3; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8004_80A4; tempval = 0x800480A4; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_80A5; tempval = 0x800080A5; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_80A6; tempval = 0x800080A6; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8014_80A7; tempval = 0x800880A7; // For non-SSC use 0x8, for SSC - 0x1C WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8004_80A8; tempval = 0x800480A8; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_80A9; tempval = 0x800080A9; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_80AA; tempval = 0x800080AA; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8004_80AB; tempval = 0x800480AB; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8003_80AC; tempval = 0x800380AC; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80EA_0152; tempval = 0x80EA0152; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80C2_0153; tempval = 0x80C20153; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); #if 0 // SSC Settings -- comment this if SSC not used tempval = 0x8000014C; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80C0014D; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80FC014E; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x8031014F; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80E70150; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x802B0151; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80EB0152; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80110156; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x805A0157; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x800080A6; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80A7001C; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); // -- SSC settings end #endif // Set to IDDQ State tempval = RDREG32(PCIE0_SDS_PCSR_CTL_2); tempval &= 0xFFF8FFFF; WRREG32(PCIE0_SDS_PCSR_CTL_2,tempval); //0x1900_0070 |= 32'h0000_0006; // Setting HARD_SYNTH, HARD_TXRX of PCIE0 SERDES tempval = RDREG32(SCU_SERDES_CTL_0); tempval |= 0x00000006; WRREG32(SCU_SERDES_CTL_0,tempval); // RXEQ Settings //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_0015; tempval = 0x80070015; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80000016; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80080017; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80780018; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x80000019; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x800a80a3; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x800000fd; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); tempval = 0x806a013a; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); // TX Driver Settings //`PCIE0_SDS_PCSR_CTL_5 = 32'h80D9_0012; tempval = 0x80DD0012; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_0013; tempval = 0x80060013; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8000_0014; tempval = 0x80000014; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h801b_000b; tempval = 0x801b000b; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h8033_000c; tempval = 0x8033000c; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_5 = 32'h80DA_8019; tempval = 0x80DA8019; WRREG32(PCIE0_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie0(); //`PCIE0_SDS_PCSR_CTL_2 |= 32'h0007_0000 ; //IPD_PCS_RX_L0 bit 16, IPD_PCS_SYNTH bit 17 and IPD_PCS_TX_L0 bit 18 tempval = RDREG32(PCIE0_SDS_PCSR_CTL_2); tempval |= 0x00070000; WRREG32(PCIE0_SDS_PCSR_CTL_2,tempval); #endif /* SERDES */ //Release the Reset of PCIE0 //0x19000204 = 32'hFFFF_FFBF); // Correction from VLSI RESET BITS:8-11, 16 to be SET to 1 tempval = RDREG32(SCU_RST_CTL0); tempval |= 0x00010F00; WRREG32(SCU_RST_CTL0,tempval); /* ____MEM space enable and BUS MASTER enable - PCIe RC0 ____ */ WRREG32(FUSIV_PCIE_ADDR(0,CMD_STAT),0x6); //Default speed change set to 1 - intiates speed change after gen1 //0x1913_280c |= 32'h0002_0000 ; tempval = RDREG32(FUSIV_PCIE_ADDR(0,LINK_WIDTH_SPEED_CHANGE)); tempval |= 0x00020000; WRREG32(FUSIV_PCIE_ADDR(0,LINK_WIDTH_SPEED_CHANGE),tempval); //ltssm enable //0x1913_0000 |= 32'h0000_0800 ; tempval = RDREG32(FUSIV_PCIE_ADDR(0,APP_SYS_CONTROL)); tempval |= 0x00000800; WRREG32(FUSIV_PCIE_ADDR(0,APP_SYS_CONTROL),tempval); //app_ent_l23 //0x1913_0034 |= 32'h0000_0010 ; tempval = RDREG32(FUSIV_PCIE_ADDR(0,PCIE_CORE_CFG)); tempval |= 0x00000010; WRREG32(FUSIV_PCIE_ADDR(0,PCIE_CORE_CFG),tempval); #if SERDES //set Tx enable //0x190E_2004 |= 32'h0080_0000 ; tempval = RDREG32(PCIE0_SDS_PCSR_CTL_1); tempval |= 0x00800000; WRREG32(PCIE0_SDS_PCSR_CTL_1,tempval); //`PCIE0_SDS_PCSR_STAT_0 Bit[0] == 1 // Wait for Bit[0] to go 1 while(1) { tempval = RDREG32(PCIE0_SDS_PCSR_STAT_0); if (tempval & 0x00000001) break; } //`PCIE0_SDS_PCSR_STAT_0 Bit[24] == 1 // Wait for Bit[24] to go 1 while(1) { tempval = RDREG32(PCIE0_SDS_PCSR_STAT_0); if (tempval & 0x01000000) break; } //`PCIE0_SDS_PCSR_STAT_0 Bit[19] == 1 // Wait for Bit[19] to go 1 while(1) { tempval = RDREG32(PCIE0_SDS_PCSR_STAT_0); if (tempval & 0x00080000) break; } #endif /* SERDES */ // PCIE0 Link up //0x1913_0004 (Bit[6] == 1'b1) /* ___ Wait for Link Up _________ */ read_count = 0; i = 0; do { tempval = RDREG32(FUSIV_PCIE_ADDR(0,CORE_STATUS)); if(tempval & CORE_STATUS_RDLH_LINK_UP) { printk("PCIE0 Link Up !!!! \n"); break; } //i++; //if(( i % 1000) == 0){ // printk(" Polling .... value is 0x%x\n",tempval); //} } while ((read_count++ <= MAX_READ_COUNT)); if (read_count >= MAX_READ_COUNT) { printk("PCIE0 link NOT UP !!!!! \n"); return PCIBIOS_SET_FAILED; }else { #if SERDES //Setting back the Serdes power sate and electrical idle muxing to pins //`PCIE0_SDS_PCSR_CTL_4 &= 32'hBFFF_FF7F ; /// PSTATE, TXELECIDLE tempval = RDREG32(PCIE0_SDS_PCSR_CTL_4); tempval &= 0xBFFFFF7F; WRREG32(PCIE0_SDS_PCSR_CTL_4,tempval); #endif /* SERDES */ // Configuration of PCIE0 RC Mode /* 0x1913_2118 = 32'h1a0); 0x1913_2004 = 32'h00000007); 0x1913_2018 = 32'h40100); 0x1913_2034 = 32'h40); 0x1913_2040 = 32'h5040); 0x1913_2050 = 32'h7040); 0x1913_2070 = 32'h10); 0x1913_2078 = 32'h2030); 0x1913_20b0 = 32'h20); 0x1913_2100 = 32'h14810001); 0x1913_2148 = 32'h10002); 0x1913_214c = 32'h01); 0x1913_2150 = 32'h0); 0x1913_215c = 32'h800000ff); 0x1913_2010 = 32'h1B000000); 0x1913_2014 = 32'h00000000); */ (*((volatile unsigned int *)(0xB9132118))) = 0x1a0; (*((volatile unsigned int *)(0xB9132004))) = 0x00000007; (*((volatile unsigned int *)(0xB9132018))) = 0x40100; (*((volatile unsigned int *)(0xB9132034))) = 0x40; (*((volatile unsigned int *)(0xB9132040))) = 0x5040; (*((volatile unsigned int *)(0xB9132050))) = 0x7040; (*((volatile unsigned int *)(0xB9132070))) = 0x10; (*((volatile unsigned int *)(0xB9132078))) = 0x2010; (*((volatile unsigned int *)(0xB91320b0))) = 0x20; (*((volatile unsigned int *)(0xB9132100))) = 0x14810001; (*((volatile unsigned int *)(0xB9132148))) = 0x10002; (*((volatile unsigned int *)(0xB913214c))) = 0x01; (*((volatile unsigned int *)(0xB9132150))) = 0x0; (*((volatile unsigned int *)(0xB913215c))) = 0x800000ff; (*((volatile unsigned int *)(0xB9132010))) = 0x0; (*((volatile unsigned int *)(0xB9132014))) = 0x0; // The below wait statement is to make sure the link is stable state and read for transaction // Wait for run rate =1 //0x1913_0004 Bit[10] == 1'b1 // Wait for Bit[10] to go 1 read_count = 0; do { tempval = RDREG32(FUSIV_PCIE_ADDR(0,CORE_STATUS)); if(tempval & CORE_STATUS_RDLH_LINK_UP) { break; } } while ((read_count++ < MAX_READ_COUNT)); if (read_count == MAX_READ_COUNT) printk("PCIE0 link NOT Stable !!!!! \n"); else { printk("PCIE0 Link Stable. Register PCIE controller!!!! \n"); mdelay(1); /*loop delay */ register_pci_controller(&fusiv_pci_controller_0); } } } void wait_done_from_serdes_pcie1() { unsigned int tempval; //`PCIE1_SDS_PCSR_CTL_5 Bit[29] == 1 // Wait for Bit[29] to go 1 //`PCIE1_SDS_PCSR_CTL_5 = 32'h2000_0000; //clearing previous response. while(1) { tempval = RDREG32(PCIE1_SDS_PCSR_CTL_5); if ((tempval & 0x20000000) != 0) { tempval = 0x20000000; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); break; } } } #ifdef CONFIG_FUSIV_PCIE_RC1 void config_pcie1() { unsigned int tempval; unsigned int read_count, i; #if SERDES tempval = RDREG32(SCU_SERDES_CTL_0); tempval &= 0xFFFFF8FF; WRREG32(SCU_SERDES_CTL_0,tempval); /*dekumar:Minumum delay should be 500us. Keeping 800us*/ udelay(800); //0x1900_0070 |= 32'h0000_0001; // POR of PCIE1 SERDES tempval = RDREG32(SCU_SERDES_CTL_0); tempval |= 0x00000100; WRREG32(SCU_SERDES_CTL_0,tempval); tempval = RDREG32(SCU_SERDES_CTL_0); tempval &= 0xFFFFF9FF; WRREG32(SCU_SERDES_CTL_0,tempval); tempval = RDREG32(PCIE1_SDS_PCSR_CTL_0); tempval |= 0x2000; WRREG32(PCIE1_SDS_PCSR_CTL_0,tempval); //`PCIE1_SDS_PCSR_CTL_4 |= 32'h8000_0002 ; //Enabling mux not taking values from pins. 32'hB5FE_3FFF tempval = RDREG32(PCIE1_SDS_PCSR_CTL_4); tempval |=0x40000080 ; // For PSTATE and TXELECIDLE WRREG32(PCIE1_SDS_PCSR_CTL_4,tempval); //`PCIE1_SDS_PCSR_CTL_5 = 32'hA0BF_0065; tempval = 0xA0BF0065; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //indirect access response check Function described above //`PCIE1_SDS_PCSR_CTL_5 = 32'h8008_0066; tempval = 0x80080066; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8008_0067; tempval = 0x80080067; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8013_0068; tempval = 0x80130068; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8013_0069; tempval = 0x80130069; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8001_006A; tempval = 0x8001006A; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8011_006B; tempval = 0x8011006B; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h804D_006C; tempval = 0x800C006C; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80AA_806F; tempval = 0x80AA806F; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_8070; tempval = 0x80008070; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8034_8071; tempval = 0x80348071; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80BF_8072; tempval = 0x80BF8072; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8008_8073; tempval = 0x80088073; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //PCIE1_SDS_PCSR_CTL_5 = 32'h8008_8074; tempval = 0x80088074; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //PCIE1_SDS_PCSR_CTL_5 = 32'h8013_8075; tempval = 0x80138075; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8013_8076; tempval = 0x80138076; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8003_8077; tempval = 0x80038077; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8014_8078; tempval = 0x80148078; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8010_8079; tempval = 0x80108079; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_807A; tempval = 0x8000807A; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8010_807B; tempval = 0x8010807B; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_807C; tempval = 0x8000807C; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_807D; tempval = 0x80FF807D; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80CF_807E; tempval = 0x80CF807E; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F7_807F; tempval = 0x80F7807F; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80E1_8080; tempval = 0x80E18080; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_8081; tempval = 0x80F58081; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FD_8082; tempval = 0x80FD8082; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FD_8083; tempval = 0x80FD8083; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_8084; tempval = 0x80FF8084; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_8085; tempval = 0x80FF8085; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_8086; tempval = 0x80FF8086; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_8087; tempval = 0x80FF8087; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80E3_8088; tempval = 0x80E38088; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80E7_8089; tempval = 0x80E78089; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80DB_808A; tempval = 0x80DB808A; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_808B; tempval = 0x80F5808B; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FD_808C; tempval = 0x80FD808C; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FD_808D; tempval = 0x80FD808D; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_808E; tempval = 0x80F5808E; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_808F; tempval = 0x80F5808F; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_8090; tempval = 0x80FF8090; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_8091; tempval = 0x80FF8091; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80E3_8092; tempval = 0x80E38092; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80E7_8093; tempval = 0x80E78093; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80DB_8094; tempval = 0x80DB8094; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_8095; tempval = 0x80F58095; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FD_8096; tempval = 0x80FD8096; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FD_8097; tempval = 0x80FD8097; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_8098; tempval = 0x80F58098; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_8099; tempval = 0x80F58099; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_809A; tempval = 0x80FF809A; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_809B; tempval = 0x80FF809B; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80FF_809C; tempval = 0x80FF809C; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80F5_809D; tempval = 0x80F5809D; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h803F_809E; tempval = 0x803F809E; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_809F; tempval = 0x8000809F; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8032_80A0; tempval = 0x803280A0; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_80A1; tempval = 0x800080A1; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8003_80A2; tempval = 0x800280A2; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8005_80A3; tempval = 0x800580A3; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8004_80A4; tempval = 0x800480A4; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_80A5; tempval = 0x800080A5; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_80A6; tempval = 0x800080A6; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8014_80A7; tempval = 0x800880A7; // For non-SSC use 0x8, for SSC - 0x1C WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8004_80A8; tempval = 0x800480A8; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_80A9; tempval = 0x800080A9; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8000_80AA; tempval = 0x800080AA; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8004_80AB; tempval = 0x800480AB; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h8003_80AC; tempval = 0x800380AC; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80EA_0152; tempval = 0x80EA0152; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_5 = 32'h80C2_0153; tempval = 0x80C20153; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); #if 0 // SSC Settings -- comment this if SSC not used tempval = 0x8000014C; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80C0014D; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80FC014E; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x8031014F; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80E70150; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x802B0151; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80EB0152; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80110156; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x805A0157; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x800080A6; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80A7001C; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); // -- SSC settings end #endif // Set to IDDQ State tempval = RDREG32(PCIE1_SDS_PCSR_CTL_2); tempval &= 0xFFF8FFFF; WRREG32(PCIE1_SDS_PCSR_CTL_2,tempval); //0x1900_0070 |= 32'h0000_0600; // Setting HARD_SYNTH, HARD_TXRX of PCIE1 SERDES tempval = RDREG32(SCU_SERDES_CTL_0); tempval |= 0x00000600; WRREG32(SCU_SERDES_CTL_0,tempval); // RXEQ Settings tempval = 0x80070015; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80000016; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80080017; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80780018; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80000019; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x800a80a3; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x800000fd; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x806a013a; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80DD0012; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80060013; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80000014; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x801b000b; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x8033000c; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); tempval = 0x80DA8019; WRREG32(PCIE1_SDS_PCSR_CTL_5,tempval); wait_done_from_serdes_pcie1(); //`PCIE1_SDS_PCSR_CTL_2 |= 32'h0007_0000 ; //IPD_PCS_RX_L0 bit 16, IPD_PCS_SYNTH bit 17 and IPD_PCS_TX_L0 bit 18 tempval = RDREG32(PCIE1_SDS_PCSR_CTL_2); tempval |= 0x00070000; WRREG32(PCIE1_SDS_PCSR_CTL_2,tempval); #endif /* SERDES */ //Release the Reset of PCIE1 //0x19000204 = 32'hFFFF_FFBF); // Correction from VLSI RESET BITS:12-15, 16 to be SET to 1 tempval = RDREG32(SCU_RST_CTL0); tempval |= 0x0001F000; WRREG32(SCU_RST_CTL0,tempval); /* ____MEM space enable and BUS MASTER enable - PCIe RC1 ____ */ WRREG32(FUSIV_PCIE_ADDR(1,CMD_STAT),0x6); //Default speed change set to 1 - intiates speed change after gen1 //0x1914_280c |= 32'h0002_0000 ; tempval = RDREG32(FUSIV_PCIE_ADDR(1,LINK_WIDTH_SPEED_CHANGE)); tempval |= 0x00020000; WRREG32(FUSIV_PCIE_ADDR(1, LINK_WIDTH_SPEED_CHANGE),tempval); //ltssm enable //0x1914_0000 |= 32'h0000_0800 ; tempval = RDREG32(FUSIV_PCIE_ADDR(1,APP_SYS_CONTROL)); tempval |= 0x00000800; WRREG32(FUSIV_PCIE_ADDR(1, APP_SYS_CONTROL),tempval); //app_ent_l23 //0x1914_0034 |= 32'h0000_0010 ; tempval = RDREG32(FUSIV_PCIE_ADDR(1,PCIE_CORE_CFG)); tempval |= 0x00000010; WRREG32(FUSIV_PCIE_ADDR(1, PCIE_CORE_CFG),tempval); #if SERDES //set Tx enable //0x190E_4004 |= 32'h0080_0000 ; tempval = RDREG32(PCIE1_SDS_PCSR_CTL_1); tempval |= 0x00800000; WRREG32(PCIE1_SDS_PCSR_CTL_1,tempval); //`PCIE1_SDS_PCSR_STAT_0 Bit[0] == 1 // Wait for Bit[0] to go 1 while(1) { tempval = RDREG32(PCIE1_SDS_PCSR_STAT_0); if (tempval & 0x00000001) break; } //`PCIE1_SDS_PCSR_STAT_0 Bit[24] == 1 // Wait for Bit[24] to go 1 while(1) { tempval = RDREG32(PCIE1_SDS_PCSR_STAT_0); if (tempval & 0x01000000) break; } //`PCIE1_SDS_PCSR_STAT_0 Bit[19] == 1 // Wait for Bit[19] to go 1 while(1) { tempval = RDREG32(PCIE1_SDS_PCSR_STAT_0); if (tempval & 0x00080000) break; } #endif /* SERDES */ // PCIE1 Link up //0x1914_0004 (Bit[6] == 1'b1) // Wait for link up /* ___ Wait for Link Up _________ */ read_count = 0; i = 0; do { tempval = RDREG32(FUSIV_PCIE_ADDR(1,CORE_STATUS)); if(tempval & CORE_STATUS_RDLH_LINK_UP) { printk("PCIE1 Link Up !!!! \n"); break; } //i++; //if(( i % 1000) == 0){ // printk(" Polling .... value is 0x%x\n",tempval); //} } while ((read_count++ <= MAX_READ_COUNT)); if (read_count >= MAX_READ_COUNT) { printk("PCIE1 link NOT UP !!!!! \n"); return PCIBIOS_SET_FAILED; } else { #if SERDES //Setting back the Serdes power sate and electrical idle muxing to pins //`PCIE1_SDS_PCSR_CTL_4 &= 32'hBFFF_FF7F ; // PSTATE, TXELECIDLE tempval = RDREG32(PCIE1_SDS_PCSR_CTL_4); tempval &= 0xBFFFFF7F; WRREG32(PCIE1_SDS_PCSR_CTL_4,tempval); #endif /* SERDES */ // Configuration of PCIE1 RC Mode /* 0x1914_2118 = 32'h1a0); 0x1914_2004 = 32'h00000007); 0x1914_2018 = 32'h40100); 0x1914_2034 = 32'h40); 0x1914_2040 = 32'h5040); 0x1914_2050 = 32'h7040); 0x1914_2070 = 32'h10); 0x1914_2078 = 32'h2030); 0x1914_20b0 = 32'h20); 0x1914_2100 = 32'h14810001); 0x1914_2148 = 32'h10002); 0x1914_214c = 32'h01); 0x1914_2150 = 32'h0); 0x1914_215c = 32'h800000ff); 0x1914_2010 = 32'h1B000000); 0x1914_2014 = 32'h00000000); */ (*((volatile unsigned int *)(0xB9142118))) = 0x1a0; (*((volatile unsigned int *)(0xB9142004))) = 0x00000007; (*((volatile unsigned int *)(0xB9142018))) = 0x40100; (*((volatile unsigned int *)(0xB9142034))) = 0x40; (*((volatile unsigned int *)(0xB9142040))) = 0x5040; (*((volatile unsigned int *)(0xB9142050))) = 0x7040; (*((volatile unsigned int *)(0xB9142070))) = 0x10; (*((volatile unsigned int *)(0xB9142078))) = 0x2010; (*((volatile unsigned int *)(0xB91420b0))) = 0x20; (*((volatile unsigned int *)(0xB9142100))) = 0x14810001; (*((volatile unsigned int *)(0xB9142148))) = 0x10002; (*((volatile unsigned int *)(0xB914214c))) = 0x01; (*((volatile unsigned int *)(0xB9142150))) = 0x0; (*((volatile unsigned int *)(0xB914215c))) = 0x800000ff; (*((volatile unsigned int *)(0xB9142010))) = 0x0; (*((volatile unsigned int *)(0xB9142014))) = 0x0; // The below wait statement is to make sure the link is stable state and read for transaction // Wait for run rate =1 //0x1914_0004 Bit[10] == 1'b1 // Wait for Bit[10] to go 1 read_count = 0; do { tempval = RDREG32(FUSIV_PCIE_ADDR(1,CORE_STATUS)); if(tempval & CORE_STATUS_RDLH_LINK_UP) { break; } } while ((read_count++ < MAX_READ_COUNT)); if (read_count == MAX_READ_COUNT) printk("PCIE1 link NOT Stable !!!!! \n"); else { printk("PCIE1 Link Stable. Register PCIE controller!!!! \n"); mdelay(1);/*loop delay */ register_pci_controller(&fusiv_pci_controller_1); } } } #endif int __init fusiv_pcibios_init(void) { config_pcie0(); #ifdef CONFIG_FUSIV_PCIE_RC1 config_pcie1(); #endif return PCIBIOS_SUCCESSFUL; } /* Do platform specific device initialization at pci_enable_device() time */ int pcibios_plat_dev_init(struct pci_dev *dev) { return 0; } arch_initcall(fusiv_pcibios_init);