diff mbox

[Linaro-uefi,01/27] Hisilicon/Hi1610/PCIe: Add performace tuning

Message ID 1478785889-24143-2-git-send-email-heyi.guo@linaro.org
State Superseded
Headers show

Commit Message

gary guo Nov. 10, 2016, 1:51 p.m. UTC
Modify PCIe transaction memory attribute to improve performance, like
SMMU bypass, cache snoopy, etc.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: hensonwang <wanghuiqiang@huawei.com>
Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
---
 .../Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf    |  3 ++
 .../Hi1610/Drivers/PcieInit1610/PcieInitLib.c      | 52 ++++++++++++++++++++++
 Chips/Hisilicon/HisiPkg.dec                        |  1 +
 Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h |  1 +
 Platforms/Hisilicon/D03/D03.dsc                    |  1 +
 5 files changed, 58 insertions(+)
 mode change 100755 => 100644 Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c

Comments

Leif Lindholm Nov. 10, 2016, 3:24 p.m. UTC | #1
On Thu, Nov 10, 2016 at 09:51:03PM +0800, Heyi Guo wrote:
> Modify PCIe transaction memory attribute to improve performance, like
> SMMU bypass, cache snoopy, etc.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: hensonwang <wanghuiqiang@huawei.com>
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
> ---
>  .../Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf    |  3 ++
>  .../Hi1610/Drivers/PcieInit1610/PcieInitLib.c      | 52 ++++++++++++++++++++++
>  Chips/Hisilicon/HisiPkg.dec                        |  1 +
>  Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h |  1 +
>  Platforms/Hisilicon/D03/D03.dsc                    |  1 +
>  5 files changed, 58 insertions(+)
>  mode change 100755 => 100644 Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> 
> diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> index 63d8bb1..8659e29 100644
> --- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> +++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> @@ -53,6 +53,9 @@
>    gHisiTokenSpaceGuid.Pcdsoctype
>    gHisiTokenSpaceGuid.PcdPcieMsiTargetAddress
>  
> +[FeaturePcd]
> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable
> +
>  [depex]
>    TRUE
>  
> diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> old mode 100755
> new mode 100644
> index 06ecf87..39b9ea7
> --- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> +++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> @@ -21,6 +21,8 @@
>  #include <Library/IoLib.h>
>  #include <Library/TimerLib.h>
>  
> +#define PCIE_SYS_REG_OFFSET 0x1000
> +
>  static PCIE_INIT_CFG mPcieIntCfg;
>  UINT64 pcie_subctrl_base[2] = {0xb0000000, BASE_4TB + 0xb0000000};
>  UINT64 pcie_subctrl_base_1610[2] = {0xa0000000, 0xb0000000};
> @@ -185,6 +187,50 @@ EFI_STATUS PcieEnableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
>  
>  }
>  
> +STATIC EFI_STATUS PciPerfTuning(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
> +{
> +    UINT32 Value;
> +    UINTN  RegSegmentOffset;
> +
> +    if (Port >= PCIE_MAX_ROOTBRIDGE) {
> +      DEBUG((DEBUG_ERROR, "Invalid port number: %d\n", Port));
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    RegSegmentOffset = PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_SYS_REG_OFFSET;
> +
> +    //Enable SMMU bypass for translation
> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
> +    //BIT13: controller master read SMMU bypass
> +    //BIT12: controller master write SMMU bypass
> +    //BIT10: SMMU bypass enable
> +    Value |= (BIT13 | BIT12 | BIT10);
> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
> +
> +    //Switch strongly order (SO) to relaxed order (RO) for write transaction
> +    RegRead(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
> +    //BIT13 | BIT12: Enable write merge and SMMU streaming ordered write acknowledge
> +    Value |= (BIT13 | BIT12);
> +    //BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17: Enable RO for all types of write transaction
> +    Value |= (BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17);
> +    RegWrite(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
> +
> +    //Force streamID for controller read operation
> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
> +    //Force using streamID in PCIE_SYS_CTRL54_REG
> +    Value &= ~(BIT30);
> +    //Set streamID to 0, bit[0:15] is for request ID and should be kept
> +    Value &= ~(0xff << 16);
> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
> +
> +    //Enable read and write snoopy
> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
> +    Value |= (BIT30 | BIT28);
> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
> +
> +    return EFI_SUCCESS;
> +}
> +
>  EFI_STATUS PcieDisableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
>  {
>      PCIE_CTRL_7_U pcie_ctrl7;
> @@ -939,6 +985,12 @@ PciePortInit (
>  
>       /* assert LTSSM enable */
>       (VOID)PcieEnableItssm(soctype, HostBridgeNum, PortIndex);
> +     if (FeaturePcdGet(PcdIsPciPerfTuningEnable)) {
> +       //PCIe will still work even if performance tuning fails,
> +       //and there is warning message inside the function to print
> +       //detailed error if there is.
> +       (VOID)PciPerfTuning(soctype, HostBridgeNum, PortIndex);
> +     }
>  
>       PcieConfigContextHi1610(soctype, HostBridgeNum, PortIndex);
>       /*
> diff --git a/Chips/Hisilicon/HisiPkg.dec b/Chips/Hisilicon/HisiPkg.dec
> index 8e46e0d..2ce60d9 100644
> --- a/Chips/Hisilicon/HisiPkg.dec
> +++ b/Chips/Hisilicon/HisiPkg.dec
> @@ -161,6 +161,7 @@
>    gHisiTokenSpaceGuid.PcdSerDesFlowCtrlFlag|0|UINT32|0x40000056
>  
>  [PcdsFeatureFlag]
> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|FALSE|BOOLEAN|0x00000066
>  
>  
>  
> diff --git a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
> index bdd80f8..539d567 100644
> --- a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
> +++ b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
> @@ -8981,6 +8981,7 @@ typedef union tagIepMsiCtrlIntStatus
>  #define PCIE_SYS_CTRL24_REG  (PCI_SYS_BASE + 0x1b4)
>  #define PCIE_SYS_CTRL28_REG  (PCI_SYS_BASE + 0x1c4)
>  #define PCIE_SYS_CTRL29_REG  (PCI_SYS_BASE + 0x1c8)
> +#define PCIE_SYS_CTRL54_REG  (PCI_SYS_BASE + 0x274)
>  #define PCIE_SYS_STATE5_REG  (PCI_SYS_BASE + 0x30)
>  #define PCIE_SYS_STATE6_REG  (PCI_SYS_BASE + 0x34)
>  #define PCIE_SYS_STATE7_REG  (PCI_SYS_BASE + 0x38)
> diff --git a/Platforms/Hisilicon/D03/D03.dsc b/Platforms/Hisilicon/D03/D03.dsc
> index 6d82627..942b2b8 100644
> --- a/Platforms/Hisilicon/D03/D03.dsc
> +++ b/Platforms/Hisilicon/D03/D03.dsc
> @@ -111,6 +111,7 @@
>    ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
>    #  It could be set FALSE to save size.
>    gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|TRUE

For everything changed by this patch:
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

But

>  
>  [PcdsFixedAtBuild.common]
>    gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"

Could you send me a patch to fix this thing I just spotted in the
context? :)

> -- 
> 1.9.1
>
Leif Lindholm Nov. 14, 2016, 1:27 p.m. UTC | #2
On Thu, Nov 10, 2016 at 09:51:03PM +0800, Heyi Guo wrote:
> Modify PCIe transaction memory attribute to improve performance, like
> SMMU bypass, cache snoopy, etc.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: hensonwang <wanghuiqiang@huawei.com>
> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>

(I did give a reviewed-by on this for v2, only asking for you to
change another thing as well.)

Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>

> ---
>  .../Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf    |  3 ++
>  .../Hi1610/Drivers/PcieInit1610/PcieInitLib.c      | 52 ++++++++++++++++++++++
>  Chips/Hisilicon/HisiPkg.dec                        |  1 +
>  Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h |  1 +
>  Platforms/Hisilicon/D03/D03.dsc                    |  1 +
>  5 files changed, 58 insertions(+)
>  mode change 100755 => 100644 Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> 
> diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> index 63d8bb1..8659e29 100644
> --- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> +++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
> @@ -53,6 +53,9 @@
>    gHisiTokenSpaceGuid.Pcdsoctype
>    gHisiTokenSpaceGuid.PcdPcieMsiTargetAddress
>  
> +[FeaturePcd]
> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable
> +
>  [depex]
>    TRUE
>  
> diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> old mode 100755
> new mode 100644
> index 06ecf87..39b9ea7
> --- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> +++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
> @@ -21,6 +21,8 @@
>  #include <Library/IoLib.h>
>  #include <Library/TimerLib.h>
>  
> +#define PCIE_SYS_REG_OFFSET 0x1000
> +
>  static PCIE_INIT_CFG mPcieIntCfg;
>  UINT64 pcie_subctrl_base[2] = {0xb0000000, BASE_4TB + 0xb0000000};
>  UINT64 pcie_subctrl_base_1610[2] = {0xa0000000, 0xb0000000};
> @@ -185,6 +187,50 @@ EFI_STATUS PcieEnableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
>  
>  }
>  
> +STATIC EFI_STATUS PciPerfTuning(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
> +{
> +    UINT32 Value;
> +    UINTN  RegSegmentOffset;
> +
> +    if (Port >= PCIE_MAX_ROOTBRIDGE) {
> +      DEBUG((DEBUG_ERROR, "Invalid port number: %d\n", Port));
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    RegSegmentOffset = PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_SYS_REG_OFFSET;
> +
> +    //Enable SMMU bypass for translation
> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
> +    //BIT13: controller master read SMMU bypass
> +    //BIT12: controller master write SMMU bypass
> +    //BIT10: SMMU bypass enable
> +    Value |= (BIT13 | BIT12 | BIT10);
> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
> +
> +    //Switch strongly order (SO) to relaxed order (RO) for write transaction
> +    RegRead(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
> +    //BIT13 | BIT12: Enable write merge and SMMU streaming ordered write acknowledge
> +    Value |= (BIT13 | BIT12);
> +    //BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17: Enable RO for all types of write transaction
> +    Value |= (BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17);
> +    RegWrite(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
> +
> +    //Force streamID for controller read operation
> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
> +    //Force using streamID in PCIE_SYS_CTRL54_REG
> +    Value &= ~(BIT30);
> +    //Set streamID to 0, bit[0:15] is for request ID and should be kept
> +    Value &= ~(0xff << 16);
> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
> +
> +    //Enable read and write snoopy
> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
> +    Value |= (BIT30 | BIT28);
> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
> +
> +    return EFI_SUCCESS;
> +}
> +
>  EFI_STATUS PcieDisableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
>  {
>      PCIE_CTRL_7_U pcie_ctrl7;
> @@ -939,6 +985,12 @@ PciePortInit (
>  
>       /* assert LTSSM enable */
>       (VOID)PcieEnableItssm(soctype, HostBridgeNum, PortIndex);
> +     if (FeaturePcdGet(PcdIsPciPerfTuningEnable)) {
> +       //PCIe will still work even if performance tuning fails,
> +       //and there is warning message inside the function to print
> +       //detailed error if there is.
> +       (VOID)PciPerfTuning(soctype, HostBridgeNum, PortIndex);
> +     }
>  
>       PcieConfigContextHi1610(soctype, HostBridgeNum, PortIndex);
>       /*
> diff --git a/Chips/Hisilicon/HisiPkg.dec b/Chips/Hisilicon/HisiPkg.dec
> index 8e46e0d..2ce60d9 100644
> --- a/Chips/Hisilicon/HisiPkg.dec
> +++ b/Chips/Hisilicon/HisiPkg.dec
> @@ -161,6 +161,7 @@
>    gHisiTokenSpaceGuid.PcdSerDesFlowCtrlFlag|0|UINT32|0x40000056
>  
>  [PcdsFeatureFlag]
> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|FALSE|BOOLEAN|0x00000066
>  
>  
>  
> diff --git a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
> index bdd80f8..539d567 100644
> --- a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
> +++ b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
> @@ -8981,6 +8981,7 @@ typedef union tagIepMsiCtrlIntStatus
>  #define PCIE_SYS_CTRL24_REG  (PCI_SYS_BASE + 0x1b4)
>  #define PCIE_SYS_CTRL28_REG  (PCI_SYS_BASE + 0x1c4)
>  #define PCIE_SYS_CTRL29_REG  (PCI_SYS_BASE + 0x1c8)
> +#define PCIE_SYS_CTRL54_REG  (PCI_SYS_BASE + 0x274)
>  #define PCIE_SYS_STATE5_REG  (PCI_SYS_BASE + 0x30)
>  #define PCIE_SYS_STATE6_REG  (PCI_SYS_BASE + 0x34)
>  #define PCIE_SYS_STATE7_REG  (PCI_SYS_BASE + 0x38)
> diff --git a/Platforms/Hisilicon/D03/D03.dsc b/Platforms/Hisilicon/D03/D03.dsc
> index 6d82627..942b2b8 100644
> --- a/Platforms/Hisilicon/D03/D03.dsc
> +++ b/Platforms/Hisilicon/D03/D03.dsc
> @@ -111,6 +111,7 @@
>    ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
>    #  It could be set FALSE to save size.
>    gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|TRUE
>  
>  [PcdsFixedAtBuild.common]
>    gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"
> -- 
> 1.9.1
>
Leif Lindholm Nov. 14, 2016, 1:31 p.m. UTC | #3
On 14 November 2016 at 13:27, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Thu, Nov 10, 2016 at 09:51:03PM +0800, Heyi Guo wrote:
>> Modify PCIe transaction memory attribute to improve performance, like
>> SMMU bypass, cache snoopy, etc.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: hensonwang <wanghuiqiang@huawei.com>
>> Signed-off-by: Heyi Guo <heyi.guo@linaro.org>
>
> (I did give a reviewed-by on this for v2, only asking for you to
> change another thing as well.)

Err, ignore this, my email client had left this flagged as unread,
whereas I was actually most of the way through reviewing this set... I
thought you had sent an updated version already :)

> Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
>
>> ---
>>  .../Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf    |  3 ++
>>  .../Hi1610/Drivers/PcieInit1610/PcieInitLib.c      | 52 ++++++++++++++++++++++
>>  Chips/Hisilicon/HisiPkg.dec                        |  1 +
>>  Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h |  1 +
>>  Platforms/Hisilicon/D03/D03.dsc                    |  1 +
>>  5 files changed, 58 insertions(+)
>>  mode change 100755 => 100644 Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
>>
>> diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
>> index 63d8bb1..8659e29 100644
>> --- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
>> +++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
>> @@ -53,6 +53,9 @@
>>    gHisiTokenSpaceGuid.Pcdsoctype
>>    gHisiTokenSpaceGuid.PcdPcieMsiTargetAddress
>>
>> +[FeaturePcd]
>> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable
>> +
>>  [depex]
>>    TRUE
>>
>> diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
>> old mode 100755
>> new mode 100644
>> index 06ecf87..39b9ea7
>> --- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
>> +++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
>> @@ -21,6 +21,8 @@
>>  #include <Library/IoLib.h>
>>  #include <Library/TimerLib.h>
>>
>> +#define PCIE_SYS_REG_OFFSET 0x1000
>> +
>>  static PCIE_INIT_CFG mPcieIntCfg;
>>  UINT64 pcie_subctrl_base[2] = {0xb0000000, BASE_4TB + 0xb0000000};
>>  UINT64 pcie_subctrl_base_1610[2] = {0xa0000000, 0xb0000000};
>> @@ -185,6 +187,50 @@ EFI_STATUS PcieEnableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
>>
>>  }
>>
>> +STATIC EFI_STATUS PciPerfTuning(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
>> +{
>> +    UINT32 Value;
>> +    UINTN  RegSegmentOffset;
>> +
>> +    if (Port >= PCIE_MAX_ROOTBRIDGE) {
>> +      DEBUG((DEBUG_ERROR, "Invalid port number: %d\n", Port));
>> +      return EFI_INVALID_PARAMETER;
>> +    }
>> +
>> +    RegSegmentOffset = PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_SYS_REG_OFFSET;
>> +
>> +    //Enable SMMU bypass for translation
>> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
>> +    //BIT13: controller master read SMMU bypass
>> +    //BIT12: controller master write SMMU bypass
>> +    //BIT10: SMMU bypass enable
>> +    Value |= (BIT13 | BIT12 | BIT10);
>> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
>> +
>> +    //Switch strongly order (SO) to relaxed order (RO) for write transaction
>> +    RegRead(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
>> +    //BIT13 | BIT12: Enable write merge and SMMU streaming ordered write acknowledge
>> +    Value |= (BIT13 | BIT12);
>> +    //BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17: Enable RO for all types of write transaction
>> +    Value |= (BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17);
>> +    RegWrite(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
>> +
>> +    //Force streamID for controller read operation
>> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
>> +    //Force using streamID in PCIE_SYS_CTRL54_REG
>> +    Value &= ~(BIT30);
>> +    //Set streamID to 0, bit[0:15] is for request ID and should be kept
>> +    Value &= ~(0xff << 16);
>> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
>> +
>> +    //Enable read and write snoopy
>> +    RegRead(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
>> +    Value |= (BIT30 | BIT28);
>> +    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
>> +
>> +    return EFI_SUCCESS;
>> +}
>> +
>>  EFI_STATUS PcieDisableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
>>  {
>>      PCIE_CTRL_7_U pcie_ctrl7;
>> @@ -939,6 +985,12 @@ PciePortInit (
>>
>>       /* assert LTSSM enable */
>>       (VOID)PcieEnableItssm(soctype, HostBridgeNum, PortIndex);
>> +     if (FeaturePcdGet(PcdIsPciPerfTuningEnable)) {
>> +       //PCIe will still work even if performance tuning fails,
>> +       //and there is warning message inside the function to print
>> +       //detailed error if there is.
>> +       (VOID)PciPerfTuning(soctype, HostBridgeNum, PortIndex);
>> +     }
>>
>>       PcieConfigContextHi1610(soctype, HostBridgeNum, PortIndex);
>>       /*
>> diff --git a/Chips/Hisilicon/HisiPkg.dec b/Chips/Hisilicon/HisiPkg.dec
>> index 8e46e0d..2ce60d9 100644
>> --- a/Chips/Hisilicon/HisiPkg.dec
>> +++ b/Chips/Hisilicon/HisiPkg.dec
>> @@ -161,6 +161,7 @@
>>    gHisiTokenSpaceGuid.PcdSerDesFlowCtrlFlag|0|UINT32|0x40000056
>>
>>  [PcdsFeatureFlag]
>> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|FALSE|BOOLEAN|0x00000066
>>
>>
>>
>> diff --git a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
>> index bdd80f8..539d567 100644
>> --- a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
>> +++ b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
>> @@ -8981,6 +8981,7 @@ typedef union tagIepMsiCtrlIntStatus
>>  #define PCIE_SYS_CTRL24_REG  (PCI_SYS_BASE + 0x1b4)
>>  #define PCIE_SYS_CTRL28_REG  (PCI_SYS_BASE + 0x1c4)
>>  #define PCIE_SYS_CTRL29_REG  (PCI_SYS_BASE + 0x1c8)
>> +#define PCIE_SYS_CTRL54_REG  (PCI_SYS_BASE + 0x274)
>>  #define PCIE_SYS_STATE5_REG  (PCI_SYS_BASE + 0x30)
>>  #define PCIE_SYS_STATE6_REG  (PCI_SYS_BASE + 0x34)
>>  #define PCIE_SYS_STATE7_REG  (PCI_SYS_BASE + 0x38)
>> diff --git a/Platforms/Hisilicon/D03/D03.dsc b/Platforms/Hisilicon/D03/D03.dsc
>> index 6d82627..942b2b8 100644
>> --- a/Platforms/Hisilicon/D03/D03.dsc
>> +++ b/Platforms/Hisilicon/D03/D03.dsc
>> @@ -111,6 +111,7 @@
>>    ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
>>    #  It could be set FALSE to save size.
>>    gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
>> +  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|TRUE
>>
>>  [PcdsFixedAtBuild.common]
>>    gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"
>> --
>> 1.9.1
>>
diff mbox

Patch

diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
index 63d8bb1..8659e29 100644
--- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
+++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitDxe.inf
@@ -53,6 +53,9 @@ 
   gHisiTokenSpaceGuid.Pcdsoctype
   gHisiTokenSpaceGuid.PcdPcieMsiTargetAddress
 
+[FeaturePcd]
+  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable
+
 [depex]
   TRUE
 
diff --git a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
old mode 100755
new mode 100644
index 06ecf87..39b9ea7
--- a/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
+++ b/Chips/Hisilicon/Hi1610/Drivers/PcieInit1610/PcieInitLib.c
@@ -21,6 +21,8 @@ 
 #include <Library/IoLib.h>
 #include <Library/TimerLib.h>
 
+#define PCIE_SYS_REG_OFFSET 0x1000
+
 static PCIE_INIT_CFG mPcieIntCfg;
 UINT64 pcie_subctrl_base[2] = {0xb0000000, BASE_4TB + 0xb0000000};
 UINT64 pcie_subctrl_base_1610[2] = {0xa0000000, 0xb0000000};
@@ -185,6 +187,50 @@  EFI_STATUS PcieEnableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
 
 }
 
+STATIC EFI_STATUS PciPerfTuning(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
+{
+    UINT32 Value;
+    UINTN  RegSegmentOffset;
+
+    if (Port >= PCIE_MAX_ROOTBRIDGE) {
+      DEBUG((DEBUG_ERROR, "Invalid port number: %d\n", Port));
+      return EFI_INVALID_PARAMETER;
+    }
+
+    RegSegmentOffset = PCIE_APB_SLAVE_BASE_1610[HostBridgeNum][Port] + PCIE_SYS_REG_OFFSET;
+
+    //Enable SMMU bypass for translation
+    RegRead(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
+    //BIT13: controller master read SMMU bypass
+    //BIT12: controller master write SMMU bypass
+    //BIT10: SMMU bypass enable
+    Value |= (BIT13 | BIT12 | BIT10);
+    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL13_REG, Value);
+
+    //Switch strongly order (SO) to relaxed order (RO) for write transaction
+    RegRead(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
+    //BIT13 | BIT12: Enable write merge and SMMU streaming ordered write acknowledge
+    Value |= (BIT13 | BIT12);
+    //BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17: Enable RO for all types of write transaction
+    Value |= (BIT29 | BIT27 | BIT25 | BIT23 | BIT21 | BIT19 | BIT17);
+    RegWrite(RegSegmentOffset + PCIE_CTRL_6_REG, Value);
+
+    //Force streamID for controller read operation
+    RegRead(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
+    //Force using streamID in PCIE_SYS_CTRL54_REG
+    Value &= ~(BIT30);
+    //Set streamID to 0, bit[0:15] is for request ID and should be kept
+    Value &= ~(0xff << 16);
+    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL54_REG, Value);
+
+    //Enable read and write snoopy
+    RegRead(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
+    Value |= (BIT30 | BIT28);
+    RegWrite(RegSegmentOffset + PCIE_SYS_CTRL19_REG, Value);
+
+    return EFI_SUCCESS;
+}
+
 EFI_STATUS PcieDisableItssm(UINT32 soctype, UINT32 HostBridgeNum, UINT32 Port)
 {
     PCIE_CTRL_7_U pcie_ctrl7;
@@ -939,6 +985,12 @@  PciePortInit (
 
      /* assert LTSSM enable */
      (VOID)PcieEnableItssm(soctype, HostBridgeNum, PortIndex);
+     if (FeaturePcdGet(PcdIsPciPerfTuningEnable)) {
+       //PCIe will still work even if performance tuning fails,
+       //and there is warning message inside the function to print
+       //detailed error if there is.
+       (VOID)PciPerfTuning(soctype, HostBridgeNum, PortIndex);
+     }
 
      PcieConfigContextHi1610(soctype, HostBridgeNum, PortIndex);
      /*
diff --git a/Chips/Hisilicon/HisiPkg.dec b/Chips/Hisilicon/HisiPkg.dec
index 8e46e0d..2ce60d9 100644
--- a/Chips/Hisilicon/HisiPkg.dec
+++ b/Chips/Hisilicon/HisiPkg.dec
@@ -161,6 +161,7 @@ 
   gHisiTokenSpaceGuid.PcdSerDesFlowCtrlFlag|0|UINT32|0x40000056
 
 [PcdsFeatureFlag]
+  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|FALSE|BOOLEAN|0x00000066
 
 
 
diff --git a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
index bdd80f8..539d567 100644
--- a/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
+++ b/Chips/Hisilicon/Include/Regs/HisiPcieV1RegOffset.h
@@ -8981,6 +8981,7 @@  typedef union tagIepMsiCtrlIntStatus
 #define PCIE_SYS_CTRL24_REG  (PCI_SYS_BASE + 0x1b4)
 #define PCIE_SYS_CTRL28_REG  (PCI_SYS_BASE + 0x1c4)
 #define PCIE_SYS_CTRL29_REG  (PCI_SYS_BASE + 0x1c8)
+#define PCIE_SYS_CTRL54_REG  (PCI_SYS_BASE + 0x274)
 #define PCIE_SYS_STATE5_REG  (PCI_SYS_BASE + 0x30)
 #define PCIE_SYS_STATE6_REG  (PCI_SYS_BASE + 0x34)
 #define PCIE_SYS_STATE7_REG  (PCI_SYS_BASE + 0x38)
diff --git a/Platforms/Hisilicon/D03/D03.dsc b/Platforms/Hisilicon/D03/D03.dsc
index 6d82627..942b2b8 100644
--- a/Platforms/Hisilicon/D03/D03.dsc
+++ b/Platforms/Hisilicon/D03/D03.dsc
@@ -111,6 +111,7 @@ 
   ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
   #  It could be set FALSE to save size.
   gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gHisiTokenSpaceGuid.PcdIsPciPerfTuningEnable|TRUE
 
 [PcdsFixedAtBuild.common]
   gArmPlatformTokenSpaceGuid.PcdFirmwareVendor|"ARM Versatile Express"