xref: /OK3568_Linux_fs/u-boot/drivers/video/drm/rk618.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * (C) Copyright 2008-2018 Fuzhou Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <common.h>
7*4882a593Smuzhiyun #include <i2c.h>
8*4882a593Smuzhiyun #include <errno.h>
9*4882a593Smuzhiyun #include <dm.h>
10*4882a593Smuzhiyun #include <dm/uclass.h>
11*4882a593Smuzhiyun #include <dm/uclass-id.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include "rk618.h"
14*4882a593Smuzhiyun 
rk618_i2c_write(struct rk618 * rk618,u16 reg,u32 val)15*4882a593Smuzhiyun int rk618_i2c_write(struct rk618 *rk618, u16 reg, u32 val)
16*4882a593Smuzhiyun {
17*4882a593Smuzhiyun 	struct dm_i2c_chip *chip = dev_get_parent_platdata(rk618->dev);
18*4882a593Smuzhiyun 	struct i2c_msg msg;
19*4882a593Smuzhiyun 	u8 buf[] = {
20*4882a593Smuzhiyun 		(reg >> 0) & 0xff, (reg >> 8) & 0xff,
21*4882a593Smuzhiyun 		(val >> 0) & 0xff, (val >> 8) & 0xff,
22*4882a593Smuzhiyun 		(val >> 16) & 0xff, (val >> 24) & 0xff
23*4882a593Smuzhiyun 	};
24*4882a593Smuzhiyun 	int ret;
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun 	msg.addr = chip->chip_addr;
27*4882a593Smuzhiyun 	msg.flags = 0;
28*4882a593Smuzhiyun 	msg.len = sizeof(buf);
29*4882a593Smuzhiyun 	msg.buf = buf;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 	ret = dm_i2c_xfer(rk618->dev, &msg, 1);
32*4882a593Smuzhiyun 	if (ret) {
33*4882a593Smuzhiyun 		dev_err(rk618->dev, "Could not execute transfer: %d\n", ret);
34*4882a593Smuzhiyun 		return ret;
35*4882a593Smuzhiyun 	}
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	return 0;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
rk618_i2c_read(struct rk618 * rk618,u16 reg,u32 * val)40*4882a593Smuzhiyun int rk618_i2c_read(struct rk618 *rk618, u16 reg, u32 *val)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	struct dm_i2c_chip *chip = dev_get_parent_platdata(rk618->dev);
43*4882a593Smuzhiyun 	u32 data;
44*4882a593Smuzhiyun 	struct i2c_msg msg[] = {
45*4882a593Smuzhiyun 		{
46*4882a593Smuzhiyun 			.addr = chip->chip_addr,
47*4882a593Smuzhiyun 			.flags = 0,
48*4882a593Smuzhiyun 			.buf = (u8 *)&reg,
49*4882a593Smuzhiyun 			.len = 2,
50*4882a593Smuzhiyun 		}, {
51*4882a593Smuzhiyun 			.addr = chip->chip_addr,
52*4882a593Smuzhiyun 			.flags = I2C_M_RD,
53*4882a593Smuzhiyun 			.buf = (u8 *)&data,
54*4882a593Smuzhiyun 			.len = 4,
55*4882a593Smuzhiyun 		}
56*4882a593Smuzhiyun 	};
57*4882a593Smuzhiyun 	int ret;
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun 	ret = dm_i2c_xfer(rk618->dev, msg, 2);
60*4882a593Smuzhiyun 	if (ret) {
61*4882a593Smuzhiyun 		dev_err(rk618->dev, "Could not execute transfer: %d\n", ret);
62*4882a593Smuzhiyun 		return ret;
63*4882a593Smuzhiyun 	}
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	*val = data;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	return 0;
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun 
rk618_frc_dither_disable(struct rk618 * rk618)70*4882a593Smuzhiyun void rk618_frc_dither_disable(struct rk618 *rk618)
71*4882a593Smuzhiyun {
72*4882a593Smuzhiyun 	rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DITHER_DISABLE);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun 
rk618_frc_dither_enable(struct rk618 * rk618)75*4882a593Smuzhiyun void rk618_frc_dither_enable(struct rk618 *rk618)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun 	rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DITHER_ENABLE);
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
rk618_frc_dclk_invert(struct rk618 * rk618)80*4882a593Smuzhiyun void rk618_frc_dclk_invert(struct rk618 *rk618)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	rk618_i2c_write(rk618, RK618_FRC_REG, FRC_DCLK_INV);
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun 
rk618_power_on(struct rk618 * rk618)85*4882a593Smuzhiyun static int rk618_power_on(struct rk618 *rk618)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	if (rk618->power_supply)
88*4882a593Smuzhiyun 		regulator_set_enable(rk618->power_supply, 1);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	if (dm_gpio_is_valid(&rk618->enable_gpio))
91*4882a593Smuzhiyun 		dm_gpio_set_value(&rk618->enable_gpio, 1);
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	mdelay(2);
94*4882a593Smuzhiyun 	dm_gpio_set_value(&rk618->reset_gpio, 0);
95*4882a593Smuzhiyun 	mdelay(4);
96*4882a593Smuzhiyun 	dm_gpio_set_value(&rk618->reset_gpio, 1);
97*4882a593Smuzhiyun 	mdelay(50);
98*4882a593Smuzhiyun 	dm_gpio_set_value(&rk618->reset_gpio, 0);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	return 0;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
rk618_cru_init(struct rk618 * rk618)103*4882a593Smuzhiyun static void rk618_cru_init(struct rk618 *rk618)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x0058, 0xffff0000);
106*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x005c, 0xffff191e);
107*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x0060, 0x00000000);
108*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x0064, 0xffff2186);
109*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x0068, 0xffff1028);
110*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x006c, 0xffff0641);
111*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x0070, 0x00800000);
112*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x0074, 0xffff1028);
113*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x0078, 0xffff0641);
114*4882a593Smuzhiyun 	rk618_i2c_write(rk618, 0x007c, 0x00800000);
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun 
rk618_probe(struct udevice * dev)117*4882a593Smuzhiyun static int rk618_probe(struct udevice *dev)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	struct rk618 *rk618 = dev_get_priv(dev);
120*4882a593Smuzhiyun 	int ret;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	rk618->dev = dev;
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
125*4882a593Smuzhiyun 					   "power-supply",
126*4882a593Smuzhiyun 					   &rk618->power_supply);
127*4882a593Smuzhiyun 	if (ret && ret != -ENOENT) {
128*4882a593Smuzhiyun 		dev_err(dev, "Cannot get power supply: %d\n", ret);
129*4882a593Smuzhiyun 		return ret;
130*4882a593Smuzhiyun 	}
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	ret = gpio_request_by_name(dev, "enable-gpios", 0,
133*4882a593Smuzhiyun 				   &rk618->enable_gpio, GPIOD_IS_OUT);
134*4882a593Smuzhiyun 	if (ret && ret != -ENOENT) {
135*4882a593Smuzhiyun 		dev_err(dev, "Cannot get enable GPIO: %d\n", ret);
136*4882a593Smuzhiyun 		return ret;
137*4882a593Smuzhiyun 	}
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	ret = gpio_request_by_name(dev, "reset-gpios", 0,
140*4882a593Smuzhiyun 				   &rk618->reset_gpio, GPIOD_IS_OUT);
141*4882a593Smuzhiyun 	if (ret) {
142*4882a593Smuzhiyun 		dev_err(dev, "Cannot get reset GPIO: %d\n", ret);
143*4882a593Smuzhiyun 		return ret;
144*4882a593Smuzhiyun 	}
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	ret = clk_get_by_name(dev, "clkin", &rk618->clkin);
147*4882a593Smuzhiyun 	if (ret < 0) {
148*4882a593Smuzhiyun 		dev_err(dev, "failed to get clkin: %d\n", ret);
149*4882a593Smuzhiyun 		return ret;
150*4882a593Smuzhiyun 	}
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	ret = clk_set_rate(&rk618->clkin, 11289600);
153*4882a593Smuzhiyun 	if (ret < 0) {
154*4882a593Smuzhiyun 		dev_err(dev, "failed to set rate: %d\n", ret);
155*4882a593Smuzhiyun 		return ret;
156*4882a593Smuzhiyun 	}
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	clk_enable(&rk618->clkin);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	ret = rk618_power_on(rk618);
161*4882a593Smuzhiyun 	if (ret) {
162*4882a593Smuzhiyun 		dev_err(dev, "failed to power on: %d\n", ret);
163*4882a593Smuzhiyun 		return ret;
164*4882a593Smuzhiyun 	}
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun 	rk618_cru_init(rk618);
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	return 0;
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun static const struct udevice_id rk618_of_match[] = {
172*4882a593Smuzhiyun 	{ .compatible = "rockchip,rk618" },
173*4882a593Smuzhiyun 	{}
174*4882a593Smuzhiyun };
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun U_BOOT_DRIVER(rk618) = {
177*4882a593Smuzhiyun 	.name = "rk618",
178*4882a593Smuzhiyun 	.id = UCLASS_I2C_GENERIC,
179*4882a593Smuzhiyun 	.of_match = rk618_of_match,
180*4882a593Smuzhiyun 	.probe = rk618_probe,
181*4882a593Smuzhiyun 	.bind = dm_scan_fdt_dev,
182*4882a593Smuzhiyun 	.priv_auto_alloc_size = sizeof(struct rk618),
183*4882a593Smuzhiyun };
184