blob: f9f8ba2bcc1ea768bac2b4585b41b5c1a6e5eb12 [file] [log] [blame]
/*
* Copyright (c) 2014, 2015-2017, 2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <common.h>
#include <pci.h>
#include <linux/sizes.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/arch-qca-common/gpio.h>
#include <asm/arch-qca-common/iomap.h>
#include <fdtdec.h>
#include <dm.h>
DECLARE_GLOBAL_DATA_PTR;
#define PCIE_RST_CTRL_PIPE_ARES 0x4
#define PCIE_RST_CTRL_PIPE_STICKY_ARES 0x100
#define PCIE_RST_CTRL_PIPE_PHY_AHB_ARES 0x800
#define PCIE_RST_CTRL_AXI_M_ARES 0x1
#define PCIE_RST_CTRL_AXI_M_STICKY_ARES 0x80
#define PCIE_RST_CTRL_AXI_S_ARES 0x2
#define PCIE_RST_CTRL_AHB_ARES 0x400
#define PCI_CFG0_RDWR 0x4
#define PCI_CFG1_RDWR 0x5
#define RD 0
#define WR 1
#define MSM_PCIE_DEV_CFG_ADDR 0x01000000
#define PCIE20_PLR_IATU_VIEWPORT 0x900
#define PCIE20_PLR_IATU_CTRL1 0x904
#define PCIE20_PLR_IATU_CTRL2 0x908
#define PCIE20_PLR_IATU_LBAR 0x90C
#define PCIE20_PLR_IATU_UBAR 0x910
#define PCIE20_PLR_IATU_LAR 0x914
#define PCIE20_PLR_IATU_LTAR 0x918
#define PCIE20_PLR_IATU_UTAR 0x91c
/* PCIE20_PARF_PHYS Registers */
#define PARF_SLV_ADDR_SPACE_SIZE 0x16C
#define SLV_ADDR_SPACE_SZ 0x40000000
#define PCIE_0_PCIE20_PARF_LTSSM 0x1B0
#define LTSSM_EN (1 << 8)
/* PCIE20_PHYS Registers */
#define PCIE_0_PORT_FORCE_REG 0x708
#define PCIE_0_ACK_F_ASPM_CTRL_REG 0x70C
#define L1_ENTRANCE_LATENCY(x) (x << 27)
#define L0_ENTRANCE_LATENCY(x) (x << 24)
#define COMMON_CLK_N_FTS(x) (x << 16)
#define ACK_N_FTS(x) (x << 8)
#define PCIE_0_GEN2_CTRL_REG 0x80C
#define FAST_TRAINING_SEQ(x) (x << 0)
#define NUM_OF_LANES(x) (x << 8)
#define DIRECT_SPEED_CHANGE (1 << 17)
#define PCIE_0_TYPE0_STATUS_COMMAND_REG_1 0x004
#define PCI_TYPE0_BUS_MASTER_EN (1 << 2)
#define PCIE_0_MISC_CONTROL_1_REG 0x8BC
#define DBI_RO_WR_EN (1 << 0)
#define PCIE_0_LINK_CAPABILITIES_REG 0x07C
#define PCIE_CAP_ASPM_OPT_COMPLIANCE (1 << 22)
#define PCIE_CAP_LINK_BW_NOT_CAP (1 << 21)
#define PCIE_CAP_DLL_ACTIVE_REP_CAP (1 << 20)
#define PCIE_CAP_L1_EXIT_LATENCY(x) (x << 15)
#define PCIE_CAP_L0S_EXIT_LATENCY(x) (x << 12)
#define PCIE_CAP_MAX_LINK_WIDTH(x) (x << 4)
#define PCIE_CAP_MAX_LINK_SPEED(x) (x << 0)
#define PCIE_0_DEVICE_CONTROL2_DEVICE_STATUS2_REG 0x098
#define PCIE_CAP_CPL_TIMEOUT_DISABLE (1 << 4)
#define PCIE_0_TYPE0_LINK_CONTROL_LINK_STATUS_REG_1 0x080
#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818
#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c
#define PCIE20_SIZE SZ_4K
#define PCIE_AXI_CONF_SIZE SZ_1M
#define PCIE_USB3_PCS_POWER_DOWN_CONTROL 0x804
#define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x34
#define QSERDES_COM_CLK_ENABLE1 0x38
#define QSERDES_COM_BG_TRIM 0x70
#define QSERDES_COM_LOCK_CMP_EN 0xC8
#define QSERDES_COM_VCO_TUNE_MAP 0x128
#define QSERDES_COM_VCO_TUNE_TIMER1 0x144
#define QSERDES_COM_VCO_TUNE_TIMER2 0x144
#define QSERDES_COM_CMN_CONFIG 0x194
#define PCIE_QSERDES_COM_PLL_IVCO 0x48
#define QSERDES_COM_HSCLK_SEL 0x178
#define PCIE_QSERDES_COM_SVS_MODE_CLK_SEL 0x19C
#define PCIE_QSERDES_COM_CORE_CLK_EN 0x18C
#define QSERDES_COM_CORECLK_DIV 0x184
#define QSERDES_COM_RESETSM_CNTRL 0xB4
#define PCIE_QSERDES_COM_BG_TIMER 0xC
#define PCIE_QSERDES_COM_SYSCLK_EN_SEL 0xAC
#define PCIE_QSERDES_COM_DEC_START_MODE0 0xD0
#define PCIE_QSERDES_COM_DIV_FRAC_START3_MODE0 0xE4
#define PCIE_QSERDES_COM_DIV_FRAC_START2_MODE0 0xE0
#define PCIE_QSERDES_COM_DIV_FRAC_START1_MODE0 0xDC
#define QSERDES_COM_LOCK_CMP3_MODE0 0x54
#define QSERDES_COM_LOCK_CMP2_MODE0 0x50
#define PCIE_QSERDES_COM_LOCK_CMP1_MODE0 0x4C
#define QSERDES_COM_CLK_SELECT 0x174
#define PCIE_QSERDES_COM_SYS_CLK_CTRL 0x3C
#define QSERDES_COM_SYSCLK_BUF_ENABLE 0x40
#define QSERDES_COM_CP_CTRL_MODE0 0x78
#define QSERDES_COM_PLL_RCTRL_MODE0 0x84
#define QSERDES_COM_PLL_CCTRL_MODE0 0x90
#define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10C
#define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
#define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0xA8
#define QSERDES_COM_VCO_TUNE_CTRL 0xC
#define QSERDES_COM_SSC_EN_CENTER 0x10
#define PCIE_QSERDES_COM_SSC_PER1 0x1C
#define QSERDES_COM_SSC_PER2 0x20
#define QSERDES_COM_SSC_ADJ_PER1 0x14
#define QSERDES_COM_SSC_ADJ_PER2 0x18
#define QSERDES_COM_SSC_STEP_SIZE1 0x24
#define QSERDES_COM_SSC_STEP_SIZE2 0x28
#define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x268
#define QSERDES_TX_LANE_MODE 0x294
#define QSERDES_TX_RES_CODE_LANE_OFFSET 0x254
#define PCIE_QSERDES_TX_RCV_DETECT_LVL_2 0x2AC
#define QSERDES_RX_SIGDET_ENABLES 0x510
#define PCIE_QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x51C
#define PCIE_QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x4D8
#define PCIE_QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x4DC
#define PCIE_QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x4E0
#define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x448
#define PCIE_QSERDES_RX_UCDR_SO_GAIN 0x41C
#define QSERDES_RX_UCDR_SO_GAIN_HALF 0x410
#define QSERDES_COM_CLK_EP_DIV 0x74
#define PCIE_USB3_PCS_ENDPOINT_REFCLK_DRIVE 0x854
#define PCIE_USB3_PCS_OSC_DTCT_ACTIONS 0x9AC
#define PCIE_USB3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK 0x8A0
#define PCIE_USB3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x9E0
#define PCIE_USB3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x9DC
#define PCIE_USB3_PCS_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x9A8
#define PCIE_USB3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK 0x8A4
#define PCIE_USB3_PCS_PLL_LOCK_CHK_DLY_TIME 0x8A8
#define QSERDES_RX_SIGDET_CNTRL 0x514
#define PCIE_USB3_PCS_RX_SIGDET_LVL 0x9D8
#define PCIE_USB3_PCS_TXDEEMPH_M6DB_V0 0x824
#define PCIE_USB3_PCS_TXDEEMPH_M3P5DB_V0 0x828
#define PCIE_USB3_PCS_SW_RESET 0x800
#define PCIE_USB3_PCS_START_CONTROL 0x808
#define PCIE20_PARF_PHY_CTRL 0x40
#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK (0x1f << 16)
#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) (x << 16)
#define PCIE20_PARF_PHY_REFCLK 0x4C
#define REF_SSP_EN BIT(16)
#define REF_USE_PAD BIT(12)
#define PCIE20_PARF_PCS_DEEMPH 0x34
#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(x) (x << 16)
#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) (x << 8)
#define PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) (x << 0)
#define PCIE20_PARF_PCS_SWING 0x38
#define PCIE20_PARF_PCS_SWING_TX_SWING_FULL(x) (x << 8)
#define PCIE20_PARF_PCS_SWING_TX_SWING_LOW(x) (x << 0)
#define PCIE20_PARF_CONFIG_BITS 0x50
#define PCIE_SFAB_AXI_S5_FCLK_CTL 0x00902154
#define PCIE20_ELBI_SYS_CTRL 0x04
#define PCS_COM_POWER_DOWN_CONTROL 0x840
#define PCIE_0_QSERDES_PLL_BIAS_EN_CLKBUFLR_EN 0x03C
#define PCIE_0_QSERDES_PLL_BIAS_EN_CTRL_BY_PSM 0x0A4
#define PCIE_0_QSERDES_PLL_CLK_SELECT 0x16C
#define PCIE_0_QSERDES_PLL_PLL_IVCO 0x050
#define PCIE_0_QSERDES_PLL_BG_TRIM 0x074
#define PCIE_0_QSERDES_PLL_CMN_CONFIG 0x18C
#define PCIE_0_QSERDES_PLL_LOCK_CMP_EN 0x0C4
#define PCIE_0_QSERDES_PLL_RESETSM_CNTRL 0x0B0
#define PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL 0x194
#define PCIE_0_QSERDES_PLL_VCO_TUNE_MAP 0x120
#define PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER1 0x13C
#define PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER2 0x140
#define PCIE_0_QSERDES_PLL_CORE_CLK_EN 0x184
#define PCIE_0_QSERDES_PLL_HSCLK_SEL 0x170
#define PCIE_0_QSERDES_PLL_DEC_START_MODE0 0x0CC
#define PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE0 0x0E0
#define PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE0 0x0DC
#define PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE0 0x0D8
#define PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE0 0x058
#define PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE0 0x054
#define PCIE_0_QSERDES_PLL_CP_CTRL_MODE0 0x080
#define PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE0 0x088
#define PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE0 0x090
#define PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE0 0x104
#define PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE0 0x100
#define PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE0 0x128
#define PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE0 0x124
#define PCIE_0_QSERDES_PLL_CORECLK_DIV 0x17C
#define PCIE_0_QSERDES_PLL_SYS_CLK_CTRL 0x044
#define PCIE_0_QSERDES_PLL_SYSCLK_BUF_ENABLE 0x048
#define PCIE_0_QSERDES_PLL_SYSCLK_EN_SEL 0x0A8
#define PCIE_0_QSERDES_PLL_BG_TIMER 0x00C
#define PCIE_0_QSERDES_PLL_DEC_START_MODE1 0x0D0
#define PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE1 0x0EC
#define PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE1 0x0E8
#define PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE1 0x0E4
#define PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE1 0x064
#define PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE1 0x060
#define PCIE_0_QSERDES_PLL_CP_CTRL_MODE1 0x084
#define PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE1 0x08C
#define PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE1 0x094
#define PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE1 0x10C
#define PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE1 0x108
#define PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE1 0x130
#define PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE1 0x12C
#define PCIE_0_QSERDES_PLL_CORECLK_DIV_MODE1 0x1B4
#define PCIE_0_QSERDES_TX0_RES_CODE_LANE_OFFSET_TX 0x23C
#define PCIE_0_QSERDES_TX0_RCV_DETECT_LVL_2 0x29C
#define PCIE_0_QSERDES_TX0_HIGHZ_DRVR_EN 0x258
#define PCIE_0_QSERDES_TX0_LANE_MODE_1 0x284
#define PCIE_0_QSERDES_RX0_SIGDET_CNTRL 0x51C
#define PCIE_0_QSERDES_RX0_SIGDET_ENABLES 0x518
#define PCIE_0_QSERDES_RX0_SIGDET_DEGLITCH_CNTRL 0x524
#define PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2 0x4EC
#define PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3 0x4F0
#define PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4 0x4F4
#define PCIE_0_QSERDES_RX0_DFE_EN_TIMER 0x5B4
#define PCIE_0_QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE 0x434
#define PCIE_0_QSERDES_RX0_UCDR_PI_CONTROLS 0x444
#define PCIE_0_QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x510
#define PCIE_0_QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2 0x514
#define PCIE_0_QSERDES_RX0_RX_MODE_10_LOW 0x598
#define PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH 0x59C
#define PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH2 0x5A0
#define PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH3 0x5A4
#define PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH4 0x5A8
#define PCIE_0_QSERDES_RX0_RX_MODE_01_LOW 0x584
#define PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH 0x588
#define PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH2 0x58C
#define PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH3 0x590
#define PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH4 0x594
#define PCIE_0_QSERDES_RX0_RX_MODE_00_LOW 0x570
#define PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH 0x574
#define PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH2 0x578
#define PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH3 0x57C
#define PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH4 0x580
#define PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_HIGH 0x4FC
#define PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_LOW 0x4F8
#define PCIE_0_PCS_COM_FLL_CNTRL2 0x89C
#define PCIE_0_PCS_COM_FLL_CNT_VAL_L 0x8A0
#define PCIE_0_PCS_COM_FLL_CNT_VAL_H_TOL 0x8A4
#define PCIE_0_PCS_COM_FLL_MAN_CODE 0x8A8
#define PCIE_0_PCS_COM_FLL_CNTRL1 0x898
#define PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H 0x9A8
#define PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L 0x9A4
#define PCIE_0_PCS_PCIE_OSC_DTCT_ACTIONS 0xC90
#define PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H 0xC44
#define PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L 0xC40
#define PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H 0xC4C
#define PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L 0xC48
#define PCIE_0_PCS_PCIE_EQ_CONFIG1 0xCA0
#define PCIE_0_PCS_PCIE_EQ_CONFIG2 0xCA4
#define PCIE_0_PCS_PCIE_POWER_STATE_CONFIG4 0xC14
#define PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG2 0xC5C
#define PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2 0xC78
#define PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4 0xC80
#define PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5 0xC84
#define PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE0 0x078
#define PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE1 0x07C
#define PCIE_0_QSERDES_PLL_CLK_ENABLE1 0x040
#define PCIE_0_PCS_COM_POWER_DOWN_CONTROL 0x840
#define PCIE_0_PCS_PCIE_ENDPOINT_REFCLK_DRIVE 0xC1C
#define PCIE_0_PCS_COM_RX_DCC_CAL_CONFIG 0x9D8
#define PCIE_0_PCS_COM_RX_SIGDET_LVL 0x988
#define PCIE_0_PCS_COM_REFGEN_REQ_CONFIG1 0x8DC
#define PCIE_0_PCS_COM_SW_RESET 0x800
#define PCIE_0_PCS_COM_START_CONTROL 0x844
#define PCIE_0_QSERDES_PLL_SSC_PER1 0x01C
#define PCIE_0_QSERDES_PLL_SSC_PER2 0x020
#define PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE0 0x024
#define PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE0 0x028
#define PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE1 0x02C
#define PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE1 0x030
#define PCIE_0_QSERDES_RX0_UCDR_FO_GAIN 0x408
#define PCIE_0_QSERDES_RX0_UCDR_SO_GAIN 0x414
#define PCIE_0_PCS_COM_G12S1_TXDEEMPH_M3P5DB 0x96C
#define PCIE_0_PCS_COM_EQ_CONFIG5 0x9EC
#define PCIE_0_PCS_PCIE_POWER_STATE_CONFIG2 0xC0C
#define PCIE_0_PCS_PCIE_PRESET_P10_PRE 0xCBC
#define PCIE_0_PCS_PCIE_PRESET_P10_POST 0xCE0
#define PARF_MHI_CLOCK_RESET_CTRL 0x174
#define BYPASS BIT(4)
#define MSTR_AXI_CLK_EN BIT(1)
#define AHB_CLK_EN BIT(0)
#define PCIE_PARF_DEVICE_TYPE 0x1000
#define DEVICE_TYPE_RC 0x4
#define PCIE30_GEN3_RELATED_OFF 0x890
#define GEN3_EQUALIZATION_DISABLE BIT(16)
#define RXEQ_RGRDLESS_RXTS BIT(13)
#define GEN3_ZRXDC_NONCOMPL BIT(0)
#define PCIE20_PARF_SYS_CTRL 0x00
#define ECAM_BLOCKER_EN_RANGE2 BIT(30)
#define MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN BIT(29)
#define ECAM_REMOVE_OFFSET_EN BIT(27)
#define ECAM_BLOCKER_EN BIT(26)
#define MST_WAKEUP_EN BIT(13)
#define SLV_WAKEUP_EN BIT(12)
#define MSTR_ACLK_CGC_DIS BIT(10)
#define SLV_ACLK_CGC_DIS BIT(9)
#define CORE_CLK_CGC_DIS BIT(6)
#define AUX_PWR_DET BIT(4)
#define CORE_CLK_2AUX_CLK_MUX_DIS BIT(3)
#define L23_CLK_RMV_DIS BIT(2)
#define L1_CLK_RMV_DIS BIT(1)
#define PARF_BLOCK_SLV_AXI_WR_BASE 0x360
#define PARF_BLOCK_SLV_AXI_WR_LIMIT 0x368
#define PARF_BLOCK_SLV_AXI_RD_BASE 0x370
#define PARF_BLOCK_SLV_AXI_RD_LIMIT 0x378
#define PARF_ECAM_BASE 0x380
#define PARF_ECAM_OFFSET_REMOVAL_BASE 0x388
#define PARF_ECAM_OFFSET_REMOVAL_LIMIT 0x390
#define PARF_BLOCK_SLV_AXI_WR_BASE_2 0x398
#define PARF_BLOCK_SLV_AXI_WR_LIMIT_2 0x3A0
#define PARF_BLOCK_SLV_AXI_RD_BASE_2 0x3A8
#define PARF_BLOCK_SLV_AXI_RD_LIMIT_2 0x3B0
#define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xA0
#define PCIE_CAP_CURR_DEEMPHASIS BIT(16)
#define SPEED_GEN3 0x3
#define PCIE_PHY_DELAY_MS 0xFFFFFFFF
static unsigned int local_buses[] = { 0, 0 };
struct pci_controller pci_hose[PCI_MAX_DEVICES];
static int phy_initialised;
extern int get_soc_version(uint32_t *soc_ver_major, uint32_t *soc_ver_minor);
struct phy_regs {
u32 reg_offset;
u32 val;
};
static const struct phy_regs pcie_phy_v2_init_seq_ipq[] = {
#if !defined(CONFIG_IPQ6018)
{ PCS_COM_POWER_DOWN_CONTROL, 0x00000001},
{ PCIE_0_QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x00000018},
{ PCIE_0_QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x00000001},
{ PCIE_0_QSERDES_PLL_CLK_SELECT, 0x00000031},
{ PCIE_0_QSERDES_PLL_PLL_IVCO, 0x0000000F},
{ PCIE_0_QSERDES_PLL_BG_TRIM, 0x0000000F},
/* delay 5ms */
{ PCIE_PHY_DELAY_MS, 0x00000005},
{ PCIE_0_QSERDES_PLL_CMN_CONFIG, 0x00000006},
{ PCIE_0_QSERDES_PLL_LOCK_CMP_EN, 0x00000042},
{ PCIE_0_QSERDES_PLL_RESETSM_CNTRL, 0x00000020},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000001},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_MAP, 0x00000004},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER1, 0x000000FF},
{ PCIE_0_QSERDES_PLL_VCO_TUNE_TIMER2, 0x0000003F},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000030},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000021},
{ PCIE_0_QSERDES_PLL_DEC_START_MODE0, 0x00000082},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x00000003},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE0, 0x00000355},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE0, 0x00035555},
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE0, 0x0000001A},
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE0, 0x00001A0A},
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE0, 0x0000000B},
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE0, 0x00000016},
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE0, 0x00000028},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE0, 0x00000000},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0x00000040},
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE0, 0x00000002},
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE0, 0x00000024},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000020},
{ PCIE_0_QSERDES_PLL_CORECLK_DIV, 0x0000000A},
{ PCIE_0_QSERDES_PLL_CLK_SELECT, 0x00000032},
{ PCIE_0_QSERDES_PLL_SYS_CLK_CTRL, 0x00000002},
{ PCIE_0_QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x00000007},
{ PCIE_0_QSERDES_PLL_SYSCLK_EN_SEL, 0x00000008},
{ PCIE_0_QSERDES_PLL_BG_TIMER, 0x0000000A},
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x00000001},
{ PCIE_0_QSERDES_PLL_DEC_START_MODE1, 0x00000068},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x00000002},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x000002AA},
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x0002AAAB},
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE1, 0x00000034},
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE1, 0x00003414},
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE1, 0x0000000B},
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE1, 0x00000016},
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE1, 0x00000028},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN1_MODE1, 0x00000000},
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0x00000040},
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE1, 0x00000003},
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE1, 0x000000B4},
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x00000005},
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00000000},
{ PCIE_0_QSERDES_PLL_CORECLK_DIV_MODE1, 0x00000008},
/*qmp_tx_init*/
{ PCIE_0_QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x00000002},
{ PCIE_0_QSERDES_TX0_RCV_DETECT_LVL_2, 0x00000012},
{ PCIE_0_QSERDES_TX0_HIGHZ_DRVR_EN, 0x00000010},
{ PCIE_0_QSERDES_TX0_LANE_MODE_1, 0x00000006},
/*qmp_rx_init*/
{ PCIE_0_QSERDES_RX0_SIGDET_CNTRL, 0x00000003},
{ PCIE_0_QSERDES_RX0_SIGDET_ENABLES, 0x0000001C},
{ PCIE_0_QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x00000014},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x0000000E},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x00000004},
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x0000001B},
{ PCIE_0_QSERDES_RX0_DFE_EN_TIMER, 0x00000004},
{ PCIE_0_QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x0000007F},
{ PCIE_0_QSERDES_RX0_UCDR_PI_CONTROLS, 0x00000070},
{ PCIE_0_QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x00000073},
{ PCIE_0_QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x00000080},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_LOW, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH2, 0x000000C8},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH3, 0x00000009},
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH4, 0x000000B1},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_LOW, 0x000000F0},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH, 0x00000002},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH2, 0x0000002F},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH3, 0x000000D3},
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH4, 0x00000040},
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00000000},
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0x000000C0},
/* pcie fll config*/
{ PCIE_0_PCS_COM_FLL_CNTRL2, 0x00000083},
{ PCIE_0_PCS_COM_FLL_CNT_VAL_L, 0x00000009},
{ PCIE_0_PCS_COM_FLL_CNT_VAL_H_TOL, 0x000000A2},
{ PCIE_0_PCS_COM_FLL_MAN_CODE, 0x00000040},
{ PCIE_0_PCS_COM_FLL_CNTRL1, 0x00000001},
{ PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_H, 0x00000000},
{ PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x00000001},
{ PCIE_0_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00000000},
{ PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_H, 0x00000000},
{ PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x00000001},
{ PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_H, 0x00000000},
{ PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x00000001},
{ PCIE_0_PCS_PCIE_EQ_CONFIG1, 0x00000011},
{ PCIE_0_PCS_PCIE_EQ_CONFIG2, 0x0000000B},
{ PCIE_0_PCS_PCIE_POWER_STATE_CONFIG4, 0x00000007},
{ PCIE_0_PCS_PCIE_OSC_DTCT_CONFIG2, 0x00000052},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG2, 0x00000050},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG4, 0x0000001A},
{ PCIE_0_PCS_PCIE_OSC_DTCT_MODE2_CONFIG5, 0x00000006},
{ PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE0, 0x00000019},
{ PCIE_0_QSERDES_PLL_CLK_EP_DIV_MODE1, 0x00000028},
{ PCIE_0_QSERDES_PLL_CLK_ENABLE1, 0x00000090},
{ PCIE_0_PCS_COM_POWER_DOWN_CONTROL, 0x00000003},
{ PCIE_0_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0x000000C1},
{ PCIE_0_PCS_COM_RX_DCC_CAL_CONFIG, 0x00000001},
{ PCIE_0_PCS_COM_RX_SIGDET_LVL, 0x000000AA},
{ PCIE_0_PCS_COM_REFGEN_REQ_CONFIG1, 0x0000000D},
{ PCIE_0_PCS_COM_SW_RESET, 0x00000000},
{ PCIE_0_PCS_COM_START_CONTROL, 0x00000003},
#else
{ PCIE_0_PCS_COM_POWER_DOWN_CONTROL, 0x03 },
{ PCIE_0_QSERDES_PLL_SSC_PER1, 0x7D },
{ PCIE_0_QSERDES_PLL_SSC_PER2, 0x01 },
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE0, 0x0A },
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE0, 0x05 },
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE1_MODE1, 0x08 },
{ PCIE_0_QSERDES_PLL_SSC_STEP_SIZE2_MODE1, 0x04 },
{ PCIE_0_QSERDES_PLL_BIAS_EN_CLKBUFLR_EN, 0x18 },
{ PCIE_0_QSERDES_PLL_CLK_ENABLE1, 0x90 },
{ PCIE_0_QSERDES_PLL_SYS_CLK_CTRL, 0x02 },
{ PCIE_0_QSERDES_PLL_SYSCLK_BUF_ENABLE, 0x07 },
{ PCIE_0_QSERDES_PLL_PLL_IVCO, 0x0F },
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE0, 0xD4 },
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE0, 0x14 },
{ PCIE_0_QSERDES_PLL_LOCK_CMP1_MODE1, 0xAA },
{ PCIE_0_QSERDES_PLL_LOCK_CMP2_MODE1, 0x29 },
{ PCIE_0_QSERDES_PLL_BG_TRIM, 0x0F },
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE0, 0x09 },
/*PCIE_0_ delay 5ms */
{ PCIE_PHY_DELAY_MS, 0x05 },
{ PCIE_0_QSERDES_PLL_CP_CTRL_MODE1, 0x09 },
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE0, 0x16 },
{ PCIE_0_QSERDES_PLL_PLL_RCTRL_MODE1, 0x16 },
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE0, 0x28 },
{ PCIE_0_QSERDES_PLL_PLL_CCTRL_MODE1, 0x28 },
{ PCIE_0_QSERDES_PLL_BIAS_EN_CTRL_BY_PSM, 0x01 },
{ PCIE_0_QSERDES_PLL_SYSCLK_EN_SEL, 0x08 },
{ PCIE_0_QSERDES_PLL_RESETSM_CNTRL, 0x20 },
{ PCIE_0_QSERDES_PLL_LOCK_CMP_EN, 0x42 },
{ PCIE_0_QSERDES_PLL_DEC_START_MODE0, 0x68 },
{ PCIE_0_QSERDES_PLL_DEC_START_MODE1, 0x53 },
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE0, 0xAB },
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE0, 0xAA },
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE0, 0x02 },
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START1_MODE1, 0x55 },
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START2_MODE1, 0x55 },
{ PCIE_0_QSERDES_PLL_DIV_FRAC_START3_MODE1, 0x05 },
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE0, 0xA0 },
{ PCIE_0_QSERDES_PLL_INTEGLOOP_GAIN0_MODE1, 0xA0 },
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE0, 0x24 },
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE0, 0x02 },
{ PCIE_0_QSERDES_PLL_VCO_TUNE1_MODE1, 0xB4 },
{ PCIE_0_QSERDES_PLL_VCO_TUNE2_MODE1, 0x03 },
{ PCIE_0_QSERDES_PLL_CLK_SELECT, 0x32 },
{ PCIE_0_QSERDES_PLL_HSCLK_SEL, 0x01 },
{ PCIE_0_QSERDES_PLL_CORE_CLK_EN, 0x00 },
{ PCIE_0_QSERDES_PLL_CMN_CONFIG, 0x06 },
{ PCIE_0_QSERDES_PLL_SVS_MODE_CLK_SEL, 0x05 },
{ PCIE_0_QSERDES_PLL_CORECLK_DIV_MODE1, 0x08 },
{ PCIE_0_QSERDES_TX0_RES_CODE_LANE_OFFSET_TX, 0x02 },
{ PCIE_0_QSERDES_TX0_LANE_MODE_1, 0x06 },
{ PCIE_0_QSERDES_TX0_RCV_DETECT_LVL_2, 0x12 },
{ PCIE_0_QSERDES_RX0_UCDR_FO_GAIN, 0x0C },
{ PCIE_0_QSERDES_RX0_UCDR_SO_GAIN, 0x02 },
{ PCIE_0_QSERDES_RX0_UCDR_SO_SATURATION_AND_ENABLE, 0x7F },
{ PCIE_0_QSERDES_RX0_UCDR_PI_CONTROLS, 0x70 },
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL2, 0x61 },
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL3, 0x04 },
{ PCIE_0_QSERDES_RX0_RX_EQU_ADAPTOR_CNTRL4, 0x1E },
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_LOW, 0xC0 },
{ PCIE_0_QSERDES_RX0_RX_IDAC_TSETTLE_HIGH, 0x00 },
{ PCIE_0_QSERDES_RX0_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x73 },
{ PCIE_0_QSERDES_RX0_RX_OFFSET_ADAPTOR_CNTRL2, 0x80 },
{ PCIE_0_QSERDES_RX0_SIGDET_ENABLES, 0x1C },
{ PCIE_0_QSERDES_RX0_SIGDET_CNTRL, 0x03 },
{ PCIE_0_QSERDES_RX0_SIGDET_DEGLITCH_CNTRL, 0x14 },
{ PCIE_0_QSERDES_RX0_RX_MODE_00_LOW, 0xF0 },
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH, 0x01 },
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH2, 0x2F },
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH3, 0xD3 },
{ PCIE_0_QSERDES_RX0_RX_MODE_00_HIGH4, 0x40 },
{ PCIE_0_QSERDES_RX0_RX_MODE_01_LOW, 0x01 },
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH, 0x02 },
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH2, 0xC8 },
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH3, 0x09 },
{ PCIE_0_QSERDES_RX0_RX_MODE_01_HIGH4, 0xB1 },
{ PCIE_0_QSERDES_RX0_RX_MODE_10_LOW, 0x00 },
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH, 0x02 },
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH2, 0xC8 },
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH3, 0x09 },
{ PCIE_0_QSERDES_RX0_RX_MODE_10_HIGH4, 0xB1 },
{ PCIE_0_QSERDES_RX0_DFE_EN_TIMER, 0x04 },
{ PCIE_0_PCS_COM_FLL_CNTRL1, 0x01 },
{ PCIE_0_PCS_COM_REFGEN_REQ_CONFIG1, 0x0D },
{ PCIE_0_PCS_COM_G12S1_TXDEEMPH_M3P5DB, 0x10 },
{ PCIE_0_PCS_COM_RX_SIGDET_LVL, 0xAA },
{ PCIE_0_PCS_COM_P2U3_WAKEUP_DLY_TIME_AUXCLK_L, 0x01 },
{ PCIE_0_PCS_COM_RX_DCC_CAL_CONFIG, 0x01 },
{ PCIE_0_PCS_COM_EQ_CONFIG5, 0x01 },
{ PCIE_0_PCS_PCIE_POWER_STATE_CONFIG2, 0x0D },
{ PCIE_0_PCS_PCIE_POWER_STATE_CONFIG4, 0x07 },
{ PCIE_0_PCS_PCIE_ENDPOINT_REFCLK_DRIVE, 0xC1 },
{ PCIE_0_PCS_PCIE_L1P1_WAKEUP_DLY_TIME_AUXCLK_L, 0x01 },
{ PCIE_0_PCS_PCIE_L1P2_WAKEUP_DLY_TIME_AUXCLK_L, 0x01 },
{ PCIE_0_PCS_PCIE_OSC_DTCT_ACTIONS, 0x00 },
{ PCIE_0_PCS_PCIE_EQ_CONFIG1, 0x11 },
{ PCIE_0_PCS_PCIE_PRESET_P10_PRE, 0x00 },
{ PCIE_0_PCS_PCIE_PRESET_P10_POST, 0x58 },
{ PCIE_0_PCS_COM_SW_RESET, 0x00 },
{ PCIE_0_PCS_COM_START_CONTROL, 0x03 },
#endif
};
enum pcie_verion{
PCIE_V0,
PCIE_V1,
PCIE_V2,
};
static const struct udevice_id pcie_ver_ids[] = {
{ .compatible = "qcom,ipq806x-pcie", .data = PCIE_V0 },
{ .compatible = "qcom,ipq40xx-pcie", .data = PCIE_V1 },
{ .compatible = "qcom,ipq807x-pcie", .data = PCIE_V2 },
{ .compatible = "qcom,ipq6018-pcie", .data = PCIE_V2 },
{ .compatible = "qcom,ipq5018-pcie", .data = PCIE_V2 },
{ },
};
struct ipq_pcie {
struct pci_controller hose;
struct fdt_resource pci_dbi;
struct fdt_resource parf;
struct fdt_resource elbi;
struct fdt_resource dm_iatu;
struct fdt_resource axi_conf;
struct fdt_resource axi_bars;
struct fdt_resource pci_rst;
struct fdt_resource pci_phy;
int rst_gpio;
int is_gen3;
int linkup;
int version;
int skip_phy_init;
};
static void ipq_pcie_write_mask(uint32_t addr,
uint32_t clear_mask, uint32_t set_mask)
{
uint32_t val;
val = (readl(addr) & ~clear_mask) | set_mask;
writel(val, addr);
}
static void ipq_pcie_parf_reset(uint32_t addr, int domain, int assert)
{
if (assert)
ipq_pcie_write_mask(addr, 0, domain);
else
ipq_pcie_write_mask(addr, domain, 0);
}
void ipq_pcie_config_cfgtype(uint32_t phyaddr)
{
uint32_t bdf, cfgtype;
cfgtype = PCI_CFG0_RDWR;
bdf = MSM_PCIE_DEV_CFG_ADDR;
writel(0, phyaddr + PCIE20_PLR_IATU_VIEWPORT);
/* Program Bdf Address */
writel(bdf, phyaddr + PCIE20_PLR_IATU_LTAR);
/* Write Config Request Type */
writel(cfgtype, phyaddr + PCIE20_PLR_IATU_CTRL1);
}
#define PCIE_ATU_CR1_OUTBOUND_6_GEN3 0xC00
#define PCIE_ATU_CR2_OUTBOUND_6_GEN3 0xC04
#define PCIE_ATU_LOWER_BASE_OUTBOUND_6_GEN3 0xC08
#define PCIE_ATU_UPPER_BASE_OUTBOUND_6_GEN3 0xC0C
#define PCIE_ATU_LIMIT_OUTBOUND_6_GEN3 0xC10
#define PCIE_ATU_LOWER_TARGET_OUTBOUND_6_GEN3 0xC14
#define PCIE_ATU_UPPER_TARGET_OUTBOUND_6_GEN3 0xC18
#define PCIE_ATU_CR1_OUTBOUND_7_GEN3 0xE00
#define PCIE_ATU_CR2_OUTBOUND_7_GEN3 0xE04
#define PCIE_ATU_LOWER_BASE_OUTBOUND_7_GEN3 0xE08
#define PCIE_ATU_UPPER_BASE_OUTBOUND_7_GEN3 0xE0C
#define PCIE_ATU_LIMIT_OUTBOUND_7_GEN3 0xE10
#define PCIE_ATU_LOWER_TARGET_OUTBOUND_7_GEN3 0xE14
#define PCIE_ATU_UPPER_TARGET_OUTBOUND_7_GEN3 0xE18
static void dw_pcie_writel_rc_gen3(uint32_t dbi_base, u32 val, u32 reg)
{
writel(val, dbi_base + reg);
}
void ipq_pcie_prog_outbound_atu(struct ipq_pcie *pcie)
{
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x4, PCIE_ATU_CR1_OUTBOUND_6_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x90000000, PCIE_ATU_CR2_OUTBOUND_6_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x0, PCIE_ATU_LOWER_BASE_OUTBOUND_6_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x0, PCIE_ATU_UPPER_BASE_OUTBOUND_6_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x00107FFFF, PCIE_ATU_LIMIT_OUTBOUND_6_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x0, PCIE_ATU_LOWER_TARGET_OUTBOUND_6_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x0, PCIE_ATU_UPPER_TARGET_OUTBOUND_6_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x5, PCIE_ATU_CR1_OUTBOUND_7_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x90000000, PCIE_ATU_CR2_OUTBOUND_7_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x200000, PCIE_ATU_LOWER_BASE_OUTBOUND_7_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x0, PCIE_ATU_UPPER_BASE_OUTBOUND_7_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x7FFFFF, PCIE_ATU_LIMIT_OUTBOUND_7_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x0, PCIE_ATU_LOWER_TARGET_OUTBOUND_7_GEN3);
dw_pcie_writel_rc_gen3(pcie->dm_iatu.start, 0x0, PCIE_ATU_UPPER_TARGET_OUTBOUND_7_GEN3);
}
int ipq_pcie_rd_conf_byte(struct pci_controller *hose, pci_dev_t dev,
int offset, u8 *val)
{
int bus = PCI_BUS (dev);
uint32_t addr;
uint32_t word_offset, byte_offset, mask;
uint32_t rd_val;
word_offset = offset & ~0x3;
byte_offset = offset & 0x3;
mask = (~0 >> (8 * (4 - 1))) << (8 * byte_offset);
ipq_pcie_config_cfgtype(hose->regions[0].phys_start);
if ((bus == local_buses[0]) || (bus == local_buses[1])) {
addr = hose->regions[0].phys_start;
} else {
addr = hose->regions[1].phys_start;
}
rd_val = readl(addr + word_offset);
*val = ((rd_val & mask) >> (8 * byte_offset));
return 0;
}
int ipq_pcie_rd_conf_word(struct pci_controller *hose, pci_dev_t dev,
int offset, u16 *val)
{
int bus = PCI_BUS (dev);
uint32_t addr;
uint32_t word_offset, byte_offset, mask;
uint32_t rd_val;
word_offset = offset & ~0x3;
byte_offset = offset & 0x3;
mask = (~0 >> (8 * (4 - 2))) << (8 * byte_offset);
ipq_pcie_config_cfgtype(hose->regions[0].phys_start);
if ((bus == local_buses[0]) || (bus == local_buses[1])) {
addr = hose->regions[0].phys_start;
} else {
addr = hose->regions[1].phys_start;
}
rd_val = readl(addr + word_offset);
*val = ((rd_val & mask) >> (8 * byte_offset));
return 0;
}
int ipq_pcie_rd_conf_dword(struct pci_controller *hose, pci_dev_t dev,
int offset, u32 *val)
{
int bus = PCI_BUS (dev);
uint32_t addr;
uint32_t word_offset, byte_offset, mask;
uint32_t rd_val;
word_offset = offset & ~0x3;
byte_offset = offset & 0x3;
mask = (~0 >> (8 * (4 - 4))) << (8 * byte_offset);
ipq_pcie_config_cfgtype(hose->regions[0].phys_start);
if ((bus == local_buses[0]) || (bus == local_buses[1])) {
addr = hose->regions[0].phys_start;
} else {
addr = hose->regions[1].phys_start;
}
rd_val = readl(addr + word_offset);
*val = ((rd_val & mask) >> (8 * byte_offset));
return 0;
}
int ipq_pcie_wr_conf_byte(struct pci_controller *hose, pci_dev_t dev,
int offset, u8 val)
{
int bus = PCI_BUS (dev);
uint32_t addr;
uint32_t word_offset, byte_offset, mask;
uint32_t rd_val, wr_val;
word_offset = offset & ~0x3;
byte_offset = offset & 0x3;
mask = (~0 >> (8 * (4 - 1))) << (8 * byte_offset);
ipq_pcie_config_cfgtype(hose->regions[0].phys_start);
if ((bus == local_buses[0]) || (bus == local_buses[1])) {
addr = hose->regions[0].phys_start;
} else {
addr = hose->regions[1].phys_start;
}
rd_val = readl(addr + word_offset);
wr_val = (rd_val & ~mask) |((val << (8 * byte_offset)) & mask);
writel(wr_val, addr + word_offset);
return 0;
}
int ipq_pcie_wr_conf_word(struct pci_controller *hose, pci_dev_t dev,
int offset, u16 val)
{
int bus = PCI_BUS (dev);
uint32_t addr;
uint32_t word_offset, byte_offset, mask;
uint32_t rd_val, wr_val;
word_offset = offset & ~0x3;
byte_offset = offset & 0x3;
mask = (~0 >> (8 * (4 - 2))) << (8 * byte_offset);
ipq_pcie_config_cfgtype(hose->regions[0].phys_start);
if ((bus == local_buses[0]) || (bus == local_buses[1])) {
addr = hose->regions[0].phys_start;
} else {
addr = hose->regions[1].phys_start;
}
rd_val = readl(addr + word_offset);
wr_val = (rd_val & ~mask) |((val << (8 * byte_offset)) & mask);
writel(wr_val, addr + word_offset);
return 0;
}
int ipq_pcie_wr_conf_dword(struct pci_controller *hose, pci_dev_t dev,
int offset, u32 val)
{
int bus = PCI_BUS (dev);
uint32_t addr;
uint32_t word_offset, byte_offset, mask;
uint32_t rd_val, wr_val;
word_offset = offset & ~0x3;
byte_offset = offset & 0x3;
mask = (~0 >> (8 * (4 - 4))) << (8 * byte_offset);
ipq_pcie_config_cfgtype(hose->regions[0].phys_start);
if ((bus == local_buses[0]) || (bus == local_buses[1])) {
addr = hose->regions[0].phys_start;
} else {
addr = hose->regions[1].phys_start;
}
rd_val = readl(addr + word_offset);
wr_val = (rd_val & ~mask) |((val << (8 * byte_offset)) & mask);
writel(wr_val, addr + word_offset);
return 0;
}
static void ipq_pcie_config_controller(struct ipq_pcie *pcie)
{
/*
* program and enable address translation region 0 (device config
* address space); region type config;
* axi config address range to device config address range
*/
writel(0, pcie->pci_dbi.start + PCIE20_PLR_IATU_VIEWPORT);
writel(4, pcie->pci_dbi.start + PCIE20_PLR_IATU_CTRL1);
writel((1 << 31), pcie->pci_dbi.start + PCIE20_PLR_IATU_CTRL2);
writel(pcie->axi_conf.start , pcie->pci_dbi.start + PCIE20_PLR_IATU_LBAR);
writel(0, pcie->pci_dbi.start + PCIE20_PLR_IATU_UBAR);
writel((pcie->axi_conf.start + pcie->axi_conf.end - 1),
pcie->pci_dbi.start + PCIE20_PLR_IATU_LAR);
writel(MSM_PCIE_DEV_CFG_ADDR,
pcie->pci_dbi.start + PCIE20_PLR_IATU_LTAR);
writel(0, pcie->pci_dbi.start + PCIE20_PLR_IATU_UTAR);
/*
* program and enable address translation region 2 (device resource
* address space); region type memory;
* axi device bar address range to device bar address range
*/
writel(2, pcie->pci_dbi.start + PCIE20_PLR_IATU_VIEWPORT);
writel(0, pcie->pci_dbi.start + PCIE20_PLR_IATU_CTRL1);
writel((1 << 31), pcie->pci_dbi.start + PCIE20_PLR_IATU_CTRL2);
writel(pcie->axi_bars.start, pcie->pci_dbi.start + PCIE20_PLR_IATU_LBAR);
writel(0, pcie->pci_dbi.start + PCIE20_PLR_IATU_UBAR);
writel((pcie->axi_bars.start + pcie->axi_bars.end
- pcie->axi_conf.end - 1), pcie->pci_dbi.start+ PCIE20_PLR_IATU_LAR);
writel(pcie->axi_bars.start, pcie->pci_dbi.start + PCIE20_PLR_IATU_LTAR);
writel(0, pcie->pci_dbi.start + PCIE20_PLR_IATU_UTAR);
/* 1K PCIE buffer setting */
writel(0x3, pcie->pci_dbi.start + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
writel(0x1, pcie->pci_dbi.start + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
}
void pcie_linkup(struct ipq_pcie *pcie)
{
int j, val;
if (pcie->version != PCIE_V2)
{
writel(SLV_ADDR_SPACE_SZ, pcie->parf.start + PARF_SLV_ADDR_SPACE_SIZE);
mdelay(100);
}
if (pcie->is_gen3) {
writel(DEVICE_TYPE_RC, pcie->parf.start + PCIE_PARF_DEVICE_TYPE);
writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
pcie->parf.start + PARF_MHI_CLOCK_RESET_CTRL);
writel(GEN3_EQUALIZATION_DISABLE | RXEQ_RGRDLESS_RXTS |
GEN3_ZRXDC_NONCOMPL, pcie->pci_dbi.start + PCIE30_GEN3_RELATED_OFF);
writel(ECAM_BLOCKER_EN_RANGE2 | MAC_PHY_POWERDOWN_IN_P2_D_MUX_EN
| ECAM_REMOVE_OFFSET_EN | ECAM_BLOCKER_EN |
MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
| SLV_ACLK_CGC_DIS | AUX_PWR_DET |
CORE_CLK_2AUX_CLK_MUX_DIS | L23_CLK_RMV_DIS,
pcie->parf.start + PCIE20_PARF_SYS_CTRL);
}
writel(0x0, pcie->pci_dbi.start + PCIE_0_PORT_FORCE_REG);
val = (L1_ENTRANCE_LATENCY(3) |
L0_ENTRANCE_LATENCY(3) |
COMMON_CLK_N_FTS(128) |
ACK_N_FTS(128));
writel(val, pcie->pci_dbi.start + PCIE_0_ACK_F_ASPM_CTRL_REG);
val = (FAST_TRAINING_SEQ(128) |
NUM_OF_LANES(2) |
DIRECT_SPEED_CHANGE);
writel(val, pcie->pci_dbi.start + PCIE_0_GEN2_CTRL_REG);
writel(PCI_TYPE0_BUS_MASTER_EN,
pcie->pci_dbi.start + PCIE_0_TYPE0_STATUS_COMMAND_REG_1);
writel(DBI_RO_WR_EN, pcie->pci_dbi.start + PCIE_0_MISC_CONTROL_1_REG);
writel(0x0002FD7F, pcie->pci_dbi.start + 0x84);
val = (PCIE_CAP_ASPM_OPT_COMPLIANCE |
PCIE_CAP_LINK_BW_NOT_CAP |
PCIE_CAP_DLL_ACTIVE_REP_CAP |
PCIE_CAP_L1_EXIT_LATENCY(4) |
PCIE_CAP_L0S_EXIT_LATENCY(4) |
PCIE_CAP_MAX_LINK_WIDTH(1) |
PCIE_CAP_MAX_LINK_SPEED(1));
writel(val, pcie->pci_dbi.start + PCIE_0_LINK_CAPABILITIES_REG);
writel(PCIE_CAP_CPL_TIMEOUT_DISABLE,
pcie->pci_dbi.start + PCIE_0_DEVICE_CONTROL2_DEVICE_STATUS2_REG);
writel(0x10110008, pcie->pci_dbi.start + PCIE_0_TYPE0_LINK_CONTROL_LINK_STATUS_REG_1);
if (pcie->is_gen3)
writel(PCIE_CAP_CURR_DEEMPHASIS | SPEED_GEN3,
pcie->pci_dbi.start + PCIE20_LNK_CONTROL2_LINK_STATUS2);
writel(LTSSM_EN, pcie->parf.start + PCIE_0_PCIE20_PARF_LTSSM);
if (pcie->version == PCIE_V2)
gpio_set_value(pcie->rst_gpio, GPIO_OUT_HIGH);
mdelay(200);
for (j = 0; j < 400; j++) {
val = readl(pcie->pci_dbi.start + PCIE_0_TYPE0_LINK_CONTROL_LINK_STATUS_REG_1);
if (val & (1 << 29)) {
printf("PCI Link Intialized\n");
pcie->linkup = 1;
break;
}
udelay(100);
}
if (pcie->is_gen3) {
writel((pcie->pci_dbi.start + 0x1000), pcie->parf.start + PARF_BLOCK_SLV_AXI_WR_BASE);
writel((pcie->pci_dbi.start + 0x100000), pcie->parf.start + PARF_BLOCK_SLV_AXI_WR_LIMIT);
writel((pcie->pci_dbi.start + 0x1000), pcie->parf.start + PARF_BLOCK_SLV_AXI_RD_BASE);
writel((pcie->pci_dbi.start + 0x100000), pcie->parf.start + PARF_BLOCK_SLV_AXI_RD_LIMIT);
writel((pcie->pci_dbi.start), pcie->parf.start + PARF_ECAM_BASE);
writel((pcie->pci_dbi.start + 0x1000), pcie->parf.start + PARF_ECAM_OFFSET_REMOVAL_BASE);
writel((pcie->pci_dbi.start + 0x200000), pcie->parf.start + PARF_ECAM_OFFSET_REMOVAL_LIMIT);
writel((pcie->pci_dbi.start + 0x108000), pcie->parf.start + PARF_BLOCK_SLV_AXI_WR_BASE_2);
writel((pcie->pci_dbi.start + 0x200000), pcie->parf.start + PARF_BLOCK_SLV_AXI_WR_LIMIT_2);
writel((pcie->pci_dbi.start + 0x108000), pcie->parf.start + PARF_BLOCK_SLV_AXI_RD_BASE_2);
writel((pcie->pci_dbi.start + 0x200000), pcie->parf.start + PARF_BLOCK_SLV_AXI_RD_LIMIT_2);
ipq_pcie_prog_outbound_atu(pcie);
} else {
ipq_pcie_config_controller(pcie);
}
}
void pcie_v0_linkup(struct ipq_pcie *pcie, int id)
{
int j;
uint32_t val;
/* assert PCIe PARF reset while powering the core */
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(6), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(2), 1);
board_pcie_clock_init(id);
/*
* de-assert PCIe PARF reset;
* wait 1us before accessing PARF registers
*/
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(2), 0);
udelay(1);
/* enable PCIe clocks and resets */
val = (readl(pcie->parf.start + PCIE20_PARF_PHY_CTRL) & ~BIT(0));
writel(val, pcie->parf.start + PCIE20_PARF_PHY_CTRL);
ipq_pcie_write_mask(pcie->parf.start + PCIE20_PARF_PHY_CTRL,
PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK,
PHY_CTRL_PHY_TX0_TERM_OFFSET(0));
/* PARF programming */
writel(PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) |
PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) |
PCIE20_PARF_PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22),
pcie->parf.start + PCIE20_PARF_PCS_DEEMPH);
writel(PCIE20_PARF_PCS_SWING_TX_SWING_FULL(0x78) |
PCIE20_PARF_PCS_SWING_TX_SWING_LOW(0x78),
pcie->parf.start + PCIE20_PARF_PCS_SWING);
writel((4<<24), pcie->parf.start + PCIE20_PARF_CONFIG_BITS);
ipq_pcie_write_mask(pcie->parf.start + PCIE20_PARF_PHY_REFCLK,
REF_USE_PAD, REF_SSP_EN);
/* enable access to PCIe slave port on system fabric */
if (id == 0) {
writel(BIT(4), PCIE_SFAB_AXI_S5_FCLK_CTL);
}
udelay(1);
/* de-assert PICe PHY, Core, POR and AXI clk domain resets */
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(5), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(4), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(3), 0);
ipq_pcie_parf_reset(pcie->pci_rst.start, BIT(0), 0);
/* enable link training */
ipq_pcie_write_mask( pcie->elbi.start + PCIE20_ELBI_SYS_CTRL, 0,
BIT(0));
udelay(500);
for (j = 0; j < 10; j++) {
val = readl(pcie->pci_dbi.start +
PCIE_0_TYPE0_LINK_CONTROL_LINK_STATUS_REG_1);
if (val & BIT(29)) {
printf("PCI%d Link Intialized\n", id);
pcie->linkup = 1;
break;
}
udelay(10000);
}
ipq_pcie_config_controller(pcie);
}
static int ipq_pcie_parse_dt(const void *fdt, int id,
struct ipq_pcie *pcie)
{
int err, rst_gpio, node;
char name[16];
snprintf(name, sizeof(name), "pci%d", id);
node = fdt_path_offset(fdt, name);
if (node < 0) {
printf("PCI%d is not defined in the device tree\n", id);
return node;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_dbi",
&pcie->pci_dbi);
if (err < 0) {
error("resource \"pads\" not found");
return err;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "parf",
&pcie->parf);
if (err < 0) {
error("resource \"afi\" not found");
return err;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "elbi",
&pcie->elbi);
if (err < 0) {
error("resource \"cs\" not found");
return err;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "axi_bars",
&pcie->axi_bars);
if (err < 0) {
error("resource \"cs\" not found");
return err;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "axi_conf",
&pcie->axi_conf);
if (err < 0) {
error("resource \"cs\" not found");
return err;
}
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_rst",
&pcie->pci_rst);
if (err < 0) {
error("resource \"cs\" not found");
return err;
}
pcie->is_gen3 = 0;
if(pcie->version == PCIE_V2) {
pcie->is_gen3 = fdtdec_get_int(fdt, node, "gen3", 0);
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_phy",
&pcie->pci_phy);
if (err < 0) {
uint32_t soc_ver_major, soc_ver_minor;
int ret;
ret = get_soc_version(&soc_ver_major, &soc_ver_minor);
if (!ret) {
if(soc_ver_major == 1) {
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_phy_gen2",
&pcie->pci_phy);
if (err < 0)
goto err;
pcie->is_gen3 = 0;
} else if(soc_ver_major == 2) {
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pci_phy_gen3",
&pcie->pci_phy);
if (err < 0)
goto err;
pcie->is_gen3 = 1;
}
} else {
goto err;
}
}
pcie->skip_phy_init =
fdtdec_get_int(fdt, node, "skip_phy_int", 0);
}
rst_gpio = fdtdec_get_int(fdt, node, "perst_gpio", 0);
if (rst_gpio <= 0) {
debug("PCI: Can't get perst_gpio\n");
return -1;
}
pcie->rst_gpio = rst_gpio;
if (pcie->is_gen3) {
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "dm_iatu",
&pcie->dm_iatu);
if (err < 0) {
error("resource \"dm_iatu\" not found");
return err;
}
}
return 0;
err:
error("resource \"phy\" not found");
return err;
}
void pci_controller_init_v1(struct ipq_pcie *pcie)
{
uint32_t val;
/* Assert cc_pcie20_mstr_axi_ares */
val = readl(pcie->pci_rst.start);
val |= PCIE_RST_CTRL_AXI_M_ARES;
writel(val, pcie->pci_rst.start);
/* Assert cc_pcie20_slv_axi_ares */
val = readl(pcie->pci_rst.start);
val |= PCIE_RST_CTRL_AXI_S_ARES;
writel(val, pcie->pci_rst.start);
/* Assert cc_pcie20_core_ares */
writel(PCIE_RST_CTRL_PIPE_ARES, pcie->pci_rst.start);
/* Assert cc_pcie20_core_sticky_area */
val = readl(pcie->pci_rst.start);
val |= PCIE_RST_CTRL_PIPE_STICKY_ARES;
writel(val, pcie->pci_rst.start);
/* Assert cc_pcie20_phy_ahb_ares */
val = readl(pcie->pci_rst.start);
val |= PCIE_RST_CTRL_PIPE_PHY_AHB_ARES;
writel(val, pcie->pci_rst.start);
/* Assert cc_pcie20_mstr_sticky_ares */
val = readl(pcie->pci_rst.start);
val |= PCIE_RST_CTRL_AXI_M_STICKY_ARES;
writel(val, pcie->pci_rst.start);
gpio_set_value(pcie->rst_gpio, GPIO_OUT_LOW);
/* Assert cc_pcie20_ahb_ares; */
val = readl(pcie->pci_rst.start);
val |= PCIE_RST_CTRL_AHB_ARES;
writel(val, pcie->pci_rst.start);
/* DeAssert cc_pcie20_ahb_ares */
val = readl(pcie->pci_rst.start);
val &= ~(PCIE_RST_CTRL_PIPE_PHY_AHB_ARES);
writel(val, pcie->pci_rst.start);
/* DeAssert cc_pcie20_pciephy_phy_ares*/
val = readl(pcie->pci_rst.start);
val &= ~(PCIE_RST_CTRL_PIPE_ARES);
writel(val, pcie->pci_rst.start);
/* DeAssert cc_pcie20_core_sticky_ares */
val = readl(pcie->pci_rst.start);
val &= ~(PCIE_RST_CTRL_PIPE_STICKY_ARES);
writel(val, pcie->pci_rst.start);
mdelay(5);
gpio_set_value(pcie->rst_gpio, GPIO_OUT_HIGH);
/* DeAssert cc_pcie20_mstr_axi_ares */
val = readl(pcie->pci_rst.start);
val &= ~(PCIE_RST_CTRL_AXI_M_ARES);
writel(val, pcie->pci_rst.start);
/* DeAssert cc_pcie20_mstr_axi_ares */
val = readl(pcie->pci_rst.start);
val &= ~(PCIE_RST_CTRL_AXI_M_STICKY_ARES);
writel(val, pcie->pci_rst.start);
/* DeAssert cc_pcie20_slv_axi_ares */
val = readl(pcie->pci_rst.start);
val &= ~(PCIE_RST_CTRL_AXI_S_ARES);
writel(val, pcie->pci_rst.start);
/* DeAssert cc_pcie20_phy_ahb_ares */
val = readl(pcie->pci_rst.start);
val &= ~(PCIE_RST_CTRL_AHB_ARES);
writel(val, pcie->pci_rst.start);
}
static const struct phy_regs pcie_phy_regs[] = {
#if !defined(CONFIG_IPQ6018)
{ PCIE_USB3_PCS_POWER_DOWN_CONTROL, 0x00000003 },
{ QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x00000018 },
{ QSERDES_COM_CLK_ENABLE1, 0x00000010 },
{ QSERDES_COM_BG_TRIM, 0x0000000f },
{ QSERDES_COM_LOCK_CMP_EN, 0x00000001 },
{ QSERDES_COM_VCO_TUNE_MAP, 0x00000000 },
{ QSERDES_COM_VCO_TUNE_TIMER1, 0x000000ff },
{ QSERDES_COM_VCO_TUNE_TIMER2, 0x0000001f },
{ QSERDES_COM_CMN_CONFIG, 0x00000006 },
{ PCIE_QSERDES_COM_PLL_IVCO, 0x0000000f },
{ QSERDES_COM_HSCLK_SEL, 0x00000000 },
{ PCIE_QSERDES_COM_SVS_MODE_CLK_SEL, 0x00000001 },
{ PCIE_QSERDES_COM_CORE_CLK_EN, 0x00000020 },
{ QSERDES_COM_CORECLK_DIV, 0x0000000a },
{ QSERDES_COM_RESETSM_CNTRL, 0x00000020 },
{ PCIE_QSERDES_COM_BG_TIMER, 0x00000009 },
{ PCIE_QSERDES_COM_SYSCLK_EN_SEL, 0x0000000a },
{ PCIE_QSERDES_COM_DEC_START_MODE0, 0x00000082 },
{ PCIE_QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00000003 },
{ PCIE_QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00000055 },
{ PCIE_QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00000055 },
{ QSERDES_COM_LOCK_CMP3_MODE0, 0x00000000 },
{ QSERDES_COM_LOCK_CMP2_MODE0, 0x0000000D },
{ PCIE_QSERDES_COM_LOCK_CMP1_MODE0, 0x00000D04 },
{ QSERDES_COM_CLK_SELECT, 0x00000033 },
{ PCIE_QSERDES_COM_SYS_CLK_CTRL, 0x00000002 },
{ QSERDES_COM_SYSCLK_BUF_ENABLE, 0x0000001f },
{ QSERDES_COM_CP_CTRL_MODE0, 0x0000000b },
{ QSERDES_COM_PLL_RCTRL_MODE0, 0x00000016 },
{ QSERDES_COM_PLL_CCTRL_MODE0, 0x00000028 },
{ QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00000000 },
{ QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x00000080 },
{ QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x00000001 },
{ QSERDES_COM_VCO_TUNE_CTRL, 0x0000000a },
{ QSERDES_COM_SSC_EN_CENTER, 0x00000001 },
{ PCIE_QSERDES_COM_SSC_PER1, 0x00000031 },
{ QSERDES_COM_SSC_PER2, 0x00000001 },
{ QSERDES_COM_SSC_ADJ_PER1, 0x00000002 },
{ QSERDES_COM_SSC_ADJ_PER2, 0x00000000 },
{ QSERDES_COM_SSC_STEP_SIZE1, 0x0000002f },
{ QSERDES_COM_SSC_STEP_SIZE2, 0x00000019 },
{ QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x00000045 },
{ QSERDES_TX_LANE_MODE, 0x00000006 },
{ QSERDES_TX_RES_CODE_LANE_OFFSET, 0x00000002 },
{ PCIE_QSERDES_TX_RCV_DETECT_LVL_2, 0x00000012 },
{ QSERDES_RX_SIGDET_ENABLES, 0x0000001c },
{ PCIE_QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x00000014 },
{ PCIE_QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x00000001 },
{ PCIE_QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3, 0x00000000 },
{ PCIE_QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4, 0x000000db },
{ QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x0000004b },
{ PCIE_QSERDES_RX_UCDR_SO_GAIN, 0x00000004 },
{ QSERDES_RX_UCDR_SO_GAIN_HALF, 0x00000004 },
{ QSERDES_COM_CLK_EP_DIV, 0x00000019 },
{ PCIE_USB3_PCS_ENDPOINT_REFCLK_DRIVE, 0x00000004 },
{ PCIE_USB3_PCS_OSC_DTCT_ACTIONS, 0x00000000 },
{ PCIE_USB3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x00000040 },
{ PCIE_USB3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB, 0x00000000 },
{ PCIE_USB3_PCS_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB, 0x00000040 },
{ PCIE_USB3_PCS_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB, 0x00000000 },
{ PCIE_USB3_PCS_LP_WAKEUP_DLY_TIME_AUXCLK, 0x00000040 },
{ PCIE_USB3_PCS_PLL_LOCK_CHK_DLY_TIME, 0x00000073 },
{ QSERDES_RX_SIGDET_CNTRL, 0x00000007 },
{ PCIE_USB3_PCS_RX_SIGDET_LVL, 0x00000099 },
{ PCIE_USB3_PCS_TXDEEMPH_M6DB_V0, 0x00000015 },
{ PCIE_USB3_PCS_TXDEEMPH_M3P5DB_V0, 0x0000000e },
{ PCIE_USB3_PCS_SW_RESET, 0x00000000 },
{ PCIE_USB3_PCS_START_CONTROL, 0x00000003 },
#endif
};
void pcie_phy_init(struct ipq_pcie *pcie)
{
int i;
const struct phy_regs *regs = pcie_phy_regs;
if (!phy_initialised) {
writel(0x10000000, pcie->parf.start + 0x358);
writel(0x10000000, pcie->parf.start + 0x8358);
mdelay(100);
phy_initialised = 1;
}
for (i = 0; i < ARRAY_SIZE(pcie_phy_regs); i++)
writel(regs[i].val, pcie->pci_phy.start + regs[i].reg_offset);
}
static inline void qca_pcie_write_reg(u32 base, u32 offset, u32 value)
{
writel(value, base + offset);
}
void pcie_phy_v2_init(struct ipq_pcie *pcie)
{
if (!pcie->skip_phy_init) {
const struct phy_regs *regs = pcie_phy_v2_init_seq_ipq;
int i, size = ARRAY_SIZE(pcie_phy_v2_init_seq_ipq);
for (i = 0; i < size; i++) {
if (regs[i].reg_offset == PCIE_PHY_DELAY_MS)
mdelay(regs[i].val);
else
writel(regs[i].val, pcie->pci_phy.start + regs[i].reg_offset);
}
mdelay(5);
}
return;
}
static int pci_ipq_ofdata_to_platdata(int id, struct ipq_pcie *pcie)
{
if (ipq_pcie_parse_dt(gd->fdt_blob, id, pcie))
return -EINVAL;
board_pci_init(id);
switch(pcie->version) {
case PCIE_V0:
pcie_v0_linkup(pcie, id);
break;
case PCIE_V1:
pci_controller_init_v1(pcie);
pcie_linkup(pcie);
break;
case PCIE_V2:
gpio_set_value(pcie->rst_gpio, GPIO_OUT_LOW);
if (pcie->is_gen3)
pcie_phy_v2_init(pcie);
else
pcie_phy_init(pcie);
pcie_linkup(pcie);
break;
default:
break;
}
return 0;
}
__weak void ipq_wifi_pci_power_enable(void)
{
return;
}
void pci_init_board (void)
{
struct ipq_pcie *pcie;
int i, bus = 0, ret;
const struct udevice_id *of_match = pcie_ver_ids;
pcie = malloc(sizeof(*pcie));
if (pcie == NULL) {
printf("PCI: Init failed. Could't allocate memory\n");
return;
}
while (of_match->compatible) {
ret = fdt_node_offset_by_compatible(gd->fdt_blob, 0,
of_match->compatible);
if (ret < 0) {
of_match++;
continue;
}
pcie->version = of_match->data;
break;
}
ipq_wifi_pci_power_enable();
for (i = 0; i < PCI_MAX_DEVICES; i++) {
pcie->linkup = 0;
pci_ipq_ofdata_to_platdata(i, pcie);
if (pcie->linkup) {
pci_hose[i].first_busno = bus;
pci_hose[i].last_busno = 0xff;
local_buses[0] = pci_hose[i].first_busno;
/* PCI memory space */
pci_set_region (pci_hose[i].regions + 0,
pcie->pci_dbi.start,
pcie->pci_dbi.start,
PCIE20_SIZE, PCI_REGION_MEM);
/* PCI device confgiuration space */
pci_set_region (pci_hose[i].regions + 1,
pcie->axi_conf.start,
pcie->axi_conf.start,
(PCIE_AXI_CONF_SIZE - 1), PCI_REGION_MEM);
pci_hose[i].region_count = 2;
pci_register_hose (&pci_hose[i]);
pci_set_ops (&pci_hose[i],
ipq_pcie_rd_conf_byte,
ipq_pcie_rd_conf_word,
ipq_pcie_rd_conf_dword,
ipq_pcie_wr_conf_byte,
ipq_pcie_wr_conf_word,
ipq_pcie_wr_conf_dword);
pci_hose[i].last_busno = pci_hose[i].first_busno + 1;
bus = pci_hose[i].last_busno + 1;
}
}
}