summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c')
-rw-r--r--drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c610
1 files changed, 610 insertions, 0 deletions
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c b/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c
new file mode 100644
index 000000000000..8ef7b8e7d686
--- /dev/null
+++ b/drivers/gpu/drm/imx/hdp/API_AFE_mcu2_dp.c
@@ -0,0 +1,610 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2016-2017 Cadence Design Systems, Inc.
+ * All rights reserved worldwide.
+ *
+ * Copyright 2018 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE SOFTWARE IS PROVIDED "AS IS",
+ * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ ******************************************************************************
+ *
+ * API_AFE_mcu2_dp.c
+ *
+ ******************************************************************************
+ */
+#include <linux/delay.h>
+#include "API_AFE_mcu2_dp.h"
+#include "../../../../mxc/hdp/all.h"
+
+static void afe_write_reg(state_struct *state,
+ ENUM_AFE_LINK_RATE link_rate,
+ unsigned int addr,
+ unsigned int val1_6,
+ unsigned int val2_1,
+ unsigned int val2_4,
+ unsigned int val2_7,
+ unsigned int val3_2,
+ unsigned int val4_3,
+ unsigned int val5_4)
+{
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ Afe_write(state, addr, val1_6); break;
+ case AFE_LINK_RATE_2_1:
+ Afe_write(state, addr, val2_1); break;
+ case AFE_LINK_RATE_2_4:
+ Afe_write(state, addr, val2_4); break;
+ case AFE_LINK_RATE_2_7:
+ Afe_write(state, addr, val2_7); break;
+ case AFE_LINK_RATE_3_2:
+ Afe_write(state, addr, val3_2); break;
+ case AFE_LINK_RATE_4_3:
+ Afe_write(state, addr, val4_3); break;
+ case AFE_LINK_RATE_5_4:
+ Afe_write(state, addr, val5_4); break;
+ default:
+ break;
+ }
+}
+
+static void phy_cfg_24mhz(state_struct *state, int num_lanes)
+{
+ int k;
+
+ for (k = 0; k < num_lanes; k++) {
+ /* Afe_write (XCVR_DIAG_LANE_FCM_EN_TO | (k << 9), 0x01e0); */
+ Afe_write(state, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9),
+ 0x0090);
+ Afe_write(state, TX_RCVDET_EN_TMR | (k << 9), 0x0960);
+ Afe_write(state, TX_RCVDET_ST_TMR | (k << 9), 0x0030);
+ }
+}
+
+static void phy_cfg_27mhz(state_struct *state, int num_lanes)
+{
+ int k;
+
+ Afe_write(state, CMN_SSM_BIAS_TMR, 0x0087);
+ Afe_write(state, CMN_PLLSM0_PLLEN_TMR, 0x001B);
+ Afe_write(state, CMN_PLLSM0_PLLPRE_TMR, 0x0036);
+ Afe_write(state, CMN_PLLSM0_PLLVREF_TMR, 0x001B);
+ Afe_write(state, CMN_PLLSM0_PLLLOCK_TMR, 0x006C);
+ Afe_write(state, CMN_ICAL_INIT_TMR, 0x0044);
+ Afe_write(state, CMN_ICAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_ICAL_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_ICAL_ADJ_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPUCAL_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPUCAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPU_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPU_ADJ_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPDCAL_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPDCAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_TXPD_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_TXPD_ADJ_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_RXCAL_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_RXCAL_ITER_TMR, 0x0006);
+ Afe_write(state, CMN_RX_ADJ_INIT_TMR, 0x0022);
+ Afe_write(state, CMN_RX_ADJ_ITER_TMR, 0x0006);
+
+ for (k = 0; k < num_lanes; k++) {
+ Afe_write(state, XCVR_PSM_CAL_TMR | (k << 9), 0x016D);
+ Afe_write(state, XCVR_PSM_A0IN_TMR | (k << 9), 0x016D);
+ Afe_write(state, XCVR_DIAG_LANE_FCM_EN_MGN_TMR | (k << 9),
+ 0x00A2);
+ Afe_write(state, TX_DIAG_BGREF_PREDRV_DELAY | (k << 9),
+ 0x0097);
+ Afe_write(state, TX_RCVDET_EN_TMR | (k << 9), 0x0A8C);
+ Afe_write(state, TX_RCVDET_ST_TMR | (k << 9), 0x0036);
+ }
+}
+
+static void phy_cfg_dp_pll0_24mhz(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ int k;
+ unsigned short rdata;
+
+ rdata = Afe_read(state, PHY_HDP_CLK_CTL);
+ rdata = rdata & 0x00FF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2400;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1200;
+ break;
+ case AFE_LINK_RATE_8_1: /* Not used in MCU2 */
+ default:
+ pr_info("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+ Afe_write(state, PHY_HDP_CLK_CTL, rdata);
+ rdata = Afe_read(state, CMN_DIAG_HSCLK_SEL);
+ rdata = rdata & 0xFFCC;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x0011;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, CMN_DIAG_HSCLK_SEL, rdata);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+ rdata = rdata & 0xCFFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x1000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)), rdata);
+ }
+ /* Gbps 1.62 2.16 2.43 2.7 3.24 4.32 5.4 */
+ Afe_write(state, CMN_PLL0_VCOCAL_INIT_TMR, 0x00F0);
+ Afe_write(state, CMN_PLL0_VCOCAL_ITER_TMR, 0x0018);
+ afe_write_reg(state, link_rate, CMN_PLL0_VCOCAL_START,
+ 0x30B9, 0x3087, 0x3096, 0x30B4, 0x30B9, 0x3087, 0x30B4);
+ afe_write_reg(state, link_rate, CMN_PLL0_INTDIV,
+ 0x0086, 0x00B3, 0x00CA, 0x00E0, 0x0086, 0x00B3, 0x00E0);
+ afe_write_reg(state, link_rate, CMN_PLL0_FRACDIV,
+ 0xF915, 0xF6C7, 0x75A1, 0xF479, 0xF915, 0xF6C7, 0xF479);
+ afe_write_reg(state, link_rate, CMN_PLL0_HIGH_THR,
+ 0x0022, 0x002D, 0x0033, 0x0038, 0x0022, 0x002D, 0x0038);
+#ifdef SSC_ON_INIT
+ /* Following register writes enable SSC on PHY's initialization. */
+ afe_write_reg(state, link_rate, CMN_PLL0_SS_CTRL1,
+ 0x0140, 0x01AB, 0x01E0, 0x0204, 0x0140, 0x01AB, 0x0204);
+ Afe_write(state, CMN_PLL0_SS_CTRL2, 0x7F03);
+#endif
+ Afe_write(state, CMN_PLL0_DSM_DIAG, 0x0020);
+ afe_write_reg(state, link_rate, CMN_PLLSM0_USER_DEF_CTRL,
+ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000);
+ Afe_write(state, CMN_DIAG_PLL0_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBH_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBL_OVRD, 0x0000);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_V2I_TUNE,
+ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007);
+ Afe_write(state, CMN_DIAG_PLL0_CP_TUNE, 0x0045);
+ Afe_write(state, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE1,
+ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE2,
+ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+ rdata = rdata & 0x8FFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), rdata);
+ }
+}
+
+/* Valid for 27 MHz only */
+static void phy_cfg_dp_pll0_27mhz(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ int k;
+ unsigned short rdata;
+
+ rdata = Afe_read(state, PHY_HDP_CLK_CTL);
+ rdata = rdata & 0x00FF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2400;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1200;
+ break;
+ case AFE_LINK_RATE_8_1: /* Not supported MCU1 or MCU2 */
+ default:
+ pr_info("Warning. Unsupported Link Rate!\n");
+ break;
+ }
+ Afe_write(state, PHY_HDP_CLK_CTL, rdata);
+ rdata = Afe_read(state, CMN_DIAG_HSCLK_SEL);
+ rdata = rdata & 0xFFCC;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x0011;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, CMN_DIAG_HSCLK_SEL, rdata);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)));
+ rdata = rdata & 0xCFFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x1000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x0000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_HSCLK_SEL | (k << 9)), rdata);
+ }
+ /* Gbps 1.62 2.16 2.43 2.7 3.24 4.32 5.4 */
+ Afe_write(state, CMN_PLL0_VCOCAL_INIT_TMR, 0x010E);
+ Afe_write(state, CMN_PLL0_VCOCAL_ITER_TMR, 0x001B);
+ afe_write_reg(state, link_rate, CMN_PLL0_VCOCAL_START,
+ 0x30B9, 0x3087, 0x3096, 0x30B4, 0x30B9, 0x3087, 0x30B4);
+ afe_write_reg(state, link_rate, CMN_PLL0_INTDIV,
+ 0x0077, 0x009F, 0x00B3, 0x00C7, 0x0077, 0x009F, 0x00C7);
+ afe_write_reg(state, link_rate, CMN_PLL0_FRACDIV,
+ 0xF9DA, 0xF7CD, 0xF6C7, 0xF5C1, 0xF9DA, 0xF7CD, 0xF5C1);
+ afe_write_reg(state, link_rate, CMN_PLL0_HIGH_THR,
+ 0x001E, 0x0028, 0x002D, 0x0032, 0x001E, 0x0028, 0x0032);
+#ifdef SSC_ON_INIT
+ /* Following register writes enable SSC on PHY's initialization. */
+ afe_write_reg(state, link_rate, CMN_PLL0_SS_CTRL1,
+ 0x0152, 0x01C2, 0x01FB, 0x0233, 0x0152, 0x01C2, 0x0233);
+ Afe_write(state, CMN_PLL0_SS_CTRL2, 0x6B04);
+#endif
+ Afe_write(state, CMN_PLL0_DSM_DIAG, 0x0020);
+ afe_write_reg(state, link_rate, CMN_PLLSM0_USER_DEF_CTRL,
+ 0x0000, 0x1000, 0x1000, 0x1000, 0x0000, 0x1000, 0x1000);
+ Afe_write(state, CMN_DIAG_PLL0_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBH_OVRD, 0x0000);
+ Afe_write(state, CMN_DIAG_PLL0_FBL_OVRD, 0x0000);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_V2I_TUNE,
+ 0x0006, 0x0007, 0x0007, 0x0007, 0x0006, 0x0007, 0x0007);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_CP_TUNE,
+ 0x0043, 0x0043, 0x0043, 0x0042, 0x0043, 0x0043, 0x0042);
+ Afe_write(state, CMN_DIAG_PLL0_LF_PROG, 0x0008);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE1,
+ 0x0100, 0x0001, 0x0001, 0x0001, 0x0100, 0x0001, 0x0001);
+ afe_write_reg(state, link_rate, CMN_DIAG_PLL0_PTATIS_TUNE2,
+ 0x0007, 0x0001, 0x0001, 0x0001, 0x0007, 0x0001, 0x0001);
+ for (k = 0; k < num_lanes; k = k + 1) {
+ rdata = Afe_read(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)));
+ rdata = rdata & 0x8FFF;
+ switch (link_rate) {
+ case AFE_LINK_RATE_1_6:
+ case AFE_LINK_RATE_2_1:
+ case AFE_LINK_RATE_2_4:
+ case AFE_LINK_RATE_2_7:
+ rdata = rdata | 0x2000;
+ break;
+ case AFE_LINK_RATE_3_2:
+ case AFE_LINK_RATE_4_3:
+ case AFE_LINK_RATE_5_4:
+ rdata = rdata | 0x1000;
+ break;
+ default:
+ break;
+ }
+ Afe_write(state, (XCVR_DIAG_PLLDRC_CTRL | (k << 9)), rdata);
+ }
+}
+
+static void phy_cfg_dp_ln(state_struct *state, int num_lanes)
+{
+ int k;
+ unsigned short rdata;
+
+ for (k = 0; k < num_lanes; k = k + 1) {
+ Afe_write(state, (XCVR_PSM_RCTRL | (k << 9)), 0xBEFC);
+ if (state->edp == 0) {
+ Afe_write(state, (TX_PSC_A0 | (k << 9)), 0x6799);
+ Afe_write(state, (TX_PSC_A1 | (k << 9)), 0x6798);
+ Afe_write(state, (TX_PSC_A2 | (k << 9)), 0x0098);
+ Afe_write(state, (TX_PSC_A3 | (k << 9)), 0x0098);
+ } else {
+ Afe_write(state, (TX_PSC_A0 | (k << 9)), 0x279B);
+ Afe_write(state, (TX_PSC_A1 | (k << 9)), 0x2798);
+ Afe_write(state, (TX_PSC_A2 | (k << 9)), 0x0098);
+ Afe_write(state, (TX_PSC_A3 | (k << 9)), 0x0098);
+
+ rdata = Afe_read(state, TX_DIAG_TX_DRV | (k << 9));
+ /* keep bits related to programmable boost */
+ rdata &= 0x0600;
+ rdata |= 0x00C0;
+ Afe_write(state, (TX_DIAG_TX_DRV | (k << 9)), rdata);
+ }
+ rdata = Afe_read(state, RX_PSC_CAL | (k << 9));
+ rdata = rdata & 0xFFBB;
+ Afe_write(state, (RX_PSC_CAL | (k << 9)), rdata);
+ rdata = Afe_read(state, RX_PSC_A0 | (k << 9));
+ rdata = rdata & 0xFFBB;
+ Afe_write(state, (RX_PSC_A0 | (k << 9)), rdata);
+ }
+}
+
+static void aux_cfg_t28hpc(state_struct *state)
+{
+#ifdef DEBUG
+ unsigned short rdata;
+#endif
+ Afe_write(state, TX_DIG_CTRL_REG_2, 36);
+
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x0100);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x0300);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_3, 0x0000);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0x2008);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0x2018);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA018);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030C);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_5, 0x0000);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_4, 0x1001);
+ cdn_usleep(150);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA098);
+ cdn_usleep(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_1, 0xA198);
+ cdn_usleep(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030d);
+ cdn_usleep(5000);
+ Afe_write(state, TX_ANA_CTRL_REG_2, 0x030f);
+ cdn_usleep(5000);
+
+#ifdef DEBUG
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_1);
+ pr_info("TX_ANA_CTRL_REG_1 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_2);
+ pr_info("TX_ANA_CTRL_REG_2 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_3);
+ pr_info("TX_ANA_CTRL_REG_3 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_4);
+ pr_info("TX_ANA_CTRL_REG_4 %x)\n", rdata);
+ rdata = Afe_read(state, TX_ANA_CTRL_REG_5);
+ pr_info("TX_ANA_CTRL_REG_5 %x)\n", rdata);
+#endif
+}
+
+void afe_init_t28hpc(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ u16 val;
+ const int phy_reset_workaround = 0;
+
+ const REFCLK_FREQ refclk = REFCLK_27MHZ;
+
+ if (AFE_check_rate_supported(link_rate) == 0) {
+ pr_err("afe_init_t28hpc(): Selected link rate not supported: 0x%x\n",
+ link_rate);
+ return;
+ }
+
+ if (phy_reset_workaround) {
+ int k;
+ uint32_t reg_val;
+ /* enable PHY isolation mode only for CMN */
+ /* register PHY_PMA_ISOLATION_CTRL */
+ Afe_write(state, 0xC81F, 0xD000);
+
+ /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div
+ * dividers
+ */
+ /* register PHY_PMA_ISO_PLL_CTRL1 */
+ reg_val = Afe_read(state, 0xC812);
+ reg_val &= 0xFF00;
+ reg_val |= 0x0012;
+ Afe_write(state, 0xC812, reg_val);
+
+ /* assert PHY reset from isolation register */
+ /* register PHY_ISO_CMN_CTRL */
+ Afe_write(state, 0xC010, 0x0000);
+
+ /* assert PMA CMN reset */
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0000);
+
+ for (k = 0; k < num_lanes; k++) {
+ /* register XCVR_DIAG_BIDI_CTRL */
+ Afe_write(state, 0x40E8 | (k << 9), 0x00FF);
+ }
+ }
+
+ val = Afe_read(state, PHY_PMA_CMN_CTRL1);
+ val = val & 0xFFF7;
+ val = val | 0x0008;
+ Afe_write(state, PHY_PMA_CMN_CTRL1, val);
+
+ Afe_write(state, CMN_DIAG_PLL0_TEST_MODE, 0x0022);
+ Afe_write(state, CMN_PSM_CLK_CTRL, 0x0016);
+
+ if (refclk == REFCLK_24MHZ) {
+ phy_cfg_24mhz(state, num_lanes);
+ phy_cfg_dp_pll0_24mhz(state, num_lanes, link_rate);
+ } else if (refclk == REFCLK_27MHZ) {
+ phy_cfg_27mhz(state, num_lanes);
+ phy_cfg_dp_pll0_27mhz(state, num_lanes, link_rate);
+ } else
+ pr_info("AFE_init() *E: Incorrect value of the refclk: %0d\n",
+ refclk);
+
+ val = Afe_read(state, PHY_PMA_CMN_CTRL1);
+ val = val & 0xFF8F;
+ /* for single ended reference clock on the cmn_ref_clk_int pin:
+ * PHY_PMA_CMN_CTRL1[6:4]=3'b011
+ * val |= 0x0030;
+ */
+
+ /* for differential clock on the refclk_p and refclk_m off chip pins:
+ * PHY_PMA_CMN_CTRL1[6:4]=3'b000
+ * val = val | 0x0030;
+ */
+ val = val | 0x0000; /* select external reference */
+ Afe_write(state, PHY_PMA_CMN_CTRL1, val);
+
+ /* for differential clock on the refclk_p and refclk_m off chip pins:
+ * CMN_DIAG_ACYA[8]=1'b1
+ */
+ Afe_write(state, CMN_DIAG_ACYA /*0x01FF*/, 0x0100);
+
+ if (phy_reset_workaround) {
+ int k;
+ /* Deassert PHY reset*/
+ /* register PHY_ISO_CMN_CTRL */
+ Afe_write(state, 0xC010, 0x0001);
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0003);
+ for (k = 0; k < num_lanes; k++) {
+ /* register XCVR_PSM_RCTRL */
+ Afe_write(state, 0x4001 | (k << 9), 0xFEFC);
+ }
+ /* Assert cmn_macro_pwr_en */
+ /* register PHY_PMA_ISO_CMN_CTRL */
+ Afe_write(state, 0xC810, 0x0013);
+
+ /* wait for cmn_macro_pwr_en_ack */
+ /* PHY_PMA_ISO_CMN_CTRL */
+ while (!(Afe_read(state, 0xC810) & (1 << 5)))
+ ;
+
+ /* wait for cmn_ready */
+ /* PHY_PMA_CMN_CTRL1 */
+ while (!(Afe_read(state, 0xC800) & (1 << 0)))
+ ;
+ }
+
+ if (state->edp != 0)
+ Afe_write(state, CMN_DIAG_CAL_CTRL, 0x0001);
+
+ phy_cfg_dp_ln(state, num_lanes);
+
+ /* Configure PHY in A2 Mode */
+ Afe_write(state, PHY_HDP_MODE_CTRL, 0x0004);
+}
+
+void afe_power_t28hpc(state_struct *state,
+ int num_lanes,
+ ENUM_AFE_LINK_RATE link_rate)
+{
+ unsigned short val;
+ int i = 0;
+
+ if (AFE_check_rate_supported(link_rate) == 0) {
+ pr_err("%s() *E: Selected link rate not supported: 0x%x\n",
+ __func__, link_rate);
+ return;
+ }
+
+ Afe_write(state, TX_DIAG_ACYA_0, 1);
+ Afe_write(state, TX_DIAG_ACYA_1, 1);
+ Afe_write(state, TX_DIAG_ACYA_2, 1);
+ Afe_write(state, TX_DIAG_ACYA_3, 1);
+
+ Afe_write(state, TXDA_CYA_AUXDA_CYA, 1);
+
+ /* Wait for A2 ACK (PHY_HDP_MODE_CTL [6] = 1’b1) */
+ do {
+ val = Afe_read(state, PHY_HDP_MODE_CTRL);
+ val = val >> 6;
+ if (i++ % 10000 == 0)
+ pr_info("Wait for A2 ACK\n");
+ } while ((val & 1) == 0);
+
+ /* Configure PHY in A0 mode (PHY must be in the A0 power
+ * state in order to transmit data)
+ */
+ Afe_write(state, PHY_HDP_MODE_CTRL, 0x0101);
+ /* Wait for A2 ACK (PHY_HDP_MODE_CTL [4] = 1’b1) */
+ do {
+ val = Afe_read(state, PHY_HDP_MODE_CTRL);
+ val = val >> 4;
+ if (i++ % 10000 == 0)
+ pr_info("Wait for A2 ACK again\n");
+ } while ((val & 1) == 0);
+
+ aux_cfg_t28hpc(state);
+
+}