diff options
Diffstat (limited to 'drivers/pci/controller/dwc/pcie-tegra194.c')
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-tegra194.c | 140 | 
1 files changed, 38 insertions, 102 deletions
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 70498689d0c0..f920e7efe118 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -183,19 +183,7 @@  #define EVENT_COUNTER_GROUP_SEL_SHIFT	24  #define EVENT_COUNTER_GROUP_5		0x5 -#define PORT_LOGIC_ACK_F_ASPM_CTRL			0x70C -#define ENTER_ASPM					BIT(30) -#define L0S_ENTRANCE_LAT_SHIFT				24 -#define L0S_ENTRANCE_LAT_MASK				GENMASK(26, 24) -#define L1_ENTRANCE_LAT_SHIFT				27 -#define L1_ENTRANCE_LAT_MASK				GENMASK(29, 27) -#define N_FTS_SHIFT					8 -#define N_FTS_MASK					GENMASK(7, 0)  #define N_FTS_VAL					52 - -#define PORT_LOGIC_GEN2_CTRL				0x80C -#define PORT_LOGIC_GEN2_CTRL_DIRECT_SPEED_CHANGE	BIT(17) -#define FTS_MASK					GENMASK(7, 0)  #define FTS_VAL						52  #define PORT_LOGIC_MSI_CTRL_INT_0_EN		0x828 @@ -296,7 +284,6 @@ struct tegra_pcie_dw {  	u8 init_link_width;  	u32 msi_ctrl_int;  	u32 num_lanes; -	u32 max_speed;  	u32 cid;  	u32 cfg_link_cap_l1sub;  	u32 pcie_cap_base; @@ -401,9 +388,9 @@ static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)  			val |= APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N;  			appl_writel(pcie, val, APPL_CAR_RESET_OVRD); -			val = dw_pcie_readl_dbi(pci, PORT_LOGIC_GEN2_CTRL); -			val |= PORT_LOGIC_GEN2_CTRL_DIRECT_SPEED_CHANGE; -			dw_pcie_writel_dbi(pci, PORT_LOGIC_GEN2_CTRL, val); +			val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); +			val |= PORT_LOGIC_SPEED_CHANGE; +			dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);  		}  	} @@ -568,42 +555,44 @@ static irqreturn_t tegra_pcie_ep_hard_irq(int irq, void *arg)  	return IRQ_HANDLED;  } -static int tegra_pcie_dw_rd_own_conf(struct pcie_port *pp, int where, int size, -				     u32 *val) +static int tegra_pcie_dw_rd_own_conf(struct pci_bus *bus, u32 devfn, int where, +				     int size, u32 *val)  { -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -  	/*  	 * This is an endpoint mode specific register happen to appear even  	 * when controller is operating in root port mode and system hangs  	 * when it is accessed with link being in ASPM-L1 state.  	 * So skip accessing it altogether  	 */ -	if (where == PORT_LOGIC_MSIX_DOORBELL) { +	if (!PCI_SLOT(devfn) && where == PORT_LOGIC_MSIX_DOORBELL) {  		*val = 0x00000000;  		return PCIBIOS_SUCCESSFUL;  	} -	return dw_pcie_read(pci->dbi_base + where, size, val); +	return pci_generic_config_read(bus, devfn, where, size, val);  } -static int tegra_pcie_dw_wr_own_conf(struct pcie_port *pp, int where, int size, -				     u32 val) +static int tegra_pcie_dw_wr_own_conf(struct pci_bus *bus, u32 devfn, int where, +				     int size, u32 val)  { -	struct dw_pcie *pci = to_dw_pcie_from_pp(pp); -  	/*  	 * This is an endpoint mode specific register happen to appear even  	 * when controller is operating in root port mode and system hangs  	 * when it is accessed with link being in ASPM-L1 state.  	 * So skip accessing it altogether  	 */ -	if (where == PORT_LOGIC_MSIX_DOORBELL) +	if (!PCI_SLOT(devfn) && where == PORT_LOGIC_MSIX_DOORBELL)  		return PCIBIOS_SUCCESSFUL; -	return dw_pcie_write(pci->dbi_base + where, size, val); +	return pci_generic_config_write(bus, devfn, where, size, val);  } +static struct pci_ops tegra_pci_ops = { +	.map_bus = dw_pcie_own_conf_map_bus, +	.read = tegra_pcie_dw_rd_own_conf, +	.write = tegra_pcie_dw_wr_own_conf, +}; +  #if defined(CONFIG_PCIEASPM)  static void disable_aspm_l11(struct tegra_pcie_dw *pcie)  { @@ -692,30 +681,23 @@ static void init_host_aspm(struct tegra_pcie_dw *pcie)  	dw_pcie_writel_dbi(pci, pcie->cfg_link_cap_l1sub, val);  	/* Program L0s and L1 entrance latencies */ -	val = dw_pcie_readl_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL); -	val &= ~L0S_ENTRANCE_LAT_MASK; -	val |= (pcie->aspm_l0s_enter_lat << L0S_ENTRANCE_LAT_SHIFT); -	val |= ENTER_ASPM; -	dw_pcie_writel_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL, val); +	val = dw_pcie_readl_dbi(pci, PCIE_PORT_AFR); +	val &= ~PORT_AFR_L0S_ENTRANCE_LAT_MASK; +	val |= (pcie->aspm_l0s_enter_lat << PORT_AFR_L0S_ENTRANCE_LAT_SHIFT); +	val |= PORT_AFR_ENTER_ASPM; +	dw_pcie_writel_dbi(pci, PCIE_PORT_AFR, val);  } -static int init_debugfs(struct tegra_pcie_dw *pcie) +static void init_debugfs(struct tegra_pcie_dw *pcie)  { -	struct dentry *d; - -	d = debugfs_create_devm_seqfile(pcie->dev, "aspm_state_cnt", -					pcie->debugfs, aspm_state_cnt); -	if (IS_ERR_OR_NULL(d)) -		dev_err(pcie->dev, -			"Failed to create debugfs file \"aspm_state_cnt\"\n"); - -	return 0; +	debugfs_create_devm_seqfile(pcie->dev, "aspm_state_cnt", pcie->debugfs, +				    aspm_state_cnt);  }  #else  static inline void disable_aspm_l12(struct tegra_pcie_dw *pcie) { return; }  static inline void disable_aspm_l11(struct tegra_pcie_dw *pcie) { return; }  static inline void init_host_aspm(struct tegra_pcie_dw *pcie) { return; } -static inline int init_debugfs(struct tegra_pcie_dw *pcie) { return 0; } +static inline void init_debugfs(struct tegra_pcie_dw *pcie) { return; }  #endif  static void tegra_pcie_enable_system_interrupts(struct pcie_port *pp) @@ -827,26 +809,24 @@ static void config_gen3_gen4_eq_presets(struct tegra_pcie_dw *pcie)  	/* Program init preset */  	for (i = 0; i < pcie->num_lanes; i++) { -		dw_pcie_read(pci->dbi_base + CAP_SPCIE_CAP_OFF -				 + (i * 2), 2, &val); +		val = dw_pcie_readw_dbi(pci, CAP_SPCIE_CAP_OFF + (i * 2));  		val &= ~CAP_SPCIE_CAP_OFF_DSP_TX_PRESET0_MASK;  		val |= GEN3_GEN4_EQ_PRESET_INIT;  		val &= ~CAP_SPCIE_CAP_OFF_USP_TX_PRESET0_MASK;  		val |= (GEN3_GEN4_EQ_PRESET_INIT <<  			   CAP_SPCIE_CAP_OFF_USP_TX_PRESET0_SHIFT); -		dw_pcie_write(pci->dbi_base + CAP_SPCIE_CAP_OFF -				 + (i * 2), 2, val); +		dw_pcie_writew_dbi(pci, CAP_SPCIE_CAP_OFF + (i * 2), val);  		offset = dw_pcie_find_ext_capability(pci,  						     PCI_EXT_CAP_ID_PL_16GT) +  				PCI_PL_16GT_LE_CTRL; -		dw_pcie_read(pci->dbi_base + offset + i, 1, &val); +		val = dw_pcie_readb_dbi(pci, offset + i);  		val &= ~PCI_PL_16GT_LE_CTRL_DSP_TX_PRESET_MASK;  		val |= GEN3_GEN4_EQ_PRESET_INIT;  		val &= ~PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_MASK;  		val |= (GEN3_GEN4_EQ_PRESET_INIT <<  			PCI_PL_16GT_LE_CTRL_USP_TX_PRESET_SHIFT); -		dw_pcie_write(pci->dbi_base + offset + i, 1, val); +		dw_pcie_writeb_dbi(pci, offset + i, val);  	}  	val = dw_pcie_readl_dbi(pci, GEN3_RELATED_OFF); @@ -892,17 +872,6 @@ static void tegra_pcie_prepare_host(struct pcie_port *pp)  	dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0); -	/* Configure FTS */ -	val = dw_pcie_readl_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL); -	val &= ~(N_FTS_MASK << N_FTS_SHIFT); -	val |= N_FTS_VAL << N_FTS_SHIFT; -	dw_pcie_writel_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL, val); - -	val = dw_pcie_readl_dbi(pci, PORT_LOGIC_GEN2_CTRL); -	val &= ~FTS_MASK; -	val |= FTS_VAL; -	dw_pcie_writel_dbi(pci, PORT_LOGIC_GEN2_CTRL, val); -  	/* Enable as 0xFFFF0001 response for CRS */  	val = dw_pcie_readl_dbi(pci, PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT);  	val &= ~(AMBA_ERROR_RESPONSE_CRS_MASK << AMBA_ERROR_RESPONSE_CRS_SHIFT); @@ -910,16 +879,6 @@ static void tegra_pcie_prepare_host(struct pcie_port *pp)  		AMBA_ERROR_RESPONSE_CRS_SHIFT);  	dw_pcie_writel_dbi(pci, PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT, val); -	/* Configure Max Speed from DT */ -	if (pcie->max_speed && pcie->max_speed != -EINVAL) { -		val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + -					PCI_EXP_LNKCAP); -		val &= ~PCI_EXP_LNKCAP_SLS; -		val |= pcie->max_speed; -		dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, -				   val); -	} -  	/* Configure Max lane width from DT */  	val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP);  	val &= ~PCI_EXP_LNKCAP_MLW; @@ -970,6 +929,8 @@ static int tegra_pcie_dw_host_init(struct pcie_port *pp)  	struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);  	u32 val, tmp, offset, speed; +	pp->bridge->ops = &tegra_pci_ops; +  	tegra_pcie_prepare_host(pp);  	if (dw_pcie_wait_for_link(pci)) { @@ -1057,8 +1018,6 @@ static const struct dw_pcie_ops tegra_dw_pcie_ops = {  };  static struct dw_pcie_host_ops tegra_pcie_dw_host_ops = { -	.rd_own_conf = tegra_pcie_dw_rd_own_conf, -	.wr_own_conf = tegra_pcie_dw_wr_own_conf,  	.host_init = tegra_pcie_dw_host_init,  	.set_num_vectors = tegra_pcie_set_msi_vec_num,  }; @@ -1129,8 +1088,6 @@ static int tegra_pcie_dw_parse_dt(struct tegra_pcie_dw *pcie)  		return ret;  	} -	pcie->max_speed = of_pci_get_max_link_speed(np); -  	ret = of_property_read_u32_index(np, "nvidia,bpmp", 1, &pcie->cid);  	if (ret) {  		dev_err(pcie->dev, "Failed to read Controller-ID: %d\n", ret); @@ -1262,9 +1219,9 @@ static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)  	 * 5.2 Link State Power Management (Page #428).  	 */ -	list_for_each_entry(child, &pp->root_bus->children, node) { +	list_for_each_entry(child, &pp->bridge->bus->children, node) {  		/* Bring downstream devices to D0 if they are not already in */ -		if (child->parent == pp->root_bus) { +		if (child->parent == pp->bridge->bus) {  			root_bus = child;  			break;  		} @@ -1641,10 +1598,7 @@ static int tegra_pcie_config_rp(struct tegra_pcie_dw *pcie)  	}  	pcie->debugfs = debugfs_create_dir(name, NULL); -	if (!pcie->debugfs) -		dev_err(dev, "Failed to create debugfs\n"); -	else -		init_debugfs(pcie); +	init_debugfs(pcie);  	return ret; @@ -1817,27 +1771,6 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie)  	val &= ~GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL;  	dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val); -	/* Configure N_FTS & FTS */ -	val = dw_pcie_readl_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL); -	val &= ~(N_FTS_MASK << N_FTS_SHIFT); -	val |= N_FTS_VAL << N_FTS_SHIFT; -	dw_pcie_writel_dbi(pci, PORT_LOGIC_ACK_F_ASPM_CTRL, val); - -	val = dw_pcie_readl_dbi(pci, PORT_LOGIC_GEN2_CTRL); -	val &= ~FTS_MASK; -	val |= FTS_VAL; -	dw_pcie_writel_dbi(pci, PORT_LOGIC_GEN2_CTRL, val); - -	/* Configure Max Speed from DT */ -	if (pcie->max_speed && pcie->max_speed != -EINVAL) { -		val = dw_pcie_readl_dbi(pci, pcie->pcie_cap_base + -					PCI_EXP_LNKCAP); -		val &= ~PCI_EXP_LNKCAP_SLS; -		val |= pcie->max_speed; -		dw_pcie_writel_dbi(pci, pcie->pcie_cap_base + PCI_EXP_LNKCAP, -				   val); -	} -  	pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci,  						      PCI_CAP_ID_EXP);  	clk_set_rate(pcie->core_clk, GEN4_CORE_CLK_FREQ); @@ -2066,6 +1999,9 @@ static int tegra_pcie_dw_probe(struct platform_device *pdev)  	pci = &pcie->pci;  	pci->dev = &pdev->dev;  	pci->ops = &tegra_dw_pcie_ops; +	pci->n_fts[0] = N_FTS_VAL; +	pci->n_fts[1] = FTS_VAL; +  	pp = &pci->pp;  	pcie->dev = &pdev->dev;  	pcie->mode = (enum dw_pcie_device_mode)data->mode;  | 
