xref: /linux/drivers/gpu/drm/omapdrm/dss/hdmi_common.c (revision 24bce201d79807b668bf9d9e0aca801c5c0d5f78)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #define DSS_SUBSYS_NAME "HDMI"
4 
5 #include <linux/kernel.h>
6 #include <linux/err.h>
7 #include <linux/of.h>
8 
9 #include "omapdss.h"
10 #include "hdmi.h"
11 
12 int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
13 	struct hdmi_phy_data *phy)
14 {
15 	struct property *prop;
16 	int r, len;
17 
18 	prop = of_find_property(ep, "lanes", &len);
19 	if (prop) {
20 		u32 lanes[8];
21 
22 		if (len / sizeof(u32) != ARRAY_SIZE(lanes)) {
23 			dev_err(&pdev->dev, "bad number of lanes\n");
24 			return -EINVAL;
25 		}
26 
27 		r = of_property_read_u32_array(ep, "lanes", lanes,
28 			ARRAY_SIZE(lanes));
29 		if (r) {
30 			dev_err(&pdev->dev, "failed to read lane data\n");
31 			return r;
32 		}
33 
34 		r = hdmi_phy_parse_lanes(phy, lanes);
35 		if (r) {
36 			dev_err(&pdev->dev, "failed to parse lane data\n");
37 			return r;
38 		}
39 	} else {
40 		static const u32 default_lanes[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
41 
42 		r = hdmi_phy_parse_lanes(phy, default_lanes);
43 		if (WARN_ON(r)) {
44 			dev_err(&pdev->dev, "failed to parse lane data\n");
45 			return r;
46 		}
47 	}
48 
49 	return 0;
50 }
51 
52 int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
53 {
54 	u32 deep_color;
55 	bool deep_color_correct = false;
56 
57 	if (n == NULL || cts == NULL)
58 		return -EINVAL;
59 
60 	/* TODO: When implemented, query deep color mode here. */
61 	deep_color = 100;
62 
63 	/*
64 	 * When using deep color, the default N value (as in the HDMI
65 	 * specification) yields to an non-integer CTS. Hence, we
66 	 * modify it while keeping the restrictions described in
67 	 * section 7.2.1 of the HDMI 1.4a specification.
68 	 */
69 	switch (sample_freq) {
70 	case 32000:
71 	case 48000:
72 	case 96000:
73 	case 192000:
74 		if (deep_color == 125)
75 			if (pclk == 27027000 || pclk == 74250000)
76 				deep_color_correct = true;
77 		if (deep_color == 150)
78 			if (pclk == 27027000)
79 				deep_color_correct = true;
80 		break;
81 	case 44100:
82 	case 88200:
83 	case 176400:
84 		if (deep_color == 125)
85 			if (pclk == 27027000)
86 				deep_color_correct = true;
87 		break;
88 	default:
89 		return -EINVAL;
90 	}
91 
92 	if (deep_color_correct) {
93 		switch (sample_freq) {
94 		case 32000:
95 			*n = 8192;
96 			break;
97 		case 44100:
98 			*n = 12544;
99 			break;
100 		case 48000:
101 			*n = 8192;
102 			break;
103 		case 88200:
104 			*n = 25088;
105 			break;
106 		case 96000:
107 			*n = 16384;
108 			break;
109 		case 176400:
110 			*n = 50176;
111 			break;
112 		case 192000:
113 			*n = 32768;
114 			break;
115 		default:
116 			return -EINVAL;
117 		}
118 	} else {
119 		switch (sample_freq) {
120 		case 32000:
121 			*n = 4096;
122 			break;
123 		case 44100:
124 			*n = 6272;
125 			break;
126 		case 48000:
127 			*n = 6144;
128 			break;
129 		case 88200:
130 			*n = 12544;
131 			break;
132 		case 96000:
133 			*n = 12288;
134 			break;
135 		case 176400:
136 			*n = 25088;
137 			break;
138 		case 192000:
139 			*n = 24576;
140 			break;
141 		default:
142 			return -EINVAL;
143 		}
144 	}
145 	/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
146 	*cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10);
147 
148 	return 0;
149 }
150