| /****************************************************************************** |
| * |
| * Copyright (C) 2016-2017 Cadence Design Systems, Inc. |
| * All rights reserved worldwide. |
| * |
| * Copyright 2017-2018 NXP |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * 3. Neither the name of the copyright holder nor the names of its contributors |
| * may be used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE SOFTWARE IS PROVIDED "AS IS", |
| * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED |
| * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE |
| * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE |
| * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| * |
| ****************************************************************************** |
| * |
| * API_AFE_t28hpc_hdmitx.c |
| * |
| ****************************************************************************** |
| */ |
| |
| #include "API_AFE_t28hpc_hdmitx.h" |
| #include "API_AFE.h" |
| #include "externs.h" |
| |
| #ifndef DEBUG |
| static inline void write16(uint32_t addr, uint16_t val) |
| { |
| afe_write(addr, val); |
| } |
| |
| static inline uint16_t read16(uint32_t addr) |
| { |
| return afe_read(addr); |
| } |
| #else |
| #define write16(addr, val) __write16(addr, val, __LINE__) |
| static inline void __write16(uint32_t addr, uint16_t val, int line) |
| { |
| afe_write(addr, val); |
| debug("write16():%4d Writting value 0x%04X at address 0x%05X (0x%04X)\n", |
| line, val, (0x20000 * 4) + (addr << 2), addr); |
| } |
| #define read16(addr) __read16(addr, __LINE__) |
| static inline uint16_t __read16(uint32_t addr, int line) |
| { |
| debug("read16():%5d Reading from address 0x%05X (0x%04X)\n", |
| line, (0x20000 * 4) + (addr << 2), addr); |
| return afe_read(addr); |
| } |
| |
| #endif |
| |
| static char inside(u32 value, u32 left_sharp_corner, |
| u32 right_sharp_corner) |
| { |
| if (value < left_sharp_corner) |
| return false; |
| if (value > right_sharp_corner) |
| return false; |
| return true; |
| } |
| |
| void aux_cfg_t28hpc(void) |
| { |
| write16(0x5025, 0x0001); |
| |
| write16(0x5024, 36); |
| |
| write16(0x5021, 0x0100); |
| write16(0x5021, 0x0300); |
| write16(0x5026, 0x0000); |
| write16(0x5020, 0x2008); |
| write16(0x5020, 0x2018); |
| write16(0x5020, 0xA018); |
| write16(0x5021, 0x030C); |
| write16(0x5029, 0x0000); |
| write16(0x5027, 0x4001); |
| write16(0x5020, 0xA098); |
| write16(0x5020, 0xA198); |
| write16(0x5021, 0x030D); |
| write16(0x5021, 0x030F); |
| } |
| |
| int phy_cfg_t28hpc(int num_lanes, VIC_MODES vic_mode, int bpp, |
| VIC_PXL_ENCODING_FORMAT format, bool pixel_clk_from_phy) |
| { |
| const int phy_reset_workaround = 1; |
| unsigned int vco_freq; |
| unsigned char k; |
| uint32_t reg_val; |
| uint32_t pixel_freq_khz = vic_table[vic_mode][PIXEL_FREQ_KHZ]; |
| uint32_t character_clock_ratio_num = 1; |
| uint32_t character_clock_ratio_den = 1; |
| uint32_t character_freq_khz; |
| const unsigned int refclk_freq_khz = 27000; |
| unsigned int ftemp, ftemp2; |
| |
| clk_ratio_t clk_ratio = 0; |
| reg_field_t cmnda_pll0_hs_sym_div_sel; |
| reg_field_t cmnda_pll0_ip_div; |
| reg_field_t cmnda_pll0_fb_div_low; |
| reg_field_t cmnda_pll0_fb_div_high; |
| reg_field_t cmn_ref_clk_dig_div; |
| reg_field_t divider_scaler; |
| reg_field_t cmnda_hs_clk_0_sel; |
| reg_field_t cmnda_hs_clk_1_sel; |
| reg_field_t tx_subrate; |
| reg_field_t voltage_to_current_coarse; |
| reg_field_t voltage_to_current; |
| reg_field_t ndac_ctrl; |
| reg_field_t pmos_ctrl; |
| reg_field_t ptat_ndac_ctrl; |
| reg_field_t charge_pump_gain; |
| reg_field_t vco_ring_select; |
| reg_field_t pll_feedback_divider_total; |
| reg_field_t cmnda_pll0_pxdiv_high; |
| reg_field_t cmnda_pll0_pxdiv_low; |
| reg_field_t coarse_code; |
| reg_field_t v2i_code; |
| reg_field_t vco_cal_code; |
| |
| cmnda_pll0_fb_div_high.value = 0x00A; |
| ftemp = pixel_freq_khz; |
| |
| debug(" VIC %d, pixel clock %u kHz\n", vic_mode, ftemp); |
| |
| /* Set field position */ |
| cmnda_pll0_hs_sym_div_sel.msb = 9; |
| cmnda_pll0_hs_sym_div_sel.lsb = 8; |
| cmnda_pll0_ip_div.msb = 7; |
| cmnda_pll0_ip_div.lsb = 0; |
| cmnda_pll0_fb_div_low.msb = 9; |
| cmnda_pll0_fb_div_low.lsb = 0; |
| cmnda_pll0_fb_div_high.msb = 9; |
| cmnda_pll0_fb_div_high.lsb = 0; |
| cmn_ref_clk_dig_div.msb = 13; |
| cmn_ref_clk_dig_div.lsb = 12; |
| divider_scaler.msb = 14; |
| divider_scaler.lsb = 12; |
| cmnda_hs_clk_0_sel.msb = 1; |
| cmnda_hs_clk_0_sel.lsb = 0; |
| cmnda_hs_clk_1_sel.msb = 1; |
| cmnda_hs_clk_1_sel.lsb = 0; |
| tx_subrate.msb = 2; |
| tx_subrate.lsb = 0; |
| voltage_to_current_coarse.msb = 2; |
| voltage_to_current_coarse.lsb = 0; |
| voltage_to_current.msb = 5; |
| voltage_to_current.lsb = 4; |
| ndac_ctrl.msb = 11; |
| ndac_ctrl.lsb = 8; |
| pmos_ctrl.msb = 7; |
| pmos_ctrl.lsb = 0; |
| ptat_ndac_ctrl.msb = 5; |
| ptat_ndac_ctrl.lsb = 0; |
| charge_pump_gain.msb = 8; |
| charge_pump_gain.lsb = 0; |
| vco_ring_select.msb = 12; |
| vco_ring_select.lsb = 12; |
| pll_feedback_divider_total.msb = 9; |
| pll_feedback_divider_total.lsb = 0; |
| cmnda_pll0_pxdiv_high.msb = 9; |
| cmnda_pll0_pxdiv_high.lsb = 0; |
| cmnda_pll0_pxdiv_low.msb = 9; |
| cmnda_pll0_pxdiv_low.lsb = 0; |
| coarse_code.msb = 7; |
| coarse_code.lsb = 0; |
| v2i_code.msb = 3; |
| v2i_code.lsb = 0; |
| vco_cal_code.msb = 8; |
| vco_cal_code.lsb = 0; |
| |
| if (phy_reset_workaround) { |
| /* register PHY_PMA_ISOLATION_CTRL */ |
| write16(0xC81F, 0xD000); /* enable PHY iso mode only for CMN */ |
| /* register PHY_PMA_ISO_PLL_CTRL1 */ |
| reg_val = read16(0xC812); |
| reg_val &= 0xFF00; |
| reg_val |= 0x0012; |
| /* set pll0_clk_datart1_div/pll0_clk_datart0_div dividers */ |
| write16(0xC812, reg_val); |
| /* register PHY_ISO_CMN_CTRL */ |
| /* assert PHY reset from isolation register */ |
| write16(0xC010, 0x0000); |
| /* register PHY_PMA_ISO_CMN_CTRL */ |
| write16(0xC810, 0x0000); /* assert PMA CMN reset */ |
| /* register XCVR_DIAG_BIDI_CTRL */ |
| for (k = 0; k < num_lanes; k++) |
| write16(0x40E8 | (k << 9), 0x00FF); |
| } |
| /*--------------------------------------------------------------- |
| * Describing Task phy_cfg_hdp |
| * --------------------------------------------------------------*/ |
| /* register PHY_PMA_CMN_CTRL1 */ |
| reg_val = read16(0xC800); |
| reg_val &= 0xFFF7; |
| reg_val |= 0x0008; |
| write16(0xC800, reg_val); |
| |
| /* register CMN_DIAG_PLL0_TEST_MODE */ |
| write16(0x01C4, 0x0020); |
| /* register CMN_PSM_CLK_CTRL */ |
| write16(0x0061, 0x0016); |
| |
| switch (format) { |
| case YCBCR_4_2_2: |
| clk_ratio = CLK_RATIO_1_1; |
| character_clock_ratio_num = 1; |
| character_clock_ratio_den = 1; |
| break; |
| case YCBCR_4_2_0: |
| switch (bpp) { |
| case 8: |
| clk_ratio = CLK_RATIO_1_2; |
| character_clock_ratio_num = 1; |
| character_clock_ratio_den = 2; |
| break; |
| case 10: |
| clk_ratio = CLK_RATIO_5_8; |
| character_clock_ratio_num = 5; |
| character_clock_ratio_den = 8; |
| break; |
| case 12: |
| clk_ratio = CLK_RATIO_3_4; |
| character_clock_ratio_num = 3; |
| character_clock_ratio_den = 4; |
| break; |
| case 16: |
| clk_ratio = CLK_RATIO_1_1; |
| character_clock_ratio_num = 1; |
| character_clock_ratio_den = 1; |
| break; |
| default: |
| debug("Invalid ColorDepth\n"); |
| } |
| break; |
| |
| default: |
| switch (bpp) { |
| /* Assume RGB */ |
| case 10: |
| clk_ratio = CLK_RATIO_5_4; |
| character_clock_ratio_num = 5; |
| character_clock_ratio_den = 4; |
| break; |
| case 12: |
| clk_ratio = CLK_RATIO_3_2; |
| character_clock_ratio_num = 3; |
| character_clock_ratio_den = 2; |
| break; |
| case 16: |
| clk_ratio = CLK_RATIO_2_1; |
| character_clock_ratio_num = 2; |
| character_clock_ratio_den = 1; |
| break; |
| default: |
| clk_ratio = CLK_RATIO_1_1; |
| character_clock_ratio_num = 1; |
| character_clock_ratio_den = 1; |
| } |
| } |
| |
| character_freq_khz = pixel_freq_khz * |
| character_clock_ratio_num / character_clock_ratio_den; |
| ftemp = pixel_freq_khz; |
| ftemp2 = character_freq_khz; |
| debug("Pixel clock frequency: %u kHz, character clock frequency: %u, color depth is %0d-bit.\n", |
| ftemp, ftemp2, bpp); |
| if (pixel_clk_from_phy == 0) { |
| /* ----------------------------------------------------------- |
| * Describing Task phy_cfg_hdmi_pll0_0pt5736 (Clock is input) |
| * -----------------------------------------------------------*/ |
| |
| /* register CMN_PLL0_VCOCAL_INIT_TMR */ |
| write16(0x0084, 0x0064); |
| /* register CMN_PLL0_VCOCAL_ITER_TMR */ |
| write16(0x0085, 0x000A); |
| /* register PHY_HDP_CLK_CTL */ |
| reg_val = read16(0xC009); |
| reg_val &= 0x00FF; |
| reg_val |= 0x1200; |
| write16(0xC009, reg_val); |
| |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| if (inside(pixel_freq_khz, 340000, 600000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x3C); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x24A); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x06); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 600); |
| } else if (inside(pixel_freq_khz, 170000, 340000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x22); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x146); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x07); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 340); |
| } else if (inside(pixel_freq_khz, 85000, 170000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| set_field_value(&cmnda_pll0_ip_div, 0x11); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x146); |
| set_field_value(&cmn_ref_clk_dig_div, 0x00); |
| set_field_value(÷r_scaler, 0x07); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 340); |
| } else if (inside(pixel_freq_khz, 42500, 85000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| set_field_value(&cmnda_pll0_ip_div, 0x08); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x132); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 320); |
| } else if (inside(pixel_freq_khz, 25000, 42500)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| set_field_value(&cmnda_pll0_ip_div, 0x05); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x182); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 400); |
| } else { |
| ftemp = pixel_freq_khz; |
| debug("Pixel clock frequency (%u) is outside of the supported range\n", |
| ftemp); |
| } |
| break; |
| |
| case CLK_RATIO_5_4: |
| if (inside(pixel_freq_khz, 272000, 480000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x30); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x24A); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x05); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 600); |
| } else if (inside(pixel_freq_khz, 136000, 272000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x1A); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x137); |
| set_field_value(&cmn_ref_clk_dig_div, 0x02); |
| set_field_value(÷r_scaler, 0x04); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 325); |
| } else if (inside(pixel_freq_khz, 68000, 136000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| set_field_value(&cmnda_pll0_ip_div, 0x0D); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x137); |
| set_field_value(&cmn_ref_clk_dig_div, 0x02); |
| set_field_value(÷r_scaler, 0x02); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 325); |
| } else if (inside(pixel_freq_khz, 34000, 68000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| set_field_value(&cmnda_pll0_ip_div, 0x06); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x11E); |
| set_field_value(&cmn_ref_clk_dig_div, 0x02); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 300); |
| } else if (inside(pixel_freq_khz, 25000, 34000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| set_field_value(&cmnda_pll0_ip_div, 0x04); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x182); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 400); |
| } else { |
| ftemp = pixel_freq_khz; |
| debug("Pixel clock frequency (%u) is outside of the supported range\n", |
| ftemp); |
| } |
| break; |
| case CLK_RATIO_3_2: |
| if (inside(pixel_freq_khz, 226000, 400000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x28); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x24A); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x04); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 600); |
| } else if (inside(pixel_freq_khz, 113000, 226000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x16); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x13C); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x05); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 330); |
| } else if (inside(pixel_freq_khz, 56000, 113000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| set_field_value(&cmnda_pll0_ip_div, 0x0B); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x13C); |
| set_field_value(&cmn_ref_clk_dig_div, 0x00); |
| set_field_value(÷r_scaler, 0x05); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 330); |
| } else if (inside(pixel_freq_khz, 28000, 56000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| set_field_value(&cmnda_pll0_ip_div, 0x06); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x15A); |
| set_field_value(&cmn_ref_clk_dig_div, 0x02); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 360); |
| } else if (inside(pixel_freq_khz, 25000, 28000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x15A); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 360); |
| } else { |
| ftemp = pixel_freq_khz; |
| debug("Pixel clock frequency (%u) is outside of the supported range\n", |
| ftemp); |
| } |
| break; |
| case CLK_RATIO_2_1: |
| if (inside(pixel_freq_khz, 170000, 300000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x22); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x29A); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x06); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 680); |
| } else if (inside(pixel_freq_khz, 85000, 170000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x11); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x146); |
| set_field_value(&cmn_ref_clk_dig_div, 0x00); |
| set_field_value(÷r_scaler, 0x07); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 340); |
| } else if (inside(pixel_freq_khz, 42500, 85000)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| set_field_value(&cmnda_pll0_ip_div, 0x08); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x132); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 320); |
| } else if (inside(pixel_freq_khz, 25000, 42500)) { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| set_field_value(&cmnda_pll0_ip_div, 0x05); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x182); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&pll_feedback_divider_total, |
| 400); |
| } else { |
| ftemp = pixel_freq_khz; |
| debug("Pixel clock frequency (%u) is outside of the supported range\n", |
| ftemp); |
| } |
| break; |
| case CLK_RATIO_1_2: |
| if (!(inside(pixel_freq_khz, 594000, 594000))) { |
| ftemp = pixel_freq_khz; |
| debug("Pixel clock frequency (%u) is outside of the supported range\n", |
| ftemp); |
| } else { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| set_field_value(&cmnda_pll0_ip_div, 0x3C); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x24A); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x06); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 600); |
| } |
| break; |
| case CLK_RATIO_5_8: |
| if (!(inside(pixel_freq_khz, 594000, 594000))) { |
| ftemp = pixel_freq_khz; |
| debug("Pixel clock frequency (%u) is outside of the supported range\n", |
| ftemp); |
| } else { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x3C); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x169); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x06); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 375); |
| } |
| break; |
| case CLK_RATIO_3_4: |
| if (!(inside(pixel_freq_khz, 594000, 594000))) { |
| ftemp = pixel_freq_khz; |
| debug("Pixel clock frequency (%u) is outside of the supported range\n", |
| ftemp); |
| } else { |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| set_field_value(&cmnda_pll0_ip_div, 0x3C); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x1B4); |
| set_field_value(&cmn_ref_clk_dig_div, 0x03); |
| set_field_value(÷r_scaler, 0x06); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 450); |
| } |
| break; |
| } |
| vco_freq = |
| pixel_freq_khz * pll_feedback_divider_total.value / |
| cmnda_pll0_ip_div.value; |
| ftemp = vco_freq; |
| debug("VCO frequency is %u kHz\n", ftemp); |
| |
| if (inside(vco_freq, 1700000, 2000000)) { |
| set_field_value(&voltage_to_current_coarse, 0x04); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x09); |
| set_field_value(&ptat_ndac_ctrl, 0x09); |
| switch (pll_feedback_divider_total.value) { |
| case 300: |
| set_field_value(&charge_pump_gain, 0x82); |
| break; |
| case 320: |
| set_field_value(&charge_pump_gain, 0x83); |
| break; |
| case 325: |
| set_field_value(&charge_pump_gain, 0x83); |
| break; |
| case 330: |
| set_field_value(&charge_pump_gain, 0x84); |
| break; |
| case 340: |
| set_field_value(&charge_pump_gain, 0x84); |
| break; |
| case 360: |
| set_field_value(&charge_pump_gain, 0x86); |
| break; |
| case 400: |
| set_field_value(&charge_pump_gain, 0xA2); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else if (inside(vco_freq, 2000000, 2400000)) { |
| set_field_value(&voltage_to_current_coarse, 0x04); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x09); |
| set_field_value(&ptat_ndac_ctrl, 0x09); |
| switch (pll_feedback_divider_total.value) { |
| case 300: |
| set_field_value(&charge_pump_gain, 0x47); |
| break; |
| case 320: |
| set_field_value(&charge_pump_gain, 0x4B); |
| break; |
| case 325: |
| set_field_value(&charge_pump_gain, 0x4C); |
| break; |
| case 330: |
| set_field_value(&charge_pump_gain, 0x80); |
| break; |
| case 340: |
| set_field_value(&charge_pump_gain, 0x81); |
| break; |
| case 360: |
| set_field_value(&charge_pump_gain, 0x82); |
| break; |
| case 400: |
| set_field_value(&charge_pump_gain, 0x84); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else if (inside(vco_freq, 2400000, 2800000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| switch (pll_feedback_divider_total.value) { |
| case 300: |
| set_field_value(&charge_pump_gain, 0x43); |
| break; |
| case 320: |
| set_field_value(&charge_pump_gain, 0x45); |
| break; |
| case 325: |
| set_field_value(&charge_pump_gain, 0x45); |
| break; |
| case 330: |
| set_field_value(&charge_pump_gain, 0x45); |
| break; |
| case 340: |
| set_field_value(&charge_pump_gain, 0x86); |
| break; |
| case 360: |
| set_field_value(&charge_pump_gain, 0x4A); |
| break; |
| case 400: |
| set_field_value(&charge_pump_gain, 0x81); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else if (inside(vco_freq, 2800000, 3400000)) { |
| set_field_value(&voltage_to_current_coarse, 0x06); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| switch (pll_feedback_divider_total.value) { |
| case 300: |
| set_field_value(&charge_pump_gain, 0x3D); |
| break; |
| case 320: |
| set_field_value(&charge_pump_gain, 0x41); |
| break; |
| case 325: |
| set_field_value(&charge_pump_gain, 0x41); |
| break; |
| case 330: |
| set_field_value(&charge_pump_gain, 0x41); |
| break; |
| case 340: |
| set_field_value(&charge_pump_gain, 0x42); |
| break; |
| case 360: |
| set_field_value(&charge_pump_gain, 0x43); |
| break; |
| case 400: |
| set_field_value(&charge_pump_gain, 0x46); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else if (inside(vco_freq, 3400000, 3900000)) { |
| set_field_value(&voltage_to_current_coarse, 0x04); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x07); |
| set_field_value(&ptat_ndac_ctrl, 0x0F); |
| switch (pll_feedback_divider_total.value) { |
| case 375: |
| set_field_value(&charge_pump_gain, 0x41); |
| break; |
| case 600: |
| set_field_value(&charge_pump_gain, 0x82); |
| break; |
| case 680: |
| set_field_value(&charge_pump_gain, 0x85); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else if (inside(vco_freq, 3900000, 4500000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x07); |
| set_field_value(&ptat_ndac_ctrl, 0x0F); |
| switch (pll_feedback_divider_total.value) { |
| case 450: |
| set_field_value(&charge_pump_gain, 0x41); |
| break; |
| case 600: |
| set_field_value(&charge_pump_gain, 0x4B); |
| break; |
| case 680: |
| set_field_value(&charge_pump_gain, 0x82); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else if (inside(vco_freq, 4500000, 5200000)) { |
| set_field_value(&voltage_to_current_coarse, 0x06); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| switch (pll_feedback_divider_total.value) { |
| case 600: |
| set_field_value(&charge_pump_gain, 0x45); |
| break; |
| case 680: |
| set_field_value(&charge_pump_gain, 0x4A); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else if (inside(vco_freq, 5200000, 6000000)) { |
| set_field_value(&voltage_to_current_coarse, 0x07); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| switch (pll_feedback_divider_total.value) { |
| case 600: |
| set_field_value(&charge_pump_gain, 0x42); |
| break; |
| case 680: |
| set_field_value(&charge_pump_gain, 0x45); |
| break; |
| default: |
| debug("pll_feedback_divider_total (%0d) is outside of the supported range for vco_freq equal %u\n", |
| pll_feedback_divider_total.value, ftemp); |
| } |
| } else |
| debug("VCO frequency %u kHz is outside of the supported range\n", |
| ftemp); |
| |
| /* register CMN_DIAG_PLL0_INCLK_CTRL */ |
| reg_val = set_reg_value(cmnda_pll0_hs_sym_div_sel); |
| reg_val |= set_reg_value(cmnda_pll0_ip_div); |
| write16(0x01CA, reg_val); |
| /* register CMN_DIAG_PLL0_FBL_OVRD */ |
| reg_val = set_reg_value(cmnda_pll0_fb_div_low); |
| reg_val |= (1 << 15); |
| write16(0x01C1, reg_val); |
| /* register PHY_PMA_CMN_CTRL1 */ |
| reg_val = read16(0xC800); |
| reg_val &= 0xCFFF; |
| reg_val |= set_reg_value(cmn_ref_clk_dig_div); |
| write16(0xC800, reg_val); |
| /* register CMN_CDIAG_REFCLK_CTRL */ |
| reg_val = read16(0x0062); |
| reg_val &= 0x8FFF; |
| reg_val |= set_reg_value(divider_scaler); |
| reg_val |= 0x00C0; |
| write16(0x0062, reg_val); |
| /* register CMN_DIAG_HSCLK_SEL */ |
| reg_val = read16(0x01E0); |
| reg_val &= 0xFF00; |
| reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 0; |
| reg_val |= (cmnda_hs_clk_1_sel.value >> 1) << 4; |
| write16(0x01E0, reg_val); |
| |
| /* register XCVR_DIAG_HSCLK_SEL */ |
| for (k = 0; k < num_lanes; k++) { |
| reg_val = read16(0x40E1 | (k << 9)); |
| reg_val &= 0xCFFF; |
| reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 12; |
| write16(0x40E1 | (k << 9), reg_val); |
| } |
| |
| /* register TX_DIAG_TX_CTRL */ |
| for (k = 0; k < num_lanes; k++) { |
| reg_val = read16(0x41E0 | (k << 9)); |
| reg_val &= 0xFF3F; |
| reg_val |= (tx_subrate.value >> 1) << 6; |
| write16(0x41E0 | (k << 9), reg_val); |
| } |
| |
| /* register CMN_PLLSM0_USER_DEF_CTRL */ |
| reg_val = set_reg_value(vco_ring_select); |
| write16(0x002F, reg_val); |
| /* register CMN_DIAG_PLL0_OVRD */ |
| write16(0x01C2, 0x0000); |
| /* register CMN_DIAG_PLL0_FBH_OVRD */ |
| reg_val = set_reg_value(cmnda_pll0_fb_div_high); |
| reg_val |= (1 << 15); |
| write16(0x01C0, reg_val); |
| /* register CMN_DIAG_PLL0_V2I_TUNE */ |
| reg_val = set_reg_value(voltage_to_current_coarse); |
| reg_val |= set_reg_value(voltage_to_current); |
| write16(0x01C5, reg_val); |
| /* register CMN_DIAG_PLL0_PTATIS_TUNE1 */ |
| reg_val = set_reg_value(pmos_ctrl); |
| reg_val |= set_reg_value(ndac_ctrl); |
| write16(0x01C8, reg_val); |
| /* register CMN_DIAG_PLL0_PTATIS_TUNE2 */ |
| reg_val = set_reg_value(ptat_ndac_ctrl); |
| write16(0x01C9, reg_val); |
| /* register CMN_DIAG_PLL0_CP_TUNE */ |
| reg_val = set_reg_value(charge_pump_gain); |
| write16(0x01C6, reg_val); |
| /* register CMN_DIAG_PLL0_LF_PROG */ |
| write16(0x01C7, 0x0008); |
| |
| /* register XCVR_DIAG_PLLDRC_CTRL */ |
| for (k = 0; k < num_lanes; k++) { |
| reg_val = read16(0x40E0 | (k << 9)); |
| reg_val &= 0xBFFF; |
| write16(0x40E0 | (k << 9), reg_val); |
| } |
| |
| } else { |
| /* Describing task phy_cfg_hdmi_pll0_0pt099_ver2 |
| (Clock is OUTPUT) */ |
| if (inside(pixel_freq_khz, 27000, 27000)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 240); |
| set_field_value(&cmnda_pll0_fb_div_low, 0xBC); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x30); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x26); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x26); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| break; |
| case CLK_RATIO_5_4: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 300); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x0EC); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x03C); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x030); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x030); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| break; |
| case CLK_RATIO_3_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 360); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x11C); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x048); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x03A); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x03A); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| break; |
| case CLK_RATIO_2_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 240); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x0BC); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x030); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x026); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x026); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| break; |
| default: |
| break; |
| } |
| } else if (inside(pixel_freq_khz, 54000, 54000)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 480); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x17C); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x060); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x026); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x026); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| break; |
| case CLK_RATIO_5_4: |
| set_field_value(&cmnda_pll0_ip_div, 0x04); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 400); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x13C); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x050); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x017); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x017); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| break; |
| case CLK_RATIO_3_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x04); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 480); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x17C); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x060); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x01C); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x01C); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| break; |
| case CLK_RATIO_2_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 240); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x0bc); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x030); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x012); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x012); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| default: |
| break; |
| } |
| } else if (inside(pixel_freq_khz, 74250, 74250)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 660); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x20c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x084); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x026); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x026); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x03); |
| break; |
| case CLK_RATIO_5_4: |
| set_field_value(&cmnda_pll0_ip_div, 0x04); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 550); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x06e); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x017); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x017); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x04); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| break; |
| case CLK_RATIO_3_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x04); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 660); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x20c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x084); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x01c); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x01c); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| break; |
| case CLK_RATIO_2_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 330); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x104); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x042); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x012); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x012); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| default: |
| break; |
| } |
| } else if (inside(pixel_freq_khz, 99000, 99000)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 440); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x15c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x058); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x012); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x012); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| break; |
| case CLK_RATIO_5_4: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 275); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x0d8); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x037); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x00b); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x00a); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| case CLK_RATIO_3_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 330); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x104); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x042); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x00d); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x00d); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| case CLK_RATIO_2_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 440); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x15c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x058); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x012); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x012); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| default: |
| break; |
| } |
| } else if (inside(pixel_freq_khz, 148500, 148500)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 660); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x20c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x084); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x012); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x012); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x02); |
| break; |
| case CLK_RATIO_5_4: |
| set_field_value(&cmnda_pll0_ip_div, 0x04); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 550); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x06e); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x00b); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x00a); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| case CLK_RATIO_3_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 495); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x188); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x063); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x00d); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x00d); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| case CLK_RATIO_2_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 660); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x20c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x084); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x012); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x012); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x02); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x02); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| default: |
| break; |
| } |
| } else if (inside(pixel_freq_khz, 198000, 198000)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 220); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x0ac); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x02c); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x003); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x003); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| case CLK_RATIO_5_4: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 550); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x06e); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x00b); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x00a); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| case CLK_RATIO_3_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 330); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x104); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x042); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x006); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x005); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| case CLK_RATIO_2_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 440); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x15c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x058); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x008); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x008); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| default: |
| break; |
| } |
| } else if (inside(pixel_freq_khz, 297000, 297000)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 330); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x104); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x042); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x003); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x003); |
| set_field_value(&vco_ring_select, 0x00); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| case CLK_RATIO_3_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 495); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x188); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x063); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x006); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x005); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| case CLK_RATIO_2_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 660); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x20c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x084); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x008); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x008); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| default: |
| ftemp = pixel_freq_khz; |
| debug("This pixel clock frequency (%u kHz) is not supported with this (%0d-bit) color depth.\n", |
| ftemp, bpp); |
| } |
| } else if (inside(pixel_freq_khz, 594000, 594000)) { |
| switch (clk_ratio) { |
| case CLK_RATIO_1_1: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 660); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x20c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x084); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x003); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x003); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| case CLK_RATIO_1_2: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 660); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x20c); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x084); |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x003); |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x003); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x02); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x01); |
| break; |
| case CLK_RATIO_5_8: |
| set_field_value(&cmnda_pll0_ip_div, 0x04); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 550); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x1b4); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x06e); |
| /* does not matter - pixel clock delivered to |
| controller from SoC */ |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x003); |
| /* does not matter - pixel clock delivered to |
| controller from SoC */ |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x003); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| case CLK_RATIO_3_4: |
| set_field_value(&cmnda_pll0_ip_div, 0x03); |
| set_field_value(&cmn_ref_clk_dig_div, 0x01); |
| set_field_value(÷r_scaler, 0x01); |
| set_field_value(&pll_feedback_divider_total, |
| 495); |
| set_field_value(&cmnda_pll0_fb_div_low, 0x188); |
| set_field_value(&cmnda_pll0_fb_div_high, 0x063); |
| /* does not matter - pixel clock delivered to |
| controller from SoC */ |
| set_field_value(&cmnda_pll0_pxdiv_low, 0x003); |
| /* does not matter - pixel clock delivered to |
| controller from SoC */ |
| set_field_value(&cmnda_pll0_pxdiv_high, 0x003); |
| set_field_value(&vco_ring_select, 0x01); |
| set_field_value(&cmnda_hs_clk_0_sel, 0x01); |
| set_field_value(&cmnda_hs_clk_1_sel, 0x01); |
| set_field_value(&tx_subrate, 0x01); |
| set_field_value(&cmnda_pll0_hs_sym_div_sel, |
| 0x00); |
| break; |
| default: |
| debug("This pixel clock frequency (%d KHz) is not supported with this (%0d-bit) color depth.\n", |
| pixel_freq_khz, bpp); |
| } |
| } else { |
| ftemp = pixel_freq_khz; |
| debug("This pixel clock frequency (%u kHz) is not supported.\n", |
| ftemp); |
| } |
| |
| vco_freq = |
| refclk_freq_khz * pll_feedback_divider_total.value / |
| cmnda_pll0_ip_div.value; |
| ftemp = vco_freq; |
| debug("VCO frequency is %u kHz\n", ftemp); |
| |
| if (inside(vco_freq, 1980000, 1980000)) { |
| set_field_value(&voltage_to_current_coarse, 0x04); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x09); |
| set_field_value(&ptat_ndac_ctrl, 0x09); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 160); |
| set_field_value(&v2i_code, 5); |
| set_field_value(&vco_cal_code, 183); |
| } else if (inside(vco_freq, 2160000, 2160000)) { |
| set_field_value(&voltage_to_current_coarse, 0x04); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x09); |
| set_field_value(&ptat_ndac_ctrl, 0x09); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 166); |
| set_field_value(&v2i_code, 6); |
| set_field_value(&vco_cal_code, 208); |
| } else if (inside(vco_freq, 2475000, 2475000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 167); |
| set_field_value(&v2i_code, 6); |
| set_field_value(&vco_cal_code, 209); |
| } else if (inside(vco_freq, 2700000, 2700000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| switch (pll_feedback_divider_total.value) { |
| case 300: |
| set_field_value(&charge_pump_gain, 0x042); |
| break; |
| case 400: |
| set_field_value(&charge_pump_gain, 0x04c); |
| break; |
| } |
| set_field_value(&coarse_code, 188); |
| set_field_value(&v2i_code, 6); |
| set_field_value(&vco_cal_code, 225); |
| } else if (inside(vco_freq, 2970000, 2970000)) { |
| set_field_value(&voltage_to_current_coarse, 0x06); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 183); |
| set_field_value(&v2i_code, 6); |
| set_field_value(&vco_cal_code, 225); |
| } else if (inside(vco_freq, 3240000, 3240000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| switch (pll_feedback_divider_total.value) { |
| case 360: |
| set_field_value(&charge_pump_gain, 0x042); |
| break; |
| case 480: |
| set_field_value(&charge_pump_gain, 0x04c); |
| break; |
| } |
| set_field_value(&coarse_code, 203); |
| set_field_value(&v2i_code, 7); |
| set_field_value(&vco_cal_code, 256); |
| } else if (inside(vco_freq, 3712500, 3712500)) { |
| set_field_value(&voltage_to_current_coarse, 0x04); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x07); |
| set_field_value(&ptat_ndac_ctrl, 0x0F); |
| set_field_value(&charge_pump_gain, 0x04c); |
| set_field_value(&coarse_code, 212); |
| set_field_value(&v2i_code, 7); |
| set_field_value(&vco_cal_code, 257); |
| } else if (inside(vco_freq, 3960000, 3960000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x07); |
| set_field_value(&ptat_ndac_ctrl, 0x0F); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 184); |
| set_field_value(&v2i_code, 6); |
| set_field_value(&vco_cal_code, 226); |
| } else if (inside(vco_freq, 4320000, 4320000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x07); |
| set_field_value(&ptat_ndac_ctrl, 0x0F); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 205); |
| set_field_value(&v2i_code, 7); |
| set_field_value(&vco_cal_code, 258); |
| } else if (inside(vco_freq, 4455000, 4455000)) { |
| set_field_value(&voltage_to_current_coarse, 0x05); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x00); |
| set_field_value(&pmos_ctrl, 0x07); |
| set_field_value(&ptat_ndac_ctrl, 0x0F); |
| switch (pll_feedback_divider_total.value) { |
| case 495: |
| set_field_value(&charge_pump_gain, 0x042); |
| break; |
| case 660: |
| set_field_value(&charge_pump_gain, 0x04c); |
| break; |
| } |
| set_field_value(&coarse_code, 219); |
| set_field_value(&v2i_code, 7); |
| set_field_value(&vco_cal_code, 272); |
| } else if (inside(vco_freq, 4950000, 4950000)) { |
| set_field_value(&voltage_to_current_coarse, 0x06); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 213); |
| set_field_value(&v2i_code, 7); |
| set_field_value(&vco_cal_code, 258); |
| } else if (inside(vco_freq, 5940000, 5940000)) { |
| set_field_value(&voltage_to_current_coarse, 0x07); |
| set_field_value(&voltage_to_current, 0x03); |
| set_field_value(&ndac_ctrl, 0x01); |
| set_field_value(&pmos_ctrl, 0x00); |
| set_field_value(&ptat_ndac_ctrl, 0x07); |
| set_field_value(&charge_pump_gain, 0x042); |
| set_field_value(&coarse_code, 244); |
| set_field_value(&v2i_code, 8); |
| set_field_value(&vco_cal_code, 292); |
| } else { |
| ftemp = vco_freq; |
| debug("Current vco_freq (%u kHz) is not supported.\n", |
| ftemp); |
| } |
| |
| /* register CMN_PLL0_VCOCAL_INIT_TMR */ |
| write16(0x0084, 0x0064); |
| /* register CMN_PLL0_VCOCAL_ITER_TMR */ |
| write16(0x0085, 0x000A); |
| /* register PHY_HDP_CLK_CTL */ |
| reg_val = read16(0xC009); |
| reg_val &= 0x00FF; |
| reg_val |= 0x2 << 8; |
| reg_val |= 0x1 << 12; |
| write16(0xC009, reg_val); |
| /* register CMN_DIAG_PLL0_INCLK_CTRL */ |
| reg_val = set_reg_value(cmnda_pll0_ip_div); |
| reg_val |= set_reg_value(cmnda_pll0_hs_sym_div_sel); |
| write16(0x01CA, reg_val); |
| /* register CMN_DIAG_PLL0_FBH_OVRD */ |
| reg_val = set_reg_value(cmnda_pll0_fb_div_high); |
| reg_val |= (1 << 15); |
| write16(0x01C0, reg_val); |
| /* register CMN_DIAG_PLL0_FBL_OVRD */ |
| reg_val = set_reg_value(cmnda_pll0_fb_div_low); |
| reg_val |= (1 << 15); |
| write16(0x01C1, reg_val); |
| /* register CMN_DIAG_PLL0_PXL_DIVL */ |
| reg_val = set_reg_value(cmnda_pll0_pxdiv_low); |
| write16(0x01CC, reg_val); |
| /* register CMN_DIAG_PLL0_PXL_DIVH */ |
| reg_val = set_reg_value(cmnda_pll0_pxdiv_high); |
| reg_val |= (1 << 15); |
| write16(0x01CB, reg_val); |
| |
| /* register TX_DIAG_TX_CTRL */ |
| for (k = 0; k < num_lanes; k++) { |
| reg_val = read16(0x41E0 | (k << 9)); |
| reg_val &= 0xFF3F; |
| reg_val |= (tx_subrate.value >> 1) << 6; |
| write16(0x41E0 | (k << 9), reg_val); |
| } |
| |
| /* register PHY_PMA_CMN_CTRL1 */ |
| reg_val = read16(0xC800); |
| reg_val &= 0xCFFF; |
| reg_val |= set_reg_value(cmn_ref_clk_dig_div); |
| write16(0xC800, reg_val); |
| /* register CMN_CDIAG_REFCLK_CTRL */ |
| reg_val = read16(0x0062); |
| reg_val &= 0x8FFF; |
| reg_val |= set_reg_value(divider_scaler); |
| reg_val |= 0x00C0; |
| write16(0x0062, reg_val); |
| /* register CMN_DIAG_HSCLK_SEL */ |
| reg_val = read16(0x01E0); |
| reg_val &= 0xFF00; |
| reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 0; |
| reg_val |= (cmnda_hs_clk_1_sel.value >> 1) << 4; |
| write16(0x01E0, reg_val); |
| /* register CMN_PLLSM0_USER_DEF_CTRL */ |
| reg_val = set_reg_value(vco_ring_select); |
| write16(0x002F, reg_val); |
| |
| /* register XCVR_DIAG_HSCLK_SEL */ |
| for (k = 0; k < num_lanes; k++) { |
| reg_val = read16(0x40E1 | (k << 9)); |
| reg_val &= 0xCFFF; |
| reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 12; |
| write16(0x40E1 | (k << 9), reg_val); |
| } |
| |
| /* register CMN_DIAG_PLL0_OVRD */ |
| write16(0x01C2, 0x0000); |
| /* register CMN_DIAG_PLL0_V2I_TUNE */ |
| reg_val = set_reg_value(voltage_to_current_coarse); |
| reg_val |= set_reg_value(voltage_to_current); |
| write16(0x01C5, reg_val); |
| /* register CMN_DIAG_PLL0_PTATIS_TUNE1 */ |
| reg_val = set_reg_value(pmos_ctrl); |
| reg_val |= set_reg_value(ndac_ctrl); |
| write16(0x01C8, reg_val); |
| /* register CMN_DIAG_PLL0_PTATIS_TUNE2 */ |
| reg_val = set_reg_value(ptat_ndac_ctrl); |
| write16(0x01C9, reg_val); |
| /* register CMN_PLL0_VCOCAL_START */ |
| reg_val = read16(0x0081); |
| reg_val &= 0xFE00; |
| reg_val |= set_reg_value(vco_cal_code); |
| write16(0x0081, reg_val); |
| /* register CMN_DIAG_PLL0_CP_TUNE */ |
| reg_val = set_reg_value(charge_pump_gain); |
| write16(0x01C6, reg_val); |
| /* register CMN_DIAG_PLL0_LF_PROG */ |
| write16(0x01C7, 0x0008); |
| |
| /* register XCVR_DIAG_PLLDRC_CTRL */ |
| for (k = 0; k < num_lanes; k++) { |
| reg_val = read16(0x40E0 | (k << 9)); |
| reg_val &= 0xBFFF; |
| write16(0x40E0 | (k << 9), reg_val); |
| } |
| } |
| |
| /* Back to task phy_cfg_hdp */ |
| |
| /* register PHY_PMA_CMN_CTRL1 */ |
| reg_val = read16(0xC800); |
| reg_val &= 0xFF8F; |
| /* for differential clock on the refclk_p and refclk_m |
| * off chip pins: PHY_PMA_CMN_CTRL1[6:4]=3'b000 */ |
| reg_val |= 0x0000; |
| write16(0xC800, reg_val); |
| |
| /* register CMN_DIAG_ACYA */ |
| write16(0x01FF, 0x0100); |
| |
| if (phy_reset_workaround) { |
| /* register PHY_ISO_CMN_CTRL */ |
| write16(0xC010, 0x0001); /* Deassert PHY reset */ |
| /* register PHY_PMA_ISO_CMN_CTRL */ |
| write16(0xC810, 0x0003); |
| for (k = 0; k < num_lanes; k++) { |
| /* register XCVR_PSM_RCTRL */ |
| write16(0x4001 | (k << 9), 0xFEFC); |
| } |
| /* register PHY_PMA_ISO_CMN_CTRL |
| * Assert cmn_macro_pwr_en*/ |
| write16(0xC810, 0x0013); |
| |
| /* PHY_PMA_ISO_CMN_CTRL |
| * wait for cmn_macro_pwr_en_ack*/ |
| while (!(read16(0xC810) & (1 << 5))) |
| ; |
| |
| /* PHY_PMA_CMN_CTRL1 wait for cmn_ready */ |
| while (!(read16(0xC800) & (1 << 0))) |
| ; |
| } else { |
| for (k = 0; k < num_lanes; k++) { |
| /* register XCVR_PSM_RCTRL */ |
| write16(0x4001 | (k << 9), 0xBEFC); |
| } |
| } |
| for (k = 0; k < num_lanes; k++) { |
| /* register TX_PSC_A0 */ |
| write16(0x4100 | (k << 9), 0x6791); |
| /* register TX_PSC_A1 */ |
| write16(0x4101 | (k << 9), 0x6790); |
| /* register TX_PSC_A2 */ |
| write16(0x4102 | (k << 9), 0x0090); |
| /* register TX_PSC_A3 */ |
| write16(0x4103 | (k << 9), 0x0090); |
| /* register RX_PSC_CAL */ |
| reg_val = read16(0x8006 | (k << 9)); |
| reg_val &= 0xFFBB; |
| write16(0x8006 | (k << 9), reg_val); |
| reg_val = read16(0x8000 | (k << 9)); |
| reg_val &= 0xFFBB; |
| write16(0x8000 | (k << 9), reg_val); |
| } |
| |
| /* End of task phy_cfg_hdp */ |
| /* register PHY_HDP_MODE_CTL */ |
| write16(0xC008, 0x0004); |
| |
| aux_cfg_t28hpc(); |
| return character_freq_khz; |
| } |
| |
| int hdmi_tx_t28hpc_power_config_seq(int num_lanes) |
| { |
| unsigned char k; |
| |
| /* Configure the power state. |
| * register TX_DIAG_ACYA */ |
| for (k = 0; k < num_lanes; k++) { |
| /* register XCVR_PSM_CAL_TMR */ |
| write16(0x41FF | (k << 9), 0x0001); |
| } |
| |
| /* register PHY_DP_MODE_CTL */ |
| while (!(read16(0xC008) & (1 << 6))) |
| ; |
| |
| /* PHY_DP_MODE_CTL */ |
| write16(0xC008, (((0x0F << num_lanes) & 0x0F) << 12) | 0x0101); |
| |
| /* PHY_DP_MODE_CTL */ |
| while (!(read16(0xC008) & (1 << 4))) |
| ; |
| |
| return 0; |
| } |