xref: /rk3399_rockchip-uboot/drivers/video/drm/max96745.c (revision 6cdc64f4b08041f0d56a055a11b857d8a9b5bae3)
152d98d47SWyon Bi // SPDX-License-Identifier: GPL-2.0+
252d98d47SWyon Bi /*
352d98d47SWyon Bi  * (C) Copyright 2022 Rockchip Electronics Co., Ltd
452d98d47SWyon Bi  */
552d98d47SWyon Bi 
652d98d47SWyon Bi #include <common.h>
752d98d47SWyon Bi #include <dm.h>
852d98d47SWyon Bi #include <errno.h>
952d98d47SWyon Bi #include <i2c.h>
1052d98d47SWyon Bi #include <max96745.h>
1152d98d47SWyon Bi #include <video_bridge.h>
12*6cdc64f4SWyon Bi #include <linux/iopoll.h>
1352d98d47SWyon Bi 
1452d98d47SWyon Bi #include "rockchip_bridge.h"
1552d98d47SWyon Bi #include "rockchip_display.h"
1652d98d47SWyon Bi #include "rockchip_panel.h"
1752d98d47SWyon Bi 
max96745_bridge_link_locked(struct udevice * dev)18*6cdc64f4SWyon Bi static bool max96745_bridge_link_locked(struct udevice *dev)
1952d98d47SWyon Bi {
20*6cdc64f4SWyon Bi 	int ret;
2152d98d47SWyon Bi 
22*6cdc64f4SWyon Bi 	ret = dm_i2c_reg_read(dev->parent, 0x002a);
23*6cdc64f4SWyon Bi 	if (ret < 0)
24*6cdc64f4SWyon Bi 		return false;
25*6cdc64f4SWyon Bi 
26*6cdc64f4SWyon Bi 	if (!FIELD_GET(LINK_LOCKED, ret))
27044a54ceSWyon Bi 		return false;
2852d98d47SWyon Bi 
29044a54ceSWyon Bi 	return true;
3052d98d47SWyon Bi }
3152d98d47SWyon Bi 
max96745_bridge_detect(struct rockchip_bridge * bridge)32*6cdc64f4SWyon Bi static bool max96745_bridge_detect(struct rockchip_bridge *bridge)
33*6cdc64f4SWyon Bi {
34*6cdc64f4SWyon Bi 	return max96745_bridge_link_locked(bridge->dev);
35*6cdc64f4SWyon Bi }
36*6cdc64f4SWyon Bi 
max96745_bridge_enable(struct rockchip_bridge * bridge)37*6cdc64f4SWyon Bi static void max96745_bridge_enable(struct rockchip_bridge *bridge)
38*6cdc64f4SWyon Bi {
39*6cdc64f4SWyon Bi 	struct udevice *dev = bridge->dev;
40*6cdc64f4SWyon Bi 	struct drm_display_mode *mode = &bridge->state->conn_state.mode;
41*6cdc64f4SWyon Bi 	u8 cxtp, tx_rate;
42*6cdc64f4SWyon Bi 	int ret;
43*6cdc64f4SWyon Bi 
44*6cdc64f4SWyon Bi 	ret = dm_i2c_reg_read(dev->parent, 0x0011);
45*6cdc64f4SWyon Bi 	if (ret < 0)
46*6cdc64f4SWyon Bi 		return;
47*6cdc64f4SWyon Bi 
48*6cdc64f4SWyon Bi 	cxtp = FIELD_GET(CXTP_A, ret);
49*6cdc64f4SWyon Bi 
50*6cdc64f4SWyon Bi 	ret = dm_i2c_reg_read(dev->parent, 0x0028);
51*6cdc64f4SWyon Bi 	if (ret < 0)
52*6cdc64f4SWyon Bi 		return;
53*6cdc64f4SWyon Bi 
54*6cdc64f4SWyon Bi 	tx_rate = FIELD_GET(TX_RATE, ret);
55*6cdc64f4SWyon Bi 
56*6cdc64f4SWyon Bi 	if (!cxtp && mode->clock > 95000 && tx_rate == 1) {
57*6cdc64f4SWyon Bi 		ret = dm_i2c_reg_clrset(dev->parent, 0x0028, TX_RATE,
58*6cdc64f4SWyon Bi 					FIELD_PREP(TX_RATE, 2));
59*6cdc64f4SWyon Bi 		if (ret < 0)
60*6cdc64f4SWyon Bi 			return;
61*6cdc64f4SWyon Bi 
62*6cdc64f4SWyon Bi 		ret = dm_i2c_reg_clrset(dev->parent, 0x0029, RESET_ONESHOT,
63*6cdc64f4SWyon Bi 					FIELD_PREP(RESET_ONESHOT, 1));
64*6cdc64f4SWyon Bi 		if (ret < 0)
65*6cdc64f4SWyon Bi 			return;
66*6cdc64f4SWyon Bi 
67*6cdc64f4SWyon Bi 		if (readx_poll_timeout(max96745_bridge_link_locked, dev, ret,
68*6cdc64f4SWyon Bi 				       ret, 200000))
69*6cdc64f4SWyon Bi 			dev_err(dev, "%s: GMSL link not locked\n", __func__);
70*6cdc64f4SWyon Bi 	}
71*6cdc64f4SWyon Bi }
72*6cdc64f4SWyon Bi 
max96745_bridge_post_disable(struct rockchip_bridge * bridge)73*6cdc64f4SWyon Bi static void max96745_bridge_post_disable(struct rockchip_bridge *bridge)
74*6cdc64f4SWyon Bi {
75*6cdc64f4SWyon Bi 	struct udevice *dev = bridge->dev;
76*6cdc64f4SWyon Bi 	u8 cxtp, tx_rate;
77*6cdc64f4SWyon Bi 	int ret;
78*6cdc64f4SWyon Bi 
79*6cdc64f4SWyon Bi 	ret = dm_i2c_reg_read(dev->parent, 0x0011);
80*6cdc64f4SWyon Bi 	if (ret < 0)
81*6cdc64f4SWyon Bi 		return;
82*6cdc64f4SWyon Bi 
83*6cdc64f4SWyon Bi 	cxtp = FIELD_GET(CXTP_A, ret);
84*6cdc64f4SWyon Bi 
85*6cdc64f4SWyon Bi 	ret = dm_i2c_reg_read(dev->parent, 0x0028);
86*6cdc64f4SWyon Bi 	if (ret < 0)
87*6cdc64f4SWyon Bi 		return;
88*6cdc64f4SWyon Bi 
89*6cdc64f4SWyon Bi 	tx_rate = FIELD_GET(TX_RATE, ret);
90*6cdc64f4SWyon Bi 
91*6cdc64f4SWyon Bi 	if (!cxtp && tx_rate == 2) {
92*6cdc64f4SWyon Bi 		ret = dm_i2c_reg_clrset(dev->parent, 0x0028, TX_RATE,
93*6cdc64f4SWyon Bi 					FIELD_PREP(TX_RATE, 1));
94*6cdc64f4SWyon Bi 		if (ret < 0)
95*6cdc64f4SWyon Bi 			return;
96*6cdc64f4SWyon Bi 
97*6cdc64f4SWyon Bi 		ret = dm_i2c_reg_clrset(dev->parent, 0x0029, RESET_ONESHOT,
98*6cdc64f4SWyon Bi 					FIELD_PREP(RESET_ONESHOT, 1));
99*6cdc64f4SWyon Bi 		if (ret < 0)
100*6cdc64f4SWyon Bi 			return;
101*6cdc64f4SWyon Bi 
102*6cdc64f4SWyon Bi 		if (readx_poll_timeout(max96745_bridge_link_locked, dev, ret,
103*6cdc64f4SWyon Bi 				       ret, 200000))
104*6cdc64f4SWyon Bi 			dev_err(dev, "%s: GMSL link not locked\n", __func__);
105*6cdc64f4SWyon Bi 	}
106*6cdc64f4SWyon Bi }
107*6cdc64f4SWyon Bi 
10852d98d47SWyon Bi static const struct rockchip_bridge_funcs max96745_bridge_funcs = {
109044a54ceSWyon Bi 	.detect		= max96745_bridge_detect,
110*6cdc64f4SWyon Bi 	.enable		= max96745_bridge_enable,
111*6cdc64f4SWyon Bi 	.post_disable	= max96745_bridge_post_disable,
11252d98d47SWyon Bi };
11352d98d47SWyon Bi 
max96745_bridge_probe(struct udevice * dev)11452d98d47SWyon Bi static int max96745_bridge_probe(struct udevice *dev)
11552d98d47SWyon Bi {
11652d98d47SWyon Bi 	struct rockchip_bridge *bridge;
11752d98d47SWyon Bi 
11852d98d47SWyon Bi 	bridge = calloc(1, sizeof(*bridge));
11952d98d47SWyon Bi 	if (!bridge)
12052d98d47SWyon Bi 		return -ENOMEM;
12152d98d47SWyon Bi 
12252d98d47SWyon Bi 	dev->driver_data = (ulong)bridge;
12352d98d47SWyon Bi 	bridge->dev = dev;
12452d98d47SWyon Bi 	bridge->funcs = &max96745_bridge_funcs;
12552d98d47SWyon Bi 
12652d98d47SWyon Bi 	return 0;
12752d98d47SWyon Bi }
12852d98d47SWyon Bi 
12952d98d47SWyon Bi static const struct udevice_id max96745_bridge_of_match[] = {
13052d98d47SWyon Bi 	{ .compatible = "maxim,max96745-bridge", },
13152d98d47SWyon Bi 	{ }
13252d98d47SWyon Bi };
13352d98d47SWyon Bi 
13452d98d47SWyon Bi U_BOOT_DRIVER(max96745_bridge) = {
13552d98d47SWyon Bi 	.name = "max96745_bridge",
13652d98d47SWyon Bi 	.id = UCLASS_VIDEO_BRIDGE,
13752d98d47SWyon Bi 	.of_match = max96745_bridge_of_match,
13852d98d47SWyon Bi 	.probe = max96745_bridge_probe,
13952d98d47SWyon Bi };
140