Compare commits

..

21 Commits

Author SHA1 Message Date
2c90f5e347 clk: tegra210b01: add plle 2025-11-08 03:16:49 +00:00
Rohith Seelaboyina
6aba9ba3f1 phy: tegra: xusb: Add T210B01 support
- Add T210b01 soc data for xusb_padctl driver
- Add uphy_management clock support
- Add PLL defaults programming

Bug 200340262

Change-Id: Ie5a685a49542221142a0a8e31e5a9ebb729a3035
Signed-off-by: Rohith Seelaboyina <rseelaboyina@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1584421
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Rakesh Babu Bodla <rbodla@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
2025-11-07 05:48:48 +00:00
a78a344fd0 [DEBUG] add stupid prints to xusb 2025-11-07 05:46:51 +00:00
c1ee39366e pci: tegra: fix link_up invocation 2025-11-06 04:14:04 +00:00
Vidya Sagar
3aa523ae1d PCI: tegra: add PCI_REASSIGN_ALL_BUS flag
adds PCI_REASSIGN_ALL_BUS pci flag so as to enable
re-assigning bus numbers (if there is any bridge device added
recently) during rescan.

Bug 200192107

Change-Id: Iffc02827a75dcb82f5e02b69e96e65b38a0b7cd6
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Reviewed-on: http://git-master/r/1144609
(cherry picked from commit 26464cda2eff345548e3271f26b00ddcd79d9264)
Reviewed-on: http://git-master/r/1176833
(cherry picked from commit bf21f6959bbecc70b4dce07329e0deea32b41b67)
Reviewed-on: http://git-master/r/1141937
(cherry picked from commit 284d2e97ce311771808d8dbd75c861a95c16d031)
Reviewed-on: http://git-master/r/1210983
(cherry picked from commit ef83e7563eb0ce4dad493abba2c92d20a67f41ac)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-4.14/+/2371135
(cherry picked from commit a43acb68398f7fd6208988684698b49962b3c6f9)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407883
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:01 +00:00
Manikanta Maddireddy
a929bd5691 PCI: tegra: Add DT support to disable CLKREQ# control on PLLE
Sometimes CLKREQ# pin connection might be missing on a platform. Add DT
support to disable CLKREQ# control on PLLE in driver. Platform device tree
can use this DT property to disable CLKREQ# control on PLLE. In kernel-5.9,
upstream device tree property "supports-clkreq" is used in place of
kernel-4.14 custom device tree property "nvidia,disable-clock-request".

bug 200420606

Change-Id: I6ac44bd99d090e158fa10e5e9b62d63e52563c8c
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786551
(cherry picked from commit 6870a94b48a4bbbe9df607802c7f7c1f61806b7b)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407880
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:01 +00:00
Manikanta Maddireddy
c40af5a19a PCI: tegra: aspm DT support
Squashed below k414 commits into single change.

PCI: tegra: Add DT support to disable per state aspm

Kernel config option provides choice to disable L0s & L1 or L1 substates
combinedly. Add DT support to disable each aspm state individually.

bug 200420606

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786548
(cherry picked from commit f3c5bcdc3ab8cadd3d24ea4d1a8e0aba7beea751)

PCI: tegra: Fix ASPM DT property parsing code

DT property "nvidia,disable-aspm-states" is part of PCIe port node.
Use correct of_node pointer to parse this property.

bug 200434876

Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-4.14/+/2383766
(cherry picked from commit 8dd957e9ecf29da4ba94471e3d74b2aef98a0643)

Change-Id: Iee1f573a103c0045d4f8f6606db13b47575b8cb9
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2408709
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: Bitan Biswas <bbiswas@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
2025-11-06 04:14:01 +00:00
Manikanta Maddireddy
51ab98c25e PCI: tegra: Bypass CLKREQ# control over PLLE
When PCIe link is L2 CLKREQ# will be floating and this might interfere
with PLL power down. Bypass CLKREQ# control over PLLE when link is in L2.

bug 1356695
bug 200420606

Change-Id: I361db03df5f9a1a8d38bd9fb816d17fc4c64a9fc
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786565
(cherry picked from commit 69e79f42f65df70b0c76e62200aca40ed3972e3b)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407877
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:01 +00:00
Manikanta Maddireddy
5f8f949eb9 PCI: tegra: Fix incorrect CLKREQ and PLLE programming
CLKREQ_EN bit should be cleared to control REFCLK through CLKREQ# pin.
Enable PCIE2PLLE bit to control PLLE through clock clamp signal.
Program PADS2PLLE and PCIE2PLLE bits only if Tegra PCIe supports L1SS.

bug 200420606

Change-Id: I04cacf64fce8eed0f17bb632457ffcc9f052819d
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786550
(cherry picked from commit e71a64e47225b848c9b8a1d33e8c80a7bdb9d3cc)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407876
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:01 +00:00
Vidya Sagar
93c3ba9fdf PCI: tegra: Fixups to avoid unnecessary wakeup from ASPM-L1.2
sets CLKREQ asserted delay to a higher value to avoid
unnecessary wake up from L1.2.ENTRY state for Tegra210

bug 200420606

Change-Id: Iec2564bfd434897f0e50cd3f0ad6bc76aacc12e8
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786545
(cherry picked from commit d7785c1e6c98e33a85ba9487d3be6ab7e518a285)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407875
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:01 +00:00
Vidya Sagar
348ae91e1a PCI: tegra: Apply sw fixups to support ASPM-L1 Sub-States
Programs Port Common_Mode_Restore_Time and Port T_POWER_ON values
(from the L1 PM Substates Capabilities Register, PCIe 4.0r0.9, sec 7.8.3.2)
to get them reflected in ASPM-L1 Sub-States capability registers.
Also adjusts internal counter values according to 19.2 MHz clk_m value.

bug 200420606

Change-Id: Ie139255e522e4476fdfbe64aa6250d0293b7ae89
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786544
(cherry picked from commit 9ac6211e1a99583618945c86748214ccc33de463)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407874
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:01 +00:00
Manikanta Maddireddy
8af3eba1f7 PCI: tegra: Configure L1 power save parameters
Programmed bits of register RP_VEND_XP_PAD_PWRDN are defined as follows,

L1(bit[0]):
 This bit, when set, causes the analog pads to power down when we're in L1.
 When clear, the LTSSM still enters L1 as required, but the analog pads
 are left at full power.
DYNAMIC(bit[1]):
 This bit, when set, causes unused analog pads to power down after
 "Dynamic Link Width Re-negotiation" takes place.  When clear, all analog
 pads remain powered up, even those that are no longer being used after
 "Dynamic Link Width Re-negotiation" down-sizes the link.
DISABLED(bit[2]):
 This bit, when set, causes the analog pads to power down when we're in the
 DISABLED_DOWN state. When clear, the LTSSM still enters DISBLED_DOWN as
 required, but the analog pads are left at full power.
L1_CLKREQ(bit[15]):
 This bit, when set, causes the analog pads to power down to
 SLEEP_MODE_L1_REQ when clkreq signal is deasserted in L1.
 (NV_PROJ__PCIE2_RP_VEND_XP_PAD_PWRDN_L1 needs to be set in order to power
 down pad in L1.)  Also, when clkreq is asserted in L1, ltssm will exit L1
 immediately. When clear, the clkreq signal doesn't affect the power
 management.
SLEEP_MODE_L1(bits[4:3]):
 It defines the 2-bit sleep-mode coding in the pad when LTSSM is in the L1
 state or DISABLED state.
SLEEP_MODE_DYNAMIC(bits[6:5]):
 It defines the 2-bit sleep-mode coding in the pad when the lane shut down
 due to dynamic link downsizing.
