xref: /linux/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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