1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <zircon/assert.h> 6 7#include <hw/reg.h> 8 9#include <ddk/debug.h> 10#include <ddk/protocol/platform-defs.h> 11 12#include <dev/pci/designware/atu-cfg.h> 13#include <soc/aml-a113/a113-gpio.h> 14#include <soc/aml-a113/a113-hw.h> 15#include <soc/aml-meson/axg-clk.h> 16 17#include "gauss.h" 18 19// Note: These are all constants for the PCIe A controller 20// PCIe B is not currently supported. 21static const pbus_mmio_t dw_pcie_mmios[] = { 22 { // elbi 23 .base = 0xf9800000, 24 .length = 0x400000, // 4MiB 25 }, 26 { // cfg 27 .base = 0xff646000, 28 .length = 0x2000, // 8KiB 29 }, 30 { // reset 31 .base = 0xffd01080, 32 .length = 0x10, // 16B 33 }, 34 { // clock/plls 35 .base = 0xff63c000, 36 .length = PAGE_SIZE, 37 }, 38}; 39 40static const pbus_irq_t dw_pcie_irqs[] = { 41 { 42 .irq = DW_PCIE_IRQ0, 43 .mode = ZX_INTERRUPT_MODE_DEFAULT, 44 }, 45 { 46 .irq = DW_PCIE_IRQ1, 47 .mode = ZX_INTERRUPT_MODE_DEFAULT, 48 }, 49}; 50 51static const pbus_gpio_t dw_pcie_gpios[] = { 52 { 53 .gpio = A113_GPIOX(19), // Reset 54 }, 55}; 56 57static const pbus_clk_t pcie_clk_gates[] = { 58 { 59 .clk = CLK_AXG_CLK81, 60 }, 61 { 62 .clk = CLK_AXG_PCIE_A, 63 }, 64 { 65 .clk = CLK_CML0_EN, 66 }, 67}; 68 69#define CFG_CPU_ADDR_BASE (0xf9c00000) 70#define CFG_CPU_ADDR_LEN (0x10000) // 64KiB of CFG Space 71#define IO_CPU_ADDR_BASE (0xf9d00000) 72#define IO_CPU_ADDR_LEN (0x10000) // 64KiB of IO Space 73#define MEM_CPU_ADDR_BASE (IO_CPU_ADDR_BASE + IO_CPU_ADDR_LEN) 74#define MEM_CPU_ADDR_LEN (0x300000) // 3MiB of memory space. 75 76static const iatu_translation_entry_t cfg_entry = { 77 .cpu_addr = CFG_CPU_ADDR_BASE, 78 .pci_addr = 0, 79 .length = CFG_CPU_ADDR_LEN, 80}; 81 82static const iatu_translation_entry_t io_entry = { 83 .cpu_addr = IO_CPU_ADDR_BASE, 84 .pci_addr = 0, 85 .length = IO_CPU_ADDR_LEN, 86}; 87 88static const iatu_translation_entry_t mem_entry = { 89 .cpu_addr = MEM_CPU_ADDR_BASE, 90 .pci_addr = MEM_CPU_ADDR_BASE, 91 .length = MEM_CPU_ADDR_LEN, 92}; 93 94static const pbus_metadata_t iatu_metadata[] = { 95 // PCIe Configuration Space 96 { 97 .type = IATU_CFG_APERTURE_METADATA, // Private Metadata 98 .data = &cfg_entry, 99 .len = sizeof(cfg_entry), 100 }, 101 102 // PCIe IO Space 103 { 104 .type = IATU_IO_APERTURE_METADATA, // Private Metadata 105 .data = &io_entry, 106 .len = sizeof(io_entry), 107 }, 108 109 // PCIe Memory space 110 { 111 .type = IATU_MMIO_APERTURE_METADATA, // Private Metadata 112 .data = &mem_entry, 113 .len = sizeof(mem_entry), 114 }, 115}; 116 117static const pbus_bti_t pci_btis[] = { 118 { 119 .iommu_index = 0, 120 .bti_id = 0, 121 }, 122}; 123 124static const pbus_dev_t pcie_dev_children[] = { 125 { 126 // Resources for child-1 127 .btis = pci_btis, 128 .bti_count = countof(pci_btis) 129 }, 130}; 131 132static const pbus_dev_t pcie_dev = { 133 .name = "aml-dw-pcie", 134 .vid = PDEV_VID_AMLOGIC, 135 .pid = PDEV_PID_GENERIC, 136 .did = PDEV_DID_DW_PCIE, 137 .mmios = dw_pcie_mmios, 138 .mmio_count = countof(dw_pcie_mmios), 139 .gpios = dw_pcie_gpios, 140 .gpio_count = countof(dw_pcie_gpios), 141 .clks = pcie_clk_gates, 142 .clk_count = countof(pcie_clk_gates), 143 .irqs = dw_pcie_irqs, 144 .irq_count = countof(dw_pcie_irqs), 145 .metadata = iatu_metadata, 146 .metadata_count = countof(iatu_metadata), 147 148 // Allow this device to publish the Kernel PCI device on the Platform Bus 149 .children = pcie_dev_children, 150 .child_count = countof(pcie_dev_children), 151}; 152 153zx_status_t gauss_pcie_init(gauss_bus_t* bus) { 154 zx_status_t st = pbus_device_add(&bus->pbus, &pcie_dev); 155 if (st != ZX_OK) { 156 zxlogf(ERROR, "gauss_clk_init: pbus_device_add failed, st = %d\n", st); 157 return st; 158 } 159 160 return ZX_OK; 161}