SLEEP_MODE_L1_CLKREQ(bits[17:16]):
 It defines the 2-bit sleep-mode coding when clkreq is deasserted in L1.
The 2-bit sleep-mode encoding is defined as:
 - L0 (0x0): Normal power-up mode
 - L1 (0x1): L1 power-down mode; Tx common mode on, Rx e-idle detect on
 - L1P (0x2): L1 power-down mode; Tx common mode off, Rx e-idle detect on
 - L1PP (0x3): L1 power-down mode; Tx common mode off, Rx e-idle detect off

bug 200420606

Change-Id: I74aa9c1460d882084b1ecccb9c0168dd667c9d84
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786547
(cherry picked from commit d7899c186f89ecf503812003b743adbae07c4cbe)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407873
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:01 +00:00
Vidya Sagar
f83cd25494 PCI: tegra: Advertise ASPM L1 PM support
Enables advertisement of ASPM-L1 support in capability
registers of applicable Tegra chips

bug 200420606

Change-Id: Ie5dbb3a262ca1c0c9cc59c91a8710bf6bd6a6900
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786543
(cherry picked from commit 7eedf2a02489b529374bc1ca95234be1f02b9119)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407872
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:14:00 +00:00
Manikanta Maddireddy
e9c1ca6fac PCI: tegra: Convert WRAP transactions to increment burst
AFI module doesn't support WRAP transactions in Tegra. WRAP instructions
from CPU targeting PCIe BAR memory can cause data corruption. This can
happen if PCIe memory is marked as normal cacheable or GRE device.
Program mselect register to convert WRAP transactions to increment burst
for slave PCIe.

bug 200353330
bug 200420606

Change-Id: I867da85eb63332708bc294238e30ad99a71f345d
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786561
(cherry picked from commit b345cfae7b7633a3a52e0f2a659baf44feee1466)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407869
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:13:45 +00:00
Manikanta Maddireddy
ddc4aa6226 PCI: tegra: Access endpoint config only if PCIe link is up
Few endpoints like Wi-Fi supports power on/off and to leverage that
root port must support hot-plug and hot-unplug. Tegra PCIe doesn't
support hot-plug and hot-unplug, however it supports endpoint power
on/off feature as follows,
 - Power off sequence:
   - Transition of PCIe link to L2
   - Power off endpoint
   - Leave root port in power up state with the link in L2
 - Power on sequence:
   - Power on endpoint
   - Apply hot reset to get PCIe link up

PCIe client driver stops accessing PCIe endpoint config and BAR registers
after endpoint is powered off. However, software applications like x11
server or lspci can access endpoint config registers in which case
host controller raises "response decoding" errors. To avoid this scenario,
add PCIe link up check in config read and write callback functions before
accessing endpoint config registers.

Change-Id: I47653cb0b580c2b764cb0ad9c42deeb9c8823c58
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-4.14/+/2371131
(cherry picked from commit be664bfdd901138222a8ea8bb17160a2fa9de04a)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407866
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 04:13:45 +00:00
Manikanta Maddireddy
0b7877f108 PCI: tegra: Add PCIe support for tegra210b01 chip
bug 200420606

Change-Id: I943e4ad90915332fbecc3ed9cb368d3f549925a6
Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1786562
(cherry picked from commit ef7328abda206df3b00364eeaeecc20103896326)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.9/+/2407885
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
2025-11-06 02:57:51 +00:00
355f66d016 t210b01: sdmmc pinmuxing 2025-11-05 05:57:02 +00:00
27390404e4 emc update 2025-11-05 05:57:02 +00:00
b6d2c6e4c0 [WAR] core: don't loop 2025-11-05 05:57:02 +00:00
fbbdd32f90 [DEBUG] emc logging 2025-11-05 05:57:02 +00:00
aef62ecd2f t210b01: disable actmon and interconnects
Signed-off-by: Thomas Makin <halorocker89@gmail.com>
2025-11-05 05:57:02 +00:00
7 changed files with 629 additions and 97 deletions

View File

