/** @file
This file contains internal PSF routines for PCH PSF lib usage
Copyright (c) 2019 Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "PchPsfPrivateLibInternal.h"
GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoI2cPsfRegs[] =
{
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C3_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C4_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_I2C5_REG_BASE
};
GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoI2cPsfRegs[] =
{
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C0_REG_BASE,
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C1_REG_BASE,
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C2_REG_BASE,
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_I2C3_REG_BASE
};
/**
Return PSF_PORT for SerialIO I2C device
@param[in] I2cNum Serial IO I2C device (I2C0, I2C1, ....)
@retval PsfPort PSF PORT structure for SerialIO I2C device
**/
PSF_PORT
PsfSerialIoI2cPort (
IN UINT32 I2cNum
)
{
PSF_PORT PsfPort;
PsfPort.PsfPid = PID_PSF3;
if (IsPchLp ()) {
if (I2cNum < ARRAY_SIZE(mPchLpSerialIoI2cPsfRegs)) {
PsfPort.RegBase = mPchLpSerialIoI2cPsfRegs[I2cNum];
return PsfPort;
}
} else {
if (I2cNum < ARRAY_SIZE(mPchHSerialIoI2cPsfRegs)) {
PsfPort.RegBase = mPchHSerialIoI2cPsfRegs[I2cNum];
return PsfPort;
}
}
ASSERT(FALSE);
return PSF_PORT_NULL;
}
GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoSpiPsfRegs[] =
{
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
};
GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoSpiPsfRegs[] =
{
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI0_REG_BASE,
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI1_REG_BASE,
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_SPI2_REG_BASE
};
/**
Return PSF_PORT for SerialIO SPI device
@param[in] SpiNum Serial IO SPI device (SPI0, SPI1, ....)
@retval PsfPort PSF PORT structure for SerialIO SPI device
**/
PSF_PORT
PsfSerialIoSpiPort (
IN UINT32 SpiNum
)
{
PSF_PORT PsfPort;
PsfPort.PsfPid = PID_PSF3;
if (IsPchLp ()) {
if (SpiNum < ARRAY_SIZE(mPchLpSerialIoSpiPsfRegs)) {
PsfPort.RegBase = mPchLpSerialIoSpiPsfRegs[SpiNum];
return PsfPort;
}
} else {
if (SpiNum < ARRAY_SIZE(mPchHSerialIoSpiPsfRegs)) {
PsfPort.RegBase = mPchHSerialIoSpiPsfRegs[SpiNum];
return PsfPort;
}
}
ASSERT(FALSE);
return PSF_PORT_NULL;
}
GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchLpSerialIoUartPsfRegs[] =
{
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_UART2_REG_BASE
};
GLOBAL_REMOVE_IF_UNREFERENCED UINT16 mPchHSerialIoUartPsfRegs[] =
{
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART0_REG_BASE,
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART1_REG_BASE,
R_CNL_PCH_H_PSF3_PCR_T0_SHDW_UART2_REG_BASE
};
/**
Return PSF_PORT for SerialIO UART device
@param[in] UartNum Serial IO UART device (UART0, UART1, ....)
@retval PsfPort PSF PORT structure for SerialIO UART device
**/
PSF_PORT
PsfSerialIoUartPort (
IN UINT32 UartNum
)
{
PSF_PORT PsfPort;
PsfPort.PsfPid = PID_PSF3;
if (IsPchLp ()) {
if (UartNum < ARRAY_SIZE(mPchLpSerialIoUartPsfRegs)) {
PsfPort.RegBase = mPchLpSerialIoUartPsfRegs[UartNum];
return PsfPort;
}
} else {
if (UartNum < ARRAY_SIZE(mPchHSerialIoUartPsfRegs)) {
PsfPort.RegBase = mPchHSerialIoUartPsfRegs[UartNum];
return PsfPort;
}
}
ASSERT(FALSE);
return PSF_PORT_NULL;
}
/**
Get EOI register data for given PSF ID
@param[in] PsfId PSF ID (1 - PSF1, 2 - PSF2, ...)
@param[out] EoiTargetBase EOI Target register
@param[out] EoiControlBase EOI Control register
@retval MaxTargets Number of supported targets
**/
UINT8
PsfEoiRegData (
UINT32 PsfId,
UINT16 *EoiTargetBase,
UINT16 *EoiControlBase
)
{
UINT8 MaxTargets;
MaxTargets = 0;
*EoiTargetBase = 0;
*EoiControlBase = 0;
switch (PsfId) {
case 1:
if (IsPchLp ()) {
*EoiTargetBase = R_CNL_PCH_LP_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
*EoiControlBase = R_CNL_PCH_LP_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
MaxTargets = 17;
} else {
*EoiTargetBase = R_CNL_PCH_H_PSF1_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
*EoiControlBase = R_CNL_PCH_H_PSF1_PCR_PSF_MC_CONTROL_MCAST0_EOI;
MaxTargets = 7;
}
break;
case 3:
*EoiTargetBase = R_CNL_PCH_PSF3_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
*EoiControlBase = R_CNL_PCH_PSF3_PCR_PSF_MC_CONTROL_MCAST0_EOI;
MaxTargets = 1;
break;
case 6:
if (IsPchH ()) {
*EoiTargetBase = R_CNL_PCH_H_PSF6_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
*EoiControlBase = R_CNL_PCH_H_PSF6_PCR_PSF_MC_CONTROL_MCAST0_EOI;
MaxTargets = 8;
}
break;
case 7:
if (IsPchH ()) {
*EoiTargetBase = R_CNL_PCH_H_PSF7_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
*EoiControlBase = R_CNL_PCH_H_PSF7_PCR_PSF_MC_CONTROL_MCAST0_EOI;
MaxTargets = 8;
}
break;
case 8:
if (IsPchH ()) {
*EoiTargetBase = R_CNL_PCH_H_PSF8_PCR_PSF_MC_AGENT_MCAST0_TGT0_EOI;
*EoiControlBase = R_CNL_PCH_H_PSF8_PCR_PSF_MC_CONTROL_MCAST0_EOI;
MaxTargets = 8;
}
break;
}
return MaxTargets;
}
GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchLpRpDestId[] =
{
{0x18000}, {0x18001}, {0x18002}, {0x18003}, // SPA: PSF1, PortID = 0
{0x18200}, {0x18201}, {0x18202}, {0x18203}, // SPB: PSF1, PortID = 2
{0x18400}, {0x18401}, {0x18402}, {0x18403}, // SPC: PSF1, PortID = 4
{0x18600}, {0x18601}, {0x18602}, {0x18603} // SPD: PSF1, PortID = 6
};
GLOBAL_REMOVE_IF_UNREFERENCED PSF_PORT_DEST_ID PchHRpDestId[] =
{
{0x68000}, {0x68001}, {0x68002}, {0x68003}, // SPA: PSF6, PortID = 0
{0x88000}, {0x88001}, {0x88002}, {0x88003}, // SPB: PSF8, PortID = 0
{0x68100}, {0x68101}, {0x68102}, {0x68103}, // SPC: PSF6, PortID = 1
{0x78000}, {0x78001}, {0x78002}, {0x78003}, // SPD: PSF7, PortID = 0
{0x78100}, {0x78101}, {0x78102}, {0x78103}, // SPE: PSF7, PortID = 1
{0x88100}, {0x88101}, {0x88102}, {0x88103} // SPF: PSF8, PortID = 1
};
/**
PCIe PSF port destination ID (psf_id:port_group_id:port_id:channel_id)
@param[in] RpIndex PCIe Root Port Index (0 based)
@retval Destination ID
**/
PSF_PORT_DEST_ID
PsfPcieDestinationId (
IN UINT32 RpIndex
)
{
if (IsPchLp ()) {
if (RpIndex < ARRAY_SIZE(PchLpRpDestId)) {
return PchLpRpDestId[RpIndex];
}
} else {
if (RpIndex < ARRAY_SIZE(PchHRpDestId)) {
return PchHRpDestId[RpIndex];
}
}
ASSERT (FALSE);
return (PSF_PORT_DEST_ID){0};
}
/**
Return PSF_PORT for PMC device
@retval PsfPort PSF PORT structure for PMC device
**/
PSF_PORT
PsfPmcPort (
VOID
)
{
PSF_PORT PsfPort;
PsfPort.PsfPid = PID_PSF3;
if (IsPchLp ()) {
PsfPort.RegBase = R_CNL_PCH_LP_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
} else {
PsfPort.RegBase = R_CNL_PCH_H_PSF3_PCR_T0_SHDW_PMC_REG_BASE;
}
return PsfPort;
}
GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchLpPsfTable[] =
{
{1, PID_PSF1},
{2, PID_PSF2},
{3, PID_PSF3},
{4, PID_PSF4},
{5, PID_CSME_PSF}
};
GLOBAL_REMOVE_IF_UNREFERENCED PSF_SEGMENT mPchHPsfTable[] =
{
{1, PID_PSF1},
{2, PID_PSF2},
{3, PID_PSF3},
{4, PID_PSF4},
{5, PID_CSME_PSF},
{6, PID_PSF6},
{7, PID_PSF7},
{8, PID_PSF8}
};
/**
Get list of supported PSF segments.
@param[out] PsfTable Array of supported PSF segments
@param[out] PsfTableLength Length of PsfTable
**/
VOID
PsfSegments (
OUT PSF_SEGMENT **PsfTable,
OUT UINT32 *PsfTableLength
)
{
if (IsPchLp ()) {
*PsfTable = mPchLpPsfTable;
*PsfTableLength = ARRAY_SIZE(mPchLpPsfTable);
} else {
*PsfTable = mPchHPsfTable;
*PsfTableLength = ARRAY_SIZE(mPchHPsfTable);
}
}