Merge branch 'stable/for-jens-4.3' of git://git.kernel.org/pub/scm/linux/kernel/git...
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / drm_edid_load.c
1 /*
2    drm_edid_load.c: use a built-in EDID data set or load it via the firmware
3                     interface
4
5    Copyright (C) 2012 Carsten Emde <C.Emde@osadl.org>
6
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License
9    as published by the Free Software Foundation; either version 2
10    of the License, or (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
20 */
21
22 #include <linux/module.h>
23 #include <linux/firmware.h>
24 #include <drm/drmP.h>
25 #include <drm/drm_crtc.h>
26 #include <drm/drm_crtc_helper.h>
27 #include <drm/drm_edid.h>
28
29 static char edid_firmware[PATH_MAX];
30 module_param_string(edid_firmware, edid_firmware, sizeof(edid_firmware), 0644);
31 MODULE_PARM_DESC(edid_firmware, "Do not probe monitor, use specified EDID blob "
32         "from built-in data or /lib/firmware instead. ");
33
34 #define GENERIC_EDIDS 6
35 static const char *generic_edid_name[GENERIC_EDIDS] = {
36         "edid/800x600.bin",
37         "edid/1024x768.bin",
38         "edid/1280x1024.bin",
39         "edid/1600x1200.bin",
40         "edid/1680x1050.bin",
41         "edid/1920x1080.bin",
42 };
43
44 static const u8 generic_edid[GENERIC_EDIDS][128] = {
45         {
46         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
47         0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48         0x05, 0x16, 0x01, 0x03, 0x6d, 0x1b, 0x14, 0x78,
49         0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
50         0x20, 0x50, 0x54, 0x01, 0x00, 0x00, 0x45, 0x40,
51         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
52         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xa0, 0x0f,
53         0x20, 0x00, 0x31, 0x58, 0x1c, 0x20, 0x28, 0x80,
54         0x14, 0x00, 0x15, 0xd0, 0x10, 0x00, 0x00, 0x1e,
55         0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
56         0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
57         0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
58         0x3d, 0x24, 0x26, 0x05, 0x00, 0x0a, 0x20, 0x20,
59         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
60         0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x53,
61         0x56, 0x47, 0x41, 0x0a, 0x20, 0x20, 0x00, 0xc2,
62         },
63         {
64         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
65         0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66         0x05, 0x16, 0x01, 0x03, 0x6d, 0x23, 0x1a, 0x78,
67         0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
68         0x20, 0x50, 0x54, 0x00, 0x08, 0x00, 0x61, 0x40,
69         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
70         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x19,
71         0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x08, 0x90,
72         0x36, 0x00, 0x63, 0x0a, 0x11, 0x00, 0x00, 0x18,
73         0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
74         0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
75         0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
76         0x3d, 0x2f, 0x31, 0x07, 0x00, 0x0a, 0x20, 0x20,
77         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
78         0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x58,
79         0x47, 0x41, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x55,
80         },
81         {
82         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
83         0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84         0x05, 0x16, 0x01, 0x03, 0x6d, 0x2c, 0x23, 0x78,
85         0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
86         0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0x81, 0x80,
87         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
88         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x30, 0x2a,
89         0x00, 0x98, 0x51, 0x00, 0x2a, 0x40, 0x30, 0x70,
90         0x13, 0x00, 0xbc, 0x63, 0x11, 0x00, 0x00, 0x1e,
91         0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
92         0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
93         0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
94         0x3d, 0x3e, 0x40, 0x0b, 0x00, 0x0a, 0x20, 0x20,
95         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
96         0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x53,
97         0x58, 0x47, 0x41, 0x0a, 0x20, 0x20, 0x00, 0xa0,
98         },
99         {
100         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
101         0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102         0x05, 0x16, 0x01, 0x03, 0x6d, 0x37, 0x29, 0x78,
103         0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
104         0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xa9, 0x40,
105         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
106         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x48, 0x3f,
107         0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40, 0xc0,
108         0x13, 0x00, 0x2b, 0xa0, 0x21, 0x00, 0x00, 0x1e,
109         0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
110         0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
111         0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
112         0x3d, 0x4a, 0x4c, 0x11, 0x00, 0x0a, 0x20, 0x20,
113         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
114         0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x55,
115         0x58, 0x47, 0x41, 0x0a, 0x20, 0x20, 0x00, 0x9d,
116         },
117         {
118         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
119         0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120         0x05, 0x16, 0x01, 0x03, 0x6d, 0x2b, 0x1b, 0x78,
121         0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
122         0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xb3, 0x00,
123         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
124         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x21, 0x39,
125         0x90, 0x30, 0x62, 0x1a, 0x27, 0x40, 0x68, 0xb0,
126         0x36, 0x00, 0xb5, 0x11, 0x11, 0x00, 0x00, 0x1e,
127         0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
128         0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
129         0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
130         0x3d, 0x40, 0x42, 0x0f, 0x00, 0x0a, 0x20, 0x20,
131         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
132         0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x57,
133         0x53, 0x58, 0x47, 0x41, 0x0a, 0x20, 0x00, 0x26,
134         },
135         {
136         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
137         0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138         0x05, 0x16, 0x01, 0x03, 0x6d, 0x32, 0x1c, 0x78,
139         0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
140         0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xd1, 0xc0,
141         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
142         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a,
143         0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
144         0x45, 0x00, 0xf4, 0x19, 0x11, 0x00, 0x00, 0x1e,
145         0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
146         0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
147         0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
148         0x3d, 0x42, 0x44, 0x0f, 0x00, 0x0a, 0x20, 0x20,
149         0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
150         0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x46,
151         0x48, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x05,
152         },
153 };
154
155 static int edid_size(const u8 *edid, int data_size)
156 {
157         if (data_size < EDID_LENGTH)
158                 return 0;
159
160         return (edid[0x7e] + 1) * EDID_LENGTH;
161 }
162
163 static void *edid_load(struct drm_connector *connector, const char *name,
164                         const char *connector_name)
165 {
166         const struct firmware *fw = NULL;
167         const u8 *fwdata;
168         u8 *edid;
169         int fwsize, builtin;
170         int i, valid_extensions = 0;
171         bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
172
173         builtin = 0;
174         for (i = 0; i < GENERIC_EDIDS; i++) {
175                 if (strcmp(name, generic_edid_name[i]) == 0) {
176                         fwdata = generic_edid[i];
177                         fwsize = sizeof(generic_edid[i]);
178                         builtin = 1;
179                         break;
180                 }
181         }
182         if (!builtin) {
183                 struct platform_device *pdev;
184                 int err;
185
186                 pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
187                 if (IS_ERR(pdev)) {
188                         DRM_ERROR("Failed to register EDID firmware platform device "
189                                   "for connector \"%s\"\n", connector_name);
190                         return ERR_CAST(pdev);
191                 }
192
193                 err = request_firmware(&fw, name, &pdev->dev);
194                 platform_device_unregister(pdev);
195                 if (err) {
196                         DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
197                                   name, err);
198                         return ERR_PTR(err);
199                 }
200
201                 fwdata = fw->data;
202                 fwsize = fw->size;
203         }
204
205         if (edid_size(fwdata, fwsize) != fwsize) {
206                 DRM_ERROR("Size of EDID firmware \"%s\" is invalid "
207                           "(expected %d, got %d\n", name,
208                           edid_size(fwdata, fwsize), (int)fwsize);
209                 edid = ERR_PTR(-EINVAL);
210                 goto out;
211         }
212
213         edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
214         if (edid == NULL) {
215                 edid = ERR_PTR(-ENOMEM);
216                 goto out;
217         }
218
219         if (!drm_edid_block_valid(edid, 0, print_bad_edid,
220                                   &connector->edid_corrupt)) {
221                 connector->bad_edid_counter++;
222                 DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
223                     name);
224                 kfree(edid);
225                 edid = ERR_PTR(-EINVAL);
226                 goto out;
227         }
228
229         for (i = 1; i <= edid[0x7e]; i++) {
230                 if (i != valid_extensions + 1)
231                         memcpy(edid + (valid_extensions + 1) * EDID_LENGTH,
232                             edid + i * EDID_LENGTH, EDID_LENGTH);
233                 if (drm_edid_block_valid(edid + i * EDID_LENGTH, i,
234                                          print_bad_edid,
235                                          NULL))
236                         valid_extensions++;
237         }
238
239         if (valid_extensions != edid[0x7e]) {
240                 u8 *new_edid;
241
242                 edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
243                 DRM_INFO("Found %d valid extensions instead of %d in EDID data "
244                     "\"%s\" for connector \"%s\"\n", valid_extensions,
245                     edid[0x7e], name, connector_name);
246                 edid[0x7e] = valid_extensions;
247
248                 new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
249                                     GFP_KERNEL);
250                 if (new_edid)
251                         edid = new_edid;
252         }
253
254         DRM_INFO("Got %s EDID base block and %d extension%s from "
255             "\"%s\" for connector \"%s\"\n", builtin ? "built-in" :
256             "external", valid_extensions, valid_extensions == 1 ? "" : "s",
257             name, connector_name);
258
259 out:
260         release_firmware(fw);
261         return edid;
262 }
263
264 int drm_load_edid_firmware(struct drm_connector *connector)
265 {
266         const char *connector_name = connector->name;
267         char *edidname = edid_firmware, *last, *colon;
268         int ret;
269         struct edid *edid;
270
271         if (*edidname == '\0')
272                 return 0;
273
274         colon = strchr(edidname, ':');
275         if (colon != NULL) {
276                 if (strncmp(connector_name, edidname, colon - edidname))
277                         return 0;
278                 edidname = colon + 1;
279                 if (*edidname == '\0')
280                         return 0;
281         }
282
283         last = edidname + strlen(edidname) - 1;
284         if (*last == '\n')
285                 *last = '\0';
286
287         edid = edid_load(connector, edidname, connector_name);
288         if (IS_ERR_OR_NULL(edid))
289                 return 0;
290
291         drm_mode_connector_update_edid_property(connector, edid);
292         ret = drm_add_edid_modes(connector, edid);
293         drm_edid_to_eld(connector, edid);
294         kfree(edid);
295
296         return ret;
297 }