1 /* 2 * Copyright (C) 2013 Red Hat 3 * Author: Rob Clark <robdclark@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "hdmi.h" 19 20 static void hdmi_phy_8x60_powerup(struct hdmi_phy *phy, 21 unsigned long int pixclock) 22 { 23 /* De-serializer delay D/C for non-lbk mode: */ 24 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG0, 25 HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3)); 26 27 if (pixclock == 27000000) { 28 /* video_format == HDMI_VFRMT_720x480p60_16_9 */ 29 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, 30 HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | 31 HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3)); 32 } else { 33 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, 34 HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | 35 HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4)); 36 } 37 38 /* No matter what, start from the power down mode: */ 39 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 40 HDMI_8x60_PHY_REG2_PD_PWRGEN | 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 PowerGen on: */ 49 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 50 HDMI_8x60_PHY_REG2_PD_PLL | 51 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 52 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 53 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 54 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 55 HDMI_8x60_PHY_REG2_PD_DESER); 56 57 /* Turn PLL power on: */ 58 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 59 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 60 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 61 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 62 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 63 HDMI_8x60_PHY_REG2_PD_DESER); 64 65 /* Write to HIGH after PLL power down de-assert: */ 66 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 67 HDMI_8x60_PHY_REG3_PLL_ENABLE); 68 69 /* ASIC power on; PHY REG9 = 0 */ 70 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); 71 72 /* Enable PLL lock detect, PLL lock det will go high after lock 73 * Enable the re-time logic 74 */ 75 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, 76 HDMI_8x60_PHY_REG12_RETIMING_EN | 77 HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN); 78 79 /* Drivers are on: */ 80 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 81 HDMI_8x60_PHY_REG2_PD_DESER); 82 83 /* If the RX detector is needed: */ 84 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 85 HDMI_8x60_PHY_REG2_RCV_SENSE_EN | 86 HDMI_8x60_PHY_REG2_PD_DESER); 87 88 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG4, 0); 89 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG5, 0); 90 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG6, 0); 91 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG7, 0); 92 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG8, 0); 93 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); 94 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG10, 0); 95 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG11, 0); 96 97 /* If we want to use lock enable based on counting: */ 98 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, 99 HDMI_8x60_PHY_REG12_RETIMING_EN | 100 HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN | 101 HDMI_8x60_PHY_REG12_FORCE_LOCK); 102 } 103 104 static void hdmi_phy_8x60_powerdown(struct hdmi_phy *phy) 105 { 106 /* Assert RESET PHY from controller */ 107 hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 108 HDMI_PHY_CTRL_SW_RESET); 109 udelay(10); 110 /* De-assert RESET PHY from controller */ 111 hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 0); 112 /* Turn off Driver */ 113 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 114 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 115 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 116 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 117 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 118 HDMI_8x60_PHY_REG2_PD_DESER); 119 udelay(10); 120 /* Disable PLL */ 121 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 0); 122 /* Power down PHY, but keep RX-sense: */ 123 hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, 124 HDMI_8x60_PHY_REG2_RCV_SENSE_EN | 125 HDMI_8x60_PHY_REG2_PD_PWRGEN | 126 HDMI_8x60_PHY_REG2_PD_PLL | 127 HDMI_8x60_PHY_REG2_PD_DRIVE_4 | 128 HDMI_8x60_PHY_REG2_PD_DRIVE_3 | 129 HDMI_8x60_PHY_REG2_PD_DRIVE_2 | 130 HDMI_8x60_PHY_REG2_PD_DRIVE_1 | 131 HDMI_8x60_PHY_REG2_PD_DESER); 132 } 133 134 const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg = { 135 .type = MSM_HDMI_PHY_8x60, 136 .powerup = hdmi_phy_8x60_powerup, 137 .powerdown = hdmi_phy_8x60_powerdown, 138 }; 139