@@ -33,20 +33,28 @@
/delete-property/ pinctrl-names;
};
emc: external-memory-controller@7001b000 {
compatible = "nvidia,tegra210b01-emc";
mc: memory-controller@70019000 {
emc: external-memory-controller@7001b000 {
compatible = "nvidia,tegra210b01-emc";
reg = <0x0 0x7001b000 0x0 0x1000>,
<0x0 0x7001e000 0x0 0x1000>,
<0x0 0x7001f000 0x0 0x1000>;
clocks = <&bpmp 0>;
clock-names = "emc";
interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&bpmp 0>;
clock-names = "emc";
#interconnect-cells = <0>;
#cooling-cells = <2>;
nvidia,bpmp = <&bpmp>;
/delete-property/ operating-points-v2;
nvidia,bpmp = <&bpmp>;
};
};
/delete-node/ external-memory-controller@7001b000;
actmon@6000c800 {
// clocks = <&tegra_car TEGRA210_CLK_ACTMON>,
// <&bpmp 0>;
status = "disabled";
clocks = <&tegra_car TEGRA210_CLK_ACTMON>,
<&bpmp 0>;
};
mmc@700b0600 {
@@ -90,10 +98,6 @@
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
};
pcie@1003000 {
compatible = "nvidia,tegra210b01-pcie";
};
/* Tegra210B01 has MBIST patched and is missing VI unit */
pmc@7000e400 {
compatible = "nvidia,tegra210b01-pmc";
@@ -103,7 +107,7 @@
};
};
bpmp@70016000 {
bpmp: bpmp@70016000 {
status = "okay";
#clock-cells = <1>;
@@ -119,35 +123,31 @@
pinmux@700008d4 {
status = "okay";
sdmmc1_drv_code_1_8V: sdmmc1_drv_code {
sdmmc1_1v8_drv: pinmux-sdmmc1-1v8-drv {
sdmmc1 {
nvidia,pins = "drive_sdmmc1";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
nvidia,pull-down-strength = <0x8>;
nvidia,pull-up-strength = <0x8>;
};
};
sdmmc1_default_drv_code_3_3V: sdmmc1_default_drv_code {
sdmmc1_3v3_drv: pinmux-sdmmc1-3v3-drv {
sdmmc1 {
nvidia,pins = "drive_sdmmc1";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
nvidia,pull-down-strength = <0x8>;
nvidia,pull-up-strength = <0x8>;
};
};
sdmmc3_drv_code_1_8V: sdmmc3_drv_code {
sdmmc3_1v8_drv: pinmux-sdmmc3-1v8-drv {
sdmmc3 {
nvidia,pins = "drive_sdmmc3";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
nvidia,pull-down-strength = <0x8>;
nvidia,pull-up-strength = <0x8>;
};
};
sdmmc3_default_drv_code_3_3V: sdmmc3_default_drv_code {
sdmmc3_3v3_drv: pinmux-sdmmc3-3v3-drv {
sdmmc3 {
nvidia,pins = "drive_sdmmc3";
nvidia,pull-down-strength = <8>;
nvidia,pull-up-strength = <8>;
nvidia,pull-down-strength = <0x8>;
nvidia,pull-up-strength = <0x8>;
};
};
};

View File

@@ -2173,6 +2173,15 @@ static int fw_devlink_create_devlink(struct device *con,
goto out;
}
/*
* SYNC_STATE_ONLY links are useless once a consumer device has probed.
* So, only create it if the consumer hasn't probed yet.
*/
if (flags & DL_FLAG_SYNC_STATE_ONLY &&
con->links.status != DL_DEV_NO_DRIVER &&
con->links.status != DL_DEV_PROBING)
goto out;
if (con != sup_dev && !device_link_add(con, sup_dev, flags)) {
dev_err(con, "Failed to create device link (0x%x) with %s\n",
flags, dev_name(sup_dev));

View File

@@ -503,6 +503,72 @@ static unsigned long tegra210_input_freq[] = {
#define PLLE_SS_COEFFICIENTS_VAL \
(PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL)
bool tegra210b01_plle_hw_sequence_is_enabled(void)
{
u32 value;
value = readl_relaxed(clk_base + PLLE_AUX);
if (value & PLLE_AUX_SEQ_ENABLE)
return true;
return false;
}
EXPORT_SYMBOL_GPL(tegra210b01_plle_hw_sequence_is_enabled);
int tegra210b01_plle_hw_sequence_start(void)
{
u32 value;
if (tegra210b01_plle_hw_sequence_is_enabled())
return 0;
/* skip if PLLE is not enabled yet */
value = readl_relaxed(clk_base + PLLE_MISC0);
if (!(value & PLLE_MISC_LOCK))
return -EIO;
value &= ~PLLE_MISC_IDDQ_SW_CTRL;
writel_relaxed(value, clk_base + PLLE_MISC0);
value = readl_relaxed(clk_base + PLLE_AUX);
value |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SS_SEQ_INCLUDE);
value &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL);
writel_relaxed(value, clk_base + PLLE_AUX);
fence_udelay(1, clk_base);
value |= PLLE_AUX_SEQ_ENABLE;
writel_relaxed(value, clk_base + PLLE_AUX);
fence_udelay(1, clk_base);
return 0;
}
EXPORT_SYMBOL_GPL(tegra210b01_plle_hw_sequence_start);
void tegra210b01_xusb_pll_hw_control_enable(void)
{
u32 val;
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL |
XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL);
val |= XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET |
XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ;
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
}
EXPORT_SYMBOL_GPL(tegra210b01_xusb_pll_hw_control_enable);
void tegra210b01_xusb_pll_hw_sequence_start(void)
{
u32 val;
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
val |= XUSBIO_PLL_CFG0_SEQ_ENABLE;
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
}
EXPORT_SYMBOL_GPL(tegra210b01_xusb_pll_hw_sequence_start);
static inline void _pll_misc_chk_default(void __iomem *base,
struct tegra_clk_pll_params *params,
u8 misc_num, u32 default_val, u32 mask)

View File

@@ -395,8 +395,12 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc)
emc->provider.xlate = tegra_emc_of_icc_xlate;
emc->provider.get_bw = tegra_emc_icc_get_init_bw;
printk("186-emc: init icc provider\n");
icc_provider_init(&emc->provider);
printk("186-emc: create icc node\n");
/* create External Memory Controller node */
node = icc_node_create(TEGRA_ICC_EMC);
if (IS_ERR(node)) {
@@ -404,14 +408,20 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc)
goto err_msg;
}
printk("186-emc: add icc node\n");
node->name = "External Memory Controller";
icc_node_add(node, &emc->provider);
printk("186-emc: link emc icc to dram\n");
/* link External Memory Controller to External Memory (DRAM) */
err = icc_link_create(node, TEGRA_ICC_EMEM);
if (err)
goto remove_nodes;
printk("186-emc: create dram node\n");
/* create External Memory node */
node = icc_node_create(TEGRA_ICC_EMEM);
if (IS_ERR(node)) {
@@ -419,16 +429,23 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc)
goto remove_nodes;
}
printk("186-emc: add dram node\n");
node->name = "External Memory (DRAM)";
icc_node_add(node, &emc->provider);
printk("186-emc: register icc provider\n");
err = icc_provider_register(&emc->provider);
if (err)
goto remove_nodes;
printk("186-emc: icc init success\n");
return 0;
remove_nodes:
printk("186-emc: removing icc nodes\n");
icc_nodes_remove(&emc->provider);
err_msg:
dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
@@ -460,16 +477,24 @@ static int tegra186_emc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, emc);
emc->dev = &pdev->dev;
printk("186-emc: emc_rate_requests_init\n");
tegra_emc_rate_requests_init(emc);
printk("186-emc: mrq supported?\n");
if (tegra_bpmp_mrq_is_supported(emc->bpmp, MRQ_EMC_DVFS_LATENCY)) {
printk("186-emc: mrq supported\n");
err = tegra186_emc_get_emc_dvfs_latency(emc);
if (err)
goto put_bpmp;
printk("186-emc: got emc dvfs latency\n");
}
if (mc && mc->soc->icc_ops) {
printk("186-emc: icc ops -> mrq supported?\n");
if (tegra_bpmp_mrq_is_supported(emc->bpmp, MRQ_BWMGR_INT)) {
printk("186-emc: mrq supported, configuring mc\n");
mc->bwmgr_mrq_supported = true;
/*
@@ -481,6 +506,8 @@ static int tegra186_emc_probe(struct platform_device *pdev)
barrier();
}
printk("186-emc: init emc interconnect\n");
/*
* Initialize the ICC even if BPMP-FW doesn't support 'MRQ_BWMGR_INT'.
* Use the flag 'mc->bwmgr_mrq_supported' within MC driver and return
@@ -497,6 +524,7 @@ static int tegra186_emc_probe(struct platform_device *pdev)
return 0;
put_bpmp:
printk("186-emc: FAILED\n");
tegra_bpmp_put(emc->bpmp);
return err;
}

View File

@@ -6,7 +6,7 @@
* Author: Mike Rapoport <mike@compulab.co.il>
*
* Based on NVIDIA PCIe driver
* Copyright (c) 2008-2009, NVIDIA Corporation.
* Copyright (c) 2008-2020, NVIDIA Corporation.
*
* Bits taken from arch/arm/mach-dove/pcie.c
*
@@ -163,10 +163,64 @@
#define AFI_PLLE_CONTROL 0x160
#define AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL (1 << 9)
#define AFI_PLLE_CONTROL_BYPASS_PCIE2PLLE_CONTROL (1 << 8)
#define AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN (1 << 1)
#define AFI_PLLE_CONTROL_PCIE2PLLE_CONTROL_EN (1 << 0)
#define AFI_PEXBIAS_CTRL_0 0x168
#define RP_PRIV_XP_DL 0x00000494
#define RP_PRIV_XP_DL_GEN2_UPD_FC_TSHOLD (0x1ff << 1)
#define RP_L1_PM_SUBSTATES_CTL 0xc00
#define RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_2 (0x1 << 0)
#define RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_1 (0x1 << 1)
#define RP_L1_PM_SUBSTATES_CTL_ASPM_L1_2 (0x1 << 2)
#define RP_L1_PM_SUBSTATES_CTL_ASPM_L1_1 (0x1 << 3)
#define RP_L1_PM_SUBSTATES_CTL_CM_RTIME_MASK (0xff << 8)
#define RP_L1_PM_SUBSTATES_CTL_CM_RTIME_SHIFT 8
#define RP_L1_PM_SUBSTATES_CTL_T_PWRN_SCL_MASK (0x3 << 16)
#define RP_L1_PM_SUBSTATES_CTL_T_PWRN_SCL_SHIFT 16
#define RP_L1_PM_SUBSTATES_CTL_T_PWRN_VAL_MASK (0x1f << 19)
#define RP_L1_PM_SUBSTATES_CTL_T_PWRN_VAL_SHIFT 19
#define RP_L1_PM_SUBSTATES_CTL_HIDE_CAP (0x1 << 24)
#define RP_L1_PM_SUBSTATES_1_CTL 0xc04
#define RP_L1_PM_SUBSTATES_1_CTL_PWR_OFF_DLY_MASK 0x1fff
#define RP_L1_PM_SUBSTATES_1_CTL_PWR_OFF_DLY 0x26
#define RP_L1SS_1_CTL_CLKREQ_ASSERTED_DLY_MASK (0x1ff << 13)
#define RP_L1SS_1_CTL_CLKREQ_ASSERTED_DLY (0x27 << 13)
#define RP_L1_PM_SUBSTATES_2_CTL 0xc08
#define RP_L1_PM_SUBSTATES_2_CTL_T_L1_2_DLY_MASK 0x1fff
#define RP_L1_PM_SUBSTATES_2_CTL_T_L1_2_DLY 0x4d
#define RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND_MASK (0xff << 13)
#define RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND (0x13 << 13)
#define RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND_COMP_MASK (0xf << 21)
#define RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND_COMP (0x2 << 21)
#define RP_RX_HDR_LIMIT 0x00000e00
#define RP_RX_HDR_LIMIT_PW_MASK (0xff << 8)
#define RP_RX_HDR_LIMIT_PW (0x0e << 8)
#define RP_TIMEOUT0 0xe24
#define RP_TIMEOUT0_PAD_PWRUP_MASK 0xff
#define RP_TIMEOUT0_PAD_PWRUP 0xa
#define RP_TIMEOUT0_PAD_PWRUP_CM_MASK 0xffff00
#define RP_TIMEOUT0_PAD_PWRUP_CM (0x180 << 8)
#define RP_TIMEOUT0_PAD_SPDCHNG_GEN2_MASK (0xff << 24)
#define RP_TIMEOUT0_PAD_SPDCHNG_GEN2 (0xa << 24)
#define RP_TIMEOUT1 0xe28
#define RP_TIMEOUT1_RCVRY_SPD_SUCCESS_EIDLE_MASK (0xff << 16)
#define RP_TIMEOUT1_RCVRY_SPD_SUCCESS_EIDLE (0x10 << 16)
#define RP_TIMEOUT1_RCVRY_SPD_UNSUCCESS_EIDLE_MASK (0xff << 24)
#define RP_TIMEOUT1_RCVRY_SPD_UNSUCCESS_EIDLE (0x74 << 24)
#define RP_ECTL_1_R1 0x00000e80
#define RP_ECTL_1_R1_TX_DRV_AMP_1C_MASK 0x3f
#define RP_ECTL_2_R1 0x00000e84
#define RP_ECTL_2_R1_RX_CTLE_1C_MASK 0xffff
@@ -180,6 +234,9 @@
#define RP_ECTL_6_R1 0x00000e94
#define RP_ECTL_6_R1_RX_EQ_CTRL_H_1C_MASK 0xffffffff
#define RP_ECTL_1_R2 0x00000ea0
#define RP_ECTL_1_R2_TX_DRV_AMP_1C_MASK 0x3f
#define RP_ECTL_2_R2 0x00000ea4
#define RP_ECTL_2_R2_RX_CTLE_1C_MASK 0xffff
@@ -199,6 +256,19 @@
#define RP_VEND_XP_OPPORTUNISTIC_UPDATEFC (1 << 28)
#define RP_VEND_XP_UPDATE_FC_THRESHOLD_MASK (0xff << 18)
#define RP_VEND_XP1 0xf04
#define RP_VEND_XP1_LINK_PVT_CTL_IGNORE_L0S (1 << 23)
#define RP_VEND_XP1_LINK_PVT_CTL_L1_ASPM_SUPPORT (1 << 21)
#define RP_XP_REF 0xf30
#define RP_XP_REF_MICROSECOND_LIMIT_MASK 0xff
#define RP_XP_REF_MICROSECOND_LIMIT 0x14
#define RP_XP_REF_MICROSECOND_ENABLE (1 << 8)
#define RP_XP_REF_CPL_TO_OVERRIDE (1 << 13)
#define RP_XP_REF_CPL_TO_CUSTOM_VALUE_MASK (0x1ffff << 14)
#define RP_XP_REF_CPL_TO_CUSTOM_VALUE (0x1770 << 14)
#define RP_VEND_CTL0 0x00000f44
#define RP_VEND_CTL0_DSK_RST_PULSE_WIDTH_MASK (0xf << 12)
#define RP_VEND_CTL0_DSK_RST_PULSE_WIDTH (0x9 << 12)
@@ -222,12 +292,23 @@
#define RP_PRIV_MISC_TMS_CLK_CLAMP_THRESHOLD (0xf << 24)
#define RP_PRIV_MISC_TMS_CLK_CLAMP_ENABLE (1 << 31)
#define RP_VEND_XP_PAD_PWRDN 0x00000f50
#define RP_VEND_XP_PAD_PWRDN_L1_EN (1 << 0)
#define RP_VEND_XP_PAD_PWRDN_DYNAMIC_EN (1 << 1)
#define RP_VEND_XP_PAD_PWRDN_DISABLED_EN (1 << 2)
#define RP_VEND_XP_PAD_PWRDN_L1_CLKREQ_EN (1 << 15)
#define RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_DYNAMIC_L1PP (3 << 5)
#define RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_L1_L1PP (3 << 3)
#define RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_L1_CLKREQ_L1PP (3 << 16)
#define RP_LINK_CONTROL_STATUS 0x00000090
#define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
#define RP_LINK_CONTROL_STATUS_2 0x000000b0
#define RP_L1_PM_SUBSTATES_CAP 0x144
#define PADS_CTL_SEL 0x0000009c
#define PADS_CTL 0x000000a0
@@ -304,12 +385,18 @@ struct tegra_pcie_soc {
bool program_deskew_time;
bool update_fc_timer;
bool has_cache_bars;
bool enable_wrap;
bool has_aspm_l1;
bool has_aspm_l1ss;
bool l1ss_rp_wake_fixup;
struct {
struct {
u32 rp_ectl_1_r1;
u32 rp_ectl_2_r1;
u32 rp_ectl_4_r1;
u32 rp_ectl_5_r1;
u32 rp_ectl_6_r1;
u32 rp_ectl_1_r2;
u32 rp_ectl_2_r2;
u32 rp_ectl_4_r2;
u32 rp_ectl_5_r2;
@@ -366,6 +453,8 @@ struct tegra_pcie_port {
void __iomem *base;
unsigned int index;
unsigned int lanes;
unsigned int aspm_state;
bool supports_clkreq;
struct phy **phys;
@@ -394,6 +483,14 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
return readl(pcie->pads + offset);
}
static bool tegra_pcie_link_up(struct tegra_pcie_port *port)
{
u32 value;
value = readl(port->base + RP_LINK_CONTROL_STATUS);
return !!(value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE);
}
/*
* The configuration space mapping on Tegra is somewhat similar to the ECAM
* defined by PCIe. However it deviates a bit in how the 4 bits for extended
@@ -459,20 +556,50 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
static int tegra_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *value)
{
struct tegra_pcie *pcie = bus->sysdata;
struct pci_dev *bridge;
struct tegra_pcie_port *port;
if (bus->number == 0)
return pci_generic_config_read32(bus, devfn, where, size,
value);
bridge = pcie_find_root_port(bus->self);
list_for_each_entry(port, &pcie->ports, list)
if (port->index + 1 == PCI_SLOT(bridge->devfn))
break;
/* If there is no link, then there is no device */
if (!tegra_pcie_link_up(port)) {
*value = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND;
}
return pci_generic_config_read(bus, devfn, where, size, value);
}
static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 value)
{
struct tegra_pcie *pcie = bus->sysdata;
struct tegra_pcie_port *port;
struct pci_dev *bridge;
if (bus->number == 0)
return pci_generic_config_write32(bus, devfn, where, size,
value);
bridge = pcie_find_root_port(bus->self);
list_for_each_entry(port, &pcie->ports, list)
if (port->index + 1 == PCI_SLOT(bridge->devfn))
break;
/* If there is no link, then there is no device */
if (!tegra_pcie_link_up(port))
return PCIBIOS_DEVICE_NOT_FOUND;
return pci_generic_config_write(bus, devfn, where, size, value);
}
@@ -529,6 +656,44 @@ static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
}
}
static void disable_aspm_l0s(struct tegra_pcie_port *port)
{
u32 val = 0;
val = readl(port->base + RP_VEND_XP1);
val |= RP_VEND_XP1_LINK_PVT_CTL_IGNORE_L0S;
writel(val, port->base + RP_VEND_XP1);
}
static void disable_aspm_l10(struct tegra_pcie_port *port)
{
u32 val = 0;
val = readl(port->base + RP_VEND_XP1);
val &= ~RP_VEND_XP1_LINK_PVT_CTL_L1_ASPM_SUPPORT;
writel(val, port->base + RP_VEND_XP1);
}
static void disable_aspm_l11(struct tegra_pcie_port *port)
{
u32 val = 0;
val = readl(port->base + RP_L1_PM_SUBSTATES_CTL);
val &= ~RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_1;
val &= ~RP_L1_PM_SUBSTATES_CTL_ASPM_L1_1;
writel(val, port->base + RP_L1_PM_SUBSTATES_CTL);
}
static void disable_aspm_l12(struct tegra_pcie_port *port)
{
u32 val = 0;
val = readl(port->base + RP_L1_PM_SUBSTATES_CTL);
val &= ~RP_L1_PM_SUBSTATES_CTL_PCI_PM_L1_2;
val &= ~RP_L1_PM_SUBSTATES_CTL_ASPM_L1_2;
writel(val, port->base + RP_L1_PM_SUBSTATES_CTL);
}
static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
{
const struct tegra_pcie_soc *soc = port->pcie->soc;
@@ -565,6 +730,47 @@ static void tegra_pcie_enable_rp_features(struct tegra_pcie_port *port)
}
writel(value, port->base + RP_PRIV_MISC);
if (soc->has_aspm_l1) {
/* Advertise ASPM-L1 state capability*/
value = readl(port->base + RP_VEND_XP1);
value |= RP_VEND_XP1_LINK_PVT_CTL_L1_ASPM_SUPPORT;
writel(value, port->base + RP_VEND_XP1);
/* Power saving configuration for L1 sleep/idle */
value = readl(port->base + RP_VEND_XP_PAD_PWRDN);
value |= RP_VEND_XP_PAD_PWRDN_DISABLED_EN;
value |= RP_VEND_XP_PAD_PWRDN_DYNAMIC_EN;
value |= RP_VEND_XP_PAD_PWRDN_L1_EN;
value |= RP_VEND_XP_PAD_PWRDN_L1_CLKREQ_EN;
value |= RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_DYNAMIC_L1PP;
value |= RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_L1_L1PP;
value |= RP_VEND_XP_PAD_PWRDN_SLEEP_MODE_L1_CLKREQ_L1PP;
writel(value, port->base + RP_VEND_XP_PAD_PWRDN);
if (port->aspm_state & 0x1)
disable_aspm_l0s(port);
if (port->aspm_state & 0x2)
disable_aspm_l10(port);
}
if (soc->has_aspm_l1ss) {
if (port->aspm_state & 0x2) {
disable_aspm_l11(port);
disable_aspm_l12(port);
}
if (port->aspm_state & 0x4)
disable_aspm_l11(port);
if (port->aspm_state & 0x8)
disable_aspm_l12(port);
/* Disable L1SS capability if CLKREQ# is not present */
if (!port->supports_clkreq) {
value = readl(port->base + RP_L1_PM_SUBSTATES_CTL);
value |= RP_L1_PM_SUBSTATES_CTL_HIDE_CAP;
writel(value, port->base + RP_L1_PM_SUBSTATES_CTL);
}
}
}
static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
@@ -572,6 +778,11 @@ static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
const struct tegra_pcie_soc *soc = port->pcie->soc;
u32 value;
value = readl(port->base + RP_ECTL_1_R1);
value &= ~RP_ECTL_1_R1_TX_DRV_AMP_1C_MASK;
value |= soc->ectl.regs.rp_ectl_1_r1;
writel(value, port->base + RP_ECTL_1_R1);
value = readl(port->base + RP_ECTL_2_R1);
value &= ~RP_ECTL_2_R1_RX_CTLE_1C_MASK;
value |= soc->ectl.regs.rp_ectl_2_r1;
@@ -593,6 +804,11 @@ static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
value |= soc->ectl.regs.rp_ectl_6_r1;
writel(value, port->base + RP_ECTL_6_R1);
value = readl(port->base + RP_ECTL_1_R2);
value &= ~RP_ECTL_1_R2_TX_DRV_AMP_1C_MASK;
value |= soc->ectl.regs.rp_ectl_1_r2;
writel(value, port->base + RP_ECTL_1_R2);
value = readl(port->base + RP_ECTL_2_R2);
value &= ~RP_ECTL_2_R2_RX_CTLE_1C_MASK;
value |= soc->ectl.regs.rp_ectl_2_r2;
@@ -615,6 +831,26 @@ static void tegra_pcie_program_ectl_settings(struct tegra_pcie_port *port)
writel(value, port->base + RP_ECTL_6_R2);
}
static void tegra_pcie_enable_wrap(void)
{
u32 val;
void __iomem *msel_base;
#define MSELECT_CONFIG_BASE 0x50060000
#define MSELECT_CONFIG_WRAP_TO_INCR_SLAVE1 BIT(28)
#define MSELECT_CONFIG_ERR_RESP_EN_SLAVE1 BIT(24)
/* Config MSELECT to support wrap trans for normal NC & GRE mapping */
msel_base = ioremap(MSELECT_CONFIG_BASE, 4);
val = readl(msel_base);
/* Enable WRAP_TO_INCR_SLAVE1 */
val |= MSELECT_CONFIG_WRAP_TO_INCR_SLAVE1;
/* Disable ERR_RESP_EN_SLAVE1 */
val &= ~MSELECT_CONFIG_ERR_RESP_EN_SLAVE1;
writel(val, msel_base);
iounmap(msel_base);
}
static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
{
const struct tegra_pcie_soc *soc = port->pcie->soc;
@@ -649,6 +885,76 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
value &= ~PCI_EXP_LNKSTA_CLS;
value |= PCI_EXP_LNKSTA_CLS_2_5GB;
writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
if (soc->enable_wrap)
tegra_pcie_enable_wrap();
if (soc->has_aspm_l1ss) {
/* Set port Common_Mode_Restore_Time to 30us */
value = readl(port->base + RP_L1_PM_SUBSTATES_CTL);
value &= ~RP_L1_PM_SUBSTATES_CTL_CM_RTIME_MASK;
value |= (0x1E << RP_L1_PM_SUBSTATES_CTL_CM_RTIME_SHIFT);
writel(value, port->base + RP_L1_PM_SUBSTATES_CTL);
/* set port T_POWER_ON to 70us */
value = readl(port->base + RP_L1_PM_SUBSTATES_CTL);
value &= ~(RP_L1_PM_SUBSTATES_CTL_T_PWRN_SCL_MASK |
RP_L1_PM_SUBSTATES_CTL_T_PWRN_VAL_MASK);
value |= (1 << RP_L1_PM_SUBSTATES_CTL_T_PWRN_SCL_SHIFT) |
(7 << RP_L1_PM_SUBSTATES_CTL_T_PWRN_VAL_SHIFT);
writel(value, port->base + RP_L1_PM_SUBSTATES_CTL);
/* Following is based on clk_m being 19.2 MHz */
value = readl(port->base + RP_TIMEOUT0);
value &= ~RP_TIMEOUT0_PAD_PWRUP_MASK;
value |= RP_TIMEOUT0_PAD_PWRUP;
value &= ~RP_TIMEOUT0_PAD_PWRUP_CM_MASK;
value |= RP_TIMEOUT0_PAD_PWRUP_CM;
value &= ~RP_TIMEOUT0_PAD_SPDCHNG_GEN2_MASK;
value |= RP_TIMEOUT0_PAD_SPDCHNG_GEN2;
writel(value, port->base + RP_TIMEOUT0);
value = readl(port->base + RP_TIMEOUT1);
value &= ~RP_TIMEOUT1_RCVRY_SPD_SUCCESS_EIDLE_MASK;
value |= RP_TIMEOUT1_RCVRY_SPD_SUCCESS_EIDLE;
value &= ~RP_TIMEOUT1_RCVRY_SPD_UNSUCCESS_EIDLE_MASK;
value |= RP_TIMEOUT1_RCVRY_SPD_UNSUCCESS_EIDLE;
writel(value, port->base + RP_TIMEOUT1);
value = readl(port->base + RP_XP_REF);
value &= ~RP_XP_REF_MICROSECOND_LIMIT_MASK;
value |= RP_XP_REF_MICROSECOND_LIMIT;
value |= RP_XP_REF_MICROSECOND_ENABLE;
value |= RP_XP_REF_CPL_TO_OVERRIDE;
value &= ~RP_XP_REF_CPL_TO_CUSTOM_VALUE_MASK;
value |= RP_XP_REF_CPL_TO_CUSTOM_VALUE;
writel(value, port->base + RP_XP_REF);
value = readl(port->base + RP_L1_PM_SUBSTATES_1_CTL);
value &= ~RP_L1_PM_SUBSTATES_1_CTL_PWR_OFF_DLY_MASK;
value |= RP_L1_PM_SUBSTATES_1_CTL_PWR_OFF_DLY;
writel(value, port->base + RP_L1_PM_SUBSTATES_1_CTL);
value = readl(port->base + RP_L1_PM_SUBSTATES_2_CTL);
value &= ~RP_L1_PM_SUBSTATES_2_CTL_T_L1_2_DLY_MASK;
value |= RP_L1_PM_SUBSTATES_2_CTL_T_L1_2_DLY;
value &= ~RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND_MASK;
value |= RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND;
value &= ~RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND_COMP_MASK;
value |= RP_L1_PM_SUBSTATES_2_CTL_MICROSECOND_COMP;
writel(value, port->base + RP_L1_PM_SUBSTATES_2_CTL);
}
if (soc->l1ss_rp_wake_fixup) {
/*
* Set CLKREQ asserted delay greater than Power_Off
* time (2us) to avoid RP wakeup in L1.2.ENTRY
*/
value = readl(port->base + RP_L1_PM_SUBSTATES_1_CTL);
value &= ~RP_L1SS_1_CTL_CLKREQ_ASSERTED_DLY_MASK;
value |= RP_L1SS_1_CTL_CLKREQ_ASSERTED_DLY;
writel(value, port->base + RP_L1_PM_SUBSTATES_1_CTL);
}
}
static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
@@ -661,8 +967,12 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
value = afi_readl(port->pcie, ctrl);
value |= AFI_PEX_CTRL_REFCLK_EN;
if (soc->has_pex_clkreq_en)
value |= AFI_PEX_CTRL_CLKREQ_EN;
if (soc->has_pex_clkreq_en) {
if (port->supports_clkreq)
value &= ~AFI_PEX_CTRL_CLKREQ_EN;
else
value |= AFI_PEX_CTRL_CLKREQ_EN;
}
value |= AFI_PEX_CTRL_OVERRIDE_EN;
@@ -1092,10 +1402,20 @@ static void tegra_pcie_enable_controller(struct tegra_pcie *pcie)
unsigned long value;
/* enable PLL power down */
if (pcie->phy) {
if (soc->has_aspm_l1ss) {
value = afi_readl(pcie, AFI_PLLE_CONTROL);
value &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL;
value |= AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN;
list_for_each_entry(port, &pcie->ports, list) {
if (!port->supports_clkreq) {
value &= ~AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN;
break;
}
}
value &= ~AFI_PLLE_CONTROL_BYPASS_PCIE2PLLE_CONTROL;
value |= AFI_PLLE_CONTROL_PCIE2PLLE_CONTROL_EN;
afi_writel(pcie, value, AFI_PLLE_CONTROL);
}
@@ -1527,6 +1847,11 @@ static void tegra_pcie_pme_turnoff(struct tegra_pcie_port *port)
val = afi_readl(pcie, AFI_PCIE_PME);
val &= ~(0x1 << soc->ports[port->index].pme.turnoff_bit);
afi_writel(pcie, val, AFI_PCIE_PME);
/* PCIe link is in L2, bypass CLKREQ# control over PLLE power down */
val = afi_readl(pcie, AFI_PLLE_CONTROL);
val |= AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL;
afi_writel(pcie, val, AFI_PLLE_CONTROL);
}
static void tegra_pcie_msi_irq(struct irq_desc *desc)
@@ -1846,15 +2171,6 @@ static void tegra_pcie_disable_interrupts(struct tegra_pcie *pcie)
afi_writel(pcie, value, AFI_INTR_MASK);
}
static void update_rp_lanes(struct tegra_pcie *pcie, u32 lanes)
{
struct tegra_pcie_port *port = NULL;
list_for_each_entry(port, &pcie->ports, list)
port->lanes = (lanes >> (port->index << 3)) & 0xFF;
}
static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
u32 *xbar)
{
@@ -1883,23 +2199,12 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
"switching to default 2x1, 1x1, 1x1 "
"configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_211;
update_rp_lanes(pcie, 0x010102);
return 0;
}
} else if (of_device_is_compatible(np, "nvidia,tegra210b01-pcie")) {
switch (lanes) {
case 0x0104:
dev_info(pcie->dev, "4x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
return 0;
default:
dev_info(pcie->dev, "wrong configuration updated in DT, "
"switching to default 4x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
update_rp_lanes(pcie, 0x0104);
return 0;
}
dev_info(dev, "4x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
return 0;
} else if (of_device_is_compatible(np, "nvidia,tegra124-pcie") ||
of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
switch (lanes) {
@@ -1912,13 +2217,6 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
dev_info(dev, "2x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1;
return 0;
default:
dev_info(pcie->dev, "wrong configuration updated in DT, "
"switching to default 4x1, 1x1 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
update_rp_lanes(pcie, 0x0104);
return 0;
}
} else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
switch (lanes) {
@@ -1936,14 +2234,6 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
dev_info(dev, "4x1, 1x2 configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
return 0;
default:
dev_info(dev, "wrong configuration updated in DT, "
"switching to default 4x1, 1x2 "
"configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
update_rp_lanes(pcie, 0x010104);
return 0;
}
} else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
switch (lanes) {
@@ -1956,14 +2246,6 @@ static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
dev_info(dev, "dual-mode configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
return 0;
default:
dev_info(dev, "wrong configuration updated in DT, "
"switching to default dual-mode "
"configuration\n");
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
update_rp_lanes(pcie, 0x000202);
return 0;
}
}
@@ -2057,8 +2339,7 @@ static int tegra_pcie_get_regulators(struct tegra_pcie *pcie, u32 lane_mask)
pcie->supplies[i++].supply = "hvdd-pex-pll";
pcie->supplies[i++].supply = "hvdd-pex";
pcie->supplies[i++].supply = "vddio-pexctl-aud";
} else if (of_device_is_compatible(np, "nvidia,tegra210-pcie") ||
of_device_is_compatible(np, "nvidia,tegra210b01-pcie")) {
} else if (of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
pcie->num_supplies = 3;
pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
@@ -2257,6 +2538,14 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
}
}
err = of_property_read_u32(port, "nvidia,disable-aspm-states",
&rp->aspm_state);
if (err < 0)
rp->aspm_state = 0;
rp->supports_clkreq = of_property_read_bool(port,
"supports-clkreq");
list_add_tail(&rp->list, &pcie->ports);
}
@@ -2450,6 +2739,10 @@ static const struct tegra_pcie_soc tegra20_pcie = {
.program_deskew_time = false,
.update_fc_timer = false,
.has_cache_bars = true,
.enable_wrap = false,
.has_aspm_l1 = false,
.has_aspm_l1ss = false,
.l1ss_rp_wake_fixup = false,
.ectl.enable = false,
};
@@ -2479,6 +2772,10 @@ static const struct tegra_pcie_soc tegra30_pcie = {
.program_deskew_time = false,
.update_fc_timer = false,
.has_cache_bars = false,
.enable_wrap = false,
.has_aspm_l1 = true,
.has_aspm_l1ss = false,
.l1ss_rp_wake_fixup = false,
.ectl.enable = false,
};
@@ -2500,6 +2797,10 @@ static const struct tegra_pcie_soc tegra124_pcie = {
.program_deskew_time = false,
.update_fc_timer = false,
.has_cache_bars = false,
.enable_wrap = false,
.has_aspm_l1 = true,
.has_aspm_l1ss = false,
.l1ss_rp_wake_fixup = false,
.ectl.enable = false,
};
@@ -2523,12 +2824,18 @@ static const struct tegra_pcie_soc tegra210_pcie = {
.program_deskew_time = true,
.update_fc_timer = true,
.has_cache_bars = false,
.enable_wrap = true,
.has_aspm_l1 = true,
.has_aspm_l1ss = true,
.l1ss_rp_wake_fixup = true,
.ectl = {
.regs = {
.rp_ectl_1_r1 = 0x0000001f,
.rp_ectl_2_r1 = 0x0000000f,
.rp_ectl_4_r1 = 0x00000067,
.rp_ectl_5_r1 = 0x55010000,
.rp_ectl_6_r1 = 0x00000001,
.rp_ectl_1_r2 = 0x0000001f,
.rp_ectl_2_r2 = 0x0000008f,
.rp_ectl_4_r2 = 0x000000c7,
.rp_ectl_5_r2 = 0x55010000,
@@ -2559,14 +2866,16 @@ static const struct tegra_pcie_soc tegra210b01_pcie = {
.has_cache_bars = false,
.ectl = {
.regs = {
.rp_ectl_1_r1 = 0x00000027,
.rp_ectl_2_r1 = 0x0000000f,
.rp_ectl_4_r1 = 0x00000067,
.rp_ectl_5_r1 = 0x55010000,
.rp_ectl_6_r1 = 0x00000001,
.rp_ectl_5_r1 = 0x00000000,
.rp_ectl_6_r1 = 0x00000000,
.rp_ectl_1_r2 = 0x00000027,
.rp_ectl_2_r2 = 0x0000008f,
.rp_ectl_4_r2 = 0x000000c7,
.rp_ectl_5_r2 = 0x55010000,
.rp_ectl_6_r2 = 0x00000001,
.rp_ectl_5_r2 = 0x00000000,
.rp_ectl_6_r2 = 0x00000000,
},
.enable = true,
},
@@ -2598,13 +2907,17 @@ static const struct tegra_pcie_soc tegra186_pcie = {
.program_deskew_time = false,
.update_fc_timer = false,
.has_cache_bars = false,
.enable_wrap = false,
.has_aspm_l1 = true,
.has_aspm_l1ss = true,
.l1ss_rp_wake_fixup = false,
.ectl.enable = false,
};
static const struct of_device_id tegra_pcie_of_match[] = {
{ .compatible = "nvidia,tegra186-pcie", .data = &tegra186_pcie },
{ .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie },
{ .compatible = "nvidia,tegra210b01-pcie", .data = &tegra210b01_pcie },
{ .compatible = "nvidia,tegra210-pcie", .data = &tegra210_pcie },
{ .compatible = "nvidia,tegra124-pcie", .data = &tegra124_pcie },
{ .compatible = "nvidia,tegra30-pcie", .data = &tegra30_pcie },
{ .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie },
@@ -2690,6 +3003,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct pci_host_bridge *host;
struct tegra_pcie_port *port;
struct tegra_pcie *pcie;
int err;
@@ -2728,6 +3042,8 @@ static int tegra_pcie_probe(struct platform_device *pdev)
goto pm_runtime_put;
}
pci_add_flags(PCI_REASSIGN_ALL_BUS);
host->ops = &tegra_pcie_ops;
host->map_irq = tegra_pcie_map_irq;

View File

@@ -230,6 +230,12 @@
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_SLEEP_VAL GENMASK(13, 12)
#define XUSB_PADCTL_UPHY_MISC_PAD_CTL2_RX_PWR_OVRD BIT(25)
#define XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL8(x) (0x460 + (x) * (0x1c))
#define CFG_ADDR(x) (((x) & 0xff) << 16)
#define CFG_WDATA(x) (((x) & 0xffff) << 0)
#define CFG_RESET (1 << 27)
#define CFG_WS (1 << 24)
#define XUSB_PADCTL_UPHY_PLL_S0_CTL1 0x860
#define XUSB_PADCTL_UPHY_PLL_S0_CTL2 0x864
@@ -240,6 +246,8 @@
#define XUSB_PADCTL_UPHY_PLL_S0_CTL8 0x87c
#define XUSB_PADCTL_UPHY_PLL_S0_CTL10 0x384
#define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1 0x960
#define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL2 0x964
@@ -407,6 +415,18 @@
#define UHSIC_STROBE_RPD_C BIT(16)
#define UHSIC_STROBE_RPD_D BIT(24)
struct init_data {
u8 cfg_addr;
u16 cfg_wdata;
};
static struct init_data usb3_pll_g1_init_data[] = {
{.cfg_addr = 0x2, .cfg_wdata = 0x0000},
{.cfg_addr = 0x3, .cfg_wdata = 0x7051},
{.cfg_addr = 0x25, .cfg_wdata = 0x0130},
{.cfg_addr = 0x1E, .cfg_wdata = 0x0017},
};
struct tegra210_xusb_fuse_calibration {
u32 hs_curr_level[4];
u32 hs_term_range_adj;
@@ -444,11 +464,38 @@ static const struct tegra_xusb_lane_map tegra210_usb3_map[] = {
{ 0, NULL, 0 }
};
static const struct tegra_xusb_lane_map tegra210b01_usb3_map[] = {
{ 0, "pcie", 5 },
{ 1, "pcie", 4 },
{ 2, "pcie", 1 },
{ 0, NULL, 0 }
};
static int t210b01_compatible(struct tegra_xusb_padctl *padctl)
{
struct device_node *np;
const char *compatible;
np = padctl->dev->of_node;
compatible = of_get_property(np, "compatible", NULL);
if (!compatible) {
dev_err(padctl->dev, "Failed to get compatible property\n");
return -ENODEV;
}
if (strstr(compatible, "tegra210b01") != NULL)
return 1;
return 0;
}
static int tegra210_usb3_lane_map(struct tegra_xusb_lane *lane)
{
const struct tegra_xusb_lane_map *map;
for (map = tegra210_usb3_map; map->type; map++) {
for (map = t210b01_compatible(lane->pad->padctl) ?
tegra210b01_usb3_map : tegra210_usb3_map;
map->type; map++) {
if (map->index == lane->index &&
strcmp(map->type, lane->pad->soc->name) == 0) {
dev_dbg(lane->pad->padctl->dev, "lane = %s map to port = usb3-%d\n",
@@ -476,6 +523,12 @@ static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
if (err < 0)
return err;
if (t210b01_compatible(padctl) == 1) {
err = clk_prepare_enable(pcie->uphy_mgmt_clk);
if (err < 0)
return err;
}
if (tegra210_plle_hw_sequence_is_enabled())
goto skip_pll_init;
@@ -483,6 +536,18 @@ static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl)
if (err < 0)
goto disable;
if (t210b01_compatible(padctl) == 1) {
for (i = 0; i < ARRAY_SIZE(usb3_pll_g1_init_data); i++) {
value = 0;
value |= CFG_ADDR(usb3_pll_g1_init_data[i].cfg_addr);
value |= CFG_WDATA(usb3_pll_g1_init_data[i].cfg_wdata);
value |= CFG_RESET;
value |= CFG_WS;
padctl_writel(padctl, value,
XUSB_PADCTL_UPHY_PLL_S0_CTL10);
}
}
value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK <<
XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT);
@@ -676,6 +741,8 @@ reset:
reset_control_assert(pcie->rst);
disable:
clk_disable_unprepare(pcie->pll);
if (t210b01_compatible(padctl) == 1)
clk_disable_unprepare(pcie->uphy_mgmt_clk);
return err;
}
@@ -697,6 +764,8 @@ static void tegra210_pex_uphy_disable(struct tegra_xusb_padctl *padctl)
}
clk_disable_unprepare(pcie->pll);
if (t210b01_compatible(padctl) == 1)
clk_disable_unprepare(pcie->uphy_mgmt_clk);
}
/* must be called under padctl->lock */
@@ -2560,12 +2629,12 @@ static const struct tegra_xusb_lane_soc tegra210_pcie_lanes[] = {
};
static const struct tegra_xusb_lane_soc tegra210b01_pcie_lanes[] = {
TEGRA210_UPHY_LANE("pcie-0", 0x028, 12, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-1", 0x028, 14, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(1)),
TEGRA210_UPHY_LANE("pcie-2", 0x028, 16, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(2)),
TEGRA210_UPHY_LANE("pcie-3", 0x028, 18, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(3)),
TEGRA210_UPHY_LANE("pcie-4", 0x028, 20, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(4)),
TEGRA210_UPHY_LANE("pcie-5", 0x028, 22, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(5)),
TEGRA210_UPHY_LANE("pcie-0", 0x28, 12, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-1", 0x28, 14, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-2", 0x28, 16, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-3", 0x28, 18, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-4", 0x28, 20, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
TEGRA210_UPHY_LANE("pcie-5", 0x28, 22, 0x3, pcie, XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL2(0)),
};
static struct tegra_xusb_usb3_port *
@@ -2816,6 +2885,15 @@ tegra210_pcie_pad_probe(struct tegra_xusb_padctl *padctl,
goto unregister;
}
if (t210b01_compatible(padctl) == 1) {
pcie->uphy_mgmt_clk = devm_clk_get(&pad->dev, "uphy_mgmt");
if (IS_ERR(pcie->uphy_mgmt_clk)) {
err = PTR_ERR(pcie->uphy_mgmt_clk);
dev_err(&pad->dev,
"failed to get uphy_mgmt_clk clock: %d\n", err);
}
}
pcie->rst = devm_reset_control_get(&pad->dev, "phy");
if (IS_ERR(pcie->rst)) {
err = PTR_ERR(pcie->rst);
@@ -3094,7 +3172,16 @@ static void tegra210_usb3_port_disable(struct tegra_xusb_port *port)
static struct tegra_xusb_lane *
tegra210_usb3_port_map(struct tegra_xusb_port *port)
{
return tegra_xusb_port_find_lane(port, tegra210_usb3_map, "usb3-ss");
int err = t210b01_compatible(port->padctl);
if (err == 1)
return tegra_xusb_port_find_lane(port,
tegra210b01_usb3_map, "usb3-ss");
else if (err == 0)
return tegra_xusb_port_find_lane(port,
tegra210_usb3_map, "usb3-ss");
else
return NULL;
}
static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = {
@@ -3287,6 +3374,14 @@ static const char * const tegra210_xusb_padctl_supply_names[] = {
"hvdd-pex-pll-e",
};
static const char * const tegra210b01_supply_names[] = {
"avdd_pll_uerefe",
"hvdd_pex_pll_e",
"dvdd_pex_pll",
"hvddio_pex",
"dvddio_pex",
};
const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc = {
.num_pads = ARRAY_SIZE(tegra210_pads),
.pads = tegra210_pads,
@@ -3325,8 +3420,8 @@ const struct tegra_xusb_padctl_soc tegra210b01_xusb_padctl_soc = {
},
},
.ops = &tegra210_xusb_padctl_ops,
.supply_names = tegra210_xusb_padctl_supply_names,
.num_supplies = ARRAY_SIZE(tegra210_xusb_padctl_supply_names),
.supply_names = tegra210b01_supply_names,
.num_supplies = ARRAY_SIZE(tegra210b01_supply_names),
.need_fake_usb3_port = true,
};
EXPORT_SYMBOL_GPL(tegra210b01_xusb_padctl_soc);

View File

@@ -564,6 +564,7 @@ static int tegra_xusb_port_init(struct tegra_xusb_port *port,
if (err < 0)
goto put_device;
printk("init done!\n");
return 0;
put_device:
@@ -799,24 +800,31 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl,
struct device_node *np;
int err = 0;
printk("adding usb2 port");
/*
* USB2 ports don't require additional properties, but if the port is
* marked as disabled there is no reason to register it.
*/
printk("find port node");
np = tegra_xusb_find_port_node(padctl, "usb2", index);
if (!np || !of_device_is_available(np))
goto out;
printk("kzalloc");
usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL);
if (!usb2) {
err = -ENOMEM;
goto out;
}
printk("init usb2 xusb port");
err = tegra_xusb_port_init(&usb2->base, padctl, np, "usb2", index);
if (err < 0)
goto out;
printk("set usb2 ops");
usb2->base.ops = padctl->soc->ports.usb2.ops;
usb2->base.lane = usb2->base.ops->map(&usb2->base);
@@ -880,6 +888,8 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl,
goto out;
}
printk("init ulpi xusb port");
err = tegra_xusb_port_init(&ulpi->base, padctl, np, "ulpi", index);
if (err < 0)
goto out;
@@ -926,6 +936,7 @@ static int tegra_xusb_add_hsic_port(struct tegra_xusb_padctl *padctl,
struct device_node *np;
int err = 0;
printk("find hsic port node");
np = tegra_xusb_find_port_node(padctl, "hsic", index);
if (!np || !of_device_is_available(np))
goto out;
@@ -936,10 +947,13 @@ static int tegra_xusb_add_hsic_port(struct tegra_xusb_padctl *padctl,
goto out;
}
printk("init hsic xusb port");
err = tegra_xusb_port_init(&hsic->base, padctl, np, "hsic", index);
if (err < 0)
goto out;
printk("setting hsic ops");
hsic->base.ops = padctl->soc->ports.hsic.ops;
hsic->base.lane = hsic->base.ops->map(&hsic->base);
@@ -1028,10 +1042,14 @@ static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl,
if (err < 0)
goto out;
printk("xusb port inited. setting ops");
usb3->base.ops = padctl->soc->ports.usb3.ops;
printk("set lane");
usb3->base.lane = usb3->base.ops->map(&usb3->base);
if (IS_ERR(usb3->base.lane)) {
printk("usb3 lane is error!");
err = PTR_ERR(usb3->base.lane);
goto out;
}