/* * * Copyright 2017 NXP * * SPDX-License-Identifier: GPL-2.0 */ #include #include #include #include #include #include #include #include void mx8x_pcie_controller_reset(sc_ipc_t ipc, u32 scr) { sc_err_t err; int i; err = sc_misc_set_control(ipc, scr, SC_C_PCIE_G_RST, 1); if (err != SC_ERR_NONE) printf("SC_R_PCIE G_RST failed! (error = %d)\n", err); for (i = 0; i < 200; i = i + 1) asm("nop"); err = sc_misc_set_control(ipc, scr, SC_C_PCIE_G_RST, 0); if (err != SC_ERR_NONE) printf("SC_R_PCIE G_RST failed! (error = %d)\n", err); err = sc_misc_set_control(ipc, scr, SC_C_PCIE_PERST, 1); if (err != SC_ERR_NONE) printf("SC_R_PCIE PCIE_RST failed! (error = %d)\n", err); err = sc_misc_set_control(ipc, scr, SC_C_PCIE_BUTTON_RST, 1); if (err != SC_ERR_NONE) printf("SC_R_PCIE BUTTON_RST failed! (error = %d)\n", err); } static void pcie_mapping_region(u32 index, u32 direction, u32 type, u32 addr, u32 size, u32 target_l, u32 target_h) { /* Select a iATU and configure its direction */ pcie_writel(index | direction, PCIE0_ATU_VIEWPORT); setbits_le32(PCIE0_ATU_CR1, type); /* Set memory address and size */ pcie_writel(addr, PCIE0_ATU_LOWER_BASE); pcie_writel(0, PCIE0_ATU_UPPER_BASE); pcie_writel((addr + size - 1), PCIE0_ATU_LIMIT); pcie_writel(target_l, PCIE0_ATU_LOWER_TARGET); pcie_writel(target_h, PCIE0_ATU_UPPER_TARGET); /* Enable this iATU */ setbits_le32(PCIE0_ATU_CR2, PCIE_ATU_ENABLE); } static void pcie_ctrlb_mapping_region(u32 index, u32 direction, u32 type, u32 addr, u32 size, u32 target_l, u32 target_h) { /* Select a iATU and configure its direction */ pcie_writel(index | direction, PCIE1_ATU_VIEWPORT); setbits_le32(PCIE1_ATU_CR1, type); /* Set memory address and size */ pcie_writel(addr, PCIE1_ATU_LOWER_BASE); pcie_writel(0, PCIE1_ATU_UPPER_BASE); pcie_writel((addr + size - 1), PCIE1_ATU_LIMIT); pcie_writel(target_l, PCIE1_ATU_LOWER_TARGET); pcie_writel(target_h, PCIE1_ATU_UPPER_TARGET); /* Enable this iATU */ setbits_le32(PCIE1_ATU_CR2, PCIE_ATU_ENABLE); } /* CFG Space --> 0x40000000 * 1st Region --> 0x41000000 * 2nd Region --> 0x42000000 * ... */ void mx8x_pcie_ctrla_setup_regions(void) { u32 i, cmd; u32 val, index; u32 is_32bit; u32 type, size; u64 size64; const u32 region_types[] = { PCIE_ATU_TYPE_MEM, PCIE_ATU_TYPE_IO, }; cmd = PCI_COMMAND_MASTER; pcie_mapping_region(0, PCIE_ATU_REGION_OUTBOUND, PCIE_ATU_TYPE_CFG0, PCIEA_CFG_PCI_BASE, PCIE_CFG_MEM_SIZE, 0, 0); index = 1; udelay(1000); for (i = 0; i < 6; i++) { val = pcie_readl(PCIEA_CFG_CPU_BASE + 0x10 + i * 4); printf("#### [%d] val=%X addr=%X\r\n ", i, val, PCIEA_CFG_CPU_BASE + 0x10 + i * 4); if (!val) continue; type = region_types[val & 0x1]; is_32bit = ((val & 0x4) == 0); pcie_writel(0xFFFFFFFF, PCIEA_CFG_CPU_BASE + 0x10 + i * 4); size = pcie_readl(PCIEA_CFG_CPU_BASE + 0x10 + i * 4); size = 0xFFFFFFFF - (size & ~0xF) + 1; if (is_32bit) { pcie_mapping_region(index, PCIE_ATU_REGION_OUTBOUND, type, PCIEA_CFG_PCI_BASE + index * 0x1000000, size, index * 0x1000000, 0); val = (val & 0xF) + index * 0x1000000; pcie_writel(val, (PCIEA_CFG_CPU_BASE + 0x10 + i * 4)); } else { pcie_writel(0xFFFFFFFF, (PCIEA_CFG_CPU_BASE + 0x10 + i * 4 + 4)); size64 = pcie_readl(PCIEA_CFG_CPU_BASE + 0x10 + i * 4 + 4); size64 = 0xFFFFFFFF - size64; size64 <<= 32; size64 |= size; size64++; pcie_mapping_region(index, PCIE_ATU_REGION_OUTBOUND, type, PCIEA_CFG_PCI_BASE + index * 0x1000000, size64, index * 0x1000000, 0); val = (val & 0xF) + index * 0x1000000; pcie_writel(val, (PCIEA_CFG_CPU_BASE + 0x10 + i * 4)); pcie_writel(0, (PCIEA_CFG_CPU_BASE + 0x10 + i * 4 + 4)); i++; } index++; if (type == PCIE_ATU_TYPE_MEM) cmd |= PCI_COMMAND_MEMORY; else cmd |= PCI_COMMAND_IO; } pcie_writel(cmd, PCIEA_CFG_CPU_BASE + 4); } /* CFG Space --> 0x80000000 * 1st Region --> 0x81000000 * 2nd Region --> 0x82000000 * ... */ void mx8x_pcie_ctrlb_setup_regions(void) { u32 i, cmd; u32 val, index; u32 is_32bit; u32 type, size; u64 size64; const u32 region_types[] = { PCIE_ATU_TYPE_MEM, PCIE_ATU_TYPE_IO, }; cmd = PCI_COMMAND_MASTER; pcie_ctrlb_mapping_region(0, PCIE_ATU_REGION_OUTBOUND, PCIE_ATU_TYPE_CFG0, PCIEB_CFG_PCI_BASE, PCIE_CFG_MEM_SIZE, 0, 0); index = 1; udelay(1000); for (i = 0; i < 6; i++) { val = pcie_readl(PCIEB_CFG_CPU_BASE + 0x10 + i * 4); printf("#### [%d] val=%X addr=%X\r\n ", i, val, PCIEB_CFG_CPU_BASE + 0x10 + i * 4); if (!val) continue; type = region_types[val & 0x1]; is_32bit = ((val & 0x4) == 0); pcie_writel(0xFFFFFFFF, PCIEB_CFG_CPU_BASE + 0x10 + i * 4); size = pcie_readl(PCIEB_CFG_CPU_BASE + 0x10 + i * 4); size = 0xFFFFFFFF - (size & ~0xF) + 1; if (is_32bit) { pcie_ctrlb_mapping_region(index, PCIE_ATU_REGION_OUTBOUND, type, PCIEB_CFG_PCI_BASE + index * 0x1000000, size, index * 0x1000000, 0); val = (val & 0xF) + index * 0x1000000; pcie_writel(val, (PCIEB_CFG_CPU_BASE + 0x10 + i * 4)); } else { pcie_writel(0xFFFFFFFF, (PCIEB_CFG_CPU_BASE + 0x10 + i * 4 + 4)); size64 = pcie_readl(PCIEB_CFG_CPU_BASE + 0x10 + i * 4 + 4); size64 = 0xFFFFFFFF - size64; size64 <<= 32; size64 |= size; size64++; pcie_ctrlb_mapping_region(index, PCIE_ATU_REGION_OUTBOUND, type, PCIEB_CFG_PCI_BASE + index * 0x1000000, size64, index * 0x1000000, 0); val = (val & 0xF) + index * 0x1000000; pcie_writel(val, (PCIEB_CFG_CPU_BASE + 0x10 + i * 4)); pcie_writel(0, (PCIEB_CFG_CPU_BASE + 0x10 + i * 4 + 4)); i++; } index++; if (type == PCIE_ATU_TYPE_MEM) cmd |= PCI_COMMAND_MEMORY; else cmd |= PCI_COMMAND_IO; } pcie_writel(cmd, PCIEB_CFG_CPU_BASE + 4); }