diff options
Diffstat (limited to 'drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c')
-rw-r--r-- | drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c | 550 |
1 files changed, 550 insertions, 0 deletions
diff --git a/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c b/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c new file mode 100644 index 000000000000..471039fb6a13 --- /dev/null +++ b/drivers/gpu/drm/imx/hdp/API_AFE_ss28fdsoi_kiran_hdmitx.c @@ -0,0 +1,550 @@ +/****************************************************************************** + * + * Copyright (C) 2016-2017 Cadence Design Systems, Inc. + * All rights reserved worldwide. + * + * 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. + * + * Copyright 2017-2018 NXP + * + ****************************************************************************** + * + * API_AFE_ss28fdsoi_kiran_hdmitx.c + * + ****************************************************************************** + */ + +#include <drm/drmP.h> +#include <linux/io.h> +#include "API_AFE_ss28fdsoi_kiran_hdmitx.h" +#include "ss28fdsoi_hdmitx_table.h" +#include "imx-hdp.h" + +int phy_cfg_hdp_ss28fdsoi(state_struct *state, + int num_lanes, + struct drm_display_mode *mode, + int bpp, + VIC_PXL_ENCODING_FORMAT format) +{ + const int phy_reset_workaround = 0; + u32 vco_freq_khz; + unsigned char i; + u32 feedback_factor; + int row; + u32 reg_val; + int pixel_freq_khz = mode->clock; + u32 character_clock_ratio_num = 1; + u32 character_clock_ratio_den = 1; + int character_freq_khz; + u32 ftemp; + clk_ratio_t clk_ratio = CLK_RATIO_1_1; + + 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 vco_ring_select; + reg_field_t pll_feedback_divider_total; + 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; + + /* Set field position in a target register */ + cmnda_pll0_fb_div_high.value = 0x00A; + 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; + vco_ring_select.msb = 12; + vco_ring_select.lsb = 12; + pll_feedback_divider_total.msb = 9; + pll_feedback_divider_total.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; + + DRM_INFO + ("phy_cfg_hdp() num_lanes: %0d, mode:%dx%dp%d, color depth: %0d-bit, encoding: %0d\n", + num_lanes, mode->hdisplay, mode->vdisplay, mode->vrefresh, bpp, format); + + /* register PHY_PMA_ISOLATION_CTRL + * enable PHY isolation mode only for CMN */ + if (phy_reset_workaround) { + Afe_write(state, 0xC81F, 0xD000); + reg_val = Afe_read(state, 0xC812); + reg_val &= 0xFF00; + reg_val |= 0x0012; + /* set cmn_pll0_clk_datart1_div/cmn_pll0_clk_datart0_div dividers */ + Afe_write(state, 0xC812, reg_val); + /* register PHY_ISO_CMN_CTRL */ + Afe_write(state, 0xC010, 0x0000); /* assert PHY reset from isolation register */ + /* register PHY_PMA_ISO_CMN_CTRL */ + Afe_write(state, 0xC810, 0x0000); /* assert PMA CMN reset */ + /* register XCVR_DIAG_BIDI_CTRL */ + for (i = 0; i < num_lanes; i++) { + Afe_write(state, 0x40E8 | (i << 9), 0x00FF); + } + } else { + /*-------------------------------------------------------------- + * Describing Task phy_cfg_hdp + * ------------------------------------------------------------*/ + /* register PHY_PMA_CMN_CTRL1 */ + for (i = 0; i < num_lanes; i++) + Afe_write(state, 0x40E8 | (i << 9), 0x007F); + } + /* register CMN_DIAG_PLL0_TEST_MODE */ + Afe_write(state, 0x01C4, 0x0022); + /* register CMN_PSM_CLK_CTRL */ + Afe_write(state, 0x0061, 0x0016); + + /* Determine the TMDS/PIXEL clock ratio */ + 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: + pr_err("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; + } + } + + /* Determine a relevant feedback factor as used + * in the ss28fdsoi_hdmitx_clock_control_table table */ + switch (clk_ratio) { + case CLK_RATIO_1_1: + feedback_factor = 1000; + break; + case CLK_RATIO_5_4: + feedback_factor = 1250; + break; + case CLK_RATIO_3_2: + feedback_factor = 1500; + break; + case CLK_RATIO_2_1: + feedback_factor = 2000; + break; + case CLK_RATIO_1_2: + feedback_factor = 500; + break; + case CLK_RATIO_5_8: + feedback_factor = 625; + break; + case CLK_RATIO_3_4: + feedback_factor = 750; + break; + } + + /* Get right row from the ss28fdsoi_hdmitx_clock_control_table table. + * Check if 'pixel_freq_khz' falls inside the + * <PIXEL_CLK_FREQ_KHZ_MIN, PIXEL_CLK_FREQ_KHZ_MAX> range. + * Consider only the rows with FEEDBACK_FACTOR column matching feedback_factor. */ + row = + get_table_row((const u32 *)&ss28fdsoi_hdmitx_clock_control_table, + SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_ROWS, + SS28FDSOI_HDMITX_CLOCK_CONTROL_TABLE_COLS, + pixel_freq_khz, PIXEL_CLK_FREQ_KHZ_MIN, + PIXEL_CLK_FREQ_KHZ_MAX, FEEDBACK_FACTOR, + feedback_factor); + + /* Check if row was found */ + ftemp = pixel_freq_khz; + if (row == -1) { + DRM_WARN("Pixel clock frequency (%u kHz) not supported for this color depth (%0d-bit), row=%d\n", + ftemp, bpp, row); + return 0; + } + DRM_INFO + ("Pixel clock frequency (%u kHz) is supported in this color depth (%0d-bit). Settings found in row %0d\n", + ftemp, bpp, row); + + character_freq_khz = + pixel_freq_khz * character_clock_ratio_num / + character_clock_ratio_den; + ftemp = character_freq_khz; + DRM_INFO("Character clock frequency: %u kHz.\n", ftemp); + + /* Extract particular values from the ss28fdsoi_hdmitx_clock_control_table table */ + set_field_value(&cmnda_pll0_hs_sym_div_sel, + ss28fdsoi_hdmitx_clock_control_table[row] + [CMNDA_PLL0_HS_SYM_DIV_SEL]); + set_field_value(&cmnda_pll0_ip_div, + ss28fdsoi_hdmitx_clock_control_table[row] + [CMNDA_PLL0_IP_DIV]); + set_field_value(&cmnda_pll0_fb_div_low, + ss28fdsoi_hdmitx_clock_control_table[row] + [CMNDA_PLL0_FB_DIV_LOW]); + set_field_value(&cmnda_pll0_fb_div_high, + ss28fdsoi_hdmitx_clock_control_table[row] + [CMNDA_PLL0_FB_DIV_HIGH]); + set_field_value(&cmn_ref_clk_dig_div, + ss28fdsoi_hdmitx_clock_control_table[row] + [CMN_REF_CLK_DIG_DIV]); + set_field_value(÷r_scaler, + ss28fdsoi_hdmitx_clock_control_table[row] + [REF_CLK_DIVIDER_SCALER]); + set_field_value(&cmnda_hs_clk_0_sel, + ss28fdsoi_hdmitx_clock_control_table[row] + [CMNDA_HS_CLK_0_SEL]); + set_field_value(&cmnda_hs_clk_1_sel, + ss28fdsoi_hdmitx_clock_control_table[row] + [CMNDA_HS_CLK_1_SEL]); + set_field_value(&tx_subrate, ss28fdsoi_hdmitx_clock_control_table[row] + [HSCLK_DIV_TX_SUB_RATE]); + set_field_value(&vco_ring_select, + ss28fdsoi_hdmitx_clock_control_table[row] + [VCO_RING_SELECT]); + set_field_value(&pll_feedback_divider_total, + ss28fdsoi_hdmitx_clock_control_table[row] + [PLL_FB_DIV_TOTAL]); + + /* Display parameters (informative message) */ + DRM_DEBUG("set_field_value() cmnda_pll0_hs_sym_div_sel : 0x%X\n", + cmnda_pll0_hs_sym_div_sel.value); + DRM_DEBUG("set_field_value() cmnda_pll0_ip_div : 0x%02X\n", + cmnda_pll0_ip_div.value); + DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_low : 0x%03X\n", + cmnda_pll0_fb_div_low.value); + DRM_DEBUG("set_field_value() cmnda_pll0_fb_div_high : 0x%03X\n", + cmnda_pll0_fb_div_high.value); + DRM_DEBUG("set_field_value() cmn_ref_clk_dig_div : 0x%X\n", + cmn_ref_clk_dig_div.value); + DRM_DEBUG("set_field_value() divider_scaler : 0x%X\n", + divider_scaler.value); + DRM_DEBUG("set_field_value() cmnda_hs_clk_0_sel : %0d\n", + cmnda_hs_clk_0_sel.value); + DRM_DEBUG("set_field_value() cmnda_hs_clk_1_sel : %0d\n", + cmnda_hs_clk_1_sel.value); + DRM_DEBUG("set_field_value() tx_subrate : %0d\n", + tx_subrate.value); + DRM_DEBUG("set_field_value() vco_ring_select : %0d\n", + vco_ring_select.value); + DRM_DEBUG("set_field_value() pll_feedback_divider_total: %0d\n", + pll_feedback_divider_total.value); + + vco_freq_khz = + pixel_freq_khz * pll_feedback_divider_total.value / + cmnda_pll0_ip_div.value; + + /* Get right row from the ss28fdsoi_hdmitx_pll_tuning_table table. + * Check if 'vco_freq_mhz' falls inside the + * <PLL_VCO_FREQ_MHZ_MIN, PLL_VCO_FREQ_MHZ_MAX> range. + * Consider only the rows with PLL_FEEDBACK_DIV_TOTAL. + * column matching pll_feedback_divider_total. */ + row = + get_table_row((const u32 *)&ss28fdsoi_hdmitx_pll_tuning_table, + SS28FDSOI_HDMITX_PLL_TUNING_TABLE_ROWS, + SS28FDSOI_HDMITX_PLL_TUNING_TABLE_COLS, vco_freq_khz, + PLL_VCO_FREQ_KHZ_MIN, PLL_VCO_FREQ_KHZ_MAX, + PLL_FEEDBACK_DIV_TOTAL, + pll_feedback_divider_total.value); + ftemp = vco_freq_khz; + if (row == -1) { + DRM_WARN("VCO frequency (%u kHz) not supported\n", ftemp); + return 0; + } + DRM_INFO + ("VCO frequency (%u kHz) is supported. Settings found in row %0d\n", + ftemp, row); + + /* Extract particular values from the ss28fdsoi_hdmitx_pll_tuning_table table */ + set_field_value(&voltage_to_current_coarse, + ss28fdsoi_hdmitx_pll_tuning_table[row] + [VOLTAGE_TO_CURRENT_COARSE]); + set_field_value(&voltage_to_current, + ss28fdsoi_hdmitx_pll_tuning_table[row] + [VOLTAGE_TO_CURRENT]); + set_field_value(&ndac_ctrl, + ss28fdsoi_hdmitx_pll_tuning_table[row][NDAC_CTRL]); + set_field_value(&pmos_ctrl, + ss28fdsoi_hdmitx_pll_tuning_table[row][PMOS_CTRL]); + set_field_value(&ptat_ndac_ctrl, + ss28fdsoi_hdmitx_pll_tuning_table[row][PTAT_NDAC_CTRL]); + set_field_value(&charge_pump_gain, + ss28fdsoi_hdmitx_pll_tuning_table[row] + [CHARGE_PUMP_GAIN]); + + /* Display parameters (informative message) */ + DRM_DEBUG("set_field_value() voltage_to_current_coarse : 0x%X\n", + voltage_to_current_coarse.value); + DRM_DEBUG("set_field_value() voltage_to_current : 0x%X\n", + voltage_to_current.value); + DRM_DEBUG("set_field_value() ndac_ctrl : 0x%X\n", + ndac_ctrl.value); + DRM_DEBUG("set_field_value() pmos_ctrl : 0x%02X\n", + pmos_ctrl.value); + DRM_DEBUG("set_field_value() ptat_ndac_ctrl : 0x%02X\n", + ptat_ndac_ctrl.value); + DRM_DEBUG("set_field_value() charge_pump_gain : 0x%03X\n", + charge_pump_gain.value); + + /* --------------------------------------------------------------- + * Describing Task phy_cfg_hdmi_pll0_0pt5736 + *---------------------------------------------------------------*/ + + Afe_write(state, 0x0081, 0x30A0); + /* register CMN_PLL0_VCOCAL_INIT_TMR */ + Afe_write(state, 0x0084, 0x0064); + /* register CMN_PLL0_VCOCAL_ITER_TMR */ + Afe_write(state, 0x0085, 0x000A); + /* register PHY_HDP_CLK_CTL */ + reg_val = Afe_read(state, 0xC009); + reg_val &= 0x00FF; + reg_val |= 0x1200; + Afe_write(state, 0xC009, reg_val); + /* 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); + Afe_write(state, 0x01CA, reg_val); + /* register CMN_DIAG_PLL0_FBL_OVRD */ + reg_val = set_reg_value(cmnda_pll0_fb_div_low); + reg_val |= (1 << 15); + Afe_write(state, 0x01C1, reg_val); + /* register PHY_PMA_CMN_CTRL1 */ + reg_val = Afe_read(state, 0xC800); + reg_val &= 0xCFFF; + reg_val |= set_reg_value(cmn_ref_clk_dig_div); + Afe_write(state, 0xC800, reg_val); + /* register CMN_CDIAG_REFCLK_CTRL */ + reg_val = set_reg_value(divider_scaler); + Afe_write(state, 0x0062, reg_val); + /* register CMN_DIAG_HSCLK_SEL */ + reg_val = Afe_read(state, 0x01E0); + reg_val &= 0xFF00; + reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 0; + reg_val |= (cmnda_hs_clk_1_sel.value >> 1) << 4; + Afe_write(state, 0x01E0, reg_val); + + /* register XCVR_DIAG_HSCLK_SEL */ + for (i = 0; i < num_lanes; i++) { + reg_val = Afe_read(state, 0x40E1 | (i << 9)); + reg_val &= 0xCFFF; + reg_val |= (cmnda_hs_clk_0_sel.value >> 1) << 12; + Afe_write(state, 0x40E1 | (i << 9), reg_val); + } + + /* register TX_DIAG_TX_CTRL */ + for (i = 0; i < num_lanes; i++) { + reg_val = Afe_read(state, 0x41E0 | (i << 9)); + reg_val &= 0xFF3F; + reg_val |= (tx_subrate.value >> 1) << 6; + Afe_write(state, 0x41E0 | (i << 9), reg_val); + } + + /* register CMN_PLLSM0_USER_DEF_CTRL */ + reg_val = set_reg_value(vco_ring_select); + Afe_write(state, 0x002F, reg_val); + /* register CMN_DIAG_PLL0_OVRD */ + Afe_write(state, 0x01C2, 0x0000); + /* register CMN_DIAG_PLL0_FBH_OVRD */ + reg_val = set_reg_value(cmnda_pll0_fb_div_high); + reg_val |= (1 << 15); + Afe_write(state, 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); + Afe_write(state, 0x01C5, reg_val); + /* register CMN_DIAG_PLL0_PTATIS_TUNE1 */ + reg_val = set_reg_value(pmos_ctrl); + reg_val |= set_reg_value(ndac_ctrl); + Afe_write(state, 0x01C8, reg_val); + /* register CMN_DIAG_PLL0_PTATIS_TUNE2 */ + reg_val = set_reg_value(ptat_ndac_ctrl); + Afe_write(state, 0x01C9, reg_val); + /* register CMN_DIAG_PLL0_CP_TUNE */ + reg_val = set_reg_value(charge_pump_gain); + Afe_write(state, 0x01C6, reg_val); + /* register CMN_DIAG_PLL0_LF_PROG */ + Afe_write(state, 0x01C7, 0x0008); + + /* register XCVR_DIAG_PLLDRC_CTRL */ + for (i = 0; i < num_lanes; i++) { + reg_val = Afe_read(state, 0x40E0 | (i << 9)); + reg_val &= 0xBFFF; + Afe_write(state, 0x40E0 | (i << 9), reg_val); + } + + /* register PHY_PMA_CMN_CTRL1 */ + reg_val = Afe_read(state, 0xC800); + reg_val &= 0xFF8F; + reg_val |= 0x0030; + Afe_write(state, 0xC800, reg_val); + + /*-------------------------------------------------------------------- + *--------------------Back to task phy_cfg_hdp------------------------ + *--------------------------------------------------------------------*/ + + if (phy_reset_workaround) { + /* register PHY_ISO_CMN_CTRL */ + Afe_write(state, 0xC010, 0x0001); // Deassert PHY reset */ + for (i = 0; i < num_lanes; i++) { + /* register TX_DIAG_ACYA */ + Afe_write(state, 0x41FF | (i << 9), 0x0001); + } + /* register PHY_PMA_ISO_CMN_CTRL */ + Afe_write(state, 0xC810, 0x0003); + for (i = 0; i < num_lanes; i++) { + /* register XCVR_PSM_RCTRL */ + Afe_write(state, 0x4001 | (i << 9), 0xFEFC); + } + /* register PHY_PMA_ISO_CMN_CTRL */ + Afe_write(state, 0xC810, 0x0013); /* Assert cmn_macro_pwr_en */ + + /* PHY_PMA_ISO_CMN_CTRL */ + while (!(Afe_read(state, 0xC810) & (1 << 5))) ; /* wait for cmn_macro_pwr_en_ack */ + + /* PHY_PMA_CMN_CTRL1 */ + while (!(Afe_read(state, 0xC800) & (1 << 0))) ; /* wait for cmn_ready */ + } else { + for (i = 0; i < num_lanes; i++) { + Afe_write(state, 0x41FF | (i << 9), 0x0001); + /* register XCVR_PSM_RCTRL */ + Afe_write(state, 0x4001 | (i << 9), 0xBEFC); + } + } + for (i = 0; i < num_lanes; i++) { + /* register TX_PSC_A0 */ + Afe_write(state, 0x4100 | (i << 9), 0x6791); + /* register TX_PSC_A1 */ + Afe_write(state, 0x4101 | (i << 9), 0x6790); + /* register TX_PSC_A2 */ + Afe_write(state, 0x4102 | (i << 9), 0x0090); + /* register TX_PSC_A3 */ + Afe_write(state, 0x4103 | (i << 9), 0x0090); + } + + /* register PHY_HDP_MODE_CTL */ + Afe_write(state, 0xC008, 0x0004); + return character_freq_khz; + +} + +#define __ARC_CONFIG__ + +int hdmi_tx_kiran_power_configuration_seq(state_struct *state, int num_lanes) +{ + /* Configure the power state. */ + + /* PHY_DP_MODE_CTL */ + while (!(Afe_read(state, 0xC008) & (1 << 6))) ; + +#ifdef __ARC_CONFIG__ + imx_arc_power_up(state); + imx_arc_calibrate(state); + imx_arc_config(state); +#endif + + /* PHY_DP_MODE_CTL */ + Afe_write(state, 0xC008, (((0x0F << num_lanes) & 0x0F) << 12) | 0x0001); + + /* PHY_DP_MODE_CTL */ + while (!(Afe_read(state, 0xC008) & (1 << 4))) ; + return 0; +} |