kernel_samsung_a53x/drivers/phy/samsung/phy-exynos-usbdp-gen2-v4.c

2788 lines
92 KiB
C
Raw Normal View History

2024-06-15 21:02:09 +02:00
// SPDX-License-Identifier: GPL-2.0
/**
*
* Copyright (c) 2021 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 of
* the License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
//#include <linux/soc/samsung/exynos-soc.h>
#include <linux/delay.h>
#include "phy-samsung-usb-cal.h"
#include "phy-exynos-usb3p1-reg.h"
#include "phy-exynos-usbdp-gen2-v4.h"
#include "phy-exynos-usbdp-gen2-v4-reg.h"
#include "phy-exynos-usbdp-gen2-v4-reg-pcs.h"
#if defined(USBDP_GEN2_DBG_OFFSET_CAL_CODE)
#define usbdp_print_offset_cal_code(...) printk(__VA_ARGS__)
#else
#define usbdp_print_offset_cal_code(...)
#endif
static void phy_exynos_usbdp_g2_v4_tune_each_late(struct exynos_usbphy_info *info, char *name, int val)
{
void __iomem *link_base = info->link_base;
u32 reg;
/* Gen2 Tx DRIVER pre-shoot, de-emphasis ctrl
* [17:12] Deemphasis
* [11:6] Level
* [5:0] Preshoot
* */
if (!strcmp(name, "sstx_deemp_ssp")) {
reg = readl(link_base + USB31DRD_LINK_LCSR_TX_DEEMPH);
reg &= ~(0x3F000);
reg |= val << 12;
writel(reg, link_base + USB31DRD_LINK_LCSR_TX_DEEMPH);
}
else if (!strcmp(name, "sstx_pre_shoot_ssp")) {
reg = readl(link_base + USB31DRD_LINK_LCSR_TX_DEEMPH);
reg &= ~(0x0003F);
reg |= val;
writel(reg, link_base + USB31DRD_LINK_LCSR_TX_DEEMPH);
}
}
void phy_exynos_usbdp_g2_v4_tune_each(struct exynos_usbphy_info *info, char *name, int val)
{
void __iomem *regs_base = info->pma_base;
void __iomem *pcs_base = info->pcs_base;
u32 reg = 0;
if (!name)
return;
if (val == -1)
return;
/*
RX Squelch Detect Threshold Control
SQTH
Gne2
0x0DF8 [3:0]
0x1DF8 [3:0]
Gne1
0x0DF8 [7:4]
0x1DF8 [7:4]
0000 0mV
0011 75mV
0100 90mV
1000 105mV
1111 255mV
*/
if (!strcmp(name, "ssrx_sqhs_th_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG037E);
reg &= USBDP_TRSV_REG037E_LN0_RX_SQHS_TH_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG037E_LN0_RX_SQHS_TH_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG037E);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG077E);
reg &= USBDP_TRSV_REG077E_LN2_RX_SQHS_TH_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG077E_LN2_RX_SQHS_TH_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG077E);
} else if (!strcmp(name, "ssrx_sqhs_th_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG037E);
reg &= USBDP_TRSV_REG037E_LN0_RX_SQHS_TH_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG037E_LN0_RX_SQHS_TH_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG037E);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG077E);
reg &= USBDP_TRSV_REG077E_LN2_RX_SQHS_TH_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG077E_LN2_RX_SQHS_TH_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG077E);
}
/*
LFPS Detect Threshold Control
LFPS RX
0x0A0C [3:1]
0x1A0C [3:1]
000 60mV
001 90mV
010 130mV
011 160mV
111 280mV
*/
else if (!strcmp(name, "ssrx_lfps_th")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0283);
reg &= USBDP_TRSV_REG0283_LN0_ANA_RX_LFPS_TH_CTRL_CLR;
reg |= USBDP_TRSV_REG0283_LN0_ANA_RX_LFPS_TH_CTRL_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0283);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0683);
reg &= USBDP_TRSV_REG0683_LN2_ANA_RX_LFPS_TH_CTRL_CLR;
reg |= USBDP_TRSV_REG0683_LN2_ANA_RX_LFPS_TH_CTRL_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0683);
}
/*
Adapation logic off
0x0AD0=00
0x1AD0=00
DFE 1tap Adapation
0x0AD0=03
0x1AD0=03
DFE all-tap Adapation (Recommand)
0x0AD0=3F
0x1AD0=3F
DFE,CTLE Adapation
0x0AD0=FF
0x1AD0=FF
*/
else if (!strcmp(name, "ssrx_adap_coef_sel")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02B4);
reg &= USBDP_TRSV_REG02B4_LN0_RX_SSLMS_ADAP_COEF_SEL__7_0_CLR;
reg |= USBDP_TRSV_REG02B4_LN0_RX_SSLMS_ADAP_COEF_SEL__7_0_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02B4);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06B4);
reg &= USBDP_TRSV_REG06B4_LN2_RX_SSLMS_ADAP_COEF_SEL__7_0_CLR;
reg |= USBDP_TRSV_REG06B4_LN2_RX_SSLMS_ADAP_COEF_SEL__7_0_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06B4);
}
/*
RX PEQ Control
0x0AD0[7] = 0 : Tune, 1 : adaptation
0x1AD0[7]
Gen1
0x0A74 [4:0]
0x1A74 [4:0]
Gen2
0x0A78 [4:0]
0x1A78 [4:0]
00000 0dB
...
01100 5dB
...
10000 6dB (Max)
*/
else if (!strcmp(name, "ssrx_mf_eq_psel_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG029D);
reg &= USBDP_TRSV_REG029D_LN0_RX_SSLMS_MF_INIT_SP_CLR;
reg |= USBDP_TRSV_REG029D_LN0_RX_SSLMS_MF_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG029D);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG069D);
reg &= USBDP_TRSV_REG069D_LN2_RX_SSLMS_MF_INIT_SP_CLR;
reg |= USBDP_TRSV_REG069D_LN2_RX_SSLMS_MF_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG069D);
} else if (!strcmp(name, "ssrx_mf_eq_psel_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG029E);
reg &= USBDP_TRSV_REG029E_LN0_RX_SSLMS_MF_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG029E_LN0_RX_SSLMS_MF_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG029E);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG069E);
reg &= USBDP_TRSV_REG069E_LN2_RX_SSLMS_MF_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG069E_LN2_RX_SSLMS_MF_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG069E);
} else if (!strcmp(name, "ssrx_mf_eq_zsel_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG025A);
reg &= USBDP_TRSV_REG025A_LN0_RX_PEQ_Z_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG025A_LN0_RX_PEQ_Z_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG025A);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG065A);
reg &= USBDP_TRSV_REG065A_LN2_RX_PEQ_Z_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG065A_LN2_RX_PEQ_Z_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG065A);
} else if (!strcmp(name, "ssrx_mf_eq_zsel_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG025A);
reg &= USBDP_TRSV_REG025A_LN0_RX_PEQ_Z_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG025A_LN0_RX_PEQ_Z_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG025A);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG065A);
reg &= USBDP_TRSV_REG065A_LN2_RX_PEQ_Z_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG065A_LN2_RX_PEQ_Z_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG065A);
}
/*
RX HF EQ Control
0x0AD0[6] = 0 : Tune, 1 : adaptation
0x1AD0[6]
Gen1
0x0A5C [4:0]
0x1A5C [4:0]
Gen2
0x0A60 [4:0]
0x1A60 [4:0]
00000 0dB
...
01100 15dB
...
10000 20dB (Max)
*/
else if (!strcmp(name, "ssrx_hf_eq_rsel_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0297);
reg &= USBDP_TRSV_REG0297_LN0_RX_SSLMS_HF_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0297_LN0_RX_SSLMS_HF_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0297);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0697);
reg &= USBDP_TRSV_REG0697_LN2_RX_SSLMS_HF_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0697_LN2_RX_SSLMS_HF_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0697);
} else if (!strcmp(name, "ssrx_hf_eq_rsel_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0298);
reg &= USBDP_TRSV_REG0298_LN0_RX_SSLMS_HF_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0298_LN0_RX_SSLMS_HF_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0298);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0698);
reg &= USBDP_TRSV_REG0698_LN2_RX_SSLMS_HF_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0698_LN2_RX_SSLMS_HF_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0698);
} else if (!strcmp(name, "ssrx_hf_eq_csel_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG024C);
reg &= USBDP_TRSV_REG024C_LN0_RX_CTLE_HF_CS_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG024C_LN0_RX_CTLE_HF_CS_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG024C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG064C);
reg &= USBDP_TRSV_REG064C_LN2_RX_CTLE_HF_CS_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG064C_LN2_RX_CTLE_HF_CS_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG064C);
} else if (!strcmp(name, "ssrx_hf_eq_csel_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG024D);
reg &= USBDP_TRSV_REG024D_LN0_RX_CTLE_HF_CS_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG024D_LN0_RX_CTLE_HF_CS_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG024D);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG064D);
reg &= USBDP_TRSV_REG064D_LN2_RX_CTLE_HF_CS_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG064D_LN2_RX_CTLE_HF_CS_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG064D);
}
/*
DFE 1 tap Control
0x0AD0[1] = 0 : Tune, 1 : adaptation
0x1AD0[1]
Gen1
0x0CD0 [6:0]
0x0D00 [6:0]
0x1CD0 [6:0]
0x1D00 [6:0]
Gen2
0x0CE8 [6:0]
0x0D18 [6:0]
0x1CE8 [6:0]
0x1D18 [6:0]
00 0mV
...
04 8mV
...
7F 254mV
*/
else if (!strcmp(name, "ssrx_dfe_1tap_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0334);
reg &= USBDP_TRSV_REG0334_LN0_RX_SSLMS_C1_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0334_LN0_RX_SSLMS_C1_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0334);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0340);
reg &= USBDP_TRSV_REG0340_LN0_RX_SSLMS_C1_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0340_LN0_RX_SSLMS_C1_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0340);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0734);
reg &= USBDP_TRSV_REG0734_LN2_RX_SSLMS_C1_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0734_LN2_RX_SSLMS_C1_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0734);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0740);
reg &= USBDP_TRSV_REG0740_LN2_RX_SSLMS_C1_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0740_LN2_RX_SSLMS_C1_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0740);
} else if (!strcmp(name, "ssrx_dfe_1tap_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG033A);
reg &= USBDP_TRSV_REG033A_LN0_RX_SSLMS_C1_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG033A_LN0_RX_SSLMS_C1_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG033A);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0346);
reg &= USBDP_TRSV_REG0346_LN0_RX_SSLMS_C1_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0346_LN0_RX_SSLMS_C1_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0346);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG073A);
reg &= USBDP_TRSV_REG073A_LN2_RX_SSLMS_C1_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG073A_LN2_RX_SSLMS_C1_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG073A);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0746);
reg &= USBDP_TRSV_REG0746_LN2_RX_SSLMS_C1_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0746_LN2_RX_SSLMS_C1_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0746);
}
/*
DFE 2 tap Control
0x0AD0[2] = 0 : Tune, 1 : adaptation
0x1AD0[2]
Gen1
0x0CD4 [6:0]
0x0D04 [6:0]
0x1CD4 [6:0]
0x1D04 [6:0]
Gen2
0x0CEC [6:0]
0x0D1C [6:0]
0x1CEC [6:0]
0x1D1C [6:0]
40 -240mV (2's complement)
7F -3.75mV
00 0mV
01 3.75mV
3F 240mV
*/
else if (!strcmp(name, "ssrx_dfe_2tap_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0335);
reg &= USBDP_TRSV_REG0335_LN0_RX_SSLMS_C2_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0335_LN0_RX_SSLMS_C2_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0335);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0341);
reg &= USBDP_TRSV_REG0341_LN0_RX_SSLMS_C2_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0341_LN0_RX_SSLMS_C2_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0341);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0735);
reg &= USBDP_TRSV_REG0735_LN2_RX_SSLMS_C2_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0735_LN2_RX_SSLMS_C2_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0735);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0741);
reg &= USBDP_TRSV_REG0741_LN2_RX_SSLMS_C2_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0741_LN2_RX_SSLMS_C2_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0741);
} else if (!strcmp(name, "ssrx_dfe_2tap_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG033B);
reg &= USBDP_TRSV_REG033B_LN0_RX_SSLMS_C2_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG033B_LN0_RX_SSLMS_C2_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG033B);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0347);
reg &= USBDP_TRSV_REG0347_LN0_RX_SSLMS_C2_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0347_LN0_RX_SSLMS_C2_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0347);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG073B);
reg &= USBDP_TRSV_REG073B_LN2_RX_SSLMS_C2_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG073B_LN2_RX_SSLMS_C2_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG073B);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0747);
reg &= USBDP_TRSV_REG0747_LN2_RX_SSLMS_C2_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0747_LN2_RX_SSLMS_C2_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0747);
}
/*
DFE 3 tap Control
0x0AD0[3] = 0 : Tune, 1 : adapation
0x1AD0[3]
Gen1
0x0CD8 [6:0]
0x0D08 [6:0]
0x1CD8 [6:0]
0x1D08 [6:0]
Gen2
0x0CF0 [6:0]
0x0D20 [6:0]
0x1CF0 [6:0]
0x1D20 [6:0]
40 -240mV (2's complement)
7F -3.75mV
00 0mV
01 3.75mV
3F 240mV
*/
else if (!strcmp(name, "ssrx_dfe_3tap_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0336);
reg &= USBDP_TRSV_REG0336_LN0_RX_SSLMS_C3_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0336_LN0_RX_SSLMS_C3_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0336);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0342);
reg &= USBDP_TRSV_REG0342_LN0_RX_SSLMS_C3_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0342_LN0_RX_SSLMS_C3_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0342);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0736);
reg &= USBDP_TRSV_REG0736_LN2_RX_SSLMS_C3_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0736_LN2_RX_SSLMS_C3_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0736);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0742);
reg &= USBDP_TRSV_REG0742_LN2_RX_SSLMS_C3_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0742_LN2_RX_SSLMS_C3_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0742);
} else if (!strcmp(name, "ssrx_dfe_3tap_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG033C);
reg &= USBDP_TRSV_REG033C_LN0_RX_SSLMS_C3_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG033C_LN0_RX_SSLMS_C3_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG033C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0348);
reg &= USBDP_TRSV_REG0348_LN0_RX_SSLMS_C3_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0348_LN0_RX_SSLMS_C3_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0348);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG073C);
reg &= USBDP_TRSV_REG073C_LN2_RX_SSLMS_C3_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG073C_LN2_RX_SSLMS_C3_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG073C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0748);
reg &= USBDP_TRSV_REG0748_LN2_RX_SSLMS_C3_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0748_LN2_RX_SSLMS_C3_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0748);
}
/*
DFE 4 tap Control
0x0AD0[4] = 0 : Tune, 1 : adapation
0x1AD0[4]
Gen1
0x0CDC [5:0]
0x0D0C [5:0]
0x1CDC [5:0]
0x1D0C [5:0]
Gen2
0x0CF4 [5:0]
0x0D24 [5:0]
0x1CF4 [5:0]
0x1D24 [5:0]
20 -120mV (2's complement)
3F -3.75mV
00 0mV
01 3.75mV
1F 120mV
*/
else if (!strcmp(name, "ssrx_dfe_4tap_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0337);
reg &= USBDP_TRSV_REG0337_LN0_RX_SSLMS_C4_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0337_LN0_RX_SSLMS_C4_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0337);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0343);
reg &= USBDP_TRSV_REG0343_LN0_RX_SSLMS_C4_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0343_LN0_RX_SSLMS_C4_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0343);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0737);
reg &= USBDP_TRSV_REG0737_LN2_RX_SSLMS_C4_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0737_LN2_RX_SSLMS_C4_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0737);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0743);
reg &= USBDP_TRSV_REG0743_LN2_RX_SSLMS_C4_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0743_LN2_RX_SSLMS_C4_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0743);
} else if (!strcmp(name, "ssrx_dfe_4tap_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG033D);
reg &= USBDP_TRSV_REG033D_LN0_RX_SSLMS_C4_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG033D_LN0_RX_SSLMS_C4_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG033D);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0349);
reg &= USBDP_TRSV_REG0349_LN0_RX_SSLMS_C4_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0349_LN0_RX_SSLMS_C4_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0349);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG073D);
reg &= USBDP_TRSV_REG073D_LN2_RX_SSLMS_C4_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG073D_LN2_RX_SSLMS_C4_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG073D);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0749);
reg &= USBDP_TRSV_REG0749_LN2_RX_SSLMS_C4_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG0749_LN2_RX_SSLMS_C4_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0749);
}
/*
DFE 5 tap Control
0x0AD0[5] = 0 : Tune, 1 : adaptation
0x1AD0[5]
Gen1
0x0CE0 [5:0]
0x0D10 [5:0]
0x1CE0 [5:0]
0x1D10 [5:0]
Gen2
0x0CF8 [5:0]
0x0D28 [7:2]
0x1CF8 [5:0]
0x1D28 [7:2]
20 -120mV (2's complement)
3F -3.75mV
00 0mV
01 3.75mV
1F 120mV
*/
else if (!strcmp(name, "ssrx_dfe_5tap_ctrl_ss")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0338);
reg &= USBDP_TRSV_REG0338_LN0_RX_SSLMS_C5_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0338_LN0_RX_SSLMS_C5_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0338);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0344);
reg &= USBDP_TRSV_REG0344_LN0_RX_SSLMS_C5_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0344_LN0_RX_SSLMS_C5_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0344);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0738);
reg &= USBDP_TRSV_REG0738_LN2_RX_SSLMS_C5_E_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0738_LN2_RX_SSLMS_C5_E_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0738);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0744);
reg &= USBDP_TRSV_REG0744_LN2_RX_SSLMS_C5_O_INIT_SP_CLR;
reg |= USBDP_TRSV_REG0744_LN2_RX_SSLMS_C5_O_INIT_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0744);
} else if (!strcmp(name, "ssrx_dfe_5tap_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG033E);
reg &= USBDP_TRSV_REG033E_LN0_RX_SSLMS_C5_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG033E_LN0_RX_SSLMS_C5_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG033E);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG034A);
reg &= USBDP_TRSV_REG034A_LN0_RX_SSLMS_C5_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG034A_LN0_RX_SSLMS_C5_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG034A);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG073E);
reg &= USBDP_TRSV_REG073E_LN2_RX_SSLMS_C5_E_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG073E_LN2_RX_SSLMS_C5_E_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG073E);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG074A);
reg &= USBDP_TRSV_REG074A_LN2_RX_SSLMS_C5_O_INIT_SSP_CLR;
reg |= USBDP_TRSV_REG074A_LN2_RX_SSLMS_C5_O_INIT_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG074A);
}
/*
CDR BW Control
Gen1
0x0EB8 [5:0]: 0x0 : Min, 0x3F : Max
0x1EB8 [5:0]
Gen2
0x0EBC [5:0]: 0x0 : Min, 0x3F : Max
0x1EBC [5:0]
*/
else if (!strcmp(name, "ssrx_cdr_fbb_fine_ctrl_sp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03AE);
reg &= USBDP_TRSV_REG03AE_LN0_RX_CDR_FBB_FINE_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG03AE_LN0_RX_CDR_FBB_FINE_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG03AE);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07AE);
reg &= USBDP_TRSV_REG07AE_LN2_RX_CDR_FBB_FINE_CTRL_SP_CLR;
reg |= USBDP_TRSV_REG07AE_LN2_RX_CDR_FBB_FINE_CTRL_SP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG07AE);
} else if (!strcmp(name, "ssrx_cdr_fbb_fine_ctrl_ssp")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03AF);
reg &= USBDP_TRSV_REG03AF_LN0_RX_CDR_FBB_FINE_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG03AF_LN0_RX_CDR_FBB_FINE_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG03AF);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07AF);
reg &= USBDP_TRSV_REG07AF_LN2_RX_CDR_FBB_FINE_CTRL_SSP_CLR;
reg |= USBDP_TRSV_REG07AF_LN2_RX_CDR_FBB_FINE_CTRL_SSP_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG07AF);
}
/*
RX Termination
0x0BB0 [1:0]: 1 : Tune, 0 : calibration
0x1BB0 [1:0]
0x0BB4 [7:4]
0x1BB4 [7:4]
0000 57 Ohm
0001 57 Ohm
0010 53 Ohm
0011 44 Ohm
1111 37 Ohm
*/
else if (!strcmp(name, "ssrx_term_cal")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02EC);
reg &= USBDP_TRSV_REG02EC_LN0_RX_RCAL_OPT_CODE_CLR;
reg |= USBDP_TRSV_REG02EC_LN0_RX_RCAL_OPT_CODE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02EC);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02ED);
reg &= USBDP_TRSV_REG02ED_LN0_RX_RTERM_CTRL_CLR;
reg |= USBDP_TRSV_REG02ED_LN0_RX_RTERM_CTRL_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02ED);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06EC);
reg &= USBDP_TRSV_REG06EC_LN2_RX_RCAL_OPT_CODE_CLR;
reg |= USBDP_TRSV_REG06EC_LN2_RX_RCAL_OPT_CODE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06EC);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06ED);
reg &= USBDP_TRSV_REG06ED_LN2_RX_RTERM_CTRL_CLR;
reg |= USBDP_TRSV_REG06ED_LN2_RX_RTERM_CTRL_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06ED);
}
/* Gen1 Tx DRIVER pre-shoot, de-emphasis, level ctrl
* [17:12] Deemphasis
* [11:6] Level
* [5:0] Preshoot
* */
else if (!strcmp(name, "sstx_amp_ss")) {
reg = readl(pcs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
reg &= ~(0x00FC0);
reg |= val << 6;
writel(reg, pcs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
}
else if (!strcmp(name, "sstx_deemp_ss")) {
reg = readl(pcs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
reg &= ~(0x3F000);
reg |= val << 12;
writel(reg, pcs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
}
else if (!strcmp(name, "sstx_pre_shoot_ss")) {
reg = readl(pcs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
reg &= ~(0x0003F);
reg |= val;
writel(reg, pcs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
}
/* Gen2 Tx DRIVER level ctrl
* [17:12] Deemphasis
* [11:6] Level
* [5:0] Preshoot
* */
else if (!strcmp(name, "sstx_amp_ssp")) {
reg = readl(pcs_base + EXYNOS_USBDP_PCS_LEQ_LOCAL_COEF);
reg &= USBDP_PCS_LEQ_LOCAL_COEF_PMA_CENTER_COEF_CLR;
reg |= USBDP_PCS_LEQ_LOCAL_COEF_PMA_CENTER_COEF_SET(val);
writel(reg, pcs_base + EXYNOS_USBDP_PCS_LEQ_LOCAL_COEF);
}
/*
TX IDRV UP
0x101C [7]: 1: Tune, 0 : From PnR logic
0x201C [7]
0x101C [6:4]
0x201C [6:4]
111 0.85V
110 1V
011 1.1V
...
000 1.2V ( Max )
*/
else if (!strcmp(name, "sstx_idrv_up")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0407);
reg &= USBDP_TRSV_REG0407_OVRD_LN1_TX_DRV_IDRV_IUP_CTRL_CLR;
reg |= USBDP_TRSV_REG0407_OVRD_LN1_TX_DRV_IDRV_IUP_CTRL_SET(1);
reg &= USBDP_TRSV_REG0407_LN1_TX_DRV_IDRV_IUP_CTRL_CLR;
reg |= USBDP_TRSV_REG0407_LN1_TX_DRV_IDRV_IUP_CTRL_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0407);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0807);
reg &= USBDP_TRSV_REG0807_OVRD_LN3_TX_DRV_IDRV_IUP_CTRL_CLR;
reg |= USBDP_TRSV_REG0807_OVRD_LN3_TX_DRV_IDRV_IUP_CTRL_SET(1);
reg &= USBDP_TRSV_REG0807_LN3_TX_DRV_IDRV_IUP_CTRL_CLR;
reg |= USBDP_TRSV_REG0807_LN3_TX_DRV_IDRV_IUP_CTRL_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0807);
}
/*
TX IDRV UP for LFPS TX
It is valid where
0x101C [7]: 0x201C [7] = 0 (Default setting)
0x0408 [6:4]
111 0.85V
110 1V
011 1.1V
...
000 1.2V ( Max )
*/
else if (!strcmp(name, "sstx_lfps_idrv_up")) {
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG0102);
reg &= USBDP_CMN_REG0102_TX_DRV_LFPS_MODE_IDRV_IUP_CTRL_CLR;
reg |= USBDP_CMN_REG0102_TX_DRV_LFPS_MODE_IDRV_IUP_CTRL_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG0102);
}
/*
TX UP Termination
0x10B0 [3:2]: 1 : Tune, 0 : calibration
0x20B0 [3:2]
0x10B4 [7:4]
0x20B4 [7:4]
0000 57 Ohm
0001 57 Ohm
0010 53 Ohm
0011 44 Ohm
1111 37 Ohm
*/
else if (!strcmp(name, "sstx_up_term")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG042C);
reg &= USBDP_TRSV_REG042C_LN1_TX_RCAL_UP_OPT_CODE_CLR;
reg |= USBDP_TRSV_REG042C_LN1_TX_RCAL_UP_OPT_CODE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG042C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG042D);
reg &= USBDP_TRSV_REG042D_LN1_TX_RCAL_UP_CODE_CLR;
reg |= USBDP_TRSV_REG042D_LN1_TX_RCAL_UP_CODE_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG042D);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG082C);
reg &= USBDP_TRSV_REG082C_LN3_TX_RCAL_UP_OPT_CODE_CLR;
reg |= USBDP_TRSV_REG082C_LN3_TX_RCAL_UP_OPT_CODE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG082C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG082D);
reg &= USBDP_TRSV_REG082D_LN3_TX_RCAL_UP_CODE_CLR;
reg |= USBDP_TRSV_REG082D_LN3_TX_RCAL_UP_CODE_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG082D);
}
/*
TX DN Termination
0x10B0 [1:0]: 1 : Tune, 0 : calibration
0x20B0 [1:0]
0x10B4 [3:0]
0x20B4 [3:0]
0000 57 Ohm
0001 57 Ohm
0010 53 Ohm
0011 44 Ohm
1111 37 Ohm
*/
else if (!strcmp(name, "sstx_dn_term")) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG042C);
reg &= USBDP_TRSV_REG042C_LN1_TX_RCAL_DN_OPT_CODE_CLR;
reg |= USBDP_TRSV_REG042C_LN1_TX_RCAL_DN_OPT_CODE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG042C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG042D);
reg &= USBDP_TRSV_REG042D_LN1_TX_RCAL_DN_CODE_CLR;
reg |= USBDP_TRSV_REG042D_LN1_TX_RCAL_DN_CODE_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG042D);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG082C);
reg &= USBDP_TRSV_REG082C_LN3_TX_RCAL_DN_OPT_CODE_CLR;
reg |= USBDP_TRSV_REG082C_LN3_TX_RCAL_DN_OPT_CODE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG082C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG082D);
reg &= USBDP_TRSV_REG082D_LN3_TX_RCAL_DN_CODE_CLR;
reg |= USBDP_TRSV_REG082D_LN3_TX_RCAL_DN_CODE_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG082D);
}
/* REXT ovrd */
else if (!strcmp(name, "rext_ovrd")) {
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG0006);
reg |= USBDP_CMN_REG0006_OVRD_BIAS_ICAL_CODE_SET(1);
reg &= USBDP_CMN_REG0006_BIAS_ICAL_CODE_CLR;
reg |= USBDP_CMN_REG0006_BIAS_ICAL_CODE_SET(val);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG0006);
}
phy_exynos_usbdp_g2_v4_tune_each_late(info, name, val);
}
static void phy_exynos_usbdp_g2_v4_ctrl_pma_ready(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->ctrl_base;
u32 reg;
/* link pipe_clock selection to pclk of PMA */
reg = readl(regs_base + EXYNOS_USBCON_CLKRST);
reg |= CLKRST_LINK_PCLK_SEL;
writel(reg, regs_base + EXYNOS_USBCON_CLKRST);
reg = readl(regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
reg |= PMA_REF_FREQ_SEL_SET(1);
/* SFR reset */
reg |= PMA_LOW_PWR;
reg |= PMA_APB_SW_RST;
/* reference clock 26MHz path from XTAL */
reg &= ~PMA_ROPLL_REF_CLK_SEL_MASK;
reg &= ~PMA_LCPLL_REF_CLK_SEL_MASK;
/* PMA_POWER_OFF */
reg |= PMA_TRSV_SW_RST;
reg |= PMA_CMN_SW_RST;
reg |= PMA_INIT_SW_RST;
writel(reg, regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
udelay(1);
reg = readl(regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
reg &= ~PMA_LOW_PWR;
writel(reg, regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
/* APB enable */
reg = readl(regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
reg &= ~PMA_APB_SW_RST;
writel(reg, regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
}
static void phy_exynos_usbdp_g2_v4_ctrl_pma_rst_release(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->ctrl_base;
u32 reg;
/* Reset release from port */
reg = readl(regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
reg &= ~PMA_TRSV_SW_RST;
reg &= ~PMA_CMN_SW_RST;
reg &= ~PMA_INIT_SW_RST;
writel(reg, regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
}
static void phy_exynos_usbdp_g2_v4_aux_force_off(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG0008);
reg &= USBDP_CMN_REG0008_OVRD_AUX_EN_CLR;
reg |= USBDP_CMN_REG0008_OVRD_AUX_EN_SET(1);
reg &= USBDP_CMN_REG0008_AUX_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG0008);
}
static inline void phy_exynos_usbdp_g2_v4_pma_default_sfr_update(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
/* 190627: CDR data mode exit GEN1 ON / GEN2 OFF */
writel(0xff, regs_base + 0x0c8c);
writel(0xff, regs_base + 0x1c8c);
writel(0x7d, regs_base + 0x0c9c);
writel(0x7d, regs_base + 0x1c9c);
/* 190708: Setting for improvement of EDS distribution */
writel(0x06, regs_base + 0x0e7c);
writel(0x00, regs_base + 0x09e0);
writel(0x36, regs_base + 0x09e4);
writel(0x06, regs_base + 0x1e7c);
writel(0x00, regs_base + 0x19e0);
writel(0x36, regs_base + 0x19e4);
/* 190707: Improve LVCC */
writel(0x30, regs_base + 0x08f0);
writel(0x30, regs_base + 0x18f0);
/* 190820: LFPS RX VIH shmoo hole */
writel(0x0c, regs_base + 0x0a08);
writel(0x0c, regs_base + 0x1a08);
/* 190820: Remove unrelated option for v4 phy */
writel(0x05, regs_base + 0x0a0c);
writel(0x05, regs_base + 0x1a0c);
/* 191128: Change Vth of RCV_DET because of TD 7.40 Polling Retry Test */
writel(0x05, regs_base + 0x104c);
writel(0x05, regs_base + 0x204c);
/* reduce Ux Exit time, Recovery.Active(TS1) n x REFCLK_PERIOD(38.4ns)
0x0CA8 0x00 ln0_rx_valid_rstn_delay_rise_sp__15_8=0
0x0CAC 0x04 ln0_rx_valid_rstn_delay_rise_sp__7_0=4
0x1CA8 0x00 ln2_rx_valid_rstn_delay_rise_sp__15_8=0
0x1CAC 0x04 ln2_rx_valid_rstn_delay_rise_sp__7_0=4
0x0CB8 0x00 ln0_rx_valid_rstn_delay_rise_ssp__15_8=0
0x0CBC 0x04 ln0_rx_valid_rstn_delay_rise_ssp__7_0=4
0x1CB8 0x00 ln2_rx_valid_rstn_delay_rise_ssp__15_8=0
0x1CBC 0x04 ln2_rx_valid_rstn_delay_rise_ssp__7_0=4
*/
/* Gen1 */
writel(0x00, regs_base + 0x0ca8);
writel(0x04, regs_base + 0x0cac);
writel(0x00, regs_base + 0x1ca8);
writel(0x04, regs_base + 0x1cac);
/* Gen2 */
writel(0x00, regs_base + 0x0cb8);
writel(0x04, regs_base + 0x0cbc);
writel(0x00, regs_base + 0x1cb8);
writel(0x04, regs_base + 0x1cbc);
/* CDR Lock Delay for JTOL Link Training */
writel(0x03, regs_base + 0x0320);
writel(0x23, regs_base + 0x0324);
/* common reset for 4lane tx */
writel(0x63, regs_base + 0x0858);
writel(0x63, regs_base + 0x1058);
writel(0x63, regs_base + 0x1858);
writel(0x63, regs_base + 0x2058);
writel(0x00, regs_base + 0x0894);
writel(0x00, regs_base + 0x0A1C);
writel(0x00, regs_base + 0x1094);
writel(0x00, regs_base + 0x1A1C);
writel(0x00, regs_base + 0x2094);
/*
* Change rx rterm to 90 ohm
*/
writel(0xA0, regs_base + 0x0BB4);
writel(0xA0, regs_base + 0x1BB4);
/*
* added setting
*/
writel(0x10, regs_base + 0x0A08);
writel(0x10, regs_base + 0x1A08);
writel(0x04, regs_base + 0x0E08);
writel(0x04, regs_base + 0x1E08);
/*
* added RX JTOL Performance improved
*/
writel(0x07, regs_base + 0x090C);
writel(0x07, regs_base + 0x190C);
writel(0x2F, regs_base + 0x08FC);
writel(0x2F, regs_base + 0x18FC);
writel(0x20, regs_base + 0x0908);
writel(0x20, regs_base + 0x1908);
writel(0x01, regs_base + 0x08D8);
writel(0x01, regs_base + 0x18D8);
writel(0x3F, regs_base + 0x08CC);
writel(0x3F, regs_base + 0x18CC);
writel(0x01, regs_base + 0x0AE0);
writel(0x01, regs_base + 0x1AE0);
writel(0x80, regs_base + 0x0AE4);
writel(0x80, regs_base + 0x1AE4);
/* change cdr_fbb_cp_ctrl_ssp[5:3] --> 7 */
writel(0x3C, regs_base + 0x0E0C);
writel(0x3C, regs_base + 0x1E0C);
/* change cdr_fbb_fine_ctrl_ssp[5:0] --> 20 */
writel(0x14, regs_base + 0x0EBC);
writel(0x14, regs_base + 0x1EBC);
writel(0x33, regs_base + 0x0E80);
writel(0x33, regs_base + 0x1E80);
/* change peq_zero[3:2] */
writel(0x2E, regs_base + 0x0968);
writel(0x2E, regs_base + 0x1968);
/* chagne vcm_i[2:0] */
writel(0x22, regs_base + 0x0954);
writel(0x22, regs_base + 0x1954);
/* chagne sadd_rl_ctrl[6] */
writel(0x20, regs_base + 0x09F0);
writel(0x20, regs_base + 0x19F0);
/* chagne rx_ctle_hf_rl_ctrl_ssp[2:0] */
writel(0x1D, regs_base + 0x091C);
writel(0x1D, regs_base + 0x191C);
/* chagne rx_ctle_hf_i_ctrl_ssp[2:0] */
writel(0x0C, regs_base + 0x0928);
writel(0x0C, regs_base + 0x1928);
/* chagne rx_sslms_hf_bin_ssp[4:0] */
writel(0x2B, regs_base + 0x0DEC);
writel(0x2B, regs_base + 0x1DEC);
/* chagne rx_sslms_mf_bin_ssp[4:0] */
writel(0x24, regs_base + 0x0DF0);
writel(0x24, regs_base + 0x1DF0);
/* change rx_hf_cs_ctrl[7:6] */
writel(0x7F, regs_base + 0x0934);
writel(0x7F, regs_base + 0x1934);
/* change rx_vga_rl_ctrl[5:3] */
writel(0x32, regs_base + 0x0948);
writel(0x32, regs_base + 0x1948);
/* change rx_vga_i_ctrl[5:3] */
writel(0x38, regs_base + 0x093C);
writel(0x38, regs_base + 0x193C);
/* change vga_bin_ssp[5:1] */
writel(0x00, regs_base + 0x0DF4);
writel(0x00, regs_base + 0x1DF4);
/* change madd_rl_cont_ssp[2:0] */
writel(0x35, regs_base + 0x09E4);
writel(0x35, regs_base + 0x19E4);
/* change madd_pbias_ctrl_ssp[5:4] */
writel(0xE7, regs_base + 0x0E04);
writel(0xE7, regs_base + 0x1E04);
/* rx_cdr_afc_vci_sel[3:1] 583mV -> 544mV */
writel(0x0A, regs_base + 0x08E8);
writel(0x0A, regs_base + 0x18E8);
}
static void phy_exynos_usbdp_g2_v4_set_pcs(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pcs_base;
u32 reg;
/* abnormal comman pattern mask */
reg = readl(regs_base + EXYNOS_USBDP_PCS_RX_BACK_END_MODE_VEC);
reg &= USBDP_PCS_RX_BACK_END_MODE_VEC_DISABLE_DATA_MASK_CLR;
writel(reg, regs_base + EXYNOS_USBDP_PCS_RX_BACK_END_MODE_VEC);
/* De-serializer enabled when U2 */
reg = readl(regs_base + EXYNOS_USBDP_PCS_PM_OUT_VEC_2);
reg &= USBDP_PCS_PM_OUT_VEC_2_B4_DYNAMIC_CLR;
reg |= USBDP_PCS_PM_OUT_VEC_2_B4_SEL_OUT_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_PCS_PM_OUT_VEC_2);
/* TX Keeper Disable, Squelch off when U3 */
reg = readl(regs_base + EXYNOS_USBDP_PCS_PM_OUT_VEC_3);
reg &= USBDP_PCS_PM_OUT_VEC_3_B7_DYNAMIC_CLR;
reg |= USBDP_PCS_PM_OUT_VEC_3_B7_SEL_OUT_SET(1);
reg &= USBDP_PCS_PM_OUT_VEC_3_B2_SEL_OUT_CLR;
reg |= USBDP_PCS_PM_OUT_VEC_3_B2_SEL_OUT_SET(1); // Squelch on when U3
writel(reg, regs_base + EXYNOS_USBDP_PCS_PM_OUT_VEC_3);
// 20180822 PCS SFR setting : Noh M.W
writel(0x05700000, regs_base + EXYNOS_USBDP_PCS_PM_NS_VEC_PS1_N1);
writel(0x01700202, regs_base + EXYNOS_USBDP_PCS_PM_NS_VEC_PS2_N0);
writel(0x01700707, regs_base + EXYNOS_USBDP_PCS_PM_NS_VEC_PS3_N0);
writel(0x0070, regs_base + EXYNOS_USBDP_PCS_PM_TIMEOUT_0);
// Block Aligner Type B
reg = readl(regs_base + EXYNOS_USBDP_PCS_RX_RX_CONTROL);
reg &= USBDP_PCS_RX_RX_CONTROL_EN_BLOCK_ALIGNER_TYPE_B_CLR;
reg |= USBDP_PCS_RX_RX_CONTROL_EN_BLOCK_ALIGNER_TYPE_B_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_PCS_RX_RX_CONTROL);
/* Block align at TS1/TS2 for Gen2 stability (Gen2 only) */
reg = readl(regs_base + EXYNOS_USBDP_PCS_RX_RX_CONTROL_DEBUG);
reg &= USBDP_PCS_RX_RX_CONTROL_DEBUG_EN_TS_CHECK_CLR;
reg |= USBDP_PCS_RX_RX_CONTROL_DEBUG_EN_TS_CHECK_SET(1);
/* increse pcs ts1 adding packet-cnt 1 --> 4
lnx_rx_valid_rstn_delay_rise_sp/ssp : 19.6us(0x200) -> 15.3us(0x4)
*/
reg &= USBDP_PCS_RX_RX_CONTROL_DEBUG_NUM_COM_FOUND_CLR;
reg |= USBDP_PCS_RX_RX_CONTROL_DEBUG_NUM_COM_FOUND_SET(4);
writel(reg, regs_base + EXYNOS_USBDP_PCS_RX_RX_CONTROL_DEBUG);
/* Gen1 Tx DRIVER pre-shoot, de-emphasis, level ctrl
* [15:12] de-emphasis
* [9:6] level - 0xb (max)
* [3:0] pre-shoot - Gen1 does not support pre-shoot
*/
reg = readl(regs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
reg &= USBDP_PCS_LEQ_HS_TX_COEF_MAP_0_LEVEL_CLR;
reg |= USBDP_PCS_LEQ_HS_TX_COEF_MAP_0_LEVEL_SET((8 << 12 | 0xB << 6 | 0x0)); // 0x82C0
writel(reg, regs_base + EXYNOS_USBDP_PCS_LEQ_HS_TX_COEF_MAP_0);
/* Gen2 Tx DRIVER level ctrl */
reg = readl(regs_base + EXYNOS_USBDP_PCS_LEQ_LOCAL_COEF);
reg &= USBDP_PCS_LEQ_LOCAL_COEF_PMA_CENTER_COEF_CLR;
reg |= USBDP_PCS_LEQ_LOCAL_COEF_PMA_CENTER_COEF_SET(0xB);
writel(reg, regs_base + EXYNOS_USBDP_PCS_LEQ_LOCAL_COEF);
/* Gen2 U1 exit LFPS duration : 900ns ~ 1.2us */
writel(0x10, regs_base + EXYNOS_USBDP_PCS_PM_TIMEOUT_3);
/* set skp_remove_th 0x2 -> 0x5 for avoiding retry problem. */
reg = readl(regs_base + EXYNOS_USBDP_PCS_RX_EBUF_PARAM);
reg &= USBDP_PCS_RX_EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE_CLR;
reg |= USBDP_PCS_RX_EBUF_PARAM_SKP_REMOVE_TH_EMPTY_MODE_SET(0x5);
writel(reg, regs_base + EXYNOS_USBDP_PCS_RX_EBUF_PARAM);
}
static inline void phy_exynos_usbdp_g2_v4_pma_lane_mux_sel(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
/* Lane configuration */
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00B8);
reg &= USBDP_CMN_REG00B8_LANE_MUX_SEL_DP_CLR;
if (info->used_phy_port == 0) {
reg |= USBDP_CMN_REG00B8_LANE_MUX_SEL_DP_SET(0xc);
} else {
reg |= USBDP_CMN_REG00B8_LANE_MUX_SEL_DP_SET(0x3);
}
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00B8);
/*
ln1_tx_rxd_en = 0
ln3_tx_rxd_en = 0
*/
if (info->used_phy_port == 0) {
/* ln3_tx_rxd_en = 0 */
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0413);
reg &= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN_CLR;
reg &= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0413);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0813);
reg &= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN_CLR;
reg |= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN_SET(1);
reg &= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_EN_CLR;
reg |= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0813);
} else {
/* ln1_tx_rxd_en = 0 */
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0413);
reg &= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN_CLR;
reg |= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN_SET(1);
reg &= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_EN_CLR;
reg |= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0413);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0813);
reg &= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN_CLR;
reg &= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0813);
}
/* dp_lane_en = 0 */
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00B9);
reg &= USBDP_CMN_REG00B9_DP_LANE_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00B9);
}
void phy_exynos_usbdp_g2_v4_tune(struct exynos_usbphy_info *info)
{
u32 cnt = 0;
if (!info) {
return;
}
if (!info->tune_param) {
return;
}
for (; info->tune_param[cnt].value != EXYNOS_USB_TUNE_LAST; cnt++) {
char *para_name;
int val;
val = info->tune_param[cnt].value;
if (val == -1) {
continue;
}
para_name = info->tune_param[cnt].name;
if (!para_name) {
break;
}
/* TODO */
phy_exynos_usbdp_g2_v4_tune_each(info, para_name, val);
}
}
static void phy_exynos_usbdp_g2_v4_tune_late(struct exynos_usbphy_info *info)
{
u32 cnt = 0;
void __iomem *link_base;
void __iomem *pcs_base;
u32 reg;
if (!info) {
return;
}
link_base = info->link_base;
pcs_base = info->pcs_base;
/* Gen2 Tx DRIVER pre-shoot, de-emphasis ctrl
* [17:12] Deemphasis
* [11:6] Level (not valid)
* [5:0] Preshoot
* */
/* normal operation, compliance pattern 15 */
reg = readl(link_base + USB31DRD_LINK_LCSR_TX_DEEMPH);
reg &= ~(0x3FFFF);
reg |= 4 << 12 | 4;
writel(reg, link_base + USB31DRD_LINK_LCSR_TX_DEEMPH);
/* compliance pattern 13 */
reg = readl(link_base + USB31DRD_LINK_LCSR_TX_DEEMPH_1);
reg &= ~(0x3FFFF);
reg |= 4;
writel(reg, link_base + USB31DRD_LINK_LCSR_TX_DEEMPH_1);
/* compliance pattern 14 */
reg = readl(link_base + USB31DRD_LINK_LCSR_TX_DEEMPH_2);
reg &= ~(0x3FFFF);
reg |= 4 << 12;
writel(reg, link_base + USB31DRD_LINK_LCSR_TX_DEEMPH_2);
/* Squelch off when U3 */
reg = readl(pcs_base + EXYNOS_USBDP_PCS_PM_OUT_VEC_3);
reg &= USBDP_PCS_PM_OUT_VEC_3_B2_SEL_OUT_CLR; // Squelch off when U3
writel(reg, pcs_base + EXYNOS_USBDP_PCS_PM_OUT_VEC_3);
if (!info->tune_param) {
return;
}
for (; info->tune_param[cnt].value != EXYNOS_USB_TUNE_LAST; cnt++) {
char *para_name;
int val;
val = info->tune_param[cnt].value;
if (val == -1) {
continue;
}
para_name = info->tune_param[cnt].name;
if (!para_name) {
break;
}
/* TODO */
phy_exynos_usbdp_g2_v4_tune_each_late(info, para_name, val);
}
}
static int phy_exynos_usbdp_g2_v4_pma_check_offset_cal_code(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
u32 code = 0;
if (info->used_phy_port == 0) {
/*
0x0F28 ln0_mon_rx_oc_dfe_adder_even
0x0F2C ln0_mon_rx_oc_dfe_adder_odd
0x0F30 ln0_mon_rx_oc_dfe_dac_adder_even
ln0_mon_rx_oc_dfe_dac_adder_odd
0x0F34 ln0_mon_rx_oc_dfe_sa_edge_even
0x0F38 ln0_mon_rx_oc_dfe_sa_edge_odd
0x0F3C ln0_mon_rx_oc_dfe_dac_edge_odd
ln0_mon_rx_oc_dfe_dac_edge_even
0x0F40 ln0_mon_rx_oc_dfe_sa_err_even
0x0F44 ln0_mon_rx_oc_dfe_sa_err_odd
0x0F48 ln0_mon_rx_oc_dfe_dac_err_even
ln0_mon_rx_oc_dfe_dac_err_odd
0x0F4C ln0_mon_rx_oc_ctle
0x072C ln0_mon_rx_oc_init_vga_code
0x0730 ln0_mon_rx_oc_init_dac_vga_code
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03CA);
code = USBDP_TRSV_REG03CA_LN0_MON_RX_OC_DFE_ADDER_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] adder e = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03CB);
code = USBDP_TRSV_REG03CB_LN0_MON_RX_OC_DFE_ADDER_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] adder o = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03CC);
code = USBDP_TRSV_REG03CC_LN0_MON_RX_OC_DFE_DAC_ADDER_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] dac_adder e/o = %02X", code);
code = USBDP_TRSV_REG03CC_LN0_MON_RX_OC_DFE_DAC_ADDER_ODD_GET(reg);
usbdp_print_offset_cal_code("/%02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03CD);
code = USBDP_TRSV_REG03CD_LN0_MON_RX_OC_DFE_SA_EDGE_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_edge e = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03CE);
code = USBDP_TRSV_REG03CE_LN0_MON_RX_OC_DFE_SA_EDGE_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_edge o = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03CF);
code = USBDP_TRSV_REG03CF_LN0_MON_RX_OC_DFE_DAC_EDGE_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] dac_edge o/e = %02X", code);
code = USBDP_TRSV_REG03CF_LN0_MON_RX_OC_DFE_DAC_EDGE_EVEN_GET(reg);
usbdp_print_offset_cal_code("/%02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03D0);
code = USBDP_TRSV_REG03D0_LN0_MON_RX_OC_DFE_SA_ERR_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_err e = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03D1);
code = USBDP_TRSV_REG03D1_LN0_MON_RX_OC_DFE_SA_ERR_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_err o = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03D2);
code = USBDP_TRSV_REG03D2_LN0_MON_RX_OC_DFE_DAC_ERR_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] dac_err e/o = %02X", code);
code = USBDP_TRSV_REG03D2_LN0_MON_RX_OC_DFE_DAC_ERR_ODD_GET(reg);
usbdp_print_offset_cal_code("/%02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03D3);
code = USBDP_TRSV_REG03D3_LN0_MON_RX_OC_CTLE_GET(reg);
usbdp_print_offset_cal_code("[OC] ctle = %02X\n", code);
/*
0x0F5C ln0_mon_rx_oc_fail__7_0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03D7);
code = USBDP_TRSV_REG03D7_LN0_MON_RX_OC_FAIL__7_0_GET(reg);
usbdp_print_offset_cal_code("[OC] oc_fail = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01CB);
code = USBDP_CMN_REG01CB_LN0_MON_RX_OC_INIT_VGA_CODE_GET(reg);
usbdp_print_offset_cal_code("[OC] oc_vga = %02X\n", code);
} else {
/*
0x0748 ln2_mon_rx_oc_init_vga_code
0x074C ln2_mon_rx_oc_init_dac_vga_code
0x1F28 ln2_mon_rx_oc_dfe_adder_even
0x1F2C ln2_mon_rx_oc_dfe_adder_odd
0x1F30 ln2_mon_rx_oc_dfe_dac_adder_even
ln2_mon_rx_oc_dfe_dac_adder_odd
0x1F34 ln2_mon_rx_oc_dfe_sa_edge_even
0x1F38 ln2_mon_rx_oc_dfe_sa_edge_odd
0x1F3C ln2_mon_rx_oc_dfe_dac_edge_odd
ln2_mon_rx_oc_dfe_dac_edge_even
0x1F40 ln2_mon_rx_oc_dfe_sa_err_even
0x1F44 ln2_mon_rx_oc_dfe_sa_err_odd
0x1F48 ln2_mon_rx_oc_dfe_dac_err_even
ln2_mon_rx_oc_dfe_dac_err_odd
0x1F4C ln2_mon_rx_oc_ctle
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07CA);
code = USBDP_TRSV_REG07CA_LN2_MON_RX_OC_DFE_ADDER_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] adder e = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07CB);
code = USBDP_TRSV_REG07CB_LN2_MON_RX_OC_DFE_ADDER_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] adder o = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07CC);
code = USBDP_TRSV_REG07CC_LN2_MON_RX_OC_DFE_DAC_ADDER_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] dac_adder e/o = %02X", code);
code = USBDP_TRSV_REG07CC_LN2_MON_RX_OC_DFE_DAC_ADDER_ODD_GET(reg);
usbdp_print_offset_cal_code("/%02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07CD);
code = USBDP_TRSV_REG07CD_LN2_MON_RX_OC_DFE_SA_EDGE_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_edge e = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07CE);
code = USBDP_TRSV_REG07CE_LN2_MON_RX_OC_DFE_SA_EDGE_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_edge o = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07CF);
code = USBDP_TRSV_REG07CF_LN2_MON_RX_OC_DFE_DAC_EDGE_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] dac_edge o/e = %02X", code);
code = USBDP_TRSV_REG07CF_LN2_MON_RX_OC_DFE_DAC_EDGE_EVEN_GET(reg);
usbdp_print_offset_cal_code("/%02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07D0);
code = USBDP_TRSV_REG07D0_LN2_MON_RX_OC_DFE_SA_ERR_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_err e = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07D1);
code = USBDP_TRSV_REG07D1_LN2_MON_RX_OC_DFE_SA_ERR_ODD_GET(reg);
usbdp_print_offset_cal_code("[OC] sa_err o = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07D2);
code = USBDP_TRSV_REG07D2_LN2_MON_RX_OC_DFE_DAC_ERR_EVEN_GET(reg);
usbdp_print_offset_cal_code("[OC] dac_err e/o = %02X", code);
code = USBDP_TRSV_REG07D2_LN2_MON_RX_OC_DFE_DAC_ERR_ODD_GET(reg);
usbdp_print_offset_cal_code("/%02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07D3);
code = USBDP_TRSV_REG07D3_LN2_MON_RX_OC_CTLE_GET(reg);
usbdp_print_offset_cal_code("[OC] ctle = %02X\n", code);
/*
0x1F5C ln2_mon_rx_oc_fail__7_0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07D7);
code = USBDP_TRSV_REG07D7_LN2_MON_RX_OC_FAIL__7_0_GET(reg);
usbdp_print_offset_cal_code("[OC] oc_fail = %02X\n", code);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01D2);
code = USBDP_CMN_REG01D2_LN2_MON_RX_OC_INIT_VGA_CODE_GET(reg);
usbdp_print_offset_cal_code("[OC] oc_vga = %02X\n", code);
}
if (code)
return -1;
else
return 0;
}
static int phy_exynos_usbdp_g2_v4_pma_check_pll_lock(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
u32 cnt;
for (cnt = 1000; cnt != 0; cnt--) {
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01C0);
if ((reg & (USBDP_CMN_REG01C0_ANA_LCPLL_LOCK_DONE_MSK
| USBDP_CMN_REG01C0_ANA_LCPLL_AFC_DONE_MSK))) {
break;
}
udelay(1);
}
if (!cnt) {
return -1;
}
return 0;
}
static int phy_exynos_usbdp_g2_v4_pma_check_cdr_lock(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
u32 cnt;
if (info->used_phy_port == 0) {
for (cnt = 1000; cnt != 0; cnt--) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03C3);
if ((reg & (USBDP_TRSV_REG03C3_LN0_MON_RX_CDR_LOCK_DONE_MSK
| USBDP_TRSV_REG03C3_LN0_MON_RX_CDR_FLD_PLL_MODE_DONE_MSK
| USBDP_TRSV_REG03C3_LN0_MON_RX_CDR_CAL_DONE_MSK
| USBDP_TRSV_REG03C3_LN0_MON_RX_CDR_AFC_DONE_MSK))) {
break;
}
udelay(1);
}
} else {
for (cnt = 1000; cnt != 0; cnt--) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07C3);
if ((reg & (USBDP_TRSV_REG07C3_LN2_MON_RX_CDR_LOCK_DONE_MSK
| USBDP_TRSV_REG07C3_LN2_MON_RX_CDR_FLD_PLL_MODE_DONE_MSK
| USBDP_TRSV_REG07C3_LN2_MON_RX_CDR_CAL_DONE_MSK
| USBDP_TRSV_REG07C3_LN2_MON_RX_CDR_AFC_DONE_MSK))) {
break;
}
udelay(1);
}
}
if (!cnt) {
return -2;
}
return 0;
}
static void phy_exynos_usbdp_g2_v4_pma_ovrd_enable(struct exynos_usbphy_info *info, u32 cmn_rate)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
/*
pcs_pll_en = 0
0x0390 0x40
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E4);
reg &= USBDP_CMN_REG00E4_OVRD_PCS_PLL_EN_CLR;
reg |= USBDP_CMN_REG00E4_OVRD_PCS_PLL_EN_SET(1);
reg &= USBDP_CMN_REG00E4_PCS_PLL_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E4);
/*
pcs_bgr_en = 0
pcs_bias_en = 0
0x0388 0xA0
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E2);
reg &= USBDP_CMN_REG00E2_OVRD_PCS_BGR_EN_CLR;
reg |= USBDP_CMN_REG00E2_OVRD_PCS_BGR_EN_SET(1);
reg &= USBDP_CMN_REG00E2_PCS_BGR_EN_CLR;
reg &= USBDP_CMN_REG00E2_OVRD_PCS_BIAS_EN_CLR;
reg |= USBDP_CMN_REG00E2_OVRD_PCS_BIAS_EN_SET(1);
reg &= USBDP_CMN_REG00E2_PCS_BIAS_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E2);
/*
cmn_rate
0x0384 0x04 // Gen1
0x05 // Gen2
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E1);
reg &= USBDP_CMN_REG00E1_OVRD_PCS_RATE_CLR;
reg |= USBDP_CMN_REG00E1_OVRD_PCS_RATE_SET(1);
reg &= USBDP_CMN_REG00E1_PCS_RATE_CLR;
reg |= USBDP_CMN_REG00E1_PCS_RATE_SET(cmn_rate); // 0: Gen1, 1: Gen2
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E1);
/*
lane_mux_sel_dp
ln1_tx_rxd_en
ln3_tx_rxd_en
0x02E0 0x30
0x104C 0x01
0x204C 0x01
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00B8);
reg &= USBDP_CMN_REG00B8_LANE_MUX_SEL_DP_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00B8);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0413);
reg &= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_COMP_EN_CLR;
reg &= USBDP_TRSV_REG0413_OVRD_LN1_TX_RXD_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0413);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0813);
reg &= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_COMP_EN_CLR;
reg &= USBDP_TRSV_REG0813_OVRD_LN3_TX_RXD_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0813);
/*
pcs_bgr_en = 1
pcs_bias_en = 1
pcs_powerdown = 0
pcs_des_en = 0
pcs_cdr_en = 1
pcs_pll_en = 1
pcs_rx_ctle_en = 1
pcs_rx_sqhs_en = 1
pcs_rx_term_en = 1
pcs_tx_drv_en =1
pcs_tx_elecidle = 1
pcs_tx_lfps_en = 0
pcs_tx_rcv_det_en =1
pcs_tx_ser_en =0
0x0388 0xFB
0x038C 0x20
0x0390 0x63
0x0394 0x03
0x0398 0xC3
0x03A4 0x03
0x03A8 0x8E
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E2);
reg &= USBDP_CMN_REG00E2_OVRD_PCS_BGR_EN_CLR;
reg |= USBDP_CMN_REG00E2_OVRD_PCS_BGR_EN_SET(1);
reg &= USBDP_CMN_REG00E2_PCS_BGR_EN_CLR;
reg |= USBDP_CMN_REG00E2_PCS_BGR_EN_SET(1);
reg &= USBDP_CMN_REG00E2_OVRD_PCS_BIAS_EN_CLR;
reg |= USBDP_CMN_REG00E2_OVRD_PCS_BIAS_EN_SET(1);
reg &= USBDP_CMN_REG00E2_PCS_BIAS_EN_CLR;
reg |= USBDP_CMN_REG00E2_PCS_BIAS_EN_SET(1);
reg &= USBDP_CMN_REG00E2_OVRD_PCS_POWERDOWN_CLR;
reg |= USBDP_CMN_REG00E2_OVRD_PCS_POWERDOWN_SET(1);
reg &= USBDP_CMN_REG00E2_PCS_POWERDOWN_CLR;
reg &= USBDP_CMN_REG00E2_OVRD_PCS_CDR_EN_CLR;
reg |= USBDP_CMN_REG00E2_OVRD_PCS_CDR_EN_SET(1);
reg &= USBDP_CMN_REG00E2_PCS_CDR_EN_CLR;
reg |= USBDP_CMN_REG00E2_PCS_CDR_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E2);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E3);
reg &= USBDP_CMN_REG00E3_OVRD_PCS_DES_EN_CLR;
reg |= USBDP_CMN_REG00E3_OVRD_PCS_DES_EN_SET(1);
reg &= USBDP_CMN_REG00E3_PCS_DES_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E3);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E4);
reg &= USBDP_CMN_REG00E4_OVRD_PCS_PLL_EN_CLR;
reg |= USBDP_CMN_REG00E4_OVRD_PCS_PLL_EN_SET(1);
reg &= USBDP_CMN_REG00E4_PCS_PLL_EN_CLR;
reg |= USBDP_CMN_REG00E4_PCS_PLL_EN_SET(1);
reg &= USBDP_CMN_REG00E4_OVRD_PCS_RX_CTLE_EN_CLR;
reg |= USBDP_CMN_REG00E4_OVRD_PCS_RX_CTLE_EN_SET(1);
reg &= USBDP_CMN_REG00E4_PCS_RX_CTLE_EN_CLR;
reg |= USBDP_CMN_REG00E4_PCS_RX_CTLE_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E4);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E5);
reg &= USBDP_CMN_REG00E5_OVRD_PCS_RX_SQHS_EN_CLR;
reg |= USBDP_CMN_REG00E5_OVRD_PCS_RX_SQHS_EN_SET(1);
reg &= USBDP_CMN_REG00E5_PCS_RX_SQHS_EN_CLR;
reg |= USBDP_CMN_REG00E5_PCS_RX_SQHS_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E5);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E6);
reg &= USBDP_CMN_REG00E6_OVRD_PCS_RX_TERM_EN_CLR;
reg |= USBDP_CMN_REG00E6_OVRD_PCS_RX_TERM_EN_SET(1);
reg &= USBDP_CMN_REG00E6_PCS_RX_TERM_EN_CLR;
reg |= USBDP_CMN_REG00E6_PCS_RX_TERM_EN_SET(1);
reg &= USBDP_CMN_REG00E6_OVRD_PCS_TX_DRV_EN_CLR;
reg |= USBDP_CMN_REG00E6_OVRD_PCS_TX_DRV_EN_SET(1);
reg &= USBDP_CMN_REG00E6_PCS_TX_DRV_EN_CLR;
reg |= USBDP_CMN_REG00E6_PCS_TX_DRV_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E6);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E9);
reg &= USBDP_CMN_REG00E9_OVRD_PCS_TX_ELECIDLE_CLR;
reg |= USBDP_CMN_REG00E9_OVRD_PCS_TX_ELECIDLE_SET(1);
reg &= USBDP_CMN_REG00E9_PCS_TX_ELECIDLE_CLR;
reg |= USBDP_CMN_REG00E9_PCS_TX_ELECIDLE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E9);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00EA);
reg &= USBDP_CMN_REG00EA_OVRD_PCS_TX_LFPS_EN_CLR;
reg |= USBDP_CMN_REG00EA_OVRD_PCS_TX_LFPS_EN_SET(1);
reg &= USBDP_CMN_REG00EA_PCS_TX_LFPS_EN_CLR;
reg &= USBDP_CMN_REG00EA_OVRD_PCS_TX_RCV_DET_EN_CLR;
reg |= USBDP_CMN_REG00EA_OVRD_PCS_TX_RCV_DET_EN_SET(1);
reg &= USBDP_CMN_REG00EA_PCS_TX_RCV_DET_EN_CLR;
reg |= USBDP_CMN_REG00EA_PCS_TX_RCV_DET_EN_SET(1);
reg &= USBDP_CMN_REG00EA_OVRD_PCS_TX_SER_EN_CLR;
reg |= USBDP_CMN_REG00EA_OVRD_PCS_TX_SER_EN_SET(1);
reg &= USBDP_CMN_REG00EA_PCS_TX_SER_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00EA);
}
static void phy_exynos_usbdp_g2_v4_pma_ovrd_pcs_rst_release(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
/*
dp_init/cmn_rstn = 1
0x038C 0xEF
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E3);
reg &= USBDP_CMN_REG00E3_OVRD_PCS_CMN_RSTN_CLR;
reg |= USBDP_CMN_REG00E3_OVRD_PCS_CMN_RSTN_SET(1);
reg &= USBDP_CMN_REG00E3_PCS_CMN_RSTN_CLR;
reg |= USBDP_CMN_REG00E3_PCS_CMN_RSTN_SET(1);
reg &= USBDP_CMN_REG00E3_OVRD_PCS_INIT_RSTN_CLR;
reg |= USBDP_CMN_REG00E3_OVRD_PCS_INIT_RSTN_SET(1);
reg &= USBDP_CMN_REG00E3_PCS_INIT_RSTN_CLR;
reg |= USBDP_CMN_REG00E3_PCS_INIT_RSTN_SET(1);
reg &= USBDP_CMN_REG00E3_OVRD_PCS_LANE_RSTN_CLR;
reg |= USBDP_CMN_REG00E3_OVRD_PCS_LANE_RSTN_SET(1);
reg &= USBDP_CMN_REG00E3_PCS_LANE_RSTN_CLR;
reg |= USBDP_CMN_REG00E3_PCS_LANE_RSTN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E3);
}
static void phy_exynos_usbdp_g2_v4_pma_ovrd_power_on(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
/*
pcs_des_en = 1
pcs_tx_ser_en =1
pcs_tx_elecidle = 0
0x038C 0xFF
0x03A4 0x02
0x03A8 0x83
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E3);
reg &= USBDP_CMN_REG00E3_OVRD_PCS_DES_EN_CLR;
reg |= USBDP_CMN_REG00E3_OVRD_PCS_DES_EN_SET(1);
reg &= USBDP_CMN_REG00E3_PCS_DES_EN_CLR;
reg |= USBDP_CMN_REG00E3_PCS_DES_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E3);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E9);
reg &= USBDP_CMN_REG00E9_OVRD_PCS_TX_ELECIDLE_CLR;
reg |= USBDP_CMN_REG00E9_OVRD_PCS_TX_ELECIDLE_SET(1);
reg &= USBDP_CMN_REG00E9_PCS_TX_ELECIDLE_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E9);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00EA);
reg &= USBDP_CMN_REG00EA_OVRD_PCS_TX_RCV_DET_EN_CLR;
reg &= USBDP_CMN_REG00EA_PCS_TX_RCV_DET_EN_CLR;
reg &= USBDP_CMN_REG00EA_OVRD_PCS_TX_SER_EN_CLR;
reg |= USBDP_CMN_REG00EA_OVRD_PCS_TX_SER_EN_SET(1);
reg &= USBDP_CMN_REG00EA_PCS_TX_SER_EN_CLR;
reg |= USBDP_CMN_REG00EA_PCS_TX_SER_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00EA);
}
static int phy_exynos_usbdp_g2_v4_pma_bist_en(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
int ret = 0;
int temp;
/* dp_lane_en = 0 */
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00B9);
reg &= USBDP_CMN_REG00B9_DP_LANE_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00B9);
/* dp_bist_en = 0 */
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00D6);
reg &= USBDP_CMN_REG00D6_DP_BIST_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00D6);
/*
pcs_bgr_en, pcs_bias_en
pcs_des_en, pcs_cdr_en
pcs_pll_en pcs_rx_ctle_en
pcs_rx_sqhs_en
pcs_rx_term_en, pcs_tx_drv_en
pcs_tx_elecidle
pcs_tx_ser_en, pcs_tx_lfps_en
ln0_ana_cdr_en
ln2_ana_cdr_en
0x0388 0xFB
0x038C 0xFF
0x0390 0x60
0x0394 0x00
0x0398 0x00
0x03A4 0x03
0x03A8 0x83
0x08B0 0x00
0x18B0 0x00
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E4);
reg &= USBDP_CMN_REG00E4_OVRD_PCS_RX_CTLE_EN_CLR;
reg &= USBDP_CMN_REG00E4_PCS_RX_CTLE_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E4);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E5);
reg &= USBDP_CMN_REG00E5_OVRD_PCS_RX_SQHS_EN_CLR;
reg &= USBDP_CMN_REG00E5_PCS_RX_SQHS_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E5);
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E6);
reg &= USBDP_CMN_REG00E6_OVRD_PCS_RX_TERM_EN_CLR;
reg &= USBDP_CMN_REG00E6_PCS_RX_TERM_EN_CLR;
reg &= USBDP_CMN_REG00E6_OVRD_PCS_TX_DRV_EN_CLR;
reg &= USBDP_CMN_REG00E6_PCS_TX_DRV_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E6);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG022C);
reg &= USBDP_TRSV_REG022C_OVRD_LN0_RX_CDR_EN_CLR;
reg &= USBDP_TRSV_REG022C_LN0_RX_CDR_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG022C);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG062C);
reg &= USBDP_TRSV_REG062C_OVRD_LN2_RX_CDR_EN_CLR;
reg &= USBDP_TRSV_REG062C_LN2_RX_CDR_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG062C);
/*
ln0/2_bist_en, ln0/2_bist_tx_en
ln0/2_bist_data_en
0x0C00 0xC4
0x1C00 0xC4
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0300);
reg &= USBDP_TRSV_REG0300_LN0_BIST_EN_CLR;
reg |= USBDP_TRSV_REG0300_LN0_BIST_EN_SET(1);
reg &= USBDP_TRSV_REG0300_LN0_BIST_DATA_EN_CLR;
reg |= USBDP_TRSV_REG0300_LN0_BIST_DATA_EN_SET(1);
reg &= USBDP_TRSV_REG0300_LN0_BIST_TX_EN_CLR;
reg |= USBDP_TRSV_REG0300_LN0_BIST_TX_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0300);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0700);
reg &= USBDP_TRSV_REG0700_LN2_BIST_EN_CLR;
reg |= USBDP_TRSV_REG0700_LN2_BIST_EN_SET(1);
reg &= USBDP_TRSV_REG0700_LN2_BIST_DATA_EN_CLR;
reg |= USBDP_TRSV_REG0700_LN2_BIST_DATA_EN_SET(1);
reg &= USBDP_TRSV_REG0700_LN2_BIST_TX_EN_CLR;
reg |= USBDP_TRSV_REG0700_LN2_BIST_TX_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0700);
/*
ln0/2_retimedlb_en
0x0BF8 0x0A
0x1BF8 0x0A
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02FE);
reg &= USBDP_TRSV_REG02FE_LN0_RETIMEDLB_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02FE);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06FE);
reg &= USBDP_TRSV_REG06FE_LN2_RETIMEDLB_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06FE);
/*
ln#_ana_tx_drv_accdrv_en
ln#_ana_tx_slb_en = 1
0x081C 0x02
0x101C 0x02
0x181C 0x02
0x201C 0x02
0x0880 0x00
0x1080 0x02
0x1880 0x00
0x2080 0x02
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0207);
reg &= USBDP_TRSV_REG0207_LN0_ANA_TX_DRV_ACCDRV_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0207);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0407);
reg &= USBDP_TRSV_REG0407_LN1_ANA_TX_DRV_ACCDRV_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0407);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0607);
reg &= USBDP_TRSV_REG0607_LN2_ANA_TX_DRV_ACCDRV_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0607);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0807);
reg &= USBDP_TRSV_REG0807_LN3_ANA_TX_DRV_ACCDRV_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0807);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0220);
reg &= USBDP_TRSV_REG0220_LN0_ANA_TX_SLB_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0220);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0420);
reg &= USBDP_TRSV_REG0420_LN1_ANA_TX_SLB_EN_CLR;
reg |= USBDP_TRSV_REG0420_LN1_ANA_TX_SLB_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0420);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0620);
reg &= USBDP_TRSV_REG0620_LN2_ANA_TX_SLB_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0620);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0820);
reg &= USBDP_TRSV_REG0820_LN3_ANA_TX_SLB_EN_CLR;
reg |= USBDP_TRSV_REG0820_LN3_ANA_TX_SLB_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0820);
/*
ln0/2_bist_auto_run
0x0BFC 0x80
0x1BFC 0x80
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02FF);
reg &= USBDP_TRSV_REG02FF_LN0_BIST_AUTO_RUN_CLR;
reg |= USBDP_TRSV_REG02FF_LN0_BIST_AUTO_RUN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02FF);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06FF);
reg &= USBDP_TRSV_REG06FF_LN2_BIST_AUTO_RUN_CLR;
reg |= USBDP_TRSV_REG06FF_LN2_BIST_AUTO_RUN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06FF);
// mdelay(5); // TODO: it is necessary experimentally
/*
ln0/2_ana_rx_slb_d_lane_sel
ln0/2_ana_rx_slb_en
0x0A10 0x38
0x1A10 0x38
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0284);
reg &= USBDP_TRSV_REG0284_LN0_ANA_RX_SLB_D_LANE_SEL_CLR;
reg |= USBDP_TRSV_REG0284_LN0_ANA_RX_SLB_D_LANE_SEL_SET(1);
reg &= USBDP_TRSV_REG0284_LN0_ANA_RX_SLB_EN_CLR;
reg |= USBDP_TRSV_REG0284_LN0_ANA_RX_SLB_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0284);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0684);
reg &= USBDP_TRSV_REG0684_LN2_ANA_RX_SLB_D_LANE_SEL_CLR;
reg |= USBDP_TRSV_REG0684_LN2_ANA_RX_SLB_D_LANE_SEL_SET(1);
reg &= USBDP_TRSV_REG0684_LN2_ANA_RX_SLB_EN_CLR;
reg |= USBDP_TRSV_REG0684_LN2_ANA_RX_SLB_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0684);
udelay(10);
temp = info->used_phy_port;
info->used_phy_port = 0;
ret |= phy_exynos_usbdp_g2_v4_pma_check_cdr_lock(info);
info->used_phy_port = 1;
ret |= phy_exynos_usbdp_g2_v4_pma_check_cdr_lock(info);
info->used_phy_port = temp;
/*
ln0/2_bist_rx_en
0x0C00 0xE4
0x1C00 0xE4
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0300);
reg &= USBDP_TRSV_REG0300_LN0_BIST_RX_EN_CLR;
reg |= USBDP_TRSV_REG0300_LN0_BIST_RX_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0300);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0700);
reg &= USBDP_TRSV_REG0700_LN2_BIST_RX_EN_CLR;
reg |= USBDP_TRSV_REG0700_LN2_BIST_RX_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0700);
if (ret)
return -3;
else
return 0;
}
static int phy_exynos_usbdp_g2_v4_pma_bist_result(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
u32 pass_flag = 0, start_flag = 0;
/*
LN0 BIST pass/start flag
LN2 BIST pass/start flag
0x0F20 (Read)
0x1F20 (Read)
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03C8);
pass_flag = USBDP_TRSV_REG03C8_LN0_MON_BIST_COMP_TEST_GET(reg);
start_flag = USBDP_TRSV_REG03C8_LN0_MON_BIST_COMP_START_GET(reg);
if (!(pass_flag & start_flag))
return -4;
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07C8);
pass_flag = USBDP_TRSV_REG07C8_LN2_MON_BIST_COMP_TEST_GET(reg);
start_flag = USBDP_TRSV_REG07C8_LN2_MON_BIST_COMP_START_GET(reg);
if (!(pass_flag & start_flag))
return -5;
return 0;
}
int phy_exynos_usbdp_g2_v4_internal_loopback(struct exynos_usbphy_info *info, u32 cmn_rate)
{
int ret = 0;
int temp;
phy_exynos_usbdp_g2_v4_ctrl_pma_ready(info);
phy_exynos_usbdp_g2_v4_aux_force_off(info);
phy_exynos_usbdp_g2_v4_pma_default_sfr_update(info);
phy_exynos_usbdp_g2_v4_tune(info);
phy_exynos_usbdp_g2_v4_pma_ovrd_enable(info, cmn_rate);
phy_exynos_usbdp_g2_v4_ctrl_pma_rst_release(info);
phy_exynos_usbdp_g2_v4_pma_ovrd_pcs_rst_release(info);
do {
ret = phy_exynos_usbdp_g2_v4_pma_check_pll_lock(info);
if (ret)
break;
phy_exynos_usbdp_g2_v4_pma_ovrd_power_on(info);
temp = info->used_phy_port;
info->used_phy_port = 0;
ret = phy_exynos_usbdp_g2_v4_pma_check_cdr_lock(info);
info->used_phy_port = temp;
if (ret)
break;
info->used_phy_port = 1;
ret = phy_exynos_usbdp_g2_v4_pma_check_cdr_lock(info);
info->used_phy_port = temp;
if (ret)
break;
mdelay(10); // it is necessary experimentally
ret = phy_exynos_usbdp_g2_v4_pma_bist_en(info);
if (ret)
break;
udelay(100);
ret = phy_exynos_usbdp_g2_v4_pma_bist_result(info);
if (ret)
break;
} while (0);
return ret;
}
void phy_exynos_usbdp_g2_v4_eom_init(struct exynos_usbphy_info *info, u32 cmn_rate)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
// EOM Sample Number ( 2^10 ) ----> applied 2^(sample_number)
if (info->used_phy_port == 0) {
/*
0x0B7C 0x00 ln0_rx_efom_num_of_sample__13_8 = 0
0x0B80 0x0A ln0_rx_efom_num_of_sample__7_0 = 0xa
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DF);
reg &= USBDP_TRSV_REG02DF_LN0_RX_EFOM_NUM_OF_SAMPLE__13_8_CLR;
reg |= USBDP_TRSV_REG02DF_LN0_RX_EFOM_NUM_OF_SAMPLE__13_8_SET(0);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DF);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02E0);
reg &= USBDP_TRSV_REG02E0_LN0_RX_EFOM_NUM_OF_SAMPLE__7_0_CLR;
if (!cmn_rate)
reg |= USBDP_TRSV_REG02E0_LN0_RX_EFOM_NUM_OF_SAMPLE__7_0_SET(0xa);
else
reg |= USBDP_TRSV_REG02E0_LN0_RX_EFOM_NUM_OF_SAMPLE__7_0_SET(0xE);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02E0);
} else {
/*
0x1B7C 0x00 ln2_rx_efom_num_of_sample__13_8 = 0
0x1B80 0x0A ln2_rx_efom_num_of_sample__7_0 = 0xa
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DF);
reg &= USBDP_TRSV_REG06DF_LN2_RX_EFOM_NUM_OF_SAMPLE__13_8_CLR;
reg |= USBDP_TRSV_REG06DF_LN2_RX_EFOM_NUM_OF_SAMPLE__13_8_SET(0);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DF);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06E0);
reg &= USBDP_TRSV_REG06E0_LN2_RX_EFOM_NUM_OF_SAMPLE__7_0_CLR;
if (!cmn_rate)
reg |= USBDP_TRSV_REG06E0_LN2_RX_EFOM_NUM_OF_SAMPLE__7_0_SET(0xa);
else
reg |= USBDP_TRSV_REG06E0_LN2_RX_EFOM_NUM_OF_SAMPLE__7_0_SET(0xE);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06E0);
}
// ovrd adap en, eom_en
if (info->used_phy_port == 0) {
/*
0x09D0 0x01 ovrd_ln0_rx_dfe_vref_odd_ctrl = 1
0x09D8 0x01 ovrd_ln0_rx_dfe_vref_even_ctrl = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0274);
reg |= USBDP_TRSV_REG0274_OVRD_LN0_RX_DFE_VREF_ODD_CTRL_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0274);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0276);
reg |= USBDP_TRSV_REG0276_OVRD_LN0_RX_DFE_VREF_EVEN_CTRL_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0276);
/*
0x099C 0x2F ovrd_ln0_rx_dfe_adap_en = 1
ln0_rx_dfe_adap_en = 0
ovrd_ln0_rx_dfe_eom_en = 1
ln0_rx_dfe_eom_en = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0267);
reg |= USBDP_TRSV_REG0267_OVRD_LN0_RX_DFE_ADAP_EN_SET(1);
reg &= USBDP_TRSV_REG0267_LN0_RX_DFE_ADAP_EN_CLR;
reg |= USBDP_TRSV_REG0267_OVRD_LN0_RX_DFE_EOM_EN_SET(1);
reg |= USBDP_TRSV_REG0267_LN0_RX_DFE_EOM_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0267);
} else {
/*
0x19D0 0x01 ovrd_ln2_rx_dfe_vref_odd_ctrl = 1
0x19D8 0x01 ovrd_ln2_rx_dfe_vref_even_ctrl = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0674);
reg |= USBDP_TRSV_REG0674_OVRD_LN2_RX_DFE_VREF_ODD_CTRL_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0674);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0676);
reg |= USBDP_TRSV_REG0676_OVRD_LN2_RX_DFE_VREF_EVEN_CTRL_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0676);
/*
0x199C 0x2F ovrd_ln2_rx_dfe_adap_en = 1
ln2_rx_dfe_adap_en = 0
ovrd_ln2_rx_dfe_eom_en = 1
ln2_rx_dfe_eom_en = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0667);
reg |= USBDP_TRSV_REG0667_OVRD_LN2_RX_DFE_ADAP_EN_SET(1);
reg &= USBDP_TRSV_REG0667_LN2_RX_DFE_ADAP_EN_CLR;
reg |= USBDP_TRSV_REG0667_OVRD_LN2_RX_DFE_EOM_EN_SET(1);
reg |= USBDP_TRSV_REG0667_LN2_RX_DFE_EOM_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0667);
}
// PI STR ( 0 min, f:max )
if (info->used_phy_port == 0) {
/*
0x09AC 0x03 ln0_ana_rx_dfe_eom_pi_str_ctrl = 3
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG026B);
reg &= USBDP_TRSV_REG026B_LN0_ANA_RX_DFE_EOM_PI_STR_CTRL_CLR;
if (!cmn_rate)
reg |= USBDP_TRSV_REG026B_LN0_ANA_RX_DFE_EOM_PI_STR_CTRL_SET(0x3);
else
reg |= USBDP_TRSV_REG026B_LN0_ANA_RX_DFE_EOM_PI_STR_CTRL_SET(0xF);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG026B);
} else {
/*
0x19AC 0x03 ln2_ana_rx_dfe_eom_pi_str_ctrl = 3
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG066B);
reg &= USBDP_TRSV_REG066B_LN2_ANA_RX_DFE_EOM_PI_STR_CTRL_CLR;
if (!cmn_rate)
reg |= USBDP_TRSV_REG066B_LN2_ANA_RX_DFE_EOM_PI_STR_CTRL_SET(0x3);
else
reg |= USBDP_TRSV_REG066B_LN2_ANA_RX_DFE_EOM_PI_STR_CTRL_SET(0xF);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG066B);
}
// EOM MODE
if (info->used_phy_port == 0) {
/*
0x0B70 0x10 ln0_rx_efom_mode = 4
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DC);
reg &= USBDP_TRSV_REG02DC_LN0_RX_EFOM_MODE_CLR;
reg |= USBDP_TRSV_REG02DC_LN0_RX_EFOM_MODE_SET(0x4);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DC);
} else {
/*
0x1B70 0x10 ln2_rx_efom_mode = 4
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DC);
reg &= USBDP_TRSV_REG06DC_LN2_RX_EFOM_MODE_CLR;
reg |= USBDP_TRSV_REG06DC_LN2_RX_EFOM_MODE_SET(0x4);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DC);
}
// EOM START SSM DISABLE
if (info->used_phy_port == 0) {
/*
0x0B74 0x10 ln0_rx_efom_start_ssm_disable = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DD);
reg &= USBDP_TRSV_REG02DD_LN0_RX_EFOM_START_SSM_DISABLE_CLR;
reg |= USBDP_TRSV_REG02DD_LN0_RX_EFOM_START_SSM_DISABLE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DD);
} else {
/*
0x1B74 0x10 ln2_rx_efom_start_ssm_disable = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DD);
reg &= USBDP_TRSV_REG06DD_LN2_RX_EFOM_START_SSM_DISABLE_CLR;
reg |= USBDP_TRSV_REG06DD_LN2_RX_EFOM_START_SSM_DISABLE_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DD);
}
// PCS EOM INPUT
/*
0x0394 0x0C ovrd_pcs_rx_fom_en = 1
pcs_rx_fom_en = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E5);
reg |= USBDP_CMN_REG00E5_OVRD_PCS_RX_FOM_EN_SET(1);
reg |= USBDP_CMN_REG00E5_PCS_RX_FOM_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E5);
// NON DATA, DE-SER EN
if (info->used_phy_port == 0) {
/*
0x0978 0x2C ovrd_ln0_rx_des_non_data_sel = 1
ln0_rx_des_non_data_sel = 0
ovrd_ln0_rx_des_rstn = 1
ln0_rx_des_rstn = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG025E);
reg |= USBDP_TRSV_REG025E_OVRD_LN0_RX_DES_NON_DATA_SEL_SET(1);
reg |= USBDP_TRSV_REG025E_OVRD_LN0_RX_DES_RSTN_SET(1);
reg |= USBDP_TRSV_REG025E_LN0_RX_DES_RSTN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG025E);
} else {
/*
0x1978 0x2C ovrd_ln2_rx_des_non_data_sel = 1
ln2_rx_des_non_data_sel = 0
ovrd_ln2_rx_des_rstn = 1
ln2_rx_des_rstn = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG065E);
reg |= USBDP_TRSV_REG065E_OVRD_LN2_RX_DES_NON_DATA_SEL_SET(1);
reg |= USBDP_TRSV_REG065E_OVRD_LN2_RX_DES_RSTN_SET(1);
reg |= USBDP_TRSV_REG065E_LN2_RX_DES_RSTN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG065E);
}
// EOM CLOCK DIV
/* it was set at phy_exynos_usbdp_g2_v2_pma_default_sfr_update
0x09A0 0x24
0x19A0 0x24
*/
if (info->used_phy_port == 0) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0268);
reg |= USBDP_TRSV_REG0268_LN0_RX_DFE_EOM_PI_DIV_SEL_SP_SET(4);
if (!cmn_rate) {
reg &= USBDP_TRSV_REG0268_LN0_RX_DFE_EOM_PI_DIV_SEL_SSP_CLR;
reg |= USBDP_TRSV_REG0268_LN0_RX_DFE_EOM_PI_DIV_SEL_SSP_SET(4);
} else {
reg &= USBDP_TRSV_REG0268_LN0_RX_DFE_EOM_PI_DIV_SEL_SSP_CLR;
reg |= USBDP_TRSV_REG0268_LN0_RX_DFE_EOM_PI_DIV_SEL_SSP_SET(2);
}
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0268);
} else {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0668);
reg |= USBDP_TRSV_REG0668_LN2_RX_DFE_EOM_PI_DIV_SEL_SP_SET(4);
if (!cmn_rate) {
reg &= USBDP_TRSV_REG0668_LN2_RX_DFE_EOM_PI_DIV_SEL_SSP_CLR;
reg |= USBDP_TRSV_REG0668_LN2_RX_DFE_EOM_PI_DIV_SEL_SSP_SET(4);
} else {
reg &= USBDP_TRSV_REG0668_LN2_RX_DFE_EOM_PI_DIV_SEL_SSP_CLR;
reg |= USBDP_TRSV_REG0668_LN2_RX_DFE_EOM_PI_DIV_SEL_SSP_SET(2);
}
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0668);
}
// EOM BIT WIDTH <----------------- Need to Confirm about value, it just predicted value
if (info->used_phy_port == 0) {
/*
Gen2
0x0B78 0x47 ln0_rx_efom_settle_time = 4
ln0_rx_efom_bit_width_sel = 1
Gen1
0x0B78 0x4F ln0_rx_efom_settle_time = 4
ln0_rx_efom_bit_width_sel = 3
*/
if (cmn_rate) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DE);
reg &= USBDP_TRSV_REG02DE_LN0_RX_EFOM_SETTLE_TIME_CLR;
reg |= USBDP_TRSV_REG02DE_LN0_RX_EFOM_SETTLE_TIME_SET(0x4);
reg &= USBDP_TRSV_REG02DE_LN0_RX_EFOM_BIT_WIDTH_SEL_CLR;
reg |= USBDP_TRSV_REG02DE_LN0_RX_EFOM_BIT_WIDTH_SEL_SET(0x1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DE);
} else {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DE);
reg &= USBDP_TRSV_REG02DE_LN0_RX_EFOM_SETTLE_TIME_CLR;
reg |= USBDP_TRSV_REG02DE_LN0_RX_EFOM_SETTLE_TIME_SET(0x4);
reg &= USBDP_TRSV_REG02DE_LN0_RX_EFOM_BIT_WIDTH_SEL_CLR;
reg |= USBDP_TRSV_REG02DE_LN0_RX_EFOM_BIT_WIDTH_SEL_SET(0x3);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DE);
}
} else {
/*
Gen2
0x1B78 0x47 ln2_rx_efom_settle_time = 4
ln2_rx_efom_bit_width_sel = 1
Gen1
0x1B78 0x4F ln2_rx_efom_settle_time = 4
ln2_rx_efom_bit_width_sel = 3
*/
if (cmn_rate) {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DE);
reg &= USBDP_TRSV_REG06DE_LN2_RX_EFOM_SETTLE_TIME_CLR;
reg |= USBDP_TRSV_REG06DE_LN2_RX_EFOM_SETTLE_TIME_SET(0x4);
reg &= USBDP_TRSV_REG06DE_LN2_RX_EFOM_BIT_WIDTH_SEL_CLR;
reg |= USBDP_TRSV_REG06DE_LN2_RX_EFOM_BIT_WIDTH_SEL_SET(0x1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DE);
} else {
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DE);
reg &= USBDP_TRSV_REG06DE_LN2_RX_EFOM_SETTLE_TIME_CLR;
reg |= USBDP_TRSV_REG06DE_LN2_RX_EFOM_SETTLE_TIME_SET(0x4);
reg &= USBDP_TRSV_REG06DE_LN2_RX_EFOM_BIT_WIDTH_SEL_CLR;
reg |= USBDP_TRSV_REG06DE_LN2_RX_EFOM_BIT_WIDTH_SEL_SET(0x3);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DE);
}
}
// Switch to 6:New EOM, E:legacy EFOM mode
/*
0x0450 0x06 efom_legacy_mode_en = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG0114);
if (!cmn_rate)
/* Gen1 : New EOM Mode */
reg &= USBDP_CMN_REG0114_EFOM_LEGACY_MODE_EN_CLR;
else
/* Gen2 10Ghz_CCO : Legacy EOM Mode */
reg |= USBDP_CMN_REG0114_EFOM_LEGACY_MODE_EN_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG0114);
}
static void phy_exynos_usbdp_g2_v4_eom_deinit(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
// EOM START ovrd clear
if (info->used_phy_port == 0) {
/*
0x0B70 0x10 ln0_ovrd_rx_efom_start = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DC);
reg &= USBDP_TRSV_REG02DC_LN0_OVRD_RX_EFOM_START_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DC);
} else {
/*
0x1B70 0x10 ln2_ovrd_rx_efom_start = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DC);
reg &= USBDP_TRSV_REG06DC_LN2_OVRD_RX_EFOM_START_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DC);
}
// EOM Sample Number clear
if (info->used_phy_port == 0) {
/*
0x0B7C 0x00 ln0_rx_efom_num_of_sample__13_8 = 0
0x0B80 0x00 ln0_rx_efom_num_of_sample__7_0 = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DF);
reg &= USBDP_TRSV_REG02DF_LN0_RX_EFOM_NUM_OF_SAMPLE__13_8_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DF);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02E0);
reg &= USBDP_TRSV_REG02E0_LN0_RX_EFOM_NUM_OF_SAMPLE__7_0_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02E0);
} else {
/*
0x1B7C 0x00 ln2_rx_efom_num_of_sample__13_8 = 0
0x1B80 0x00 ln2_rx_efom_num_of_sample__7_0 = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DF);
reg &= USBDP_TRSV_REG06DF_LN2_RX_EFOM_NUM_OF_SAMPLE__13_8_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DF);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06E0);
reg &= USBDP_TRSV_REG06E0_LN2_RX_EFOM_NUM_OF_SAMPLE__7_0_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06E0);
}
// ovrd adap en, eom_en
if (info->used_phy_port == 0) {
/*
0x09D0 0x00 ovrd_ln0_rx_dfe_vref_odd_ctrl = 0
0x09D8 0x00 ovrd_ln0_rx_dfe_vref_even_ctrl = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0274);
reg &= USBDP_TRSV_REG0274_OVRD_LN0_RX_DFE_VREF_ODD_CTRL_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0274);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0276);
reg &= USBDP_TRSV_REG0276_OVRD_LN0_RX_DFE_VREF_EVEN_CTRL_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0276);
/*
0x099C 0x1C ovrd_ln0_rx_dfe_adap_en = 0
ln0_rx_dfe_adap_en = 1
ovrd_ln0_rx_dfe_eom_en = 0
ln0_rx_dfe_eom_en = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0267);
reg &= USBDP_TRSV_REG0267_OVRD_LN0_RX_DFE_ADAP_EN_CLR;
reg |= USBDP_TRSV_REG0267_LN0_RX_DFE_ADAP_EN_SET(1);
reg &= USBDP_TRSV_REG0267_OVRD_LN0_RX_DFE_EOM_EN_CLR;
reg &= USBDP_TRSV_REG0267_LN0_RX_DFE_EOM_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0267);
} else {
/*
0x19D0 0x00 ovrd_ln2_rx_dfe_vref_odd_ctrl = 0
0x19D8 0x00 ovrd_ln2_rx_dfe_vref_even_ctrl = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0674);
reg &= USBDP_TRSV_REG0674_OVRD_LN2_RX_DFE_VREF_ODD_CTRL_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0674);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0676);
reg &= USBDP_TRSV_REG0676_OVRD_LN2_RX_DFE_VREF_EVEN_CTRL_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0676);
/*
0x099C 0x1C ovrd_ln0_rx_dfe_adap_en = 0
ln0_rx_dfe_adap_en = 1
ovrd_ln0_rx_dfe_eom_en = 0
ln0_rx_dfe_eom_en = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0667);
reg &= USBDP_TRSV_REG0667_OVRD_LN2_RX_DFE_ADAP_EN_CLR;
reg |= USBDP_TRSV_REG0667_LN2_RX_DFE_ADAP_EN_SET(1);
reg &= USBDP_TRSV_REG0667_OVRD_LN2_RX_DFE_EOM_EN_CLR;
reg &= USBDP_TRSV_REG0667_LN2_RX_DFE_EOM_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0667);
}
// PI STR ( 0 min, f:max )
if (info->used_phy_port == 0) {
/*
0x09AC 0x00 ln0_ana_rx_dfe_eom_pi_str_ctrl = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG026B);
reg &= USBDP_TRSV_REG026B_LN0_ANA_RX_DFE_EOM_PI_STR_CTRL_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG026B);
} else {
/*
0x19AC 0x00 ln2_ana_rx_dfe_eom_pi_str_ctrl = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG066B);
reg &= USBDP_TRSV_REG066B_LN2_ANA_RX_DFE_EOM_PI_STR_CTRL_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG066B);
}
// EOM MODE
if (info->used_phy_port == 0) {
/*
0x0B70 0x00 ln0_rx_efom_mode = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DC);
reg &= USBDP_TRSV_REG02DC_LN0_RX_EFOM_MODE_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DC);
} else {
/*
0x1B70 0x00 ln2_rx_efom_mode = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DC);
reg &= USBDP_TRSV_REG06DC_LN2_RX_EFOM_MODE_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DC);
}
// EOM START SSM DISABLE
if (info->used_phy_port == 0) {
/*
0x0B74 0x00 ln0_rx_efom_start_ssm_disable = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DD);
reg &= USBDP_TRSV_REG02DD_LN0_RX_EFOM_START_SSM_DISABLE_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DD);
} else {
/*
0x1B74 0x00 ln2_rx_efom_start_ssm_disable = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DD);
reg &= USBDP_TRSV_REG06DD_LN2_RX_EFOM_START_SSM_DISABLE_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DD);
}
// PCS EOM INPUT
/*
0x0394 0x00 ovrd_pcs_rx_fom_en = 0
pcs_rx_fom_en = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG00E5);
reg &= USBDP_CMN_REG00E5_OVRD_PCS_RX_FOM_EN_CLR;
reg &= USBDP_CMN_REG00E5_PCS_RX_FOM_EN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_CMN_REG00E5);
// NON DATA, DE-SER EN
if (info->used_phy_port == 0) {
/*
0x0978 0x00 ovrd_ln0_rx_des_non_data_sel = 0
ovrd_ln0_rx_des_rstn = 0
ln0_rx_des_rstn = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG025E);
reg &= USBDP_TRSV_REG025E_OVRD_LN0_RX_DES_NON_DATA_SEL_CLR;
reg &= USBDP_TRSV_REG025E_OVRD_LN0_RX_DES_RSTN_CLR;
reg &= USBDP_TRSV_REG025E_LN0_RX_DES_RSTN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG025E);
} else {
/*
0x1978 0x00 ovrd_ln2_rx_des_non_data_sel = 0
ovrd_ln2_rx_des_rstn = 0
ln2_rx_des_rstn = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG065E);
reg &= USBDP_TRSV_REG065E_OVRD_LN2_RX_DES_NON_DATA_SEL_CLR;
reg &= USBDP_TRSV_REG065E_OVRD_LN2_RX_DES_RSTN_CLR;
reg &= USBDP_TRSV_REG065E_LN2_RX_DES_RSTN_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG065E);
}
// EOM BIT WIDTH
if (info->used_phy_port == 0) {
/*
0x0B78 0x07 ln0_rx_efom_settle_time = 0
ln0_rx_efom_bit_width_sel = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DE);
reg &= USBDP_TRSV_REG02DE_LN0_RX_EFOM_SETTLE_TIME_CLR;
reg &= USBDP_TRSV_REG02DE_LN0_RX_EFOM_BIT_WIDTH_SEL_CLR;
reg |= USBDP_TRSV_REG02DE_LN0_RX_EFOM_BIT_WIDTH_SEL_SET(0x1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DE);
} else {
/*
0x1B78 0x07 ln2_rx_efom_settle_time = 0
ln2_rx_efom_bit_width_sel = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DE);
reg &= USBDP_TRSV_REG06DE_LN2_RX_EFOM_SETTLE_TIME_CLR;
reg &= USBDP_TRSV_REG06DE_LN2_RX_EFOM_BIT_WIDTH_SEL_CLR;
reg |= USBDP_TRSV_REG06DE_LN2_RX_EFOM_BIT_WIDTH_SEL_SET(0x1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DE);
}
}
void phy_exynos_usbdp_g2_v4_eom_start(struct exynos_usbphy_info *info, u32 ph_sel, u32 def_vref)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
// EOM PHASE SETTING
if (info->used_phy_port == 0) {
/*
0x0B94 ln0_rx_efom_eom_ph_sel
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02E5);
reg &= USBDP_TRSV_REG02E5_LN0_RX_EFOM_EOM_PH_SEL_CLR;
reg |= USBDP_TRSV_REG02E5_LN0_RX_EFOM_EOM_PH_SEL_SET(ph_sel);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02E5);
} else {
/*
0x1B94 ln2_rx_efom_eom_ph_sel
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06E5);
reg &= USBDP_TRSV_REG06E5_LN2_RX_EFOM_EOM_PH_SEL_CLR;
reg |= USBDP_TRSV_REG06E5_LN2_RX_EFOM_EOM_PH_SEL_SET(ph_sel);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06E5);
}
// EOM VREF SETTING
if (info->used_phy_port == 0) {
/*
0x09D4 ln0_rx_dfe_vref_odd_ctrl__7_0
0x09DC ln0_rx_dfe_vref_even_ctrl__7_0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0275);
reg &= USBDP_TRSV_REG0275_LN0_RX_DFE_VREF_ODD_CTRL__7_0_CLR;
reg |= USBDP_TRSV_REG0275_LN0_RX_DFE_VREF_ODD_CTRL__7_0_SET(def_vref);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0275);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0277);
reg &= USBDP_TRSV_REG0277_LN0_RX_DFE_VREF_EVEN_CTRL__7_0_CLR;
reg |= USBDP_TRSV_REG0277_LN0_RX_DFE_VREF_EVEN_CTRL__7_0_SET(def_vref);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0277);
} else {
/*
0x19D4 ln2_rx_dfe_vref_odd_ctrl__7_0
0x19DC ln2_rx_dfe_vref_even_ctrl__7_0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0675);
reg &= USBDP_TRSV_REG0675_LN2_RX_DFE_VREF_ODD_CTRL__7_0_CLR;
reg |= USBDP_TRSV_REG0675_LN2_RX_DFE_VREF_ODD_CTRL__7_0_SET(def_vref);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0675);
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG0677);
reg &= USBDP_TRSV_REG0677_LN2_RX_DFE_VREF_EVEN_CTRL__7_0_CLR;
reg |= USBDP_TRSV_REG0677_LN2_RX_DFE_VREF_EVEN_CTRL__7_0_SET(def_vref);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG0677);
}
// EOM START
if (info->used_phy_port == 0) {
/*
0x0B70 0x13 ln0_ovrd_rx_efom_start = 1
ln0_rx_efom_start = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DC);
reg |= USBDP_TRSV_REG02DC_LN0_OVRD_RX_EFOM_START_SET(1);
reg |= USBDP_TRSV_REG02DC_LN0_RX_EFOM_START_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DC);
} else {
/*
0x1B70 0x13 ln2_ovrd_rx_efom_start = 1
ln2_rx_efom_start = 1
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DC);
reg |= USBDP_TRSV_REG06DC_LN2_OVRD_RX_EFOM_START_SET(1);
reg |= USBDP_TRSV_REG06DC_LN2_RX_EFOM_START_SET(1);
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DC);
}
}
int phy_exynos_usbdp_g2_v4_eom_get_done_status(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
u32 eom_done = 0;
// Check efom_done
if (info->used_phy_port == 0) {
/*
0x0F98 ln0_mon_rx_efom_done
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG03E6);
eom_done = USBDP_TRSV_REG03E6_LN0_MON_RX_EFOM_DONE_GET(reg);
} else {
/*
0x1F98 ln2_mon_rx_efom_done
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG07E6);
eom_done = USBDP_TRSV_REG07E6_LN2_MON_RX_EFOM_DONE_GET(reg);
}
if (eom_done)
return 0;
else
return -1;
}
u64 phy_exynos_usbdp_g2_v4_eom_get_err_cnt(struct exynos_usbphy_info *info, u32 cmn_rate)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
u64 err_cnt_lo = 0;
u64 err_cnt_hi = 0;
// Get error count
if (!cmn_rate) {
if (info->used_phy_port == 0) {
/*
0x077C ln0_mon_rx_efom_err_cnt__7_0
0x0778 ln0_mon_rx_efom_err_cnt__15_8
0x0774 ln0_mon_rx_efom_err_cnt__23_16
0x0770 ln0_mon_rx_efom_err_cnt__31_24
0x076C ln0_mon_rx_efom_err_cnt__39_32
0x0768 ln0_mon_rx_efom_err_cnt__47_40
0x0764 ln0_mon_rx_efom_err_cnt__52_48
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01DF);
err_cnt_lo |= USBDP_CMN_REG01DF_LN0_MON_RX_EFOM_ERR_CNT__7_0_GET(reg) << 0;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01DE);
err_cnt_lo |= USBDP_CMN_REG01DE_LN0_MON_RX_EFOM_ERR_CNT__15_8_GET(reg) << 8;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01DD);
err_cnt_lo |= USBDP_CMN_REG01DD_LN0_MON_RX_EFOM_ERR_CNT__23_16_GET(reg) << 16;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01DC);
err_cnt_lo |= USBDP_CMN_REG01DC_LN0_MON_RX_EFOM_ERR_CNT__31_24_GET(reg) << 24;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01DB);
err_cnt_hi |= USBDP_CMN_REG01DB_LN0_MON_RX_EFOM_ERR_CNT__39_32_GET(reg) << 0;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01DA);
err_cnt_hi |= USBDP_CMN_REG01DA_LN0_MON_RX_EFOM_ERR_CNT__47_40_GET(reg) << 4;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01D9);
err_cnt_hi |= USBDP_CMN_REG01D9_LN0_MON_RX_EFOM_ERR_CNT__52_48_GET(reg) << 8;
} else {
/*
0x0798 ln2_mon_rx_efom_err_cnt__7_0
0x0794 ln2_mon_rx_efom_err_cnt__15_8
0x0790 ln2_mon_rx_efom_err_cnt__23_16
0x078c ln2_mon_rx_efom_err_cnt__31_24
0x0788 ln2_mon_rx_efom_err_cnt__39_32
0x0784 ln2_mon_rx_efom_err_cnt__47_40
0x0780 ln2_mon_rx_efom_err_cnt__52_48
*/
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01E6);
err_cnt_lo |= USBDP_CMN_REG01E6_LN2_MON_RX_EFOM_ERR_CNT__7_0_GET(reg) << 0;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01E5);
err_cnt_lo |= USBDP_CMN_REG01E5_LN2_MON_RX_EFOM_ERR_CNT__15_8_GET(reg) << 8;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01E4);
err_cnt_lo |= USBDP_CMN_REG01E4_LN2_MON_RX_EFOM_ERR_CNT__23_16_GET(reg) << 16;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01E3);
err_cnt_lo |= USBDP_CMN_REG01E3_LN2_MON_RX_EFOM_ERR_CNT__31_24_GET(reg) << 24;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01E2);
err_cnt_hi |= USBDP_CMN_REG01E2_LN2_MON_RX_EFOM_ERR_CNT__39_32_SET(reg) << 0;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01E1);
err_cnt_hi |= USBDP_CMN_REG01E1_LN2_MON_RX_EFOM_ERR_CNT__47_40_GET(reg) << 4;
reg = readl(regs_base + EXYNOS_USBDP_CMN_REG01E0);
err_cnt_hi |= USBDP_CMN_REG01E0_LN2_MON_RX_EFOM_ERR_CNT__52_48_SET(reg) << 8;
}
return err_cnt_hi << 32 | err_cnt_lo;
} else {
if (info->used_phy_port == 0) {
err_cnt_lo = readl(regs_base + EXYNOS_USBDP_TRSV_REG03E8);
err_cnt_hi = readl(regs_base + EXYNOS_USBDP_TRSV_REG03E7);
} else {
err_cnt_lo = readl(regs_base + EXYNOS_USBDP_TRSV_REG07E8);
err_cnt_hi = readl(regs_base + EXYNOS_USBDP_TRSV_REG07E7);
}
return err_cnt_hi << 8 | err_cnt_lo;
}
}
void phy_exynos_usbdp_g2_v4_eom_stop(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->pma_base;
u32 reg;
// EOM STOP
if (info->used_phy_port == 0) {
/*
0x0B70 0x12 ln0_rx_efom_start = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG02DC);
reg &= USBDP_TRSV_REG02DC_LN0_RX_EFOM_START_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG02DC);
} else {
/*
0x1B70 0x12 ln2_rx_efom_start = 0
*/
reg = readl(regs_base + EXYNOS_USBDP_TRSV_REG06DC);
reg &= USBDP_TRSV_REG06DC_LN2_RX_EFOM_START_CLR;
writel(reg, regs_base + EXYNOS_USBDP_TRSV_REG06DC);
}
}
void phy_exynos_usbdp_g2_v4_eom(struct exynos_usbphy_info *info, struct usb_eom_result_s *eom_result, u32 cmn_rate)
{
u32 ph_sel, def_vref = 0;
u64 err_cnt = 0;
u32 test_cnt = 0;
u32 UI_CNT, ui_no;
pr_info("cmn_rate = %d\n", cmn_rate);
phy_exynos_usbdp_g2_v4_eom_init(info, cmn_rate); // 0: Gen1, 1: Gen2
if (!cmn_rate) UI_CNT = 1; /* Gen1 */
else UI_CNT = 2; /* Gen2 */
for (ui_no = 0; ui_no < UI_CNT; ui_no++) {
for (ph_sel = 0; ph_sel < EOM_PH_SEL_MAX; ph_sel++) {
for (def_vref = 0; def_vref < EOM_DEF_VREF_MAX; def_vref++) {
phy_exynos_usbdp_g2_v4_eom_start(info, ph_sel, def_vref);
while (phy_exynos_usbdp_g2_v4_eom_get_done_status(info));
err_cnt = phy_exynos_usbdp_g2_v4_eom_get_err_cnt(info, cmn_rate);
phy_exynos_usbdp_g2_v4_eom_stop(info);
// Save result
eom_result[test_cnt].phase = ph_sel;
eom_result[test_cnt].vref = def_vref;
eom_result[test_cnt].err = err_cnt;
test_cnt++;
}
}
}
phy_exynos_usbdp_g2_v4_eom_deinit(info);
}
int phy_exynos_usbdp_g2_v4_enable(struct exynos_usbphy_info *info)
{
int ret = 0;
phy_exynos_usbdp_g2_v4_ctrl_pma_ready(info);
phy_exynos_usbdp_g2_v4_aux_force_off(info);
phy_exynos_usbdp_g2_v4_pma_default_sfr_update(info);
phy_exynos_usbdp_g2_v4_set_pcs(info);
phy_exynos_usbdp_g2_v4_tune(info);
phy_exynos_usbdp_g2_v4_pma_lane_mux_sel(info);
phy_exynos_usbdp_g2_v4_ctrl_pma_rst_release(info);
ret = phy_exynos_usbdp_g2_v4_pma_check_pll_lock(info);
if (!ret) {
ret = phy_exynos_usbdp_g2_v4_pma_check_cdr_lock(info);
}
mdelay(10);
phy_exynos_usbdp_g2_v4_tune_late(info);
phy_exynos_usbdp_g2_v4_pma_check_offset_cal_code(info);
return 0;
}
void phy_exynos_usbdp_g2_v4_disable(struct exynos_usbphy_info *info)
{
void __iomem *regs_base = info->ctrl_base;
u32 reg;
// Change pipe pclk to suspend_clk
reg = readl(regs_base + EXYNOS_USBCON_CLKRST);
reg &= ~CLKRST_LINK_PCLK_SEL;
writel(reg, regs_base + EXYNOS_USBCON_CLKRST);
// powerdown and ropll/lcpll refclk off for reducing powerdown current
reg = readl(regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
reg &= ~PMA_ROPLL_REF_CLK_SEL_MASK;
reg |= PMA_ROPLL_REF_CLK_SEL_SET(1);
reg &= ~PMA_LCPLL_REF_CLK_SEL_MASK;
reg |= PMA_LCPLL_REF_CLK_SEL_SET(1);
reg |= (PMA_TRSV_SW_RST | PMA_CMN_SW_RST | PMA_INIT_SW_RST | PMA_APB_SW_RST);
writel(reg, regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
udelay(100);
reg &= ~(PMA_TRSV_SW_RST | PMA_CMN_SW_RST | PMA_INIT_SW_RST | PMA_APB_SW_RST);
reg |= PMA_LOW_PWR;
writel(reg, regs_base + EXYNOS_USBCON_COMBO_PMA_CTRL);
}