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