blob: 9e3da0681ca0db433bf14e2ea8f1e6b6e6481d75 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <zircon/assert.h>
#include <hw/reg.h>
#include <ddk/debug.h>
#include <ddk/protocol/platform-defs.h>
#include <soc/aml-a113/a113-gpio.h>
#include <soc/aml-a113/a113-hw.h>
#include <soc/aml-meson/axg-clk.h>
#include <dev/pci/amlogic-pcie/atu-cfg.h>
#include "gauss.h"
// Note: These are all constants for the PCIe A controller
// PCIe B is not currently supported.
static const pbus_mmio_t dw_pcie_mmios[] = {
{ // elbi
.base = 0xf9800000,
.length = 0x400000, // 4MiB
},
{ // phy
.base = 0xff644000,
.length = 0x2000, // 8KiB
},
{ // cfg
.base = 0xff646000,
.length = 0x2000, // 8KiB
},
{ // reset
.base = 0xffd01080,
.length = 0x10, // 16B
},
{ // config
.base = 0xf9c00000,
.length = 0x400000, // 4MiB
},
{ // clock/plls
.base = 0xff63c000,
.length = PAGE_SIZE,
},
};
static const pbus_irq_t dw_pcie_irqs[] = {
{
.irq = DW_PCIE_IRQ0,
.mode = ZX_INTERRUPT_MODE_DEFAULT,
},
{
.irq = DW_PCIE_IRQ1,
.mode = ZX_INTERRUPT_MODE_DEFAULT,
},
};
static const pbus_gpio_t dw_pcie_gpios[] = {
{
.gpio = A113_GPIOX(19), // Reset
},
};
static const pbus_clk_t pcie_clk_gates[] = {
{
.clk = CLK_AXG_CLK81,
},
{
.clk = CLK_AXG_PCIE_A,
},
{
.clk = CLK_CML0_EN,
},
};
#define CFG_CPU_ADDR_BASE (0xf9c00000)
#define CFG_CPU_ADDR_LEN (0x10000) // 64KiB of CFG Space
#define IO_CPU_ADDR_BASE (0xf9d00000)
#define IO_CPU_ADDR_LEN (0x10000) // 64KiB of IO Space
#define MEM_CPU_ADDR_BASE (IO_CPU_ADDR_BASE + IO_CPU_ADDR_LEN)
#define MEM_CPU_ADDR_LEN (0x300000) // 3MiB of memory space.
static const iatu_translation_entry_t cfg_entry = {
.cpu_addr = CFG_CPU_ADDR_BASE,
.pci_addr = 0,
.length = CFG_CPU_ADDR_LEN,
};
static const iatu_translation_entry_t io_entry = {
.cpu_addr = IO_CPU_ADDR_BASE,
.pci_addr = 0,
.length = IO_CPU_ADDR_LEN,
};
static const iatu_translation_entry_t mem_entry = {
.cpu_addr = MEM_CPU_ADDR_BASE,
.pci_addr = MEM_CPU_ADDR_BASE,
.length = MEM_CPU_ADDR_LEN,
};
static const pbus_metadata_t iatu_metadata[] = {
// PCIe Configuration Space
{
.type = IATU_CFG_APERTURE_METADATA, // Private Metadata
.extra = 0,
.data = &cfg_entry,
.len = sizeof(cfg_entry),
},
// PCIe IO Space
{
.type = IATU_IO_APERTURE_METADATA, // Private Metadata
.extra = 0,
.data = &io_entry,
.len = sizeof(io_entry),
},
// PCIe Memory space
{
.type = IATU_MMIO_APERTURE_METADATA, // Private Metadata
.extra = 0,
.data = &mem_entry,
.len = sizeof(mem_entry),
},
};
static const pbus_dev_t pcie_dev = {
.name = "aml-dw-pcie",
.vid = PDEV_VID_AMLOGIC,
.pid = PDEV_PID_GENERIC,
.did = PDEV_DID_DW_PCIE,
.mmios = dw_pcie_mmios,
.mmio_count = countof(dw_pcie_mmios),
.gpios = dw_pcie_gpios,
.gpio_count = countof(dw_pcie_gpios),
.clks = pcie_clk_gates,
.clk_count = countof(pcie_clk_gates),
.irqs = dw_pcie_irqs,
.irq_count = countof(dw_pcie_irqs),
.metadata = iatu_metadata,
.metadata_count = countof(iatu_metadata),
};
zx_status_t gauss_pcie_init(gauss_bus_t* bus) {
zx_status_t st = pbus_device_add(&bus->pbus, &pcie_dev, 0);
if (st != ZX_OK) {
zxlogf(ERROR, "gauss_clk_init: pbus_device_add failed, st = %d\n", st);
return st;
}
return ZX_OK;
}