| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- /*
- * Copyright (c) 2012 MediaTek Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * 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.
- */
- #include <debug.h>
- #include <reg.h>
- #include <platform/bitops.h>
- #include <platform/mt_reg_base.h>
- #include <platform/mt_typedefs.h>
- #include <platform/timer.h>
- #include <mt_ssusb_sifslv_ippc.h>
- #include <mt_ssusb.h>
- #include <mt_ssusbphy.h>
- #include <mt_usbphy_a60810.h>
- #include <mt_ssusb_usb3_mac_csr.h>
- #ifdef MACH_FPGA
- #define CFG_FPGA_PLATFORM (1)
- #else
- #define DBG_PHY_CALIBRATION 1
- #endif
- #ifdef DBG_USB_PHY
- #define PHY_LOG(x...) dprintf(INFO, "[USB][PHY] " x)
- #else
- #define PHY_LOG(x...) do{} while(0)
- #endif
- #define PHY_DRV_SHIFT 3
- #define PHY_PHASE_SHIFT 3
- #define PHY_PHASE_DRV_SHIFT 1
- #if CFG_FPGA_PLATFORM
- u32 u2_slew_rate_calibration_a60810(struct u3phy_info *info)
- {
- u32 i=0;
- u32 fgRet = 0;
- u32 u4FmOut = 0;
- u32 u4Tmp = 0;
- // => RG_USB20_HSTX_SRCAL_EN = 1
- // enable HS TX SR calibration
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr5)
- , A60810_RG_USB20_HSTX_SRCAL_EN_OFST, A60810_RG_USB20_HSTX_SRCAL_EN, 1);
- mdelay(1);
- // => RG_FRCK_EN = 1
- // Enable free run clock
- u3_phy_write_field32(((u32)&info->sifslv_fm_regs_a->fmmonr1)
- , A60810_RG_FRCK_EN_OFST, A60810_RG_FRCK_EN, 0x1);
- // => RG_CYCLECNT = 0x400
- // Setting cyclecnt = 0x400
- u3_phy_write_field32(((u32)&info->sifslv_fm_regs_a->fmcr0)
- , A60810_RG_CYCLECNT_OFST, A60810_RG_CYCLECNT, 0x400);
- // => RG_FREQDET_EN = 1
- // Enable frequency meter
- u3_phy_write_field32(((u32)&info->sifslv_fm_regs_a->fmcr0)
- , A60810_RG_FREQDET_EN_OFST, A60810_RG_FREQDET_EN, 0x1);
- // wait for FM detection done, set 10ms timeout
- for (i=0; i<10; i++) {
- // => u4FmOut = USB_FM_OUT
- // read FM_OUT
- u4FmOut = u3_phy_read_reg32(((u32)&info->sifslv_fm_regs_a->fmmonr0));
- PHY_LOG("FM_OUT value: u4FmOut = %d(0x%08X)\n", u4FmOut, u4FmOut);
- // check if FM detection done
- if (u4FmOut != 0) {
- fgRet = 0;
- PHY_LOG("FM detection done! loop = %d\n", i);
- break;
- }
- fgRet = 1;
- mdelay(1);
- }
- // => RG_FREQDET_EN = 0
- // disable frequency meter
- u3_phy_write_field32(((u32)&info->sifslv_fm_regs_a->fmcr0)
- , A60810_RG_FREQDET_EN_OFST, A60810_RG_FREQDET_EN, 0);
- // => RG_FRCK_EN = 0
- // disable free run clock
- u3_phy_write_field32(((u32)&info->sifslv_fm_regs_a->fmmonr1)
- , A60810_RG_FRCK_EN_OFST, A60810_RG_FRCK_EN, 0);
- // => RG_USB20_HSTX_SRCAL_EN = 0
- // disable HS TX SR calibration
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr5)
- , A60810_RG_USB20_HSTX_SRCAL_EN_OFST, A60810_RG_USB20_HSTX_SRCAL_EN, 0);
- mdelay(1);
- if (u4FmOut == 0) {
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr5)
- , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL, 0x4);
- fgRet = 1;
- } else {
- // set reg = (1024/FM_OUT) * REF_CK * U2_SR_COEF_A60810 / 1000 (round to the nearest digits)
- u4Tmp = (((1024 * 26 * U2_SR_COEF_A60810) / u4FmOut) + 500) / 1000;
- PHY_LOG("SR calibration value u1SrCalVal = %d\n", (u8)u4Tmp);
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr5)
- , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL, u4Tmp);
- }
- PHY_LOG("[USBPHY] %s ends\n", __func__);
- return fgRet;
- }
- int phy_change_pipe_phase_a60810(struct u3phy_info *info, int phy_drv, int pipe_phase)
- {
- int drv_reg_value;
- int phase_reg_value;
- int temp;
- drv_reg_value = phy_drv << PHY_DRV_SHIFT;
- phase_reg_value = (pipe_phase << PHY_PHASE_SHIFT) | (phy_drv << PHY_PHASE_DRV_SHIFT);
- temp = u3_phy_read_reg8(((u32)&info->sifslv_chip_regs_a->gpio_ctla)+2);
- temp &= ~(0x3 << PHY_DRV_SHIFT);
- temp |= drv_reg_value;
- u3_phy_write_reg8(((u32)&info->sifslv_chip_regs_a->gpio_ctla)+2, temp);
- temp = u3_phy_read_reg8(((u32)&info->sifslv_chip_regs_a->gpio_ctla)+3);
- temp &= ~((0x3 << PHY_PHASE_DRV_SHIFT) | (0x1f << PHY_PHASE_SHIFT));
- temp |= phase_reg_value;
- u3_phy_write_reg8(((u32)&info->sifslv_chip_regs_a->gpio_ctla)+3, temp);
- return TRUE;
- }
- void phy_init_a60810(struct u3phy_info *info)
- {
- PHY_LOG("phy_init_a60810==========\n");
- //BANK 0x00
- //for U2 hS eye diagram
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr1)
- , A60810_RG_USB20_TERM_VREF_SEL_OFST, A60810_RG_USB20_TERM_VREF_SEL, 0x05);
- //for U2 hS eye diagram
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr1)
- , A60810_RG_USB20_VRT_VREF_SEL_OFST, A60810_RG_USB20_VRT_VREF_SEL, 0x05);
- //for U2 sensititvity
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr6)
- , A60810_RG_USB20_SQTH_OFST, A60810_RG_USB20_SQTH, 0x04);
- //BANK 0x10
- //disable ssusb_p3_entry to work around resume from P3 bug
- u3_phy_write_field32(((u32)&info->u3phyd_regs_a->phyd_lfps0)
- , A60810_RG_SSUSB_P3_ENTRY_OFST, A60810_RG_SSUSB_P3_ENTRY, 0x00);
- //force disable ssusb_p3_entry to work around resume from P3 bug
- u3_phy_write_field32(((u32)&info->u3phyd_regs_a->phyd_lfps0)
- , A60810_RG_SSUSB_P3_ENTRY_SEL_OFST, A60810_RG_SSUSB_P3_ENTRY_SEL, 0x01);
- //BANK 0x40
- // fine tune SSC delta1 to let SSC min average ~0ppm
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg19)
- , A60810_RG_SSUSB_PLL_SSC_DELTA1_U3_OFST, A60810_RG_SSUSB_PLL_SSC_DELTA1_U3, 0x46);
- //u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg19)
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg21)
- , A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H_OFST, A60810_RG_SSUSB_PLL_SSC_DELTA1_PE1H, 0x40);
- // fine tune SSC delta to let SSC min average ~0ppm
- // Fine tune SYSPLL to improve phase noise
- // I2C 60 0x08[01:00] 0x03 RW RG_SSUSB_PLL_BC_U3
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg4)
- , A60810_RG_SSUSB_PLL_BC_U3_OFST, A60810_RG_SSUSB_PLL_BC_U3, 0x3);
- // I2C 60 0x08[12:10] 0x03 RW RG_SSUSB_PLL_DIVEN_U3
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg4)
- , A60810_RG_SSUSB_PLL_DIVEN_U3_OFST, A60810_RG_SSUSB_PLL_DIVEN_U3, 0x3);
- // I2C 60 0x0C[03:00] 0x01 RW RG_SSUSB_PLL_IC_U3
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg5)
- , A60810_RG_SSUSB_PLL_IC_U3_OFST, A60810_RG_SSUSB_PLL_IC_U3, 0x1);
- // I2C 60 0x0C[23:22] 0x01 RW RG_SSUSB_PLL_BR_U3
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg5)
- , A60810_RG_SSUSB_PLL_BR_U3_OFST, A60810_RG_SSUSB_PLL_BR_U3, 0x1);
- // I2C 60 0x10[03:00] 0x01 RW RG_SSUSB_PLL_IR_U3
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg6)
- , A60810_RG_SSUSB_PLL_IR_U3_OFST, A60810_RG_SSUSB_PLL_IR_U3, 0x1);
- // I2C 60 0x14[03:00] 0x0F RW RG_SSUSB_PLL_BP_U3
- u3_phy_write_field32(((u32)&info->u3phya_da_regs_a->reg7)
- //// , A60810_RG_SSUSB_PLL_BP_U3, A60810_RG_SSUSB_PLL_BP_U3, 0xF);
- , A60810_RG_SSUSB_PLL_BP_U3_OFST, A60810_RG_SSUSB_PLL_BP_U3, 0x0f);
- //BANK 0x60
- //force xtal pwd mode enable
- u3_phy_write_field32(((u32)&info->spllc_regs_a->u3d_xtalctl_2)
- , A60810_RG_SSUSB_FORCE_XTAL_PWD_OFST, A60810_RG_SSUSB_FORCE_XTAL_PWD, 0x1);
- //force bias pwd mode enable
- u3_phy_write_field32(((u32)&info->spllc_regs_a->u3d_xtalctl_2)
- , A60810_RG_SSUSB_FORCE_BIAS_PWD_OFST, A60810_RG_SSUSB_FORCE_BIAS_PWD, 0x1);
- //force xtal pwd mode off to work around xtal drv de
- u3_phy_write_field32(((u32)&info->spllc_regs_a->u3d_xtalctl_2)
- , A60810_RG_SSUSB_XTAL_PWD_OFST, A60810_RG_SSUSB_XTAL_PWD, 0x0);
- //force bias pwd mode off to work around xtal drv de
- u3_phy_write_field32(((u32)&info->spllc_regs_a->u3d_xtalctl_2)
- , A60810_RG_SSUSB_BIAS_PWD_OFST, A60810_RG_SSUSB_BIAS_PWD, 0x0);
- //******** test chip settings ***********
- //BANK 0x00
- // slew rate setting
- u3_phy_write_field32(((u32)&info->u2phy_regs_a->usbphyacr5)
- , A60810_RG_USB20_HSTX_SRCTRL_OFST, A60810_RG_USB20_HSTX_SRCTRL, 0x4);
- //BANK 0x50
- // PIPE setting BANK5
- // PIPE drv = 2
- u3_phy_write_reg8(((u32)&info->sifslv_chip_regs_a->gpio_ctla)+2, 0x10);
- // PIPE phase
- //u3_phy_write_reg8(((u32)&info->sifslv_chip_regs_a->gpio_ctla)+3, 0xdc);
- u3_phy_write_reg8(((u32)&info->sifslv_chip_regs_a->gpio_ctla)+3, 0x24);
- }
- #endif
|