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