1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2c2539483SSimon Glass /*
3147fd3acSPhilipp Tomsich  * Copyright (c) 2017 Theobroma Systems Design und Consulting GmbH
4c2539483SSimon Glass  * Copyright (c) 2015 Google, Inc
5c2539483SSimon Glass  * Copyright 2014 Rockchip Inc.
6c2539483SSimon Glass  */
7c2539483SSimon Glass 
8c2539483SSimon Glass #include <common.h>
9c2539483SSimon Glass #include <clk.h>
10c2539483SSimon Glass #include <display.h>
11c2539483SSimon Glass #include <dm.h>
12cc232a9dSJernej Skrabec #include <dw_hdmi.h>
13c2539483SSimon Glass #include <edid.h>
14c2539483SSimon Glass #include <regmap.h>
15c2539483SSimon Glass #include <syscon.h>
16c2539483SSimon Glass #include <asm/gpio.h>
1712085239SPhilipp Tomsich #include <asm/hardware.h>
18c2539483SSimon Glass #include <asm/io.h>
19c2539483SSimon Glass #include <asm/arch/clock.h>
20147fd3acSPhilipp Tomsich #include <asm/arch/hardware.h>
21147fd3acSPhilipp Tomsich #include "rk_hdmi.h"
22147fd3acSPhilipp Tomsich #include "rk_vop.h" /* for rk_vop_probe_regulators */
23c2539483SSimon Glass 
24c2539483SSimon Glass static const struct hdmi_phy_config rockchip_phy_config[] = {
25c2539483SSimon Glass 	{
260fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 74250000,
27c2539483SSimon Glass 		.sym_ctr = 0x8009, .term = 0x0004, .vlev_ctr = 0x0272,
28c2539483SSimon Glass 	}, {
290fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 148500000,
30c2539483SSimon Glass 		.sym_ctr = 0x802b, .term = 0x0004, .vlev_ctr = 0x028d,
31c2539483SSimon Glass 	}, {
320fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 297000000,
33c2539483SSimon Glass 		.sym_ctr = 0x8039, .term = 0x0005, .vlev_ctr = 0x028d,
34c2539483SSimon Glass 	}, {
35f210e557SPhilipp Tomsich 		.mpixelclock = 584000000,
36f210e557SPhilipp Tomsich 		.sym_ctr = 0x8039, .term = 0x0000, .vlev_ctr = 0x019d,
37f210e557SPhilipp Tomsich 	}, {
38c2539483SSimon Glass 		.mpixelclock = ~0ul,
39c2539483SSimon Glass 		.sym_ctr = 0x0000, .term = 0x0000, .vlev_ctr = 0x0000,
40c2539483SSimon Glass 	}
41c2539483SSimon Glass };
42c2539483SSimon Glass 
43c2539483SSimon Glass static const struct hdmi_mpll_config rockchip_mpll_cfg[] = {
44c2539483SSimon Glass 	{
450fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 40000000,
46c2539483SSimon Glass 		.cpce = 0x00b3, .gmp = 0x0000, .curr = 0x0018,
47c2539483SSimon Glass 	}, {
480fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 65000000,
49c2539483SSimon Glass 		.cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
50c2539483SSimon Glass 	}, {
510fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 66000000,
52c2539483SSimon Glass 		.cpce = 0x013e, .gmp = 0x0003, .curr = 0x0038,
53c2539483SSimon Glass 	}, {
5494412745SNickey Yang Nickey Yang 		.mpixelclock = 83500000,
55c2539483SSimon Glass 		.cpce = 0x0072, .gmp = 0x0001, .curr = 0x0028,
56c2539483SSimon Glass 	}, {
570fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 146250000,
58c2539483SSimon Glass 		.cpce = 0x0051, .gmp = 0x0002, .curr = 0x0038,
59c2539483SSimon Glass 	}, {
600fc41e55SNickey Yang Nickey Yang 		.mpixelclock = 148500000,
61c2539483SSimon Glass 		.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
62c2539483SSimon Glass 	}, {
63f210e557SPhilipp Tomsich 		.mpixelclock = 272000000,
64f210e557SPhilipp Tomsich 		.cpce = 0x0040, .gmp = 0x0003, .curr = 0x0000,
65f210e557SPhilipp Tomsich 	}, {
66f210e557SPhilipp Tomsich 		.mpixelclock = 340000000,
67f210e557SPhilipp Tomsich 		.cpce = 0x0040, .gmp = 0x0003, .curr = 0x0000,
68f210e557SPhilipp Tomsich 	}, {
69c2539483SSimon Glass 		.mpixelclock = ~0ul,
70c2539483SSimon Glass 		.cpce = 0x0051, .gmp = 0x0003, .curr = 0x0000,
71c2539483SSimon Glass 	}
72c2539483SSimon Glass };
73c2539483SSimon Glass 
rk_hdmi_read_edid(struct udevice * dev,u8 * buf,int buf_size)74147fd3acSPhilipp Tomsich int rk_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
75c2539483SSimon Glass {
76c2539483SSimon Glass 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
77c2539483SSimon Glass 
78cc232a9dSJernej Skrabec 	return dw_hdmi_read_edid(&priv->hdmi, buf, buf_size);
79c2539483SSimon Glass }
80c2539483SSimon Glass 
rk_hdmi_ofdata_to_platdata(struct udevice * dev)81147fd3acSPhilipp Tomsich int rk_hdmi_ofdata_to_platdata(struct udevice *dev)
82c2539483SSimon Glass {
83c2539483SSimon Glass 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
84cc232a9dSJernej Skrabec 	struct dw_hdmi *hdmi = &priv->hdmi;
85c2539483SSimon Glass 
8618e48776SPhilipp Tomsich 	hdmi->ioaddr = (ulong)dev_read_addr(dev);
87cc232a9dSJernej Skrabec 	hdmi->mpll_cfg = rockchip_mpll_cfg;
88cc232a9dSJernej Skrabec 	hdmi->phy_cfg = rockchip_phy_config;
89cc232a9dSJernej Skrabec 
90147fd3acSPhilipp Tomsich 	/* hdmi->i2c_clk_{high,low} are set up by the SoC driver */
91147fd3acSPhilipp Tomsich 
92cc232a9dSJernej Skrabec 	hdmi->reg_io_width = 4;
93cc232a9dSJernej Skrabec 	hdmi->phy_set = dw_hdmi_phy_cfg;
94cc232a9dSJernej Skrabec 
95c2539483SSimon Glass 	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
96c2539483SSimon Glass 
97c2539483SSimon Glass 	return 0;
98c2539483SSimon Glass }
99c2539483SSimon Glass 
rk_hdmi_probe_regulators(struct udevice * dev,const char * const * names,int cnt)100147fd3acSPhilipp Tomsich void rk_hdmi_probe_regulators(struct udevice *dev,
101147fd3acSPhilipp Tomsich 			      const char * const *names, int cnt)
102c2539483SSimon Glass {
103147fd3acSPhilipp Tomsich 	rk_vop_probe_regulators(dev, names, cnt);
104147fd3acSPhilipp Tomsich }
105147fd3acSPhilipp Tomsich 
rk_hdmi_probe(struct udevice * dev)106147fd3acSPhilipp Tomsich int rk_hdmi_probe(struct udevice *dev)
107147fd3acSPhilipp Tomsich {
108c2539483SSimon Glass 	struct rk_hdmi_priv *priv = dev_get_priv(dev);
109cc232a9dSJernej Skrabec 	struct dw_hdmi *hdmi = &priv->hdmi;
110c2539483SSimon Glass 	int ret;
111c2539483SSimon Glass 
112cc232a9dSJernej Skrabec 	ret = dw_hdmi_phy_wait_for_hpd(hdmi);
113c2539483SSimon Glass 	if (ret < 0) {
114c2539483SSimon Glass 		debug("hdmi can not get hpd signal\n");
115c2539483SSimon Glass 		return -1;
116c2539483SSimon Glass 	}
117c2539483SSimon Glass 
118cc232a9dSJernej Skrabec 	dw_hdmi_init(hdmi);
119cc232a9dSJernej Skrabec 	dw_hdmi_phy_init(hdmi);
120c2539483SSimon Glass 
121c2539483SSimon Glass 	return 0;
122c2539483SSimon Glass }
123