first and last commit
This commit is contained in:
commit
1bf4efd552
2612 files changed
+636500
No files matched your search
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
#ifndef _APCIE_COMMON_REGS_H
|
||||
#define _APCIE_COMMON_REGS_H
|
||||
|
||||
#include <platform/soc/hwregbase.h>
|
||||
|
||||
#define rAPCIE_PHY_RST_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x040 + (n) * 0x010))
|
||||
#define rAPCIE_PHY_CLKREQ_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x044 + (n) * 0x010))
|
||||
|
||||
#define APCIE_PHY_RST_CTRL_phy_sw_reset (1 << 0)
|
||||
|
||||
#define rAPCIE_NANDSYSCLK_CTRL (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x080))
|
||||
|
||||
#define rAPCIE_PORT_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x100 + (n) * 0x80))
|
||||
#define rAPCIE_PORT_SQUELCH_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x104 + (n) * 0x80))
|
||||
#define rAPCIE_PORT_REFCLK_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x108 + (n) * 0x80))
|
||||
#define rAPCIE_PORT_OVERRIDE_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x10c + (n) * 0x80))
|
||||
#define rAPCIE_PORT_CLKREQ_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x110 + (n) * 0x80))
|
||||
#define rAPCIE_PORT_ACG_IDLE_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x114 + (n) * 0x80))
|
||||
#define rAPCIE_PORT_RST_CTRL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x118 + (n) * 0x80))
|
||||
#define rAPCIE_PIPE_OVERRIDE_VAL(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x11c + (n) * 0x80))
|
||||
#define rAPCIE_PORT_PRIORITY(n) (*(volatile uint32_t *)(APCIE_COMMON_BASE_ADDR + 0x120 + (n) * 0x80))
|
||||
|
||||
#define APCIE_PORT_CTRL_port_en (1 << 0)
|
||||
#define APCIE_PORT_CTRL_appclk_auto_dis (1 << 8)
|
||||
#define APCIE_PORT_CTRL_nvme_en (1 << 16)
|
||||
#define APCIE_PORT_CTRL_muxed_auxclk_auto_dis (1 << 20)
|
||||
|
||||
#define APCIE_PORT_REFCLK_CTRL_refclk_en (1 << 0)
|
||||
#define APCIE_PORT_REFCLK_CTRL_refclk_auto_dis (1 << 8)
|
||||
|
||||
#define APCIE_PORT_OVERRIDE_CTRL_pipe_ovr_en (1 << 0)
|
||||
|
||||
#define APCIE_PORT_RST_CTRL_perst_n (1 << 0)
|
||||
|
||||
#define APCIE_PHY_BASE_ADDR(port) (PCI_REG_BASE + 0x1000000 * ((port) + 1) + 0x5000)
|
||||
|
||||
#define rAPCIE_PHY_PHY_REF_USE_PAD(port) (*(volatile uint32_t *)(APCIE_PHY_BASE_ADDR(port) + 0xc3c))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
/*
|
||||
* Copyright (C) 2012-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* This document is the property of Apple Inc.
|
||||
* It is considered confidential and proprietary.
|
||||
*
|
||||
* This document may not be reproduced or transmitted in any form,
|
||||
* in whole or in part, without the express written permission of
|
||||
* Apple Inc.
|
||||
*/
|
||||
|
||||
#include <debug.h>
|
||||
#include <arch/arm/arm.h>
|
||||
#include <drivers/apcie.h>
|
||||
#include <drivers/dart.h>
|
||||
#include <drivers/pci.h>
|
||||
#include <lib/devicetree.h>
|
||||
#include <platform.h>
|
||||
#include <platform/apcie_regs.h>
|
||||
#include <platform/gpio.h>
|
||||
#include <platform/gpiodef.h>
|
||||
#include <platform/timer.h>
|
||||
#include <platform/soc/hwclocks.h>
|
||||
#include <platform/soc/hwisr.h>
|
||||
#include <platform/soc/hwregbase.h>
|
||||
#include <sys.h>
|
||||
#include <sys/menu.h>
|
||||
#include "apcie_common_regs.h"
|
||||
|
||||
static bool s3e_mode;
|
||||
static bool s3e_reset_on_enable;
|
||||
static uint32_t link_enable_count;
|
||||
|
||||
struct apcie_dbi_overrides {
|
||||
uint32_t offset;
|
||||
uint32_t mask;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
static struct apcie_dbi_overrides apcie_dbi_overrides[] = {
|
||||
// Enable 64-bit addresses
|
||||
{ 0x024, 0x00000001, 1 },
|
||||
// Don't advertise L0s support
|
||||
{ 0x07c, 0x00000400, 0 },
|
||||
// Set T_POWER_OFF field in the L1_substates register to 2 (<rdar://problem/17813587>)
|
||||
{ 0xb44, 0x00000003, 2 },
|
||||
};
|
||||
|
||||
bool external_refclk;
|
||||
|
||||
|
||||
// selects internal vs external refclk. must be called before
|
||||
// enabling the first link
|
||||
void apcie_use_external_refclk(bool use)
|
||||
{
|
||||
external_refclk = use;
|
||||
}
|
||||
|
||||
void apcie_set_s3e_mode(bool reset_on_enable)
|
||||
{
|
||||
s3e_mode = true;
|
||||
s3e_reset_on_enable = reset_on_enable;
|
||||
}
|
||||
|
||||
#if !SUB_PLATFORM_T7000
|
||||
static void apcie_enable_phy_clkreq(uint32_t phy)
|
||||
{
|
||||
// Note, the function number might change for future platforms
|
||||
if (phy == 0) {
|
||||
gpio_configure(GPIO_PCIE_PHY01_CLKREQ, GPIO_CFG_FUNC1);
|
||||
} else if (phy == 1) {
|
||||
gpio_configure(GPIO_PCIE_PHY23_CLKREQ, GPIO_CFG_FUNC1);
|
||||
} else {
|
||||
panic("apcie: unknown phy %u", phy);
|
||||
}
|
||||
rAPCIE_PHY_CLKREQ_CTRL(phy) |= 1;
|
||||
}
|
||||
|
||||
static void apcie_disable_phy_clkreq(uint32_t phy)
|
||||
{
|
||||
rAPCIE_PHY_CLKREQ_CTRL(phy) &= ~1;
|
||||
if (phy == 0) {
|
||||
gpio_configure(GPIO_PCIE_PHY01_CLKREQ, GPIO_CFG_DFLT);
|
||||
} else if (phy == 1) {
|
||||
gpio_configure(GPIO_PCIE_PHY23_CLKREQ, GPIO_CFG_DFLT);
|
||||
} else {
|
||||
panic("apcie: unknown phy %u", phy);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void apcie_enable_external_refclk(void)
|
||||
{
|
||||
// Sequence from section 6.1.5 of Fiji/Capri APCIe spec (updated to r1.04.44)
|
||||
|
||||
// 1) Set APCIE_COMMON_APCIE_RST_CTRL_{0/1}.apcie_phy_sw_reset to place the PHY in reset.
|
||||
for (int i = 0; i < APCIE_NUM_LINKS; i += 2)
|
||||
rAPCIE_PHY_RST_CTRL(i / 2) |= APCIE_PHY_RST_CTRL_phy_sw_reset;
|
||||
// 2) To access the PHY, the link shall be enabled.
|
||||
for (int i = 0; i < APCIE_NUM_LINKS; i+= 2)
|
||||
rAPCIE_PORT_CTRL(i) |= APCIE_PORT_CTRL_port_en;
|
||||
// 3) De-assert PERST# to the root controller
|
||||
for (int i = 0; i < APCIE_NUM_LINKS; i+= 2)
|
||||
rAPCIE_PORT_RST_CTRL(i) |= APCIE_PORT_RST_CTRL_perst_n;
|
||||
// 4) Select the external REFCLK
|
||||
for (int i = 0; i < APCIE_NUM_LINKS; i+= 2)
|
||||
rAPCIE_PHY_PHY_REF_USE_PAD(i) = 1;
|
||||
// c) Insert a DMB barrier instruction to insure that the external REFCLK switch occurs
|
||||
// before the port is disabled.
|
||||
platform_memory_barrier();
|
||||
// 5) Assert PERST# to the root controller
|
||||
for (int i = 0; i < APCIE_NUM_LINKS; i+= 2)
|
||||
rAPCIE_PORT_RST_CTRL(i) &= ~APCIE_PORT_RST_CTRL_perst_n;
|
||||
// 6) Disable the link(s)
|
||||
for (int i = 0; i < APCIE_NUM_LINKS; i+= 2)
|
||||
rAPCIE_PORT_CTRL(i) &= ~APCIE_PORT_CTRL_port_en;
|
||||
// 7) Release the PHY(s) from reset
|
||||
for (int i = 0; i < APCIE_NUM_LINKS; i += 2)
|
||||
rAPCIE_PHY_RST_CTRL(i / 2) &= ~APCIE_PHY_RST_CTRL_phy_sw_reset;
|
||||
}
|
||||
|
||||
static void apcie_enable_root_complex(void)
|
||||
{
|
||||
clock_gate(CLK_PCIE, true);
|
||||
#if SUB_PLATFORM_T7000
|
||||
// Fiji uses the clock mesh for refclk, Capri has a dedicated PLL for refclk
|
||||
if (!external_refclk)
|
||||
clock_gate(CLK_PCIE_REF, true);
|
||||
#endif
|
||||
clock_gate(CLK_PCIE_AUX, true);
|
||||
spin(10);
|
||||
|
||||
if (external_refclk)
|
||||
apcie_enable_external_refclk();
|
||||
|
||||
if (s3e_mode) {
|
||||
if (s3e_reset_on_enable) {
|
||||
gpio_configure(GPIO_S3E_RESETN, GPIO_CFG_OUT_0);
|
||||
}
|
||||
|
||||
gpio_configure(GPIO_NAND_SYS_CLK, GPIO_CFG_FUNC0);
|
||||
rAPCIE_NANDSYSCLK_CTRL = 1;
|
||||
|
||||
// S3e spec requires 32 24 Mhz clock cycles from NANDSYSCLK to reset deassertion.
|
||||
// The Maui spec requires 100 microseconds, so we'll follow that to match the behavior
|
||||
// we'll be using in Maui
|
||||
spin(100);
|
||||
|
||||
gpio_configure(GPIO_S3E_RESETN, GPIO_CFG_OUT_1);
|
||||
}
|
||||
}
|
||||
|
||||
static void apcie_disable_root_complex(void)
|
||||
{
|
||||
clock_set_device_reset(CLK_PCIE, true);
|
||||
spin(1);
|
||||
clock_gate(CLK_PCIE, false);
|
||||
|
||||
clock_set_device_reset(CLK_PCIE, false);
|
||||
}
|
||||
|
||||
// Implements the enable sequence from APCIe spec section 6.1 as it applies to
|
||||
// APCIE_COMMON registers. The portion of the sequence that affects the APCIE_CONFIG
|
||||
// registers is handled in common code
|
||||
static void apcie_enable_link_hardware(uint32_t link)
|
||||
{
|
||||
ASSERT(link < APCIE_NUM_LINKS);
|
||||
|
||||
dprintf(DEBUG_INFO, "apcie: Enabling link %d%s\n", link, external_refclk ? " with external refclk" : "");
|
||||
|
||||
// Make sure PERST# starts out as asserted
|
||||
rAPCIE_PORT_RST_CTRL(link) &= ~APCIE_PORT_RST_CTRL_perst_n;
|
||||
|
||||
// 2) 100Mhz REFCLK is enabled
|
||||
if (!external_refclk) {
|
||||
rAPCIE_PORT_REFCLK_CTRL(link) |= APCIE_PORT_REFCLK_CTRL_refclk_en;
|
||||
|
||||
#if !SUB_PLATFORM_T7000
|
||||
while(!clock_get_pcie_refclk_good())
|
||||
spin(10);
|
||||
#endif
|
||||
} else {
|
||||
// On Capri, the PHY asserts an external clkreq enable GPIO
|
||||
// when it wants the external refclk to be enabled. On Fiji the
|
||||
// external refclk is required to always be enabled
|
||||
#if !SUB_PLATFORM_T7000
|
||||
apcie_enable_phy_clkreq(link / 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 3) 10 us wait
|
||||
spin(10);
|
||||
|
||||
// 4) Target PCIE link is enabled
|
||||
rAPCIE_PORT_OVERRIDE_CTRL(link) &= ~APCIE_PORT_OVERRIDE_CTRL_pipe_ovr_en;
|
||||
rAPCIE_PORT_CTRL(link) |= APCIE_PORT_CTRL_port_en;
|
||||
|
||||
#if SUPPORT_FPGA
|
||||
rAPCIE_PORT_CTRL(link) |= APCIE_PORT_CTRL_muxed_auxclk_auto_dis;
|
||||
#endif
|
||||
|
||||
// 5) De-assert PERST# for the target PCIE link.
|
||||
rAPCIE_PORT_RST_CTRL(link) |= APCIE_PORT_RST_CTRL_perst_n;
|
||||
|
||||
// 6b) DBI register overrides
|
||||
// Unlock access to the readonly registers
|
||||
rAPCIE_CONFIG_SPACE32(link, 0x8bc) |= 1;
|
||||
for (unsigned i = 0; i < sizeof(apcie_dbi_overrides) / sizeof(apcie_dbi_overrides[0]); i++) {
|
||||
uint32_t offset = apcie_dbi_overrides[i].offset;
|
||||
uint32_t mask = apcie_dbi_overrides[i].mask;
|
||||
uint32_t value = apcie_dbi_overrides[i].value;
|
||||
rAPCIE_CONFIG_SPACE32(link, offset) = (rAPCIE_CONFIG_SPACE32(link, offset) & ~mask) | value;
|
||||
}
|
||||
// Lock access to the readonly registers
|
||||
rAPCIE_CONFIG_SPACE32(link, 0x8bc) &= ~1;
|
||||
}
|
||||
|
||||
static void apcie_disable_link_hardware(uint32_t link)
|
||||
{
|
||||
ASSERT(link < APCIE_NUM_LINKS);
|
||||
|
||||
rAPCIE_PORT_RST_CTRL(link) &= ~APCIE_PORT_RST_CTRL_perst_n;
|
||||
rAPCIE_PORT_REFCLK_CTRL(link) &= ~APCIE_PORT_REFCLK_CTRL_refclk_en;
|
||||
rAPCIE_PORT_CTRL(link) &= ~APCIE_PORT_CTRL_port_en;
|
||||
rAPCIE_PORT_OVERRIDE_CTRL(link) |= APCIE_PORT_OVERRIDE_CTRL_pipe_ovr_en;
|
||||
#if !SUB_PLATFORM_T7000
|
||||
if (external_refclk) {
|
||||
// If the other link on this PHY is already disabled, go ahead
|
||||
// and disable the external refclk settings and GPIO
|
||||
if ((rAPCIE_PORT_CTRL(link ^ 1) & APCIE_PORT_CTRL_port_en) == 0) {
|
||||
apcie_disable_phy_clkreq(link / 2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool apcie_enable_link(uint32_t link)
|
||||
{
|
||||
struct apcie_link_config *config = &apcie_link_configs[link];
|
||||
struct apcie_link_status *status = &apcie_link_statuses[link];
|
||||
utime_t start;
|
||||
uint32_t force_width;
|
||||
|
||||
ASSERT(link < APCIE_NUM_LINKS);
|
||||
|
||||
if (status->enabled)
|
||||
return true;
|
||||
|
||||
// Clocks to PCIe don't default to on since it isn't used in POR configurations
|
||||
if (link_enable_count == 0) {
|
||||
apcie_enable_root_complex();
|
||||
}
|
||||
|
||||
// Make sure PERST# starts out as asserted
|
||||
gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0);
|
||||
gpio_configure(config->clkreq_gpio, GPIO_CFG_IN);
|
||||
|
||||
// wait for CLKREQ# to be asserted
|
||||
dprintf(DEBUG_INFO, "apcie: waiting for clkreq...");
|
||||
start = system_time();
|
||||
while (gpio_read(config->clkreq_gpio) != 0) {
|
||||
if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) {
|
||||
dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for CLKREQ# on link %u\n", link);
|
||||
goto cleanup;
|
||||
}
|
||||
spin(1);
|
||||
}
|
||||
dprintf(DEBUG_INFO, " done\n");
|
||||
|
||||
gpio_configure(config->clkreq_gpio, GPIO_CFG_FUNC0);
|
||||
|
||||
// Do required initialization in APCIE_COMMON registers
|
||||
apcie_enable_link_hardware(link);
|
||||
|
||||
// Apply tunables
|
||||
rAPCIE_CONFIG_INBCTRL(link) |= APCIE_CONFIG_INBCTRL_CPL_MUST_PUSH_EN;
|
||||
rAPCIE_CONFIG_OUTBCTRL(link) |= APCIE_CONFIG_OUTBCTRL_EARLY_PT_RESP_EN;
|
||||
rAPCIE_CONFIG_PMETOACK_TMOTLIM(link) = 0x28;
|
||||
|
||||
// PCIe spec requires a 100 microsecond delay from REFCLK starting
|
||||
// to PERST being deasserted
|
||||
spin(100);
|
||||
|
||||
// 5) De-assert PERST# for the target PCIE link.
|
||||
gpio_configure(config->perst_gpio, GPIO_CFG_OUT_1);
|
||||
|
||||
// Limit link speed to Gen1
|
||||
rAPCIE_PCIE_CAP_LINK_CONTROL2(link) = (rAPCIE_PCIE_CAP_LINK_CONTROL2(link) & ~0xfU) | 1;
|
||||
|
||||
// Limit link width if requested by the platform. If the platform returns 0,
|
||||
// let the hardware autonegotiate the width using its default parameters
|
||||
force_width = platform_get_pcie_link_width(link);
|
||||
if (force_width != 0) {
|
||||
ASSERT(force_width <= 2);
|
||||
|
||||
uint32_t gen2_ctrl;
|
||||
gen2_ctrl = rAPCIE_PORT_LOGIC_GEN2_CTRL(link);
|
||||
gen2_ctrl &= ~(0x1ff << 8);
|
||||
gen2_ctrl |= (force_width << 8);
|
||||
rAPCIE_PORT_LOGIC_GEN2_CTRL(link) = gen2_ctrl;
|
||||
|
||||
uint32_t port_link_ctrl;
|
||||
port_link_ctrl = rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(link);
|
||||
port_link_ctrl &= ~(0x3f << 16);
|
||||
port_link_ctrl |= ((1 << (force_width - 1)) << 16);
|
||||
rAPCIE_PORT_LOGIC_PORT_LINK_CTRL(link) = port_link_ctrl;
|
||||
}
|
||||
|
||||
rAPCIE_COUNTER_COMMAND(link) = APCIE_COUNTER_CLEAR | APCIE_COUNTER_ENABLE;
|
||||
|
||||
// 6c) Software sets LINKCFG.ltssm_en to start link training
|
||||
rAPCIE_CONFIG_LINKCFG(link) |= APCIE_CONFIG_LINKCFG_LTSSM_EN;
|
||||
|
||||
|
||||
start = system_time();
|
||||
while ((rAPCIE_CONFIG_LINKSTS(link) & APCIE_CONFIG_LINKSTS_LINK_STATUS) == 0) {
|
||||
if (time_has_elapsed(start, APCIE_ENABLE_TIMEOUT)) {
|
||||
uint32_t linkpmgrsts;
|
||||
dprintf(DEBUG_CRITICAL, "apcie: Timeout waiting for LinkUp on link %u\n", link);
|
||||
dprintf(DEBUG_CRITICAL, "apcie: LINKSTS 0x%08x\n", rAPCIE_CONFIG_LINKSTS(link));
|
||||
linkpmgrsts = rAPCIE_CONFIG_LINKPMGRSTS(link);
|
||||
dprintf(DEBUG_CRITICAL, "apcie: LINKPMGRSTS 0x%08x (LTSSM state %d)\n", linkpmgrsts, (linkpmgrsts >> 9) & 0x1F);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
spin(10);
|
||||
}
|
||||
|
||||
status->enabled = true;
|
||||
link_enable_count++;
|
||||
|
||||
dart_init(config->dart_id);
|
||||
|
||||
apcie_setup_root_port_bridge(link, config);
|
||||
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0);
|
||||
spin(10);
|
||||
gpio_configure(config->perst_gpio, GPIO_CFG_DFLT);
|
||||
gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT);
|
||||
|
||||
apcie_disable_link_hardware(link);
|
||||
|
||||
if (link_enable_count == 0) {
|
||||
apcie_disable_root_complex();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void apcie_disable_link(uint32_t link)
|
||||
{
|
||||
struct apcie_link_config *config = &apcie_link_configs[link];
|
||||
struct apcie_link_status *status = &apcie_link_statuses[link];
|
||||
utime_t start;
|
||||
|
||||
ASSERT(link < APCIE_NUM_LINKS);
|
||||
|
||||
if (!status->enabled)
|
||||
return;
|
||||
|
||||
dprintf(DEBUG_INFO, "apcie: Disabling link %d\n", link);
|
||||
|
||||
rAPCIE_COUNTER_COMMAND(link) = 0;
|
||||
|
||||
// Request PMETO and clear the previous status indications
|
||||
rAPCIE_CONFIG_PMETO(link) = 1 | (3 << 4);
|
||||
|
||||
start = system_time();
|
||||
while (rAPCIE_CONFIG_PMETO(link) & 1) {
|
||||
if (time_has_elapsed(start, 10000)) {
|
||||
dprintf(DEBUG_CRITICAL, "apcie: timeout waiting for PME_To_Ack, continuing\n");
|
||||
break;
|
||||
}
|
||||
spin(10);
|
||||
}
|
||||
|
||||
start = system_time();
|
||||
while ((rAPCIE_CONFIG_LINKSTS(link) & APCIE_CONFIG_LINKSTS_L2_STATE) == 0) {
|
||||
if (time_has_elapsed(start, 10000)) {
|
||||
dprintf(DEBUG_CRITICAL, "apcie: link did not go into L2, continuing\n");
|
||||
break;
|
||||
}
|
||||
spin(10);
|
||||
}
|
||||
|
||||
gpio_configure(config->perst_gpio, GPIO_CFG_OUT_0);
|
||||
// delay to allow PERST# signal to settle before letting the pulldown hold it low
|
||||
// and to allow the endpoint to handle PERST# before removing REFCLK
|
||||
spin(25);
|
||||
gpio_configure(config->perst_gpio, GPIO_CFG_DFLT);
|
||||
gpio_configure(config->clkreq_gpio, GPIO_CFG_DFLT);
|
||||
|
||||
#if DEBUG_BUILD
|
||||
dart_assert_unmapped(config->dart_id);
|
||||
#endif
|
||||
|
||||
apcie_disable_link_hardware(link);
|
||||
|
||||
status->enabled = false;
|
||||
link_enable_count--;
|
||||
|
||||
if (link_enable_count == 0) {
|
||||
apcie_disable_root_complex();
|
||||
}
|
||||
|
||||
apcie_free_port_bridge(link);
|
||||
}
|
||||
|
||||
uint32_t apcie_get_link_enable_count(void)
|
||||
{
|
||||
return link_enable_count;
|
||||
}
|
||||
|
||||
#if WITH_DEVICETREE
|
||||
void apcie_update_devicetree(DTNode *apcie_node)
|
||||
{
|
||||
uint32_t propSize;
|
||||
char *propName;
|
||||
void *propData;
|
||||
|
||||
propName = "dbi-overrides";
|
||||
if (FindProperty(apcie_node, &propName, &propData, &propSize)) {
|
||||
if (propSize < sizeof(apcie_dbi_overrides))
|
||||
panic("dbi-overrides property is too small");
|
||||
memcpy(propData, apcie_dbi_overrides, sizeof(apcie_dbi_overrides));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct apcie_link_config platform_apcie_link_configs[APCIE_NUM_LINKS] = {
|
||||
[0] = {
|
||||
.perst_gpio = GPIO_PCIE0_PERST,
|
||||
.clkreq_gpio = GPIO_PCIE0_CLKREQ,
|
||||
.dart_id = PCIE_PORT0_DART_ID,
|
||||
},
|
||||
[1] = {
|
||||
.perst_gpio = GPIO_PCIE1_PERST,
|
||||
.clkreq_gpio = GPIO_PCIE1_CLKREQ,
|
||||
.dart_id = PCIE_PORT1_DART_ID,
|
||||
},
|
||||
#if SUB_PLATFORM_T7001
|
||||
[2] = {
|
||||
.perst_gpio = GPIO_PCIE2_PERST,
|
||||
.clkreq_gpio = GPIO_PCIE2_CLKREQ,
|
||||
.dart_id = PCIE_PORT2_DART_ID,
|
||||
},
|
||||
[3] = {
|
||||
.perst_gpio = GPIO_PCIE3_PERST,
|
||||
.clkreq_gpio = GPIO_PCIE3_CLKREQ,
|
||||
.dart_id = PCIE_PORT3_DART_ID,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
void platform_register_pci_busses(void)
|
||||
{
|
||||
apcie_init();
|
||||
}
|
||||
|
||||
uint64_t platform_map_host_to_pci_addr(uintptr_t addr)
|
||||
{
|
||||
// Right now we're only supporting 32-bit PCI addresses
|
||||
// for aPCIe, so just lop off the top 32 bits
|
||||
return addr & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uintptr_t platform_map_pci_to_host_addr(uint64_t addr)
|
||||
{
|
||||
// Right now we're only supporting 32-bit PCI addresses
|
||||
// for aPCIe
|
||||
ASSERT((addr & ~0xFFFFFFFFULL) == 0);
|
||||
return PCI_32BIT_BASE + (addr & (PCI_32BIT_LEN - 1));
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2014 Apple Inc. All rights reserved.
|
||||
#
|
||||
# This document is the property of Apple Computer, Inc.
|
||||
# It is considered confidential and proprietary.
|
||||
#
|
||||
# This document may not be reproduced or transmitted in any form,
|
||||
# in whole or in part, without the express written permission of
|
||||
# Apple Computer, Inc.
|
||||
#
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
ALL_OBJS += \
|
||||
$(LOCAL_DIR)/apcie_v1.o \
|
||||
Reference in new issue
Block a user