Compare commits
16 Commits
testing-6/
...
testing-6.
| Author | SHA1 | Date | |
|---|---|---|---|
| 8746e76486 | |||
| 60832e95c5 | |||
| ea57749891 | |||
| d224e99d2c | |||
| 33d34b5ac8 | |||
| 71d2767b92 | |||
| 3484f914c9 | |||
| 57ae2f4faa | |||
| c29dd5c99e | |||
| f7485a509b | |||
| 201a374323 | |||
| 335d7b24e1 | |||
| 3e038a2f95 | |||
|
|
a52caa6411 | ||
|
|
9cf1f30f0a | ||
| 9b8622f15f |
978
arch/arm64/boot/dts/nvidia/tegra210-prods.dtsi
Normal file
978
arch/arm64/boot/dts/nvidia/tegra210-prods.dtsi
Normal file
@@ -0,0 +1,978 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2025, NVIDIA CORPORATION. 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 as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/ {
|
||||
host1x@50000000 {
|
||||
sor@54540000 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod_c_dp {
|
||||
prod = <
|
||||
0x0000005c 0x0f000f10 0x01000310 // SOR_NV_PDISP_SOR_PLL0_0 27:24=ICHPMP 0x01
|
||||
// 11:08=VCOCAP 0x03
|
||||
// 04:04=RESISTORSEL 0x01
|
||||
0x00000060 0x03f00100 0x00400100 // SOR_NV_PDISP_SOR_PLL1_0 25:24=LVDSCM 0x00
|
||||
// 23:20=LOADADJ 0x04
|
||||
// 08:08=TMDS_TERM 0x01
|
||||
0x00000068 0x00002000 0x00002000 // SOR_NV_PDISP_SOR_PLL3_0 13:13=PLVVDD_MODE 0x01
|
||||
0x00000070 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LVDS_0
|
||||
0x00000180 0x00000001 0x00000001 // SOR_NV_PDISP_SOR_DP_SPARE0_0 00:00=SEQ_ENABLE 0x01
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
sor@54580000 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod_list_hdmi_soc = "prod_c_hdmi_0m_54m", "prod_c_hdmi_54m_111m",
|
||||
"prod_c_hdmi_111m_223m", "prod_c_hdmi_223m_300m",
|
||||
"prod_c_hdmi_300m_600m";
|
||||
prod {
|
||||
prod = <
|
||||
0x000003a0 0x00000001 0x00000001 // SOR_NV_PDISP_INPUT_CONTROL 00:00=HDMI_SRC_SELECT 0x1
|
||||
0x0000005c 0x0f000700 0x01000000 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x0
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333A3A3A // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3A
|
||||
// 15:08=LANE1_DP_LANE1 0x3A
|
||||
// 07:00=LANE0_DP_LANE2 0x3A
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00401000 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x10
|
||||
>;
|
||||
};
|
||||
prod_c_hdmi_0m_54m {
|
||||
prod = <
|
||||
0x000003a0 0x000000002 0x00000002 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x1
|
||||
0x0000005c 0x0f000700 0x01000000 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x0
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333A3A3A // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3A
|
||||
// 15:08=LANE1_DP_LANE1 0x3A
|
||||
// 07:00=LANE0_DP_LANE2 0x3A
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00401000 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x10
|
||||
>;
|
||||
};
|
||||
prod_c_hdmi_54m_111m {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000002 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x1
|
||||
0x0000005c 0x0f000700 0x01000100 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x1
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333A3A3A // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3A
|
||||
// 15:08=LANE1_DP_LANE1 0x3A
|
||||
// 07:00=LANE0_DP_LANE2 0x3A
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00404000 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x40
|
||||
|
||||
>;
|
||||
};
|
||||
prod_c_hdmi_111m_223m {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000000 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x0
|
||||
0x0000005c 0x0f000700 0x01000300 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x3
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0xff0fe0ff 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333A3A3A // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3A
|
||||
// 15:08=LANE1_DP_LANE1 0x3A
|
||||
// 07:00=LANE0_DP_LANE2 0x3A
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00406600 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x66
|
||||
>;
|
||||
};
|
||||
prod_c_hdmi_223m_300m {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000000 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x0
|
||||
0x0000005c 0x0f000700 0x01000300 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x3
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x0A000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0xA
|
||||
0x00000138 0xffffffff 0x333F3F3F // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3F
|
||||
// 15:08=LANE1_DP_LANE1 0x3F
|
||||
// 07:00=LANE0_DP_LANE2 0x3F
|
||||
0x00000148 0xffffffff 0x00171717 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x17
|
||||
// 15:08=LANE1_DP_LANE1 0x17
|
||||
// 07:00=LANE0_DP_LANE2 0x17
|
||||
0x00000170 0x0040ff00 0x00406600 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x66
|
||||
>;
|
||||
};
|
||||
prod_c_hdmi_300m_600m {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000002 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x1
|
||||
0x0000005c 0x0f000700 0x01000300 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x3
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333F3F3F // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3f
|
||||
// 15:08=LANE1_DP_LANE1 0x3f
|
||||
// 07:00=LANE0_DP_LANE2 0x3f
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00406600 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x66
|
||||
>;
|
||||
};
|
||||
/* HDMI prod-settings for fall-back to old DT config
|
||||
* when prod_list_hdmi_soc/board are not found */
|
||||
prod_c_54M {
|
||||
prod = <
|
||||
0x000003a0 0x000000002 0x00000002 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x1
|
||||
0x0000005c 0x0f000700 0x01000000 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x0
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333A3A3A // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3A
|
||||
// 15:08=LANE1_DP_LANE1 0x3A
|
||||
// 07:00=LANE0_DP_LANE2 0x3A
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00401000 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x10
|
||||
>;
|
||||
};
|
||||
prod_c_75M {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000002 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x1
|
||||
0x0000005c 0x0f000700 0x01000100 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x1
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333A3A3A // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3A
|
||||
// 15:08=LANE1_DP_LANE1 0x3A
|
||||
// 07:00=LANE0_DP_LANE2 0x3A
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00404000 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x40
|
||||
|
||||
>;
|
||||
};
|
||||
prod_c_150M {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000000 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x0
|
||||
0x0000005c 0x0f000700 0x01000300 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x3
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0xff0fe0ff 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333A3A3A // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3A
|
||||
// 15:08=LANE1_DP_LANE1 0x3A
|
||||
// 07:00=LANE0_DP_LANE2 0x3A
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00406600 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x66
|
||||
>;
|
||||
};
|
||||
prod_c_300M {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000000 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x0
|
||||
0x0000005c 0x0f000700 0x01000300 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x3
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x0A000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0xA
|
||||
0x00000138 0xffffffff 0x333F3F3F // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3F
|
||||
// 15:08=LANE1_DP_LANE1 0x3F
|
||||
// 07:00=LANE0_DP_LANE2 0x3F
|
||||
0x00000148 0xffffffff 0x00171717 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x17
|
||||
// 15:08=LANE1_DP_LANE1 0x17
|
||||
// 07:00=LANE0_DP_LANE2 0x17
|
||||
0x00000170 0x0040ff00 0x00406600 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x66
|
||||
>;
|
||||
};
|
||||
prod_c_600M {
|
||||
prod = <
|
||||
0x000003a0 0x00000002 0x00000002 // SOR_NV_PDISP_INPUT_CONTROL 01:01=ARM_VIDEO_RANGE 0x1
|
||||
0x0000005c 0x0f000700 0x01000300 // SOR_NV_PDISP_SOR_PLL0_0 11:08=VCOCAP 0x3
|
||||
// 27:24=ICHPMP 0x1
|
||||
0x00000060 0x00f01f00 0x00401380 // SOR_NV_PDISP_SOR_PLL1_0 08:08=TMDS_TERM 0x1
|
||||
// 12:09=TMDS_TERMADJ 0x9
|
||||
// 23:20=LOADADJ 0x4
|
||||
0x00000068 0x0f000000 0x08000000 // SOR_NV_PSIDP_SOR_PLL3_0 27:24=BG_VREF_LEVEL 0x8
|
||||
0x00000138 0xffffffff 0x333F3F3F // SOR_NV_PDISP_SOR_LANE_DRIVE_CURRENT0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x33
|
||||
// 23:16=LANE2_DP_LANE0 0x3f
|
||||
// 15:08=LANE1_DP_LANE1 0x3f
|
||||
// 07:00=LANE0_DP_LANE2 0x3f
|
||||
0x00000148 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LANE_PREEMPHASIS0_0
|
||||
// 31:24=LANE3_DP_LANE3 0x00
|
||||
// 23:16=LANE2_DP_LANE0 0x00
|
||||
// 15:08=LANE1_DP_LANE1 0x00
|
||||
// 07:00=LANE0_DP_LANE2 0x00
|
||||
0x00000170 0x0040ff00 0x00406600 // SOR_NV_PDISP_SOR_DP_PADCTL0_0
|
||||
// 22:22=TX_PU 0x1
|
||||
// 15:08=TX_PU_VALUE 0x66
|
||||
>;
|
||||
};
|
||||
|
||||
prod_c_dp {
|
||||
prod = <
|
||||
0x0000005c 0x0f000f10 0x01000310 // SOR_NV_PDISP_SOR_PLL0_0 27:24=ICHPMP 0x01
|
||||
// 11:08=VCOCAP 0x03
|
||||
// 04:04=RESISTORSEL 0x01
|
||||
0x00000060 0x03f00100 0x00400100 // SOR_NV_PDISP_SOR_PLL1_0 25:24=LVDSCM 0x00
|
||||
// 23:20=LOADADJ 0x04
|
||||
// 08:08=TMDS_TERM 0x01
|
||||
0x00000068 0x00002000 0x00002000 // SOR_NV_PDISP_SOR_PLL3_0 13:13=PLVVDD_MODE 0x01
|
||||
0x00000070 0xffffffff 0x00000000 // SOR_NV_PDISP_SOR_LVDS_0
|
||||
0x00000180 0x00000001 0x00000001 // SOR_NV_PDISP_SOR_DP_SPARE0_0 00:00=SEQ_ENABLE 0x01
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dpaux@545c0000 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
|
||||
prod_c_dpaux_dp {
|
||||
prod = <
|
||||
0x00000124 0x000037fe 0x000024c2
|
||||
>;
|
||||
};
|
||||
prod_c_dpaux_hdmi {
|
||||
prod = <
|
||||
0x00000124 0x00000700 0x00000400
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dpaux@54040000 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod_c_dpaux_dp {
|
||||
prod = <
|
||||
0x00000124 0x000037fe 0x000024c2
|
||||
>;
|
||||
};
|
||||
prod_c_dpaux_hdmi {
|
||||
prod = <
|
||||
0x00000124 0x00000700 0x00000400
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
pinmux@700008d4 {
|
||||
prod-settings {
|
||||
#prod-cells = <4>;
|
||||
prod {
|
||||
status = "okay";
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0x1C4 0xF7F7F000 0x51212000
|
||||
0 0x128 0x01F1F000 0x01010000 //GPIO_PZ0 DRVUP-DN
|
||||
0 0x12C 0x01F1F000 0x01010000 //GPIO_PZ1 DRVUP-DN
|
||||
0 0x1C8 0xF0003FFD 0x00001040
|
||||
0 0x1DC 0xF7F7F000 0x51212000
|
||||
0 0x1E0 0xF0003FFD 0x00001040
|
||||
0 0x23C 0x01F1F000 0x01F1F000 //TOUCH_CLK DRVUP-DN
|
||||
0 0x20 0x01F1F000 0x01010000 //AUD_MCLK
|
||||
0 0x44 0x01F1F000 0x01010000 //CAM1_MCLK DRVUP-DN
|
||||
0 0x50 0x01F1F000 0x01010000 //CAM2_MCLK DRVUP-DN
|
||||
0 0x58 0x01F1F000 0x01010000 //CAM_AF_EN DRVUP-DN
|
||||
0 0x5C 0x01F1F000 0x01010000 //CAM_FLASH_EN DRVUP-DN
|
||||
0 0xA0 0x01F1F000 0x01010000 //I2S4B DIN
|
||||
0 0xA4 0x01F1F000 0x01010000 //I2S4B DOUT
|
||||
0 0xA8 0x01F1F000 0x01010000 //I2S4B FS
|
||||
0 0xAC 0x01F1F000 0x01010000 //I2S4B SCLK
|
||||
0 0xB0 0x01F1F000 0x01F1F000 //DMIC1 CLK
|
||||
0 0xB4 0x01F1F000 0x01F1F000 //DMIC1 DATA
|
||||
0 0xB8 0x01F1F000 0x01F1F000 //DMIC2 CLK
|
||||
0 0xBC 0x01F1F000 0x01F1F000 //DMIC2 DATA
|
||||
0 0xC0 0x01F1F000 0x01F1F000 //DMIC3 CLK
|
||||
0 0xC4 0x01F1F000 0x01F1F000 //DMIC3 DATA
|
||||
1 0x00 0x00007200 0x00002000
|
||||
1 0x04 0x00007200 0x00002000
|
||||
1 0x08 0x00007200 0x00002000
|
||||
1 0x0C 0x00007200 0x00002000
|
||||
1 0x10 0x00007200 0x00002000
|
||||
1 0x14 0x00007200 0x00002000
|
||||
1 0x1C 0x00007200 0x00002000
|
||||
1 0x20 0x00007200 0x00002000
|
||||
1 0x24 0x00007200 0x00002000
|
||||
1 0x28 0x00007200 0x00002000
|
||||
1 0x2C 0x00007200 0x00002000
|
||||
1 0x30 0x00007200 0x00002000
|
||||
1 0x160 0x00001000 0x00001000>;
|
||||
};
|
||||
|
||||
i2s2_prod {
|
||||
prod = <0 0xB0 0x01F1F000 0x01010000 // FS
|
||||
0 0xB4 0x01F1F000 0x01010000 // DIN
|
||||
0 0xB8 0x01F1F000 0x01010000 // DOUT
|
||||
0 0xBC 0x01F1F000 0x01010000>; // SCLK
|
||||
};
|
||||
|
||||
spi1_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0x200 0xF0000000 0x50000000
|
||||
0 0x204 0xF0000000 0x50000000
|
||||
0 0x208 0xF0000000 0x50000000
|
||||
0 0x20c 0xF0000000 0x50000000
|
||||
0 0x210 0xF0000000 0x50000000
|
||||
1 0x50 0x00006000 0x00006040
|
||||
1 0x54 0x00006000 0x00006040
|
||||
1 0x58 0x00006000 0x00006040
|
||||
1 0x5c 0x00006000 0x00006040
|
||||
1 0x60 0x00006000 0x00006040>;
|
||||
};
|
||||
spi2_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0x214 0xF0000000 0xd0000000
|
||||
0 0x218 0xF0000000 0xd0000000
|
||||
0 0x21c 0xF0000000 0xd0000000
|
||||
0 0x220 0xF0000000 0xd0000000
|
||||
0 0x224 0xF0000000 0xd0000000
|
||||
1 0x64 0x00006000 0x00006040
|
||||
1 0x68 0x00006000 0x00006040
|
||||
1 0x6c 0x00006000 0x00006040
|
||||
1 0x70 0x00006000 0x00006040
|
||||
1 0x74 0x00006000 0x00006040>;
|
||||
};
|
||||
spi3_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0xcc 0x01404000 0x01414000
|
||||
0 0xd0 0x01404000 0x01414000
|
||||
0 0x140 0x01404000 0x01414000
|
||||
0 0x144 0x01404000 0x01414000>;
|
||||
};
|
||||
spi4_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0x268 0x01404000 0x01414000
|
||||
0 0x26c 0x01404000 0x01414000
|
||||
0 0x270 0x01404000 0x01414000
|
||||
0 0x274 0x01404000 0x01414000>;
|
||||
};
|
||||
i2c0_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0xD4 0x01F1F000 0x0001F000
|
||||
0 0xD8 0x01F1F000 0x0001F000
|
||||
1 0xBC 0x00001100 0x00000000
|
||||
1 0xC0 0x00001100 0x00000000>;
|
||||
};
|
||||
i2c1_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0xDC 0x01F1F000 0x0001F000
|
||||
0 0xE0 0x01F1F000 0x0001F000
|
||||
1 0xC4 0x00001100 0x00000000
|
||||
1 0xC8 0x00001100 0x00000000>;
|
||||
};
|
||||
i2c2_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0xE4 0x01F1F000 0x0001F000
|
||||
0 0xE8 0x01F1F000 0x0001F000
|
||||
1 0xCC 0x00001100 0x00000000
|
||||
1 0xD0 0x00001100 0x00000000
|
||||
0 0x60 0x01F1F000 0x0001F000
|
||||
0 0x64 0x01F1F000 0x0001F000
|
||||
1 0xD4 0x00001100 0x00000000
|
||||
1 0xD8 0x00001100 0x00000000>;
|
||||
};
|
||||
i2c4_prod {
|
||||
nvidia,prod-boot-init;
|
||||
prod = <0 0x198 0x01F1F000 0x0001F000
|
||||
0 0x19C 0x01F1F000 0x0001F000
|
||||
1 0xDC 0x00001100 0x00000000
|
||||
1 0xE0 0x00001100 0x00000000>;
|
||||
};
|
||||
i2c0_hs_prod {
|
||||
prod = <0 0xD4 0x01F1F000 0x01F1F000
|
||||
0 0xD8 0x01F1F000 0x01F1F000
|
||||
1 0xBC 0x00001100 0x00001000
|
||||
1 0xC0 0x00001100 0x00001000>;
|
||||
};
|
||||
i2c1_hs_prod {
|
||||
prod = <0 0xDC 0x01F1F000 0x01F1F000
|
||||
0 0xE0 0x01F1F000 0x01F1F000
|
||||
1 0xC4 0x00001100 0x00001000
|
||||
1 0xC8 0x00001100 0x00001000>;
|
||||
};
|
||||
i2c2_hs_prod {
|
||||
prod = <0 0xE4 0x01F1F000 0x01F1F000
|
||||
0 0xE8 0x01F1F000 0x01F1F000
|
||||
1 0xCC 0x00001100 0x00001000
|
||||
1 0xD0 0x00001100 0x00001000
|
||||
0 0x60 0x01F1F000 0x01F1F000
|
||||
0 0x64 0x01F1F000 0x01F1F000
|
||||
1 0xD4 0x00001100 0x00001000
|
||||
1 0xD8 0x00001100 0x00001000>;
|
||||
};
|
||||
i2c4_hs_prod {
|
||||
prod = <0 0x198 0x01F1F000 0x01F1F000
|
||||
0 0x19C 0x01F1F000 0x01F1F000
|
||||
1 0xDC 0x00001100 0x00001000
|
||||
1 0xE0 0x00001100 0x00001000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
spi@7000d400 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod {
|
||||
prod = <0x04 0x00000fff 0x0>;
|
||||
};
|
||||
prod_c_flash {
|
||||
status = "disabled";
|
||||
/* enabled for spi flash rom */
|
||||
prod = <0x04 0x0000003f 0x00000007>;
|
||||
};
|
||||
prod_c_loop {
|
||||
status = "disabled";
|
||||
/* enabled for spi loopback mode */
|
||||
prod = <0x04 0x00000fff 0x0000044b>;
|
||||
};
|
||||
};
|
||||
};
|
||||
spi@7000d600 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod {
|
||||
prod = <0x04 0x00000fff 0x0>;
|
||||
};
|
||||
prod_c_flash {
|
||||
status = "disabled";
|
||||
/* enabled for spi flash rom */
|
||||
prod = <0x04 0x0000003f 0x00000006>;
|
||||
};
|
||||
prod_c_loop {
|
||||
status = "disabled";
|
||||
/* enabled for spi loopback mode */
|
||||
prod = <0x04 0x00000fff 0x0000044b>;
|
||||
};
|
||||
};
|
||||
};
|
||||
spi@7000d800 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod {
|
||||
prod = <0x04 0x00000fff 0x0>;
|
||||
};
|
||||
prod_c_flash {
|
||||
status = "disabled";
|
||||
/* enabled for spi flash rom */
|
||||
prod = <0x04 0x0000003f 0x00000008>;
|
||||
};
|
||||
prod_c_loop {
|
||||
status = "disabled";
|
||||
/* enabled for spi loopback mode */
|
||||
prod = <0x04 0x00000fff 0x0000044b>;
|
||||
};
|
||||
};
|
||||
};
|
||||
spi@7000da00 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod {
|
||||
prod = <0x04 0x00000fff 0x0>;
|
||||
};
|
||||
prod_c_flash {
|
||||
status = "disabled";
|
||||
/* enabled for spi loopback mode */
|
||||
prod = <0x04 0x00000fff 0x0000044b>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
padctl@7009f000 {
|
||||
prod-settings {
|
||||
#prod-cells = <4>;
|
||||
prod_c_bias {
|
||||
prod = <
|
||||
0 0x00000284 0x0000003f 0x0000003a
|
||||
>;
|
||||
};
|
||||
prod_c_bias_a02 {
|
||||
prod = <
|
||||
0 0x00000284 0x0000003f 0x00000038
|
||||
>;
|
||||
};
|
||||
prod_c_utmi0 {
|
||||
prod = <
|
||||
0 0x00000084 0x00000020 0x00000040
|
||||
>;
|
||||
};
|
||||
prod_c_utmi1 {
|
||||
prod = <
|
||||
0 0x000000C4 0x00000020 0x00000040
|
||||
>;
|
||||
};
|
||||
prod_c_utmi2 {
|
||||
prod = <
|
||||
0 0x00000104 0x00000020 0x00000040
|
||||
>;
|
||||
};
|
||||
prod_c_utmi3 {
|
||||
prod = <
|
||||
0 0x00000144 0x00000020 0x00000040
|
||||
>;
|
||||
};
|
||||
prod_c_ss0 {
|
||||
prod = <
|
||||
0 0x00000a60 0x00030000 0x00020000
|
||||
0 0x00000a64 0x0000ffff 0x000000fc
|
||||
0 0x00000a68 0xffffffff 0xc0077f1f
|
||||
0 0x00000a74 0xffffffff 0xfcf01368
|
||||
>;
|
||||
};
|
||||
prod_c_ss1 {
|
||||
prod = <
|
||||
0 0x00000aa0 0x00030000 0x00020000
|
||||
0 0x00000aa4 0x0000ffff 0x000000fc
|
||||
0 0x00000aa8 0xffffffff 0xc0077f1f
|
||||
0 0x00000ab4 0xffffffff 0xfcf01368
|
||||
>;
|
||||
};
|
||||
prod_c_ss2 {
|
||||
prod = <
|
||||
0 0x00000ae0 0x00030000 0x00020000
|
||||
0 0x00000ae4 0x0000ffff 0x000000fc
|
||||
0 0x00000ae8 0xffffffff 0xc0077f1f
|
||||
0 0x00000af4 0xffffffff 0xfcf01368
|
||||
>;
|
||||
};
|
||||
prod_c_ss3 {
|
||||
prod = <
|
||||
0 0x00000b20 0x00030000 0x00020000
|
||||
0 0x00000b24 0x0000ffff 0x000000fc
|
||||
0 0x00000b28 0xffffffff 0xc0077f1f
|
||||
0 0x00000b34 0xffffffff 0xfcf01368
|
||||
>;
|
||||
};
|
||||
prod_c_hsic0 {
|
||||
prod = <
|
||||
0 0x00000344 0x0000001f 0x0000001c
|
||||
>;
|
||||
};
|
||||
prod_c_hsic1 {
|
||||
prod = <
|
||||
0 0x00000344 0x0000001f 0x0000001c
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
sata@70020000 {
|
||||
prod-settings {
|
||||
#prod-cells = <4>;
|
||||
prod {
|
||||
prod = <
|
||||
0 0x00000680 0x00000001 0x00000001 // SATA_CHX_INDEX_0 0
|
||||
0 0x00000690 0x00000FFF 0x00000715 // SATA_CHX_PHY_CTRL1_GEN1_0 31:0
|
||||
0 0x00000694 0x000FF0FF 0x0000E01B // SATA_CHX_PHY_CTRL1_GEN2_0 31:0
|
||||
0 0x000006d0 0xFFFFFFFF 0x00AB000F // SATA_CHX_PHY_CTRL11_0 31:0
|
||||
0 0x00000170 0x0000F000 0x00007000 // NV_PROJ_SATA_FIFO_0 15:12
|
||||
2 0x00000960 0x03000000 0x01000000 // XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL_1_0 25:24
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mmc@700b0600 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
|
||||
prod_c_ds {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_ddr52 {
|
||||
prod = <0x00000100 0x1FFF0000 0x00000000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs200 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00004000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs400 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00004000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs533 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00002000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30000505 0x30000505>;
|
||||
};
|
||||
|
||||
|
||||
prod {
|
||||
prod = <
|
||||
0x0000100 0x1FFF000E 0x8090028 // SDMMC_VENDOR_CLOCK_CNTRL_0 28:24=TRIM_VAL 0x5
|
||||
// 23:16=TAP_VAL 0x9
|
||||
// 05:05=SDR50_TUNING_OVERRIDE 0x1
|
||||
// 03:03=PADPIPE_CLKEN_OVERRIDE 0x1
|
||||
// 02:02=SPI_MODE_CLKEN_OVERRIDE 0x0
|
||||
// 01:01=INPUT_IO_CLK 0x0
|
||||
0x0000010C 0x00003F00 0x00002800 //SDMMC_VENDOR_CAP_OVERRIDES_0 13:8=DQS_TRIM_VAL 0x28
|
||||
0x00001C0 0x08001FC0 0x8000040 // SDMMC_VENDOR_TUNING_CNTRL0_0 12:06=MUL_M 0x1
|
||||
// 27:27=RETUNING_REQ_EN_ON_CRC_ERR_DETECTION 0x1
|
||||
0x00001C4 0x00000077 0x0 // SDMMC_VENDOR_TUNING_CNTRL1_0 02:00=STEP_SIZE_SDR50 0x0
|
||||
// 06:04=STEP_SIZE_SDR104_HS200 0x0
|
||||
0x0000120 0x00020001 0x00001 // SDMMC_VENDOR_MISC_CNTRL_0 0:0=ERASE_TIMEOUT_LIMIT 0x1
|
||||
// 17:17=SDMMC_SPARE1[1] 0x0
|
||||
0x0000128 0x43000000 0x00000000 // SDMMC_VENDOR_MISC_CNTRL2_0 30:30=SDMMC_CLK_OVR_ON 0x0
|
||||
// 25:25=ADMA3_CLKEN_OVERRIDE 0x0
|
||||
// 24:24=CQE_CLKEN_OVERRIDE 0x0
|
||||
0x00001F0 0x00080000 0x00080000 // SDMMC_IO_SPARE_0 19:19=SPARE_OUT[3] 0x1
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mmc@700b0400 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
|
||||
prod_c_ds {
|
||||
prod = <0x00000100 0x00FF0000 0x00010000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x3000007D>;
|
||||
};
|
||||
prod_c_hs {
|
||||
prod = <0x00000100 0x00FF0000 0x00010000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x3000007D>;
|
||||
};
|
||||
prod_c_sdr12 {
|
||||
prod = <0x00000100 0x00FF0000 0x00010000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_sdr25 {
|
||||
prod = <0x00000100 0x00FF0000 0x00010000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_sdr50 {
|
||||
prod = <0x00000100 0x00FF0000 0x00010000
|
||||
0x000001C0 0x0000E000 0x00008000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_sdr104 {
|
||||
prod = <0x00000100 0x00FF0000 0x00010000
|
||||
0x000001C0 0x0000E000 0x00004000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_ddr52 {
|
||||
prod = <0x00000100 0x1FFF0000 0x00000000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
|
||||
prod {
|
||||
prod = <
|
||||
0x0000100 0x1FFF000E 0x3090028 // SDMMC_VENDOR_CLOCK_CNTRL_0 28:24=TRIM_VAL 0x5
|
||||
// 23:16=TAP_VAL 0x9
|
||||
// 05:05=SDR50_TUNING_OVERRIDE 0x1
|
||||
// 03:03=PADPIPE_CLKEN_OVERRIDE 0x1
|
||||
// 02:02=SPI_MODE_CLKEN_OVERRIDE 0x0
|
||||
// 01:01=INPUT_IO_CLK 0x0
|
||||
0x00001C0 0x08001FC0 0x8000040 // SDMMC_VENDOR_TUNING_CNTRL0_0 12:06=MUL_M 0x1
|
||||
// 27:27=RETUNING_REQ_EN_ON_CRC_ERR_DETECTION 0x1
|
||||
0x00001C4 0x00000077 0x0 // SDMMC_VENDOR_TUNING_CNTRL1_0 02:00=STEP_SIZE_SDR50 0x0
|
||||
// 06:04=STEP_SIZE_SDR104_HS200 0x0
|
||||
0x0000120 0x00020001 0x00001 // SDMMC_VENDOR_MISC_CNTRL_0 0:0=ERASE_TIMEOUT_LIMIT 0x1
|
||||
// 17:17=SDMMC_SPARE1[1] 0x0
|
||||
0x0000128 0x43000000 0x00000000 // SDMMC_VENDOR_MISC_CNTRL2_0 30:30=SDMMC_CLK_OVR_ON 0x0
|
||||
// 25:25=ADMA3_CLKEN_OVERRIDE 0x0
|
||||
// 24:24=CQE_CLKEN_OVERRIDE 0x0
|
||||
0x00001F0 0x00080000 0x00080000 // SDMMC_IO_SPARE_0 19:19=SPARE_OUT[3] 0x1
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mmc@700b0200 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
|
||||
prod_c_ds {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_sdr12 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_sdr25 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_sdr50 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00008000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_sdr104 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00004000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_ddr52 {
|
||||
prod = <0x00000100 0x1FFF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs200 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00004000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs400 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00004000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30000505>;
|
||||
};
|
||||
prod_c_hs533 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00002000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30000505 0x30000505>;
|
||||
};
|
||||
|
||||
prod {
|
||||
prod = <
|
||||
0x0000100 0x1FFF000E 0x8090028 // SDMMC_VENDOR_CLOCK_CNTRL_0 28:24=TRIM_VAL 0x5
|
||||
// 23:16=TAP_VAL 0x9
|
||||
// 05:05=SDR50_TUNING_OVERRIDE 0x1
|
||||
// 03:03=PADPIPE_CLKEN_OVERRIDE 0x1
|
||||
// 02:02=SPI_MODE_CLKEN_OVERRIDE 0x0
|
||||
// 01:01=INPUT_IO_CLK 0x0
|
||||
0x00001C0 0x08001FC0 0x8000040 // SDMMC_VENDOR_TUNING_CNTRL0_0 12:06=MUL_M 0x1
|
||||
// 27:27=RETUNING_REQ_EN_ON_CRC_ERR_DETECTION 0x1
|
||||
0x00001C4 0x00000077 0x0 // SDMMC_VENDOR_TUNING_CNTRL1_0 02:00=STEP_SIZE_SDR50 0x0
|
||||
// 06:04=STEP_SIZE_SDR104_HS200 0x0
|
||||
0x0000120 0x00020001 0x00001 // SDMMC_VENDOR_MISC_CNTRL_0 0:0=ERASE_TIMEOUT_LIMIT 0x1
|
||||
// 17:17=SDMMC_SPARE1[1] 0x0
|
||||
0x0000128 0x43000000 0x00000000 // SDMMC_VENDOR_MISC_CNTRL2_0 30:30=SDMMC_CLK_OVR_ON 0x0
|
||||
// 25:25=ADMA3_CLKEN_OVERRIDE 0x0
|
||||
// 24:24=CQE_CLKEN_OVERRIDE 0x0
|
||||
0x00001F0 0x00080000 0x00080000 // SDMMC_IO_SPARE_0 19:19=SPARE_OUT[3] 0x1
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mmc@700b0000 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
|
||||
prod_c_ds {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x3000007D>;
|
||||
};
|
||||
prod_c_hs {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x3000007D>;
|
||||
};
|
||||
prod_c_sdr12 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_sdr25 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_sdr50 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00008000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_sdr104 {
|
||||
prod = <0x00000100 0x00FF0000 0x00040000
|
||||
0x000001C0 0x0000E000 0x00004000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
prod_c_ddr52 {
|
||||
prod = <0x00000100 0x1FFF0000 0x00000000
|
||||
0x000001E0 0x0000000F 0x00000007
|
||||
0x000001E4 0x30077F7F 0x30007B7B>;
|
||||
};
|
||||
|
||||
|
||||
prod {
|
||||
prod = <
|
||||
0x0000100 0x1FFF000E 0x2090028 // SDMMC_VENDOR_CLOCK_CNTRL_0 28:24=TRIM_VAL 0x5
|
||||
// 23:16=TAP_VAL 0x9
|
||||
// 05:05=SDR50_TUNING_OVERRIDE 0x1
|
||||
// 03:03=PADPIPE_CLKEN_OVERRIDE 0x1
|
||||
// 02:02=SPI_MODE_CLKEN_OVERRIDE 0x0
|
||||
// 01:01=INPUT_IO_CLK 0x0
|
||||
0x00001C0 0x08001FC0 0x8000040 // SDMMC_VENDOR_TUNING_CNTRL0_0 12:06=MUL_M 0x1
|
||||
// 27:27=RETUNING_REQ_EN_ON_CRC_ERR_DETECTION 0x1
|
||||
0x00001C4 0x00000077 0x0 // SDMMC_VENDOR_TUNING_CNTRL1_0 02:00=STEP_SIZE_SDR50 0x0
|
||||
// 06:04=STEP_SIZE_SDR104_HS200 0x0
|
||||
0x0000120 0x00020001 0x00001 // SDMMC_VENDOR_MISC_CNTRL_0 0:0=ERASE_TIMEOUT_LIMIT 0x1
|
||||
// 17:17=SDMMC_SPARE1[1] 0x0
|
||||
0x0000128 0x43000000 0x00000000 // SDMMC_VENDOR_MISC_CNTRL2_0 30:30=SDMMC_CLK_OVR_ON 0x0
|
||||
// 25:25=ADMA3_CLKEN_OVERRIDE 0x0
|
||||
// 24:24=CQE_CLKEN_OVERRIDE 0x0
|
||||
0x00001F0 0x00080000 0x00080000 // SDMMC_IO_SPARE_0 19:19=SPARE_OUT[3] 0x1
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mipi@700e3000 {
|
||||
prod-settings {
|
||||
#prod-cells = <3>;
|
||||
prod_c_dphy_dsi {
|
||||
prod = <
|
||||
0x00000038 0x00001f00 0x00000200 //MIPI_CAL_DSIA_MIPI_CAL_CONFIG_0 12:8=MIPI_CAL_HSPUOSDSIA 0x2
|
||||
0x0000003c 0x00001f00 0x00000200 //MIPI_CAL_DSIB_MIPI_CAL_CONFIG_0 12:8=MIPI_CAL_HSPUOSDSIB 0x2
|
||||
0x00000040 0x00001f00 0x00000200 //MIPI_CAL_DSIC_MIPI_CAL_CONFIG_0 12:8=MIPI_CAL_HSPUOSDSIC 0x2
|
||||
0x00000044 0x00001f00 0x00000200 //MIPI_CAL_DSID_MIPI_CAL_CONFIG_0 12:8=MIPI_CAL_HSPUOSDSID 0x2
|
||||
|
||||
0x0000005c 0x00000f00 0x00000300 //MIPI_CAL_MIPI_BIAS_PAD_CFG1_0 11:8=PAD_DRIV_UP_REF 0x3
|
||||
0x00000060 0x000f00f0 0x00010010 //MIPI_CAL_MIPI_BIAS_PAD_CFG2_0 07:04=PAD_VAUXP_LEVEL 0x1
|
||||
// 19:16=PAD_VCLAMP_LEVEL 0x1
|
||||
0x00000064 0x0000001f 0x00000002 //MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2_0 04:00=MIPI_CAL_HSCLKPUOSDSIA 0x2
|
||||
0x00000068 0x0000001f 0x00000002 //MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2_0 04:00=MIPI_CAL_HSCLKPUOSDSIB 0x2
|
||||
0x00000070 0x0000001f 0x00000002 //MIPI_CAL_DSIC_MIPI_CAL_CONFIG_2_0 04:00=MIPI_CAL_HSCLKPUOSDSIC 0x2
|
||||
0x00000074 0x0000001f 0x00000002 //MIPI_CAL_DSID_MIPI_CAL_CONFIG_2_0 04:00=MIPI_CAL_HSCLKPUOSDSID 0x2
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
@@ -1321,11 +1321,9 @@
|
||||
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
|
||||
nvidia,default-tap = <0x2>;
|
||||
nvidia,default-trim = <0x4>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4_OUT0>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
|
||||
assigned-clock-rates = <200000000>, <1000000000>, <1000000000>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
@@ -1388,8 +1386,8 @@
|
||||
nvidia,default-tap = <0x8>;
|
||||
nvidia,default-trim = <0x0>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
|
||||
nvidia,dqs-trim = <40>;
|
||||
mmc-hs400-1_8v;
|
||||
status = "disabled";
|
||||
|
||||
1257
arch/arm64/boot/dts/nvidia/tegra210b01-prods.dtsi
Normal file
1257
arch/arm64/boot/dts/nvidia/tegra210b01-prods.dtsi
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,11 @@
|
||||
|
||||
pcie@1003000 {
|
||||
compatible = "nvidia,tegra210b01-pcie";
|
||||
|
||||
// do not config pex_io_dpd on b01
|
||||
/delete-property/ pinctrl-names;
|
||||
/delete-property/ pinctrl-0;
|
||||
/delete-property/ pinctrl-1;
|
||||
};
|
||||
|
||||
host1x@50000000 {
|
||||
@@ -35,36 +40,50 @@
|
||||
compatible = "nvidia,tegra210b01-car";
|
||||
};
|
||||
|
||||
// pinmux@700008d4 {
|
||||
// status = "okay";
|
||||
// sdmmc1_1v8_drv: pinmux-sdmmc1-1v8-drv {
|
||||
// sdmmc1 {
|
||||
// nvidia,pull-down-strength = <0x8>;
|
||||
// nvidia,pull-up-strength = <0x8>;
|
||||
// };
|
||||
// };
|
||||
actmon@6000c800 {
|
||||
clocks = <&tegra_car TEGRA210_CLK_ACTMON>,
|
||||
<&bpmp 0>;
|
||||
clock-names = "actmon", "emc";
|
||||
resets = <&tegra_car 119>;
|
||||
reset-names = "actmon";
|
||||
///delete-property/ operating-points-v2;
|
||||
///delete-property/ interconnects;
|
||||
///delete-property/ interconnect-names;
|
||||
};
|
||||
|
||||
// sdmmc1_3v3_drv: pinmux-sdmmc1-3v3-drv {
|
||||
// sdmmc1 {
|
||||
// nvidia,pull-down-strength = <0x8>;
|
||||
// nvidia,pull-up-strength = <0x8>;
|
||||
// };
|
||||
// };
|
||||
pinmux@700008d4 {
|
||||
sdmmc1_1v8_drv: pinmux-sdmmc1-1v8-drv {
|
||||
sdmmc1 {
|
||||
nvidia,pins = "drive_sdmmc1";
|
||||
nvidia,pull-down-strength = <0x8>;
|
||||
nvidia,pull-up-strength = <0x8>;
|
||||
};
|
||||
};
|
||||
|
||||
// sdmmc3_1v8_drv: pinmux-sdmmc3-1v8-drv {
|
||||
// sdmmc3 {
|
||||
// nvidia,pull-down-strength = <0x8>;
|
||||
// nvidia,pull-up-strength = <0x8>;
|
||||
// };
|
||||
// };
|
||||
sdmmc1_3v3_drv: pinmux-sdmmc1-3v3-drv {
|
||||
sdmmc1 {
|
||||
nvidia,pins = "drive_sdmmc1";
|
||||
nvidia,pull-down-strength = <0x8>;
|
||||
nvidia,pull-up-strength = <0x8>;
|
||||
};
|
||||
};
|
||||
|
||||
// sdmmc3_3v3_drv: pinmux-sdmmc3-3v3-drv {
|
||||
// sdmmc3 {
|
||||
// nvidia,pull-down-strength = <0x8>;
|
||||
// nvidia,pull-up-strength = <0x8>;
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
sdmmc3_1v8_drv: pinmux-sdmmc3-1v8-drv {
|
||||
sdmmc3 {
|
||||
nvidia,pins = "drive_sdmmc3";
|
||||
nvidia,pull-down-strength = <0x8>;
|
||||
nvidia,pull-up-strength = <0x8>;
|
||||
};
|
||||
};
|
||||
|
||||
sdmmc3_3v3_drv: pinmux-sdmmc3-3v3-drv {
|
||||
sdmmc3 {
|
||||
nvidia,pins = "drive_sdmmc3";
|
||||
nvidia,pull-down-strength = <0x8>;
|
||||
nvidia,pull-up-strength = <0x8>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
i2c@7000d100 {
|
||||
/delete-property/ pinctrl-0;
|
||||
@@ -92,30 +111,45 @@
|
||||
/delete-node/ external-memory-controller@7001b000;
|
||||
|
||||
mmc@700b0000 {
|
||||
compatible = "nvidia,tegra210b01-sdhci";
|
||||
nvidia,default-tap = <0xb>;
|
||||
nvidia,default-trim = <0xe>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4_OUT2>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
|
||||
nvidia,pad-autocal-pull-up-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-up-offset-1v8 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-1v8 = <0x06>;
|
||||
|
||||
};
|
||||
|
||||
mmc@700b0200 {
|
||||
compatible = "nvidia,tegra210b01-sdhci";
|
||||
nvidia,default-tap = <0x8>;
|
||||
nvidia,default-trim = <0xd>;
|
||||
nvidia,pad-autocal-pull-up-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-up-offset-1v8 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-1v8 = <0x06>;
|
||||
};
|
||||
|
||||
mmc@700b0400 {
|
||||
compatible = "nvidia,tegra210b01-sdhci";
|
||||
nvidia,default-tap = <0xb>;
|
||||
nvidia,default-trim = <0x12>;
|
||||
nvidia,pad-autocal-pull-up-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-up-offset-1v8 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-1v8 = <0x06>;
|
||||
};
|
||||
|
||||
mmc@700b0600 {
|
||||
compatible = "nvidia,tegra210b01-sdhci";
|
||||
nvidia,default-tap = <0x9>;
|
||||
nvidia,default-trim = <0xd>;
|
||||
assigned-clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
|
||||
<&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
|
||||
assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT2>;
|
||||
nvidia,dqs-trim = <0x28>;
|
||||
nvidia,pad-autocal-pull-up-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-3v3 = <0x06>;
|
||||
nvidia,pad-autocal-pull-up-offset-1v8 = <0x06>;
|
||||
nvidia,pad-autocal-pull-down-offset-1v8 = <0x06>;
|
||||
};
|
||||
|
||||
/* Tegra210B01 has MBIST patched and is missing VI unit */
|
||||
|
||||
@@ -1812,7 +1812,7 @@ static struct div_nmp pllss_nmp = {
|
||||
static struct tegra_clk_pll_freq_table pll_c4_vco_freq_table[] = {
|
||||
{ 12000000, 600000000, 50, 1, 1, 0 },
|
||||
{ 13000000, 600000000, 46, 1, 1, 0 }, /* actual: 598.0 MHz */
|
||||
{ 38400000, 600000000, 62, 4, 1, 0 }, /* actual: 595.2 MHz */
|
||||
{ 38400000, 998400000, 78, 3, 1, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
@@ -1824,14 +1824,16 @@ static const struct clk_div_table pll_vco_post_div_table[] = {
|
||||
{ .val = 4, .div = 5 },
|
||||
{ .val = 5, .div = 6 },
|
||||
{ .val = 6, .div = 8 },
|
||||
{ .val = 7, .div = 10 },
|
||||
{ .val = 8, .div = 12 },
|
||||
{ .val = 9, .div = 16 },
|
||||
{ .val = 10, .div = 12 },
|
||||
{ .val = 7, .div = 9 },
|
||||
{ .val = 8, .div = 10 },
|
||||
{ .val = 9, .div = 12 },
|
||||
{ .val = 10, .div = 15 },
|
||||
{ .val = 11, .div = 16 },
|
||||
{ .val = 12, .div = 20 },
|
||||
{ .val = 13, .div = 24 },
|
||||
{ .val = 14, .div = 32 },
|
||||
{ .val = 12, .div = 18 },
|
||||
{ .val = 13, .div = 20 },
|
||||
{ .val = 14, .div = 24 },
|
||||
{ .val = 15, .div = 30 },
|
||||
{ .val = 16, .div = 32 },
|
||||
{ .val = 0, .div = 0 },
|
||||
};
|
||||
|
||||
|
||||
@@ -1705,7 +1705,6 @@ static struct div_nmp pllss_nmp = {
|
||||
|
||||
static struct tegra_clk_pll_freq_table pll_c4_vco_freq_table[] = {
|
||||
{ 38400000, 998400000, 52, 2, 1, 0 },
|
||||
{ 38400000, 787200000, 41, 2, 1, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
@@ -2177,9 +2176,9 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_i2s0] = { .dt_id = TEGRA210_CLK_I2S0, .present = true },
|
||||
[tegra_clk_apbdma] = { .dt_id = TEGRA210_CLK_APBDMA, .present = true },
|
||||
[tegra_clk_kfuse] = { .dt_id = TEGRA210_CLK_KFUSE, .present = true },
|
||||
[tegra_clk_sbc1_9] = { .dt_id = TEGRA210_CLK_SBC1, .present = true },
|
||||
[tegra_clk_sbc2_9] = { .dt_id = TEGRA210_CLK_SBC2, .present = true },
|
||||
[tegra_clk_sbc3_9] = { .dt_id = TEGRA210_CLK_SBC3, .present = true },
|
||||
[tegra_clk_sbc1_9] = { .dt_id = TEGRA210_CLK_SBC1, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_sbc2_9] = { .dt_id = TEGRA210_CLK_SBC2, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_sbc3_9] = { .dt_id = TEGRA210_CLK_SBC3, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_i2c5] = { .dt_id = TEGRA210_CLK_I2C5, .present = true },
|
||||
[tegra_clk_csi] = { .dt_id = TEGRA210_CLK_CSI, .present = true },
|
||||
[tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true },
|
||||
@@ -2189,20 +2188,20 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true },
|
||||
[tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true },
|
||||
[tegra_clk_i2c3] = { .dt_id = TEGRA210_CLK_I2C3, .present = true },
|
||||
[tegra_clk_sbc4_9] = { .dt_id = TEGRA210_CLK_SBC4, .present = true },
|
||||
[tegra_clk_sbc4_9] = { .dt_id = TEGRA210_CLK_SBC4, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_sdmmc3_9] = { .dt_id = TEGRA210_CLK_SDMMC3, .present = true },
|
||||
[tegra_clk_pcie] = { .dt_id = TEGRA210_CLK_PCIE, .present = true },
|
||||
[tegra_clk_owr_8] = { .dt_id = TEGRA210_CLK_OWR, .present = true },
|
||||
[tegra_clk_afi] = { .dt_id = TEGRA210_CLK_AFI, .present = true },
|
||||
[tegra_clk_csite_8] = { .dt_id = TEGRA210_CLK_CSITE, .present = true },
|
||||
[tegra_clk_soc_therm_8] = { .dt_id = TEGRA210_CLK_SOC_THERM, .present = true },
|
||||
[tegra_clk_soc_therm_8] = { .dt_id = TEGRA210_CLK_SOC_THERM, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_dtv] = { .dt_id = TEGRA210_CLK_DTV, .present = true },
|
||||
[tegra_clk_i2cslow] = { .dt_id = TEGRA210_CLK_I2CSLOW, .present = true },
|
||||
[tegra_clk_i2cslow] = { .dt_id = TEGRA210_CLK_I2CSLOW, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_tsec_8] = { .dt_id = TEGRA210_CLK_TSEC, .present = true },
|
||||
[tegra_clk_xusb_host] = { .dt_id = TEGRA210_CLK_XUSB_HOST, .present = true },
|
||||
[tegra_clk_csus] = { .dt_id = TEGRA210_CLK_CSUS, .present = true },
|
||||
[tegra_clk_mselect] = { .dt_id = TEGRA210_CLK_MSELECT, .present = true },
|
||||
[tegra_clk_tsensor] = { .dt_id = TEGRA210_CLK_TSENSOR, .present = true },
|
||||
[tegra_clk_tsensor] = { .dt_id = TEGRA210_CLK_TSENSOR, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_i2s3] = { .dt_id = TEGRA210_CLK_I2S3, .present = true },
|
||||
[tegra_clk_i2s4] = { .dt_id = TEGRA210_CLK_I2S4, .present = true },
|
||||
[tegra_clk_i2c4] = { .dt_id = TEGRA210_CLK_I2C4, .present = true },
|
||||
@@ -2217,8 +2216,8 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_sata_8] = { .dt_id = TEGRA210_CLK_SATA, .present = true },
|
||||
[tegra_clk_hda_8] = { .dt_id = TEGRA210_CLK_HDA, .present = true },
|
||||
[tegra_clk_hda2hdmi] = { .dt_id = TEGRA210_CLK_HDA2HDMI, .present = true },
|
||||
[tegra_clk_cilab] = { .dt_id = TEGRA210_CLK_CILAB, .present = true },
|
||||
[tegra_clk_cilcd] = { .dt_id = TEGRA210_CLK_CILCD, .present = true },
|
||||
[tegra_clk_cilab] = { .dt_id = TEGRA210_CLK_CILAB, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_cilcd] = { .dt_id = TEGRA210_CLK_CILCD, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_cile] = { .dt_id = TEGRA210_CLK_CILE, .present = true },
|
||||
[tegra_clk_dsialp] = { .dt_id = TEGRA210_CLK_DSIALP, .present = true },
|
||||
[tegra_clk_dsiblp] = { .dt_id = TEGRA210_CLK_DSIBLP, .present = true },
|
||||
@@ -2238,7 +2237,7 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, },
|
||||
[tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true },
|
||||
[tegra_clk_spdif_in_8] = { .dt_id = TEGRA210_CLK_SPDIF_IN, .present = true },
|
||||
[tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .present = true },
|
||||
[tegra_clk_spdif_out] = { .dt_id = TEGRA210_CLK_SPDIF_OUT, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_vi_10] = { .dt_id = TEGRA210_CLK_VI, .present = true },
|
||||
[tegra_clk_vi_sensor_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR, .present = true },
|
||||
[tegra_clk_fuse] = { .dt_id = TEGRA210_CLK_FUSE, .present = true },
|
||||
@@ -2276,7 +2275,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_pll_u_60m] = { .dt_id = TEGRA210_CLK_PLL_U_60M, .present = true },
|
||||
[tegra_clk_pll_u_48m] = { .dt_id = TEGRA210_CLK_PLL_U_48M, .present = true },
|
||||
[tegra_clk_pll_x] = { .dt_id = TEGRA210_CLK_PLL_X, .present = true },
|
||||
[tegra_clk_pll_x_out0] = { .dt_id = TEGRA210_CLK_PLL_X_OUT0, .present = true },
|
||||
[tegra_clk_pll_re_vco] = { .dt_id = TEGRA210_CLK_PLL_RE_VCO, .present = true },
|
||||
[tegra_clk_pll_re_out] = { .dt_id = TEGRA210_CLK_PLL_RE_OUT, .present = true },
|
||||
[tegra_clk_spdif_in_sync] = { .dt_id = TEGRA210_CLK_SPDIF_IN_SYNC, .present = true },
|
||||
@@ -2310,7 +2308,6 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_hclk] = { .dt_id = TEGRA210_CLK_HCLK, .present = true },
|
||||
[tegra_clk_pclk] = { .dt_id = TEGRA210_CLK_PCLK, .present = true },
|
||||
[tegra_clk_cclk_g] = { .dt_id = TEGRA210_CLK_CCLK_G, .present = true },
|
||||
[tegra_clk_cclk_lp] = { .dt_id = TEGRA210_CLK_CCLK_LP, .present = true },
|
||||
[tegra_clk_dfll_ref] = { .dt_id = TEGRA210_CLK_DFLL_REF, .present = true },
|
||||
[tegra_clk_dfll_soc] = { .dt_id = TEGRA210_CLK_DFLL_SOC, .present = true },
|
||||
[tegra_clk_vi_sensor2_8] = { .dt_id = TEGRA210_CLK_VI_SENSOR2, .present = true },
|
||||
@@ -2325,8 +2322,8 @@ static struct tegra_clk tegra210_clks[tegra_clk_max] __initdata = {
|
||||
[tegra_clk_spdif_mux] = { .dt_id = TEGRA210_CLK_SPDIF_MUX, .present = true },
|
||||
[tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true },
|
||||
[tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true },
|
||||
[tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true },
|
||||
[tegra_clk_sdmmc_legacy] = { .dt_id = TEGRA210_CLK_SDMMC_LEGACY, .present = true },
|
||||
[tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_sdmmc_legacy] = { .dt_id = TEGRA210_CLK_SDMMC_LEGACY, .use_integer_div = true, .present = true },
|
||||
[tegra_clk_tsecb] = { .dt_id = TEGRA210_CLK_TSECB, .present = true },
|
||||
[tegra_clk_uartape] = { .dt_id = TEGRA210_CLK_UARTAPE, .present = true },
|
||||
[tegra_clk_vi_i2c] = { .dt_id = TEGRA210_CLK_VI_I2C, .present = true },
|
||||
@@ -2535,7 +2532,7 @@ static void tegra210_utmi_hw_sequencer_enable(void)
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
static int tegra210_enable_utmipll(void)
|
||||
static int tegra210b01_enable_utmipll(void)
|
||||
{
|
||||
u32 reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
|
||||
bool hw_on = reg & UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE;
|
||||
@@ -2618,7 +2615,7 @@ static int tegra210_enable_pllu(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra210_init_pllu(void)
|
||||
static int tegra210b01_init_pllu(void)
|
||||
{
|
||||
u32 reg;
|
||||
int err;
|
||||
@@ -2676,7 +2673,7 @@ static int tegra210_init_pllu(void)
|
||||
}
|
||||
|
||||
/* enable UTMIPLL hw control if not yet done by the bootloader */
|
||||
return tegra210_enable_utmipll();
|
||||
return tegra210b01_enable_utmipll();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2876,7 +2873,7 @@ static __init void tegra210_periph_clk_init(struct device_node *np,
|
||||
tegra210_clk_register_mc("mc", "emc");
|
||||
}
|
||||
|
||||
static void __init tegra210_pll_init(void __iomem *clk_base,
|
||||
static void __init tegra210b01_pll_init(void __iomem *clk_base,
|
||||
void __iomem *pmc)
|
||||
{
|
||||
struct clk *clk;
|
||||
@@ -2921,7 +2918,7 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
|
||||
clks[TEGRA210_CLK_PLL_C3] = clk;
|
||||
|
||||
/* PLLU_VCO */
|
||||
if (!tegra210_init_pllu()) {
|
||||
if (!tegra210b01_init_pllu()) {
|
||||
clk = clk_register_fixed_rate(NULL, "pll_u_vco", "pll_ref", 0,
|
||||
480*1000*1000);
|
||||
clk_register_clkdev(clk, "pll_u_vco", NULL);
|
||||
@@ -3030,8 +3027,8 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
|
||||
clks[TEGRA210_CLK_PLL_E] = clk;
|
||||
|
||||
/* PLLC4 */
|
||||
clk = tegra_clk_register_pllre_tegra210("pll_c4_vco", "pll_ref",
|
||||
clk_base, pmc, 0, &pll_c4_vco_params, NULL, pll_ref_freq);
|
||||
clk = tegra_clk_register_pllre("pll_c4_vco", "pll_ref", clk_base, pmc,
|
||||
0, &pll_c4_vco_params, NULL, pll_ref_freq);
|
||||
clk_register_clkdev(clk, "pll_c4_vco", NULL);
|
||||
clks[TEGRA210_CLK_PLL_C4] = clk;
|
||||
|
||||
@@ -3098,6 +3095,55 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
|
||||
clks[TEGRA210_CLK_PLL_P_UPHY_OUT] = clk;
|
||||
}
|
||||
|
||||
static char *tegra210b01_determine_pllc4_rate(void)
|
||||
{
|
||||
struct device_node *node;
|
||||
u32 val;
|
||||
int out0_ratio, i;
|
||||
unsigned long sdmmc_max_rate = 0;
|
||||
struct clk *clk;
|
||||
char *sclk_high_clk;
|
||||
|
||||
for_each_compatible_node(node, NULL, "nvidia,tegra210-sdhci") {
|
||||
if (!of_device_is_available(node))
|
||||
continue;
|
||||
|
||||
if (!of_property_read_u32(node, "max-frequency", &val)
|
||||
&& val > sdmmc_max_rate)
|
||||
sdmmc_max_rate = val;
|
||||
}
|
||||
|
||||
switch (sdmmc_max_rate) {
|
||||
case 266000000:
|
||||
sclk_high_clk = "pll_c4_out1";
|
||||
pll_c4_vco_params.fixed_rate = 798000000;
|
||||
out0_ratio = 4;
|
||||
break;
|
||||
default:
|
||||
sclk_high_clk = "pll_c4_out3";
|
||||
pll_c4_vco_params.fixed_rate = 1000000000;
|
||||
out0_ratio = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
pll_c4_vco_params.fixed_rate /= pll_ref_freq/pll_c4_vco_params.mdiv_default;
|
||||
pll_c4_vco_params.fixed_rate *= pll_ref_freq/pll_c4_vco_params.mdiv_default;
|
||||
|
||||
val = readl(clk_base + PLLC4_BASE);
|
||||
for (i = 0; pll_vco_post_div_table[i].div; i++)
|
||||
if (pll_vco_post_div_table[i].div >= out0_ratio)
|
||||
break;
|
||||
val &= ~GENMASK(23, 19);
|
||||
val |= pll_vco_post_div_table[i].val << pll_c4_vco_params.div_nmp->divp_shift;
|
||||
writel(val, clk_base + PLLC4_BASE);
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "pll_c4_out0", "pll_c4_vco", 0,
|
||||
1, pll_vco_post_div_table[i].div);
|
||||
clks[TEGRA210_CLK_PLL_C4_OUT0] = clk;
|
||||
|
||||
return sclk_high_clk;
|
||||
}
|
||||
|
||||
/* Tegra210 CPU clock and reset control functions */
|
||||
static void tegra210_wait_cpu_in_reset(u32 cpu)
|
||||
{
|
||||
@@ -3179,7 +3225,7 @@ static void tegra210_clk_resume(void)
|
||||
fence_udelay(2, clk_base);
|
||||
|
||||
/* restore PLLs and all peripheral clock rates */
|
||||
tegra210_init_pllu();
|
||||
tegra210b01_init_pllu();
|
||||
clk_restore_context();
|
||||
|
||||
/* restore saved context of peripheral clocks and reset state */
|
||||
@@ -3223,12 +3269,9 @@ static const struct of_device_id pmc_match[] __initconst = {
|
||||
};
|
||||
|
||||
static struct tegra_clk_init_table t210b01_init_table[] __initdata = {
|
||||
{ TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1,
|
||||
TEGRA_TABLE_RATE_CHANGE_OVERCLOCK },
|
||||
{ TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 0, 1,
|
||||
TEGRA_TABLE_RATE_CHANGE_OVERCLOCK },
|
||||
{ TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0,
|
||||
TEGRA_TABLE_RATE_CHANGE_OVERCLOCK },
|
||||
{ TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1, TEGRA_TABLE_RATE_CHANGE_OVERCLOCK },
|
||||
//{ TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 0, 1, TEGRA_TABLE_RATE_CHANGE_OVERCLOCK },
|
||||
{ TEGRA210_CLK_PLL_DP, TEGRA210_CLK_CLK_MAX, 270000000, 0, TEGRA_TABLE_RATE_CHANGE_OVERCLOCK },
|
||||
{ TEGRA210_CLK_PLL_P_UPHY_OUT, TEGRA210_CLK_CLK_MAX, 102000000, 1 },
|
||||
{ TEGRA210_CLK_SDMMC_LEGACY, TEGRA210_CLK_PLL_P, 12000000, 0 },
|
||||
{ TEGRA210_CLK_I2CSLOW, TEGRA210_CLK_CLK_32K, 32000, 0 },
|
||||
@@ -3399,48 +3442,6 @@ static int tegra210b01_reset_deassert(unsigned long id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum clk_id tegra210b01_integer_div_id[] = {
|
||||
tegra_clk_cilab,
|
||||
tegra_clk_cilcd,
|
||||
|
||||
tegra_clk_spdif_out,
|
||||
|
||||
tegra_clk_sbc1_9,
|
||||
tegra_clk_sbc2_9,
|
||||
tegra_clk_sbc3_9,
|
||||
tegra_clk_sbc4_9,
|
||||
|
||||
tegra_clk_sdmmc_legacy,
|
||||
tegra_clk_i2cslow,
|
||||
tegra_clk_qspi,
|
||||
|
||||
tegra_clk_soc_therm_8,
|
||||
tegra_clk_tsensor,
|
||||
};
|
||||
|
||||
static void tegra210b01_adjust_clks(struct tegra_clk *tegra_clks)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Remove CPU_LP claster clocks */
|
||||
tegra_clks[tegra_clk_cclk_lp].present = false;
|
||||
tegra_clks[tegra_clk_pll_x_out0].present = false;
|
||||
|
||||
/* Prevent 1:1.5 fractional divider setting */
|
||||
div1_5_not_allowed = true;
|
||||
|
||||
/* Prevent any fractional setting */
|
||||
for (i = 0; i < ARRAY_SIZE(tegra210b01_integer_div_id); i++) {
|
||||
enum clk_id cid = tegra210b01_integer_div_id[i];
|
||||
|
||||
if (cid >= tegra_clk_max || !tegra_clks[cid].present) {
|
||||
pr_warn("%s: clk %d is not present\n", __func__, cid);
|
||||
continue;
|
||||
}
|
||||
tegra_clks[cid].use_integer_div = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra210b01_clock_init - Tegra210-specific clock initialization
|
||||
* @np: struct device_node * of the DT node for the SoC CAR IP block
|
||||
@@ -3453,6 +3454,7 @@ static void tegra210b01_adjust_clks(struct tegra_clk *tegra_clks)
|
||||
static void __init tegra210b01_clock_init(struct device_node *np)
|
||||
{
|
||||
struct device_node *node;
|
||||
char *sclk_high_clk;
|
||||
u32 value, clk_m_div;
|
||||
|
||||
clk_base = of_iomap(np, 0);
|
||||
@@ -3481,7 +3483,8 @@ static void __init tegra210b01_clock_init(struct device_node *np)
|
||||
if (!clks)
|
||||
return;
|
||||
|
||||
tegra210b01_adjust_clks(tegra210_clks);
|
||||
/* Prevent 1:1.5 fractional divider setting */
|
||||
div1_5_not_allowed = true;
|
||||
|
||||
value = readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT;
|
||||
clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1;
|
||||
@@ -3492,7 +3495,8 @@ static void __init tegra210b01_clock_init(struct device_node *np)
|
||||
return;
|
||||
|
||||
tegra_fixed_clk_init(tegra210_clks);
|
||||
tegra210_pll_init(clk_base, pmc_base);
|
||||
sclk_high_clk = tegra210b01_determine_pllc4_rate();
|
||||
tegra210b01_pll_init(clk_base, pmc_base);
|
||||
tegra210_periph_clk_init(np, clk_base, pmc_base);
|
||||
tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
|
||||
tegra210_audio_plls,
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
|
||||
u8 frac_width, u8 flags)
|
||||
{
|
||||
u64 divider_ux1 = parent_rate;
|
||||
s64 divider_ux1 = parent_rate;
|
||||
int mul;
|
||||
|
||||
if (!rate)
|
||||
return 0;
|
||||
return div_mask(width);
|
||||
|
||||
mul = 1 << frac_width;
|
||||
|
||||
@@ -31,9 +31,6 @@ int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
|
||||
if (flags & TEGRA_DIVIDER_INT)
|
||||
divider_ux1 *= mul;
|
||||
|
||||
if (!div1_5_not_allowed && divider_ux1 < mul)
|
||||
return 0;
|
||||
|
||||
divider_ux1 -= mul;
|
||||
|
||||
if (divider_ux1 > div_mask(width))
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/tegra_prod.h>
|
||||
|
||||
#define BYTES_PER_FIFO_WORD 4
|
||||
|
||||
@@ -64,6 +65,10 @@
|
||||
#define I2C_CLK_DIVISOR 0x06c
|
||||
#define I2C_CLK_DIVISOR_STD_FAST_MODE GENMASK(31, 16)
|
||||
#define I2C_CLK_DIVISOR_HSMODE GENMASK(15, 0)
|
||||
#define I2C_CLK_DIVISOR_STD_FAST_MODE_START 16
|
||||
#define I2C_CLK_DIVISOR_STD_FAST_MODE_WIDTH 16
|
||||
#define I2C_CLK_DIVISOR_HSMODE_START 0
|
||||
#define I2C_CLK_DIVISOR_HSMODE_WIDTH 16
|
||||
|
||||
#define DVC_CTRL_REG1 0x000
|
||||
#define DVC_CTRL_REG1_INTR_EN BIT(10)
|
||||
@@ -108,21 +113,45 @@
|
||||
#define I2C_MST_CORE_CLKEN_OVR BIT(0)
|
||||
|
||||
#define I2C_INTERFACE_TIMING_0 0x094
|
||||
#define I2C_INTERFACE_TIMING_THIGH GENMASK(13, 8)
|
||||
#define I2C_INTERFACE_TIMING_TLOW GENMASK(5, 0)
|
||||
#define I2C_INTERFACE_TIMING_THIGH GENMASK(15, 8)
|
||||
#define I2C_INTERFACE_TIMING_TLOW GENMASK(7, 0)
|
||||
#define I2C_INTERFACE_TIMING_THIGH_START 8
|
||||
#define I2C_INTERFACE_TIMING_THIGH_WIDTH 8
|
||||
#define I2C_INTERFACE_TIMING_TLOW_START 0
|
||||
#define I2C_INTERFACE_TIMING_TLOW_WIDTH 8
|
||||
|
||||
#define I2C_INTERFACE_TIMING_1 0x098
|
||||
#define I2C_INTERFACE_TIMING_TBUF GENMASK(29, 24)
|
||||
#define I2C_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
|
||||
#define I2C_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
|
||||
#define I2C_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
|
||||
#define I2C_INTERFACE_TIMING_TBUF_START 24
|
||||
#define I2C_INTERFACE_TIMING_TBUF_WIDTH 6
|
||||
#define I2C_INTERFACE_TIMING_TSU_STO_START 16
|
||||
#define I2C_INTERFACE_TIMING_TSU_STO_WIDTH 6
|
||||
#define I2C_INTERFACE_TIMING_THD_STA_START 8
|
||||
#define I2C_INTERFACE_TIMING_THD_STA_WIDTH 6
|
||||
#define I2C_INTERFACE_TIMING_TSU_STA_START 0
|
||||
#define I2C_INTERFACE_TIMING_TSU_STA_WIDTH 6
|
||||
|
||||
#define I2C_HS_INTERFACE_TIMING_0 0x09c
|
||||
#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(13, 8)
|
||||
#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(5, 0)
|
||||
#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(15, 8)
|
||||
#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(7, 0)
|
||||
#define I2C_HS_INTERFACE_TIMING_THIGH_START 8
|
||||
#define I2C_HS_INTERFACE_TIMING_THIGH_WIDTH 8
|
||||
#define I2C_HS_INTERFACE_TIMING_TLOW_START 0
|
||||
#define I2C_HS_INTERFACE_TIMING_TLOW_WIDTH 8
|
||||
|
||||
#define I2C_HS_INTERFACE_TIMING_1 0x0a0
|
||||
#define I2C_HS_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
|
||||
#define I2C_HS_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
|
||||
#define I2C_HS_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
|
||||
#define I2C_HS_INTERFACE_TIMING_TSU_STO_START 16
|
||||
#define I2C_HS_INTERFACE_TIMING_TSU_STO_WIDTH 6
|
||||
#define I2C_HS_INTERFACE_TIMING_THD_STA_START 8
|
||||
#define I2C_HS_INTERFACE_TIMING_THD_STA_WIDTH 6
|
||||
#define I2C_HS_INTERFACE_TIMING_TSU_STA_START 0
|
||||
#define I2C_HS_INTERFACE_TIMING_TSU_STA_WIDTH 6
|
||||
|
||||
#define I2C_MST_FIFO_CONTROL 0x0b4
|
||||
#define I2C_MST_FIFO_CONTROL_RX_FLUSH BIT(0)
|
||||
@@ -288,6 +317,8 @@ struct tegra_i2c_dev {
|
||||
dma_addr_t dma_phys;
|
||||
void *dma_buf;
|
||||
|
||||
struct tegra_prod *prod_list;
|
||||
|
||||
bool multimaster_mode;
|
||||
bool atomic_mode;
|
||||
bool dma_mode;
|
||||
@@ -604,42 +635,46 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
|
||||
static void tegra_i2c_write_prod_settings(struct tegra_i2c_dev *i2c_dev,
|
||||
const char *prod_name)
|
||||
{
|
||||
u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode;
|
||||
acpi_handle handle = ACPI_HANDLE(i2c_dev->dev);
|
||||
struct i2c_timings *t = &i2c_dev->timings;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* The reset shouldn't ever fail in practice. The failure will be a
|
||||
* sign of a severe problem that needs to be resolved. Still we don't
|
||||
* want to fail the initialization completely because this may break
|
||||
* kernel boot up since voltage regulators use I2C. Hence, we will
|
||||
* emit a noisy warning on error, which won't stay unnoticed and
|
||||
* won't hose machine entirely.
|
||||
*/
|
||||
if (handle)
|
||||
err = acpi_evaluate_object(handle, "_RST", NULL, NULL);
|
||||
else
|
||||
err = reset_control_reset(i2c_dev->rst);
|
||||
err = tegra_prod_set_by_name(&i2c_dev->base, prod_name, i2c_dev->prod_list);
|
||||
if (err < 0)
|
||||
dev_dbg_once(i2c_dev->dev,
|
||||
"Prod config not found for I2C: %d\n", err);
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(err);
|
||||
static void tegra_i2c_config_prod_settings(struct tegra_i2c_dev *i2c_dev)
|
||||
{
|
||||
struct i2c_timings *t = &i2c_dev->timings;
|
||||
char *prod_name;
|
||||
|
||||
if (IS_DVC(i2c_dev))
|
||||
tegra_dvc_init(i2c_dev);
|
||||
switch (t->bus_freq_hz) {
|
||||
case I2C_MAX_FAST_MODE_PLUS_FREQ + 1 ... I2C_MAX_HIGH_SPEED_MODE_FREQ:
|
||||
prod_name = "prod_c_hs";
|
||||
break;
|
||||
case I2C_MAX_FAST_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
|
||||
prod_name = "prod_c_fmplus";
|
||||
break;
|
||||
case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_FREQ:
|
||||
prod_name = "prod_c_fm";
|
||||
break;
|
||||
case 0 ... I2C_MAX_STANDARD_MODE_FREQ:
|
||||
default:
|
||||
prod_name = "prod_c_sm";
|
||||
break;
|
||||
}
|
||||
|
||||
val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
|
||||
FIELD_PREP(I2C_CNFG_DEBOUNCE_CNT, 2);
|
||||
tegra_i2c_write_prod_settings(i2c_dev, "prod");
|
||||
tegra_i2c_write_prod_settings(i2c_dev, prod_name);
|
||||
}
|
||||
|
||||
if (i2c_dev->hw->has_multi_master_mode)
|
||||
val |= I2C_CNFG_MULTI_MASTER_MODE;
|
||||
|
||||
i2c_writel(i2c_dev, val, I2C_CNFG);
|
||||
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
|
||||
|
||||
if (IS_VI(i2c_dev))
|
||||
tegra_i2c_vi_init(i2c_dev);
|
||||
static void tegra_i2c_set_clk_params(struct tegra_i2c_dev *i2c_dev)
|
||||
{
|
||||
u32 val, clk_divisor, tsu_thd, tlow, thigh, non_hs_mode;
|
||||
struct i2c_timings *t = &i2c_dev->timings;
|
||||
|
||||
switch (t->bus_freq_hz) {
|
||||
case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
|
||||
@@ -680,6 +715,23 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
|
||||
*/
|
||||
if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
|
||||
i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
|
||||
}
|
||||
|
||||
static int tegra_i2c_set_div_clk(struct tegra_i2c_dev *i2c_dev)
|
||||
{
|
||||
u32 clk_multiplier, tlow, thigh, non_hs_mode;
|
||||
struct i2c_timings *t = &i2c_dev->timings;
|
||||
u32 timing, clk_divisor;
|
||||
int err;
|
||||
|
||||
timing = i2c_readl(i2c_dev, I2C_INTERFACE_TIMING_0);
|
||||
|
||||
tlow = FIELD_GET(I2C_INTERFACE_TIMING_TLOW, timing);
|
||||
thigh = FIELD_GET(I2C_INTERFACE_TIMING_THIGH, timing);
|
||||
|
||||
clk_divisor = i2c_readl(i2c_dev, I2C_CLK_DIVISOR);
|
||||
|
||||
non_hs_mode = FIELD_GET(I2C_CLK_DIVISOR_STD_FAST_MODE, clk_divisor);
|
||||
|
||||
clk_multiplier = (tlow + thigh + 2) * (non_hs_mode + 1);
|
||||
|
||||
@@ -690,6 +742,54 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
|
||||
{
|
||||
acpi_handle handle = ACPI_HANDLE(i2c_dev->dev);
|
||||
u32 val;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* The reset shouldn't ever fail in practice. The failure will be a
|
||||
* sign of a severe problem that needs to be resolved. Still we don't
|
||||
* want to fail the initialization completely because this may break
|
||||
* kernel boot up since voltage regulators use I2C. Hence, we will
|
||||
* emit a noisy warning on error, which won't stay unnoticed and
|
||||
* won't hose machine entirely.
|
||||
*/
|
||||
if (handle)
|
||||
err = acpi_evaluate_object(handle, "_RST", NULL, NULL);
|
||||
else
|
||||
err = reset_control_reset(i2c_dev->rst);
|
||||
|
||||
WARN_ON_ONCE(err);
|
||||
|
||||
if (IS_DVC(i2c_dev))
|
||||
tegra_dvc_init(i2c_dev);
|
||||
|
||||
val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
|
||||
FIELD_PREP(I2C_CNFG_DEBOUNCE_CNT, 2);
|
||||
|
||||
if (i2c_dev->hw->has_multi_master_mode)
|
||||
val |= I2C_CNFG_MULTI_MASTER_MODE;
|
||||
|
||||
i2c_writel(i2c_dev, val, I2C_CNFG);
|
||||
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
|
||||
|
||||
if (IS_VI(i2c_dev))
|
||||
tegra_i2c_vi_init(i2c_dev);
|
||||
|
||||
if (i2c_dev->prod_list)
|
||||
tegra_i2c_config_prod_settings(i2c_dev);
|
||||
else
|
||||
tegra_i2c_set_clk_params(i2c_dev);
|
||||
|
||||
err = tegra_i2c_set_div_clk(i2c_dev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!IS_DVC(i2c_dev) && !IS_VI(i2c_dev)) {
|
||||
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
|
||||
|
||||
@@ -1786,6 +1886,12 @@ static int tegra_i2c_probe(struct platform_device *pdev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
i2c_dev->prod_list = devm_tegra_prod_get(i2c_dev->dev);
|
||||
if (IS_ERR_OR_NULL(i2c_dev->prod_list)) {
|
||||
dev_dbg(&pdev->dev, "Prod-setting not available\n");
|
||||
i2c_dev->prod_list = NULL;
|
||||
}
|
||||
|
||||
tegra_i2c_parse_dt(i2c_dev);
|
||||
|
||||
err = tegra_i2c_init_reset(i2c_dev);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
* Copyright (C) 2013 Google, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <soc/tegra/common.h>
|
||||
#include <linux/tegra_prod.h>
|
||||
|
||||
#include "sdhci-cqhci.h"
|
||||
#include "sdhci-pltfm.h"
|
||||
@@ -37,21 +38,28 @@
|
||||
#define SDHCI_TEGRA_VENDOR_CLOCK_CTRL 0x100
|
||||
#define SDHCI_CLOCK_CTRL_TAP_MASK 0x00ff0000
|
||||
#define SDHCI_CLOCK_CTRL_TAP_SHIFT 16
|
||||
#define SDHCI_CLOCK_CTRL_TAP_WIDTH 8
|
||||
#define SDHCI_CLOCK_CTRL_TRIM_MASK 0x1f000000
|
||||
#define SDHCI_CLOCK_CTRL_TRIM_SHIFT 24
|
||||
#define SDHCI_CLOCK_CTRL_TRIM_WIDTH 5
|
||||
#define SDHCI_CLOCK_CTRL_SDR50_TUNING_OVERRIDE BIT(5)
|
||||
#define SDHCI_CLOCK_CTRL_PADPIPE_CLKEN_OVERRIDE BIT(3)
|
||||
#define SDHCI_CLOCK_CTRL_SPI_MODE_CLKEN_OVERRIDE BIT(2)
|
||||
|
||||
#define SDHCI_TEGRA_VENDOR_SYS_SW_CTRL 0x104
|
||||
#define SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE BIT(31)
|
||||
#define SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE_SHIFT 31
|
||||
#define SDHCI_TEGRA_SYS_SW_CTRL_ENHANCED_STROBE_WIDTH 1
|
||||
|
||||
#define SDHCI_TEGRA_VENDOR_CAP_OVERRIDES 0x10c
|
||||
#define SDHCI_TEGRA_CAP_OVERRIDES_DQS_TRIM_MASK 0x00003f00
|
||||
#define SDHCI_TEGRA_CAP_OVERRIDES_DQS_TRIM_SHIFT 8
|
||||
#define SDHCI_TEGRA_CAP_OVERRIDES_DQS_TRIM_WIDTH 6
|
||||
|
||||
#define SDHCI_TEGRA_VENDOR_MISC_CTRL 0x120
|
||||
#define SDHCI_MISC_CTRL_ERASE_TIMEOUT_LIMIT BIT(0)
|
||||
#define SDHCI_MISC_CTRL_ERASE_TIMEOUT_LIMIT_SHIFT 0
|
||||
#define SDHCI_MISC_CTRL_ERASE_TIMEOUT_LIMIT_WIDTH 1
|
||||
#define SDHCI_MISC_CTRL_ENABLE_SDR104 0x8
|
||||
#define SDHCI_MISC_CTRL_ENABLE_SDR50 0x10
|
||||
#define SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300 0x20
|
||||
@@ -64,6 +72,8 @@
|
||||
#define SDHCI_TEGRA_DLLCAL_STA_ACTIVE BIT(31)
|
||||
|
||||
#define SDHCI_VNDR_TUN_CTRL0_0 0x1c0
|
||||
#define SDHCI_VNDR_TUN_CTRL0_CMD_CRC_ERR_EN_SHIFT 28
|
||||
#define SDHCI_VNDR_TUN_CTRL0_CMD_CRC_ERR_EN_WIDTH 1
|
||||
#define SDHCI_VNDR_TUN_CTRL0_TUN_HW_TAP 0x20000
|
||||
#define SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_MASK 0x03fc0000
|
||||
#define SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_SHIFT 18
|
||||
@@ -71,9 +81,12 @@
|
||||
#define SDHCI_VNDR_TUN_CTRL0_MUL_M_SHIFT 6
|
||||
#define SDHCI_VNDR_TUN_CTRL0_TUN_ITER_MASK 0x000e000
|
||||
#define SDHCI_VNDR_TUN_CTRL0_TUN_ITER_SHIFT 13
|
||||
#define SDHCI_VNDR_TUN_CTRL0_TUN_ITER_WIDTH 3
|
||||
#define TRIES_128 2
|
||||
#define TRIES_256 4
|
||||
#define SDHCI_VNDR_TUN_CTRL0_TUN_WORD_SEL_MASK 0x7
|
||||
#define SDHCI_VNDR_TUN_CTRL0_DIV_N_SHIFT 3
|
||||
#define SDHCI_VNDR_TUN_CTRL0_DIV_N_WIDTH 3
|
||||
|
||||
#define SDHCI_TEGRA_VNDR_TUN_CTRL1_0 0x1c4
|
||||
#define SDHCI_TEGRA_VNDR_TUN_STATUS0 0x1C8
|
||||
@@ -134,6 +147,20 @@
|
||||
SDHCI_TRNS_BLK_CNT_EN | \
|
||||
SDHCI_TRNS_DMA)
|
||||
|
||||
static char prod_device_states[MMC_TIMING_COUNTER][20] = {
|
||||
"prod_c_ds", /* MMC_TIMING_LEGACY */
|
||||
"prod_c_hs", /* MMC_TIMING_MMC_HS */
|
||||
"prod_c_hs", /* MMC_TIMING_SD_HS */
|
||||
"prod_c_sdr12", /* MMC_TIMING_UHS_SDR12 */
|
||||
"prod_c_sdr25", /* MMC_TIMING_UHS_SDR25 */
|
||||
"prod_c_sdr50", /* MMC_TIMING_UHS_SDR50 */
|
||||
"prod_c_sdr104", /* MMC_TIMING_UHS_SDR104 */
|
||||
"prod_c_ddr52", /* MMC_TIMING_UHS_DDR50 */
|
||||
"prod_c_ddr52", /* MMC_TIMING_MMC_DDR52 */
|
||||
"prod_c_hs200", /* MMC_TIMING_MMC_HS200 */
|
||||
"prod_c_hs400", /* MMC_TIMING_MMC_HS400 */
|
||||
};
|
||||
|
||||
struct sdhci_tegra_soc_data {
|
||||
const struct sdhci_pltfm_data *pdata;
|
||||
u64 dma_mask;
|
||||
@@ -183,6 +210,7 @@ struct sdhci_tegra {
|
||||
unsigned long curr_clk_rate;
|
||||
u8 tuned_tap_delay;
|
||||
u32 stream_id;
|
||||
struct tegra_prod *prod_list;
|
||||
};
|
||||
|
||||
static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
|
||||
@@ -362,6 +390,19 @@ static void tegra_sdhci_set_tap(struct sdhci_host *host, unsigned int tap)
|
||||
}
|
||||
}
|
||||
|
||||
static void tegra_sdhci_write_prod_settings(struct sdhci_host *host,
|
||||
const char *prod_name)
|
||||
{
|
||||
int err;
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
|
||||
|
||||
err = tegra_prod_set_by_name(&host->ioaddr, prod_name, tegra_host->prod_list);
|
||||
if (err < 0)
|
||||
dev_dbg_once(mmc_dev(host->mmc),
|
||||
"Prod config not found for SDHCI: %d\n", err);
|
||||
}
|
||||
|
||||
static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
@@ -374,6 +415,8 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
|
||||
if (!(mask & SDHCI_RESET_ALL))
|
||||
return;
|
||||
|
||||
tegra_sdhci_write_prod_settings(host, "prod");
|
||||
|
||||
tegra_sdhci_set_tap(host, tegra_host->default_tap);
|
||||
|
||||
misc_ctrl = sdhci_readl(host, SDHCI_TEGRA_VENDOR_MISC_CTRL);
|
||||
@@ -941,7 +984,7 @@ static void tegra_sdhci_post_tuning(struct sdhci_host *host)
|
||||
u32 avg_tap_dly, val, min_tap_dly, max_tap_dly;
|
||||
u8 fixed_tap, start_tap, end_tap, window_width;
|
||||
u8 thdupper, thdlower;
|
||||
u8 num_iter;
|
||||
u16 num_iter;
|
||||
u32 clk_rate_mhz, period_ps, bestcase, worstcase;
|
||||
|
||||
/* retain HW tuned tap to use incase if no correction is needed */
|
||||
@@ -973,7 +1016,33 @@ static void tegra_sdhci_post_tuning(struct sdhci_host *host)
|
||||
end_tap = (val >> SDHCI_TEGRA_VNDR_TUN_STATUS1_END_TAP_SHIFT) &
|
||||
SDHCI_TEGRA_VNDR_TUN_STATUS1_TAP_MASK;
|
||||
window_width = end_tap - start_tap;
|
||||
num_iter = host->tuning_loop_count;
|
||||
|
||||
num_iter = (sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0) &
|
||||
SDHCI_VNDR_TUN_CTRL0_TUN_ITER_MASK) >>
|
||||
SDHCI_VNDR_TUN_CTRL0_TUN_ITER_SHIFT;
|
||||
|
||||
switch (num_iter) {
|
||||
case 0:
|
||||
num_iter = 40;
|
||||
break;
|
||||
case 1:
|
||||
num_iter = 64;
|
||||
break;
|
||||
case 2:
|
||||
num_iter = 128;
|
||||
break;
|
||||
case 3:
|
||||
num_iter = 196;
|
||||
break;
|
||||
case 4:
|
||||
num_iter = 256;
|
||||
break;
|
||||
default:
|
||||
WARN_ON("Invalid value of number of tuning iterations");
|
||||
}
|
||||
|
||||
host->tuning_loop_count = num_iter;
|
||||
|
||||
/*
|
||||
* partial window includes edges of the tuning range.
|
||||
* merged window includes more taps so window width is higher
|
||||
@@ -985,6 +1054,8 @@ static void tegra_sdhci_post_tuning(struct sdhci_host *host)
|
||||
mmc_hostname(host->mmc));
|
||||
tegra_sdhci_tap_correction(host, thdupper, thdlower,
|
||||
fixed_tap);
|
||||
pr_info("%s: Tap value after applying correction %u\n",
|
||||
mmc_hostname(host->mmc), tegra_host->tuned_tap_delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1008,11 +1079,12 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
|
||||
{
|
||||
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
||||
struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
|
||||
bool set_default_tap = false;
|
||||
bool set_default_tap = false; // opposite of tuning_mode
|
||||
bool set_num_tun_iter = false;
|
||||
bool set_dqs_trim = false;
|
||||
bool do_hs400_dll_cal = false;
|
||||
u8 iter = TRIES_256;
|
||||
u32 val;
|
||||
bool set_padpipe_clk_override = false;
|
||||
u32 ret;
|
||||
|
||||
tegra_host->ddr_signaling = false;
|
||||
switch (timing) {
|
||||
@@ -1021,12 +1093,13 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
case MMC_TIMING_MMC_HS200:
|
||||
/* Don't set default tap on tunable modes. */
|
||||
iter = TRIES_128;
|
||||
set_num_tun_iter = true;
|
||||
break;
|
||||
case MMC_TIMING_MMC_HS400:
|
||||
set_dqs_trim = true;
|
||||
do_hs400_dll_cal = true;
|
||||
iter = TRIES_128;
|
||||
set_padpipe_clk_override = true;
|
||||
set_num_tun_iter = true;
|
||||
break;
|
||||
case MMC_TIMING_MMC_DDR52:
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
@@ -1038,18 +1111,6 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
|
||||
break;
|
||||
}
|
||||
|
||||
val = sdhci_readl(host, SDHCI_VNDR_TUN_CTRL0_0);
|
||||
val &= ~(SDHCI_VNDR_TUN_CTRL0_TUN_ITER_MASK |
|
||||
SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_MASK |
|
||||
SDHCI_VNDR_TUN_CTRL0_MUL_M_MASK);
|
||||
val |= (iter << SDHCI_VNDR_TUN_CTRL0_TUN_ITER_SHIFT |
|
||||
0 << SDHCI_VNDR_TUN_CTRL0_START_TAP_VAL_SHIFT |
|
||||
1 << SDHCI_VNDR_TUN_CTRL0_MUL_M_SHIFT);
|
||||
sdhci_writel(host, val, SDHCI_VNDR_TUN_CTRL0_0);
|
||||
sdhci_writel(host, 0, SDHCI_TEGRA_VNDR_TUN_CTRL1_0);
|
||||
|
||||
host->tuning_loop_count = (iter == TRIES_128) ? 128 : 256;
|
||||
|
||||
sdhci_set_uhs_signaling(host, timing);
|
||||
|
||||
tegra_sdhci_pad_autocalib(host);
|
||||
@@ -1059,6 +1120,29 @@ static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
|
||||
else
|
||||
tegra_sdhci_set_tap(host, tegra_host->default_tap);
|
||||
|
||||
/*set padpipe_clk_override*/
|
||||
if (set_padpipe_clk_override) {
|
||||
ret = tegra_prod_set_by_name_partially(&host->ioaddr,
|
||||
prod_device_states[timing], tegra_host->prod_list,
|
||||
0, SDHCI_TEGRA_VENDOR_CLOCK_CTRL,
|
||||
SDHCI_CLOCK_CTRL_PADPIPE_CLKEN_OVERRIDE);
|
||||
if (ret < 0)
|
||||
dev_err(mmc_dev(host->mmc),
|
||||
"Failed to set padpipe clk override value for timing %d, %d\n",
|
||||
timing, ret);
|
||||
}
|
||||
/* Set number of tuning iterations */
|
||||
if (set_num_tun_iter) {
|
||||
ret = tegra_prod_set_by_name_partially(&host->ioaddr,
|
||||
prod_device_states[timing], tegra_host->prod_list,
|
||||
0, SDHCI_VNDR_TUN_CTRL0_0,
|
||||
SDHCI_VNDR_TUN_CTRL0_TUN_WORD_SEL_MASK <<
|
||||
SDHCI_VNDR_TUN_CTRL0_TUN_ITER_SHIFT);
|
||||
if (ret < 0)
|
||||
dev_err(mmc_dev(host->mmc),
|
||||
"Failed to set number of iterations for timing %d, %d\n",
|
||||
timing, ret);
|
||||
}
|
||||
if (set_dqs_trim)
|
||||
tegra_sdhci_set_dqs_trim(host, tegra_host->dqs_trim);
|
||||
|
||||
@@ -1129,6 +1213,12 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
|
||||
static int tegra_sdhci_init_pinctrl_info(struct device *dev,
|
||||
struct sdhci_tegra *tegra_host)
|
||||
{
|
||||
tegra_host->prod_list = devm_tegra_prod_get(dev);
|
||||
if (IS_ERR_OR_NULL(tegra_host->prod_list)) {
|
||||
dev_dbg(dev, "Prod-setting not available\n");
|
||||
tegra_host->prod_list = NULL;
|
||||
}
|
||||
|
||||
tegra_host->pinctrl_sdmmc = devm_pinctrl_get(dev);
|
||||
if (IS_ERR(tegra_host->pinctrl_sdmmc)) {
|
||||
dev_dbg(dev, "No pinctrl info, err: %ld\n",
|
||||
@@ -1506,6 +1596,19 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
|
||||
.max_tap_delay = 185,
|
||||
};
|
||||
|
||||
static const struct sdhci_tegra_soc_data soc_data_tegra210b01 = {
|
||||
.pdata = &sdhci_tegra210_pdata,
|
||||
.dma_mask = DMA_BIT_MASK(34),
|
||||
.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
|
||||
NVQUIRK_HAS_PADCALIB |
|
||||
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
|
||||
NVQUIRK_ENABLE_SDR50 |
|
||||
NVQUIRK_ENABLE_SDR104 |
|
||||
NVQUIRK_HAS_TMCLK,
|
||||
.min_tap_delay = 91,
|
||||
.max_tap_delay = 149,
|
||||
};
|
||||
|
||||
static const struct sdhci_ops tegra186_sdhci_ops = {
|
||||
.get_ro = tegra_sdhci_get_ro,
|
||||
.read_w = tegra_sdhci_readw,
|
||||
@@ -1577,6 +1680,7 @@ static const struct of_device_id sdhci_tegra_dt_match[] = {
|
||||
{ .compatible = "nvidia,tegra194-sdhci", .data = &soc_data_tegra194 },
|
||||
{ .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 },
|
||||
{ .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 },
|
||||
{ .compatible = "nvidia,tegra210b01-sdhci", .data = &soc_data_tegra210b01 },
|
||||
{ .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 },
|
||||
{ .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 },
|
||||
{ .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
|
||||
|
||||
@@ -2171,6 +2171,15 @@ 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)
|
||||
{
|
||||
@@ -2199,12 +2208,22 @@ 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(dev, "4x1, 1x1 configuration\n");
|
||||
*xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
|
||||
return 0;
|
||||
default:
|
||||
dev_info(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,tegra124-pcie") ||
|
||||
of_device_is_compatible(np, "nvidia,tegra210-pcie")) {
|
||||
switch (lanes) {
|
||||
@@ -2217,6 +2236,13 @@ 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(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) {
|
||||
@@ -2339,7 +2365,8 @@ 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")) {
|
||||
} else if (of_device_is_compatible(np, "nvidia,tegra210-pcie") ||
|
||||
of_device_is_compatible(np, "nvidia,tegra210b01-pcie")) {
|
||||
pcie->num_supplies = 3;
|
||||
|
||||
pcie->supplies = devm_kcalloc(pcie->dev, pcie->num_supplies,
|
||||
@@ -2851,7 +2878,7 @@ static const struct tegra_pcie_soc tegra210b01_pcie = {
|
||||
.msi_base_shift = 8,
|
||||
.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
|
||||
.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
|
||||
.pads_refclk_cfg0 = 0x90b890b8,
|
||||
.pads_refclk_cfg0 = 0xb0b880b8,
|
||||
/* FC threshold is bit[25:18] */
|
||||
.update_fc_threshold = 0x01800000,
|
||||
.has_pex_clkreq_en = true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2016-2022, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2016-2024, NVIDIA CORPORATION. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tegra_prod.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
@@ -239,6 +240,24 @@
|
||||
|
||||
#define TEGRA_UTMI_PAD_MAX 4
|
||||
|
||||
/* Prod fields */
|
||||
#define USB2_OTG_PADX_CTL0_LS_RSLEW_FIELD_START 17
|
||||
#define USB2_OTG_PADX_CTL0_LS_RSLEW_FIELD_WIDTH 4
|
||||
#define USB2_OTG_PADX_CTL0_LS_FSLEW_FIELD_START 21
|
||||
#define USB2_OTG_PADX_CTL0_LS_FSLEW_FIELD_WIDTH 4
|
||||
|
||||
#define USB2_OTG_PADX_CTL3_HS_TXEQ_FIELD_START 1
|
||||
#define USB2_OTG_PADX_CTL3_HS_TXEQ_FIELD_WIDTH 3
|
||||
|
||||
#define USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_FIELD_START 3
|
||||
#define USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_FIELD_WIDTH 3
|
||||
#define USB2_BIAS_PAD_CTL1_TRK_START_TIMER_FIELD_START 12
|
||||
#define USB2_BIAS_PAD_CTL1_TRK_START_TIMER_FIELD_WIDTH 7
|
||||
#define USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_FIELD_START 19
|
||||
#define USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_FIELD_WIDTH 7
|
||||
|
||||
#define XUSB_PADCTL_USB2_OTG_PADX_CTL3(x) (0x94 + (x) * 0x40)
|
||||
|
||||
#define TEGRA186_LANE(_name, _offset, _shift, _mask, _type) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
@@ -267,6 +286,8 @@ struct tegra186_xusb_padctl {
|
||||
struct tegra_xusb_padctl base;
|
||||
void __iomem *ao_regs;
|
||||
|
||||
/* prod settings */
|
||||
struct tegra_prod *prod_list;
|
||||
struct tegra_xusb_fuse_calibration calib;
|
||||
|
||||
/* UTMI bias and tracking */
|
||||
@@ -850,6 +871,14 @@ static int tegra186_utmi_phy_set_mode(struct phy *phy, enum phy_mode mode,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tegra186_utmi_write_prod_settings(struct tegra_xusb_padctl *padctl,
|
||||
const char *prod_name)
|
||||
{
|
||||
struct tegra186_xusb_padctl *priv = to_tegra186_xusb_padctl(padctl);
|
||||
|
||||
return tegra_prod_set_by_name(&padctl->regs, prod_name, priv->prod_list);
|
||||
}
|
||||
|
||||
static int tegra186_utmi_phy_power_on(struct phy *phy)
|
||||
{
|
||||
struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
|
||||
@@ -867,6 +896,12 @@ static int tegra186_utmi_phy_power_on(struct phy *phy)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (priv->prod_list) {
|
||||
int err = tegra186_utmi_write_prod_settings(padctl, "prod");
|
||||
if (err)
|
||||
dev_dbg(dev, "failed to apply prod settings\n");
|
||||
}
|
||||
|
||||
value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX);
|
||||
value &= ~(USB2_PORT_MASK << USB2_PORT_SHIFT(index));
|
||||
value |= (PORT_XUSB << USB2_PORT_SHIFT(index));
|
||||
@@ -1512,6 +1547,12 @@ tegra186_xusb_padctl_probe(struct device *dev,
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
|
||||
priv->prod_list = devm_tegra_prod_get(dev);
|
||||
if (IS_ERR_OR_NULL(priv->prod_list)) {
|
||||
dev_dbg(dev, "Prod-settings is not available\n");
|
||||
priv->prod_list = NULL;
|
||||
}
|
||||
|
||||
return &priv->base;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@ source "drivers/platform/olpc/Kconfig"
|
||||
|
||||
source "drivers/platform/surface/Kconfig"
|
||||
|
||||
source "drivers/platform/tegra/Kconfig"
|
||||
|
||||
source "drivers/platform/x86/Kconfig"
|
||||
|
||||
source "drivers/platform/arm64/Kconfig"
|
||||
|
||||
@@ -12,4 +12,5 @@ obj-$(CONFIG_GOLDFISH) += goldfish/
|
||||
obj-$(CONFIG_CHROME_PLATFORMS) += chrome/
|
||||
obj-$(CONFIG_CZNIC_PLATFORMS) += cznic/
|
||||
obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-$(CONFIG_ARM64_PLATFORM_DEVICES) += arm64/
|
||||
|
||||
24
drivers/platform/tegra/Kconfig
Normal file
24
drivers/platform/tegra/Kconfig
Normal file
@@ -0,0 +1,24 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Tegra Platform Specific Drivers
|
||||
#
|
||||
|
||||
menuconfig TEGRA_PLATFORM_DEVICES
|
||||
bool "Tegra Platform Specific Device Drivers"
|
||||
default y
|
||||
help
|
||||
Say Y here to get to see options for device drivers of various
|
||||
Tegra platforms. This option itself does not add any kernel code.
|
||||
|
||||
If you say N, all options in this submenu will be skipped and
|
||||
disabled.
|
||||
|
||||
if TEGRA_PLATFORM_DEVICES
|
||||
|
||||
config TEGRA_PROD_LEGACY
|
||||
def_bool y
|
||||
help
|
||||
This config helps client driver to identify whether prod
|
||||
framework is implemented as legacy method or not.
|
||||
|
||||
endif # TEGRA_PLATFORM_DEVICES
|
||||
3
drivers/platform/tegra/Makefile
Normal file
3
drivers/platform/tegra/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
obj-$(CONFIG_TEGRA_PROD_LEGACY) += tegra_prod.o
|
||||
620
drivers/platform/tegra/tegra_prod.c
Normal file
620
drivers/platform/tegra/tegra_prod.c
Normal file
@@ -0,0 +1,620 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2017, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/tegra_prod.h>
|
||||
|
||||
#define PROD_TUPLE_NUM (sizeof(struct prod_tuple)/sizeof(u32))
|
||||
|
||||
/* tegra_prod: Tegra Prod list for the given submodule
|
||||
* @n_prod_cells: Number of prod setting cells.
|
||||
*/
|
||||
struct tegra_prod {
|
||||
struct tegra_prod_config *prod_config;
|
||||
int num; /* number of tegra_prod*/
|
||||
int n_prod_cells;
|
||||
};
|
||||
|
||||
struct prod_tuple {
|
||||
u32 index; /* Address base index */
|
||||
u32 addr; /* offset address*/
|
||||
u32 mask; /* mask */
|
||||
u32 val; /* value */
|
||||
};
|
||||
|
||||
struct tegra_prod_config {
|
||||
const char *name;
|
||||
struct prod_tuple *prod_tuple;
|
||||
int count; /* number of prod_tuple*/
|
||||
bool boot_init;
|
||||
};
|
||||
|
||||
static int tegra_prod_get_child_tupple_count(struct device *dev,
|
||||
struct device_node *np,
|
||||
int n_tupple)
|
||||
{
|
||||
struct device_node *child;
|
||||
int count;
|
||||
int total_tupple = 0;
|
||||
|
||||
count = of_property_count_u32_elems(np, "prod");
|
||||
if (count > 0) {
|
||||
if ((count < n_tupple) || (count % n_tupple != 0)) {
|
||||
dev_err(dev, "Node %s has invalid entries\n", np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
total_tupple = count / n_tupple;
|
||||
}
|
||||
|
||||
for_each_available_child_of_node(np, child) {
|
||||
count = tegra_prod_get_child_tupple_count(dev, child, n_tupple);
|
||||
if (count < 0)
|
||||
return count;
|
||||
|
||||
total_tupple += count;
|
||||
}
|
||||
|
||||
return total_tupple;
|
||||
}
|
||||
|
||||
static int tegra_prod_read_prod_data(struct device *dev,
|
||||
struct device_node *np,
|
||||
struct prod_tuple *p_tuple,
|
||||
int n_tupple)
|
||||
{
|
||||
u32 pval;
|
||||
int count;
|
||||
int t_count;
|
||||
int cnt;
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
count = of_property_count_u32_elems(np, "prod");
|
||||
if (count <= 0) {
|
||||
dev_dbg(dev, "Node %s: prod prop not found\n", np->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
t_count = count / n_tupple;
|
||||
for (cnt = 0; cnt < t_count; cnt++, p_tuple++) {
|
||||
index = cnt * n_tupple;
|
||||
|
||||
if (n_tupple == 4) {
|
||||
ret = of_property_read_u32_index(np, "prod", index,
|
||||
&pval);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to parse prod of node %s\n",
|
||||
np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
p_tuple->index = pval;
|
||||
index++;
|
||||
} else {
|
||||
p_tuple->index = 0;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32_index(np, "prod", index, &pval);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to parse address of node %s\n",
|
||||
np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
p_tuple->addr = pval;
|
||||
index++;
|
||||
|
||||
ret = of_property_read_u32_index(np, "prod", index, &pval);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to parse mask of node %s\n",
|
||||
np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
p_tuple->mask = pval;
|
||||
index++;
|
||||
|
||||
ret = of_property_read_u32_index(np, "prod", index, &pval);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to parse value of node %s\n",
|
||||
np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
p_tuple->val = pval;
|
||||
}
|
||||
|
||||
return t_count;
|
||||
}
|
||||
|
||||
static int tegra_prod_read_node_tupple(struct device *dev,
|
||||
struct device_node *np,
|
||||
struct prod_tuple *p_tuple,
|
||||
int n_tupple)
|
||||
{
|
||||
int ret = 0;
|
||||
int sindex;
|
||||
struct device_node *child;
|
||||
|
||||
ret = tegra_prod_read_prod_data(dev, np, p_tuple, n_tupple);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
sindex = ret;
|
||||
p_tuple += ret;
|
||||
|
||||
for_each_available_child_of_node(np, child) {
|
||||
ret = tegra_prod_read_node_tupple(dev, child,
|
||||
p_tuple, n_tupple);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
sindex += ret;
|
||||
p_tuple += ret;
|
||||
}
|
||||
|
||||
return sindex;
|
||||
}
|
||||
|
||||
/* Process the tupples and optimise for the register configuration for
|
||||
* Same location.
|
||||
*/
|
||||
static void tegra_prod_optimise_tupple(struct prod_tuple *p_tuple,
|
||||
int n_tupple)
|
||||
{
|
||||
struct prod_tuple *ti, *tj;
|
||||
u32 mask;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n_tupple; ++i) {
|
||||
ti = p_tuple + i;
|
||||
for (j = i + 1; j < n_tupple; ++j) {
|
||||
tj = p_tuple + j;
|
||||
if (ti->index != tj->index)
|
||||
continue;
|
||||
|
||||
if (ti->addr != tj->addr)
|
||||
continue;
|
||||
|
||||
mask = ti->mask & tj->mask;
|
||||
if (!mask)
|
||||
continue;
|
||||
|
||||
ti->val &= ~mask;
|
||||
ti->mask &= ~mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_prod_parse_dt - Read the prod setting form Device tree.
|
||||
* @np: device node from which the property value is to be read.
|
||||
* @np_prod: Prod setting node.
|
||||
* @tegra_prod: The list of tegra prods.
|
||||
*
|
||||
* Read the prod setting form DT according the prod name in tegra prod list.
|
||||
* prod tuple will be allocated dynamically according to the tuple number of
|
||||
* each prod in DT.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
|
||||
static int tegra_prod_parse_dt(struct device *dev,
|
||||
const struct device_node *np,
|
||||
const struct device_node *np_prod,
|
||||
struct tegra_prod *tegra_prod)
|
||||
{
|
||||
struct device_node *child;
|
||||
struct tegra_prod_config *t_prod;
|
||||
struct prod_tuple *p_tuple;
|
||||
int n_child;
|
||||
int n_tupple = 3;
|
||||
int ret;
|
||||
int count;
|
||||
u32 pval;
|
||||
bool mask_opt;
|
||||
|
||||
if (!tegra_prod || !tegra_prod->prod_config) {
|
||||
dev_err(dev, "Node %s: Invalid tegra prods list.\n", np->name);
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
mask_opt = of_property_read_bool(np_prod, "enable-mask-optimisation");
|
||||
|
||||
ret = of_property_read_u32(np_prod, "#prod-cells", &pval);
|
||||
if (!ret)
|
||||
n_tupple = pval;
|
||||
if ((n_tupple != 3) && (n_tupple != 4)) {
|
||||
dev_err(dev, "Node %s: Prod cells not supported\n", np->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
tegra_prod->n_prod_cells = n_tupple;
|
||||
|
||||
n_child = 0;
|
||||
for_each_available_child_of_node(np_prod, child) {
|
||||
t_prod = &tegra_prod->prod_config[n_child];
|
||||
t_prod->name = child->name;
|
||||
|
||||
count = tegra_prod_get_child_tupple_count(dev, child, n_tupple);
|
||||
if (count < 0) {
|
||||
dev_err(dev, "Node %s: Child has not proper setting\n",
|
||||
child->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
dev_err(dev, "Node %s: prod prop not found\n",
|
||||
child->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
t_prod->count = count;
|
||||
|
||||
t_prod->prod_tuple = devm_kcalloc(dev, t_prod->count,
|
||||
sizeof(*p_tuple), GFP_KERNEL);
|
||||
if (!t_prod->prod_tuple)
|
||||
return -ENOMEM;
|
||||
|
||||
t_prod->boot_init = of_property_read_bool(child,
|
||||
"nvidia,prod-boot-init");
|
||||
|
||||
ret = tegra_prod_read_node_tupple(dev, child,
|
||||
t_prod->prod_tuple, n_tupple);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Node %s: Reading prod setting failed: %d\n",
|
||||
child->name, ret);
|
||||
return ret;
|
||||
}
|
||||
if (t_prod->count != ret) {
|
||||
dev_err(dev, "Node %s: prod read failed: exp %d read %d\n",
|
||||
child->name, t_prod->count, ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Optimise the prod configuration */
|
||||
if (mask_opt)
|
||||
tegra_prod_optimise_tupple(t_prod->prod_tuple,
|
||||
t_prod->count);
|
||||
|
||||
|
||||
n_child++;
|
||||
}
|
||||
|
||||
tegra_prod->num = n_child;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_prod_set_tuple - Only set a tuple.
|
||||
* @base: base address of the register.
|
||||
* @prod_tuple: the tuple to set.
|
||||
* @new_mask: Mask override value, 0 means use from tupple.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
static int tegra_prod_set_tuple(void __iomem **base,
|
||||
struct prod_tuple *prod_tuple,
|
||||
u32 new_mask)
|
||||
{
|
||||
u32 reg;
|
||||
u32 mask = (new_mask) ? new_mask : prod_tuple->mask;
|
||||
|
||||
if (!prod_tuple)
|
||||
return -EINVAL;
|
||||
|
||||
reg = readl(base[prod_tuple->index] + prod_tuple->addr);
|
||||
reg = ((reg & ~mask) | (prod_tuple->val & mask));
|
||||
|
||||
writel(reg, base[prod_tuple->index] + prod_tuple->addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_prod_set - Set one prod setting.
|
||||
* @base: base address of the register.
|
||||
* @tegra_prod: the prod setting to set.
|
||||
*
|
||||
* Set all the tuples in one tegra_prod.
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
static int tegra_prod_set(void __iomem **base,
|
||||
struct tegra_prod_config *tegra_prod)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!tegra_prod)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < tegra_prod->count; i++) {
|
||||
ret = tegra_prod_set_tuple(base, &tegra_prod->prod_tuple[i], 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* tegra_prod_set_list - Set all the prod settings of the list in sequence.
|
||||
* @base: base address of the register.
|
||||
* @tegra_prod: the list of tegra prods.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int tegra_prod_set_list(void __iomem **base,
|
||||
struct tegra_prod *tegra_prod)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!tegra_prod)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < tegra_prod->num; i++) {
|
||||
ret = tegra_prod_set(base, &tegra_prod->prod_config[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_prod_set_list);
|
||||
|
||||
/**
|
||||
* tegra_prod_set_boot_init - Set all the prod settings of the list in sequence
|
||||
* Which are needed for boot initialisation.
|
||||
* @base: base address of the register.
|
||||
* @tegra_prod: the list of tegra prods.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int tegra_prod_set_boot_init(void __iomem **base,
|
||||
struct tegra_prod *tegra_prod)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!tegra_prod)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < tegra_prod->num; i++) {
|
||||
if (!tegra_prod->prod_config[i].boot_init)
|
||||
continue;
|
||||
ret = tegra_prod_set(base, &tegra_prod->prod_config[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_prod_set_boot_init);
|
||||
|
||||
/**
|
||||
* tegra_prod_set_by_name - Set the prod setting according the name.
|
||||
* @base: base address of the register.
|
||||
* @name: the name of tegra prod need to set.
|
||||
* @tegra_prod: the list of tegra prods.
|
||||
*
|
||||
* Find the tegra prod in the list according to the name. Then set
|
||||
* that tegra prod.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int tegra_prod_set_by_name(void __iomem **base, const char *name,
|
||||
struct tegra_prod *tegra_prod)
|
||||
{
|
||||
int i;
|
||||
struct tegra_prod_config *t_prod;
|
||||
|
||||
if (!tegra_prod)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < tegra_prod->num; i++) {
|
||||
t_prod = &tegra_prod->prod_config[i];
|
||||
if (!strcasecmp(t_prod->name, name))
|
||||
return tegra_prod_set(base, t_prod);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_prod_set_by_name);
|
||||
|
||||
/**
|
||||
* tegra_prod_set_by_name_partially - Set the prod setting from list partially
|
||||
* under given prod name. The matching is done
|
||||
* qith index, offset and mask.
|
||||
* @base: base address of the register.
|
||||
* @name: the name of tegra prod need to set.
|
||||
* @tegra_prod: the list of tegra prods.
|
||||
* @index: Index of base address.
|
||||
* @offset: Offset of the register.
|
||||
* @mask: Mask field on given register.
|
||||
*
|
||||
* Find the tegra prod in the list according to the name. Then set
|
||||
* that tegra prod which has matching of index, offset and mask.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int tegra_prod_set_by_name_partially(void __iomem **base, const char *name,
|
||||
struct tegra_prod *tegra_prod, u32 index,
|
||||
u32 offset, u32 mask)
|
||||
{
|
||||
struct tegra_prod_config *t_prod;
|
||||
int ret;
|
||||
int i;
|
||||
bool found = false;
|
||||
|
||||
if (!tegra_prod)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < tegra_prod->num; i++) {
|
||||
t_prod = &tegra_prod->prod_config[i];
|
||||
if (!strcasecmp(t_prod->name, name)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -ENODEV;
|
||||
|
||||
for (i = 0; i < t_prod->count; i++) {
|
||||
struct prod_tuple *ptuple = &t_prod->prod_tuple[i];;
|
||||
|
||||
if ((ptuple->index != index) || (ptuple->addr != offset) ||
|
||||
((ptuple->mask & mask) != mask))
|
||||
continue;
|
||||
|
||||
ret = tegra_prod_set_tuple(base, ptuple, mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_prod_set_by_name_partially);
|
||||
|
||||
bool tegra_prod_by_name_supported(struct tegra_prod *tegra_prod,
|
||||
const char *name)
|
||||
{
|
||||
int i;
|
||||
struct tegra_prod_config *t_prod;
|
||||
|
||||
if (!tegra_prod)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < tegra_prod->num; i++) {
|
||||
t_prod = &tegra_prod->prod_config[i];
|
||||
if (!t_prod)
|
||||
break;
|
||||
|
||||
if (!strcasecmp(t_prod->name, name))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(tegra_prod_by_name_supported);
|
||||
|
||||
/**
|
||||
* tegra_prod_init - Init tegra prod list.
|
||||
# @dev: Device handle.
|
||||
* @np: device node from which the property value is to be read.
|
||||
*
|
||||
* Query all the prod settings under DT node & Init the tegra prod list
|
||||
* automatically.
|
||||
*
|
||||
* Returns 0 on success, -EINVAL for wrong prod number, -ENOMEM if failed
|
||||
* to allocate memory for tegra prod list.
|
||||
*/
|
||||
static struct tegra_prod *tegra_prod_init(struct device *dev,
|
||||
const struct device_node *np)
|
||||
{
|
||||
struct tegra_prod *tegra_prod;
|
||||
struct device_node *np_prod;
|
||||
int prod_num = 0;
|
||||
int ret;
|
||||
|
||||
np_prod = of_get_child_by_name(np, "prod-settings");
|
||||
if (!np_prod)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
/* Check whether child is enabled or not */
|
||||
if (!of_device_is_available(np_prod)) {
|
||||
dev_err(dev, "Node %s: Node is not enabled\n", np_prod->name);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
prod_num = of_get_child_count(np_prod);
|
||||
if (prod_num <= 0) {
|
||||
dev_err(dev, "Node %s: No child node for prod settings\n",
|
||||
np_prod->name);
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
|
||||
tegra_prod = devm_kzalloc(dev, sizeof(*tegra_prod), GFP_KERNEL);
|
||||
if (!tegra_prod)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
tegra_prod->prod_config = devm_kcalloc(dev, prod_num,
|
||||
sizeof(*tegra_prod->prod_config),
|
||||
GFP_KERNEL);
|
||||
if (!tegra_prod->prod_config)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
tegra_prod->num = prod_num;
|
||||
|
||||
ret = tegra_prod_parse_dt(dev, np, np_prod, tegra_prod);
|
||||
if (ret) {
|
||||
dev_err(dev, "Node %s: Failed to read the Prod Setting.\n",
|
||||
np->name);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return tegra_prod;
|
||||
}
|
||||
|
||||
static void devm_tegra_prod_release(struct device *dev, void *res)
|
||||
{
|
||||
}
|
||||
|
||||
struct tegra_prod *devm_tegra_prod_get(struct device *dev)
|
||||
{
|
||||
struct tegra_prod **ptr, *prod_list;
|
||||
|
||||
ptr = devres_alloc(devm_tegra_prod_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
prod_list = tegra_prod_init(dev, dev->of_node);
|
||||
if (IS_ERR(prod_list)) {
|
||||
devres_free(ptr);
|
||||
return prod_list;
|
||||
}
|
||||
|
||||
*ptr = prod_list;
|
||||
devres_add(dev, ptr);
|
||||
|
||||
return prod_list;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_tegra_prod_get);
|
||||
|
||||
struct tegra_prod *devm_tegra_prod_get_from_node(struct device *dev,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct tegra_prod **ptr, *prod_list;
|
||||
|
||||
ptr = devres_alloc(devm_tegra_prod_release, sizeof(*ptr), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
prod_list = tegra_prod_init(dev, np);
|
||||
if (IS_ERR(prod_list)) {
|
||||
devres_free(ptr);
|
||||
return prod_list;
|
||||
}
|
||||
|
||||
*ptr = prod_list;
|
||||
devres_add(dev, ptr);
|
||||
|
||||
return prod_list;
|
||||
}
|
||||
EXPORT_SYMBOL(devm_tegra_prod_get_from_node);
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/tegra_prod.h>
|
||||
|
||||
#define SPI_COMMAND1 0x000
|
||||
#define SPI_BIT_LENGTH(x) (((x) & 0x1f) << 0)
|
||||
@@ -63,6 +64,10 @@
|
||||
#define SPI_COMMAND2 0x004
|
||||
#define SPI_TX_TAP_DELAY(x) (((x) & 0x3F) << 6)
|
||||
#define SPI_RX_TAP_DELAY(x) (((x) & 0x3F) << 0)
|
||||
#define SPI_COMMAND2_RX_CLK_TAP_DELAY_START 0
|
||||
#define SPI_COMMAND2_RX_CLK_TAP_DELAY_WIDTH 6
|
||||
#define SPI_COMMAND2_TX_CLK_TAP_DELAY_START 6
|
||||
#define SPI_COMMAND2_TX_CLK_TAP_DELAY_WIDTH 6
|
||||
|
||||
#define SPI_CS_TIMING1 0x008
|
||||
#define SPI_SETUP_HOLD(setup, hold) (((setup) << 4) | (hold))
|
||||
@@ -146,6 +151,10 @@
|
||||
#define DATA_DIR_TX (1 << 0)
|
||||
#define DATA_DIR_RX (1 << 1)
|
||||
|
||||
#define SPI_MISC 0x194
|
||||
#define SPI_MISC_CLKEN_OVERRIDE_START 31
|
||||
#define SPI_MISC_CLKEN_OVERRIDE_WIDTH 1
|
||||
|
||||
#define SPI_DMA_TIMEOUT (msecs_to_jiffies(1000))
|
||||
#define DEFAULT_SPI_DMA_BUF_LEN (16*1024)
|
||||
#define TX_FIFO_EMPTY_COUNT_MAX SPI_TX_FIFO_EMPTY_COUNT(0x40)
|
||||
@@ -218,6 +227,7 @@ struct tegra_spi_data {
|
||||
dma_addr_t tx_dma_phys;
|
||||
struct dma_async_tx_descriptor *tx_dma_desc;
|
||||
const struct tegra_spi_soc_data *soc_data;
|
||||
struct tegra_prod *prod_list;
|
||||
};
|
||||
|
||||
static int tegra_spi_runtime_suspend(struct device *dev);
|
||||
@@ -716,6 +726,31 @@ static void tegra_spi_deinit_dma_param(struct tegra_spi_data *tspi,
|
||||
dma_release_channel(dma_chan);
|
||||
}
|
||||
|
||||
static void tegra_spi_write_prod_settings(struct tegra_spi_data *tspi,
|
||||
const char *prod_name)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = tegra_prod_set_by_name(&tspi->base, prod_name, tspi->prod_list);
|
||||
if (err < 0)
|
||||
dev_dbg_once(tspi->dev,
|
||||
"Prod config not found for SPI: %d\n", err);
|
||||
}
|
||||
|
||||
static void tegra_spi_set_prod(struct tegra_spi_data *tspi, int cs)
|
||||
{
|
||||
char prod_name[15];
|
||||
|
||||
/* Avoid write to register for transfers to last used device */
|
||||
if (tspi->last_used_cs == cs)
|
||||
return;
|
||||
|
||||
sprintf(prod_name, "prod_c_cs%d", cs);
|
||||
tegra_spi_write_prod_settings(tspi, "prod");
|
||||
tegra_spi_write_prod_settings(tspi, prod_name);
|
||||
tspi->last_used_cs = cs;
|
||||
}
|
||||
|
||||
static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
|
||||
{
|
||||
struct tegra_spi_data *tspi = spi_controller_get_devdata(spi->controller);
|
||||
@@ -841,6 +876,7 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
|
||||
command1 &= ~SPI_CS_SW_VAL;
|
||||
}
|
||||
|
||||
if (!tspi->prod_list) {
|
||||
if (tspi->last_used_cs != spi_get_chipselect(spi, 0)) {
|
||||
if (cdata && cdata->tx_clk_tap_delay)
|
||||
tx_tap = cdata->tx_clk_tap_delay;
|
||||
@@ -852,6 +888,9 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
|
||||
tegra_spi_writel(tspi, command2, SPI_COMMAND2);
|
||||
tspi->last_used_cs = spi_get_chipselect(spi, 0);
|
||||
}
|
||||
} else {
|
||||
tegra_spi_set_prod(tspi, spi_get_chipselect(spi, 0));
|
||||
}
|
||||
|
||||
} else {
|
||||
command1 = tspi->command1_reg;
|
||||
@@ -1328,6 +1367,11 @@ static int tegra_spi_probe(struct platform_device *pdev)
|
||||
|
||||
tspi->host = host;
|
||||
tspi->dev = &pdev->dev;
|
||||
tspi->prod_list = devm_tegra_prod_get(tspi->dev);
|
||||
if (IS_ERR_OR_NULL(tspi->prod_list)) {
|
||||
dev_dbg(&pdev->dev, "Prod settings list not initialized\n");
|
||||
tspi->prod_list = NULL;
|
||||
}
|
||||
spin_lock_init(&tspi->lock);
|
||||
|
||||
tspi->soc_data = of_device_get_match_data(&pdev->dev);
|
||||
@@ -1396,12 +1440,14 @@ static int tegra_spi_probe(struct platform_device *pdev)
|
||||
reset_control_assert(tspi->rst);
|
||||
udelay(2);
|
||||
reset_control_deassert(tspi->rst);
|
||||
tspi->last_used_cs = host->num_chipselect + 1;
|
||||
/* initialize CS with 0 in probe */
|
||||
tegra_spi_set_prod(tspi, 0);
|
||||
tspi->def_command1_reg = SPI_M_S;
|
||||
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
|
||||
tspi->spi_cs_timing1 = tegra_spi_readl(tspi, SPI_CS_TIMING1);
|
||||
tspi->spi_cs_timing2 = tegra_spi_readl(tspi, SPI_CS_TIMING2);
|
||||
tspi->def_command2_reg = tegra_spi_readl(tspi, SPI_COMMAND2);
|
||||
tspi->last_used_cs = host->num_chipselect + 1;
|
||||
pm_runtime_put(&pdev->dev);
|
||||
ret = request_threaded_irq(tspi->irq, tegra_spi_isr,
|
||||
tegra_spi_isr_thread, IRQF_ONESHOT,
|
||||
|
||||
@@ -2928,6 +2928,11 @@ pointer_reference {
|
||||
kind: POINTER
|
||||
pointee_type_id: 0x0b4592c2
|
||||
}
|
||||
pointer_reference {
|
||||
id: 0x08451a23
|
||||
kind: POINTER
|
||||
pointee_type_id: 0x0b548e10
|
||||
}
|
||||
pointer_reference {
|
||||
id: 0x084a0a2a
|
||||
kind: POINTER
|
||||
@@ -341018,6 +341023,11 @@ struct_union {
|
||||
member_id: 0x321ff48e
|
||||
}
|
||||
}
|
||||
struct_union {
|
||||
id: 0x0b548e10
|
||||
kind: STRUCT
|
||||
name: "tegra_prod"
|
||||
}
|
||||
struct_union {
|
||||
id: 0x539be05c
|
||||
kind: STRUCT
|
||||
@@ -389996,6 +390006,11 @@ function {
|
||||
parameter_id: 0x5d8155a5
|
||||
parameter_id: 0x4585663f
|
||||
}
|
||||
function {
|
||||
id: 0x2329dac5
|
||||
return_type_id: 0x08451a23
|
||||
parameter_id: 0x0258f96e
|
||||
}
|
||||
function {
|
||||
id: 0x244ac93e
|
||||
return_type_id: 0x1847a854
|
||||
@@ -423314,6 +423329,13 @@ function {
|
||||
parameter_id: 0x3da0a8e3
|
||||
parameter_id: 0x0faae5b1
|
||||
}
|
||||
function {
|
||||
id: 0x9e556887
|
||||
return_type_id: 0x6720d32f
|
||||
parameter_id: 0x0cbf60eb
|
||||
parameter_id: 0x3e10b518
|
||||
parameter_id: 0x08451a23
|
||||
}
|
||||
function {
|
||||
id: 0x9e559491
|
||||
return_type_id: 0x6720d32f
|
||||
@@ -423322,6 +423344,16 @@ function {
|
||||
parameter_id: 0x1479c6e7
|
||||
parameter_id: 0x2d8ee262
|
||||
}
|
||||
function {
|
||||
id: 0x9e567dc1
|
||||
return_type_id: 0x6720d32f
|
||||
parameter_id: 0x0cbf60eb
|
||||
parameter_id: 0x3e10b518
|
||||
parameter_id: 0x08451a23
|
||||
parameter_id: 0xc9082b19
|
||||
parameter_id: 0xc9082b19
|
||||
parameter_id: 0xc9082b19
|
||||
}
|
||||
function {
|
||||
id: 0x9e584c40
|
||||
return_type_id: 0x6720d32f
|
||||
@@ -462049,6 +462081,15 @@ elf_symbol {
|
||||
type_id: 0x2195423c
|
||||
full_name: "devm_tegra_memory_controller_get"
|
||||
}
|
||||
elf_symbol {
|
||||
id: 0x91b997b0
|
||||
name: "devm_tegra_prod_get"
|
||||
is_defined: true
|
||||
symbol_type: FUNCTION
|
||||
crc: 0x80f2a5af
|
||||
type_id: 0x2329dac5
|
||||
full_name: "devm_tegra_prod_get"
|
||||
}
|
||||
elf_symbol {
|
||||
id: 0x0dd13028
|
||||
name: "devm_thermal_of_cooling_device_register"
|
||||
@@ -507215,6 +507256,24 @@ elf_symbol {
|
||||
type_id: 0x8cffc9f3
|
||||
full_name: "tegra_powergate_sequence_power_up"
|
||||
}
|
||||
elf_symbol {
|
||||
id: 0x6e57088a
|
||||
name: "tegra_prod_set_by_name"
|
||||
is_defined: true
|
||||
symbol_type: FUNCTION
|
||||
crc: 0x94a77d4c
|
||||
type_id: 0x9e556887
|
||||
full_name: "tegra_prod_set_by_name"
|
||||
}
|
||||
elf_symbol {
|
||||
id: 0xc54062b4
|
||||
name: "tegra_prod_set_by_name_partially"
|
||||
is_defined: true
|
||||
symbol_type: FUNCTION
|
||||
crc: 0xa19f1486
|
||||
type_id: 0x9e567dc1
|
||||
full_name: "tegra_prod_set_by_name_partially"
|
||||
}
|
||||
elf_symbol {
|
||||
id: 0xcb1a674c
|
||||
name: "tegra_sku_info"
|
||||
@@ -521651,6 +521710,7 @@ interface {
|
||||
symbol_id: 0x4433b91a
|
||||
symbol_id: 0x072870b6
|
||||
symbol_id: 0x43a4025b
|
||||
symbol_id: 0x91b997b0
|
||||
symbol_id: 0x0dd13028
|
||||
symbol_id: 0xfc46114a
|
||||
symbol_id: 0x5dc64161
|
||||
@@ -526664,6 +526724,8 @@ interface {
|
||||
symbol_id: 0x12723a3b
|
||||
symbol_id: 0xdee7b025
|
||||
symbol_id: 0xcfccceca
|
||||
symbol_id: 0x6e57088a
|
||||
symbol_id: 0xc54062b4
|
||||
symbol_id: 0xcb1a674c
|
||||
symbol_id: 0xfc1cafae
|
||||
symbol_id: 0x5bbd3545
|
||||
|
||||
@@ -205,6 +205,7 @@
|
||||
devm_snd_soc_register_component
|
||||
devm_tegra_core_dev_init_opp_table
|
||||
devm_tegra_memory_controller_get
|
||||
devm_tegra_prod_get
|
||||
devm_thermal_of_zone_register
|
||||
devm_usb_get_phy_by_node
|
||||
_dev_notice
|
||||
@@ -1189,6 +1190,7 @@
|
||||
tegra_powergate_power_off
|
||||
tegra_powergate_remove_clamping
|
||||
tegra_powergate_sequence_power_up
|
||||
tegra_prod_set_by_name
|
||||
tegra_sku_info
|
||||
thermal_zone_device_priv
|
||||
thermal_zone_device_update
|
||||
@@ -2407,6 +2409,7 @@
|
||||
sdhci_setup_host
|
||||
sdhci_start_signal_voltage_switch
|
||||
sdhci_suspend_host
|
||||
tegra_prod_set_by_name_partially
|
||||
|
||||
# required by serial-tegra.ko
|
||||
handle_sysrq
|
||||
|
||||
@@ -65,6 +65,7 @@ struct mmc_ios {
|
||||
#define MMC_TIMING_MMC_HS400 10
|
||||
#define MMC_TIMING_SD_EXP 11
|
||||
#define MMC_TIMING_SD_EXP_1_2V 12
|
||||
#define MMC_TIMING_COUNTER 11
|
||||
|
||||
unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */
|
||||
|
||||
|
||||
126
include/linux/tegra_prod.h
Normal file
126
include/linux/tegra_prod.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TEGRA_PRODS_H
|
||||
#define _TEGRA_PRODS_H
|
||||
|
||||
struct tegra_prod;
|
||||
|
||||
/**
|
||||
* tegra_prod_set_list(): Set all prods configurations
|
||||
* @base: List of IO mapped registers.
|
||||
* @tegra_prod: tegra_prod handle which is allocated by devm_tegra_prod_get()
|
||||
* or tegra_prod_get_from_node();
|
||||
*
|
||||
* Configure all the prod configuration listed on prod-setting nodes.
|
||||
*
|
||||
* Returns 0 on success otherwise negive error number for failed case.
|
||||
*/
|
||||
int tegra_prod_set_list(void __iomem **base, struct tegra_prod *tegra_prod);
|
||||
|
||||
/**
|
||||
* tegra_prod_set_boot_init(): Set all prods configurations which has boot init
|
||||
* flag on the prod setting nodes.
|
||||
* @base: List of IO mapped registers.
|
||||
* @tegra_prod: tegra_prod handle which is allocated by devm_tegra_prod_get()
|
||||
* or tegra_prod_get_from_node();
|
||||
*
|
||||
* Configure all the prod configuration listed on prod-setting nodes.
|
||||
*
|
||||
* Returns 0 on success otherwise negive error number for failed case.
|
||||
*/
|
||||
int tegra_prod_set_boot_init(void __iomem **base,
|
||||
struct tegra_prod *tegra_prod);
|
||||
|
||||
/**
|
||||
* tegra_prod_set_by_name(): Set prod configuration with specific prod name.
|
||||
* This is used for conditional prod configurations.
|
||||
* @base: List of IO mapped registers.
|
||||
* @name: Name of conditional prod which need to be configure.
|
||||
* @tegra_prod: tegra_prod handle which is allocated by devm_tegra_prod_get()
|
||||
* or tegra_prod_get_from_node();
|
||||
*
|
||||
* Configure prod configuration with specific prod name for conditional
|
||||
* prod configurations.
|
||||
*
|
||||
* Returns 0 on success otherwise negive error number for failed case.
|
||||
*/
|
||||
int tegra_prod_set_by_name(void __iomem **base, const char *name,
|
||||
struct tegra_prod *tegra_prod);
|
||||
|
||||
/**
|
||||
* tegra_prod_set_by_name_partially - Set the prod setting from list partially
|
||||
* under given prod name. The matching is done
|
||||
* qith index, offset and mask.
|
||||
* @base: base address of the register.
|
||||
* @name: the name of tegra prod need to set.
|
||||
* @tegra_prod: the list of tegra prods.
|
||||
* @index: Index of base address.
|
||||
* @offset: Offset of the register.
|
||||
* @mask: Mask field on given register.
|
||||
*
|
||||
* Find the tegra prod in the list according to the name. Then set
|
||||
* that tegra prod which has matching of index, offset and mask.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int tegra_prod_set_by_name_partially(void __iomem **base, const char *name,
|
||||
struct tegra_prod *tegra_prod, u32 index,
|
||||
u32 offset, u32 mask);
|
||||
|
||||
/**
|
||||
* tegra_prod_by_name_supported - Tell whether tegra prod will be supported by
|
||||
* given name or not.
|
||||
* @tegra_prod: the list of tegra prods.
|
||||
* @name: the name of tegra prod need to set.
|
||||
*
|
||||
* Find the tegra prod in the list according to the name. If it exist then
|
||||
* return true else false.
|
||||
*/
|
||||
bool tegra_prod_by_name_supported(struct tegra_prod *tegra_prod,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* devm_tegra_prod_get(): Get the prod handle from the device.
|
||||
* @dev: Device handle on which prod setting nodes are available.
|
||||
*
|
||||
* Parse the prod-setting node of the dev->of_node and keep all prod
|
||||
* setting data in prod handle.
|
||||
* This handle is used for setting prod configurations.
|
||||
*
|
||||
* Returns valid prod_list handle on success or pointer to the error
|
||||
* when it failed.
|
||||
*/
|
||||
struct tegra_prod *devm_tegra_prod_get(struct device *dev);
|
||||
|
||||
/**
|
||||
* devm_tegra_prod_get_from_node(): Get the prod handle from the node.
|
||||
* @dev: Device handle.
|
||||
* @np: Node pointer on which prod setting nodes are available.
|
||||
*
|
||||
* Parse the prod-setting node of the node pointer "np" and keep all prod
|
||||
* setting data in prod handle.
|
||||
* This handle is used for setting prod configurations.
|
||||
*
|
||||
* Returns valid prod_list handle on success or pointer to the error
|
||||
* when it failed.
|
||||
* The allocated resource is released by driver core framework when device
|
||||
* is unbinded and so no need to call any release APIs for the tegra_prod
|
||||
* handle.
|
||||
*/
|
||||
struct tegra_prod *devm_tegra_prod_get_from_node(struct device *dev,
|
||||
struct device_node *np);
|
||||
#endif
|
||||
Reference in New Issue
Block a user