1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2013 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 */ 6 7 #include <linux/delay.h> 8 9 #include "hdmi.h" 10 11 static void hdmi_phy_8x60_powerup(struct hdmi_phy *phy, 12 unsigned long int pixclock) 13 { 14 /* De-serializer delay D/C for non-lbk mode: */ 15 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG0, 16 HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3)); 17 18 if (pixclock == 27000000) { 19 /* video_format == HDMI_VFRMT_720x480p60_16_9 */ 20 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, 21 HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | 22 HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3)); 23 } else { 24 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, 25 HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | 26 HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4)); 27 } 28 29 /* No matter what, start from the power down mode: */ 30 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 31 HDMI_8x60_PHY_REG2_PD_PWRGEN | 32 HDMI_8x60_PHY_REG2_PD_PLL | 33 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 34 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 35 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 36 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 37 HDMI_8x60_PHY_REG2_PD_DESER); 38 39 /* Turn PowerGen on: */ 40 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 41 HDMI_8x60_PHY_REG2_PD_PLL | 42 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 43 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 44 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 45 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 46 HDMI_8x60_PHY_REG2_PD_DESER); 47 48 /* Turn PLL power on: */ 49 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 50 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 51 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 52 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 53 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 54 HDMI_8x60_PHY_REG2_PD_DESER); 55 56 /* Write to HIGH after PLL power down de-assert: */ 57 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 58 HDMI_8x60_PHY_REG3_PLL_ENABLE); 59 60 /* ASIC power on; PHY REG9 = 0 */ 61 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); 62 63 /* Enable PLL lock detect, PLL lock det will go high after lock 64 * Enable the re-time logic 65 */ 66 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, 67 HDMI_8x60_PHY_REG12_RETIMING_EN | 68 HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN); 69 70 /* Drivers are on: */ 71 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 72 HDMI_8x60_PHY_REG2_PD_DESER); 73 74 /* If the RX detector is needed: */ 75 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 76 HDMI_8x60_PHY_REG2_RCV_SENSE_EN | 77 HDMI_8x60_PHY_REG2_PD_DESER); 78 79 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG4, 0); 80 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG5, 0); 81 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG6, 0); 82 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG7, 0); 83 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG8, 0); 84 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); 85 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG10, 0); 86 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG11, 0); 87 88 /* If we want to use lock enable based on counting: */ 89 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, 90 HDMI_8x60_PHY_REG12_RETIMING_EN | 91 HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN | 92 HDMI_8x60_PHY_REG12_FORCE_LOCK); 93 } 94 95 static void hdmi_phy_8x60_powerdown(struct hdmi_phy *phy) 96 { 97 /* Assert RESET PHY from controller */ 98 hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 99 HDMI_PHY_CTRL_SW_RESET); 100 udelay(10); 101 /* De-assert RESET PHY from controller */ 102 hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 0); 103 /* Turn off Driver */ 104 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 105 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 106 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 107 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 108 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 109 HDMI_8x60_PHY_REG2_PD_DESER); 110 udelay(10); 111 /* Disable PLL */ 112 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 0); 113 /* Power down PHY, but keep RX-sense: */ 114 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 115 HDMI_8x60_PHY_REG2_RCV_SENSE_EN | 116 HDMI_8x60_PHY_REG2_PD_PWRGEN | 117 HDMI_8x60_PHY_REG2_PD_PLL | 118 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 119 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 120 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 121 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 122 HDMI_8x60_PHY_REG2_PD_DESER); 123 } 124 125 static const char * const hdmi_phy_8x60_reg_names[] = { 126 "core-vdda", 127 }; 128 129 static const char * const hdmi_phy_8x60_clk_names[] = { 130 "slave_iface", 131 }; 132 133 const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg = { 134 .type = MSM_HDMI_PHY_8x60, 135 .powerup = hdmi_phy_8x60_powerup, 136 .powerdown = hdmi_phy_8x60_powerdown, 137 .reg_names = hdmi_phy_8x60_reg_names, 138 .num_regs = ARRAY_SIZE(hdmi_phy_8x60_reg_names), 139 .clk_names = hdmi_phy_8x60_clk_names, 140 .num_clks = ARRAY_SIZE(hdmi_phy_8x60_clk_names), 141 }; 142