drm/i915/gvt: correct the emulation in TLB control handler
[sfrench/cifs-2.6.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 * const 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 = match_string(generic_edid_name, GENERIC_EDIDS, name);
174         if (builtin >= 0) {
175                 fwdata = generic_edid[builtin];
176                 fwsize = sizeof(generic_edid[builtin]);
177         } else {
178                 struct platform_device *pdev;
179                 int err;
180
181                 pdev = platform_device_register_simple(connector_name, -1, NULL, 0);
182                 if (IS_ERR(pdev)) {
183                         DRM_ERROR("Failed to register EDID firmware platform device "
184                                   "for connector \"%s\"\n", connector_name);
185                         return ERR_CAST(pdev);
186                 }
187
188                 err = request_firmware(&fw, name, &pdev->dev);
189                 platform_device_unregister(pdev);
190                 if (err) {
191                         DRM_ERROR("Requesting EDID firmware \"%s\" failed (err=%d)\n",
192                                   name, err);
193                         return ERR_PTR(err);
194                 }
195
196                 fwdata = fw->data;
197                 fwsize = fw->size;
198         }
199
200         if (edid_size(fwdata, fwsize) != fwsize) {
201                 DRM_ERROR("Size of EDID firmware \"%s\" is invalid "
202                           "(expected %d, got %d\n", name,
203                           edid_size(fwdata, fwsize), (int)fwsize);
204                 edid = ERR_PTR(-EINVAL);
205                 goto out;
206         }
207
208         edid = kmemdup(fwdata, fwsize, GFP_KERNEL);
209         if (edid == NULL) {
210                 edid = ERR_PTR(-ENOMEM);
211                 goto out;
212         }
213
214         if (!drm_edid_block_valid(edid, 0, print_bad_edid,
215                                   &connector->edid_corrupt)) {
216                 connector->bad_edid_counter++;
217                 DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ",
218                     name);
219                 kfree(edid);
220                 edid = ERR_PTR(-EINVAL);
221                 goto out;
222         }
223
224         for (i = 1; i <= edid[0x7e]; i++) {
225                 if (i != valid_extensions + 1)
226                         memcpy(edid + (valid_extensions + 1) * EDID_LENGTH,
227                             edid + i * EDID_LENGTH, EDID_LENGTH);
228                 if (drm_edid_block_valid(edid + i * EDID_LENGTH, i,
229                                          print_bad_edid,
230                                          NULL))
231                         valid_extensions++;
232         }
233
234         if (valid_extensions != edid[0x7e]) {
235                 u8 *new_edid;
236
237                 edid[EDID_LENGTH-1] += edid[0x7e] - valid_extensions;
238                 DRM_INFO("Found %d valid extensions instead of %d in EDID data "
239                     "\"%s\" for connector \"%s\"\n", valid_extensions,
240                     edid[0x7e], name, connector_name);
241                 edid[0x7e] = valid_extensions;
242
243                 new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH,
244                                     GFP_KERNEL);
245                 if (new_edid)
246                         edid = new_edid;
247         }
248
249         DRM_INFO("Got %s EDID base block and %d extension%s from "
250             "\"%s\" for connector \"%s\"\n", (builtin >= 0) ? "built-in" :
251             "external", valid_extensions, valid_extensions == 1 ? "" : "s",
252             name, connector_name);
253
254 out:
255         release_firmware(fw);
256         return edid;
257 }
258
259 int drm_load_edid_firmware(struct drm_connector *connector)
260 {
261         const char *connector_name = connector->name;
262         char *edidname, *last, *colon, *fwstr, *edidstr, *fallback = NULL;
263         int ret;
264         struct edid *edid;
265
266         if (edid_firmware[0] == '\0')
267                 return 0;
268
269         /*
270          * If there are multiple edid files specified and separated
271          * by commas, search through the list looking for one that
272          * matches the connector.
273          *
274          * If there's one or more that doesn't specify a connector, keep
275          * the last one found one as a fallback.
276          */
277         fwstr = kstrdup(edid_firmware, GFP_KERNEL);
278         edidstr = fwstr;
279
280         while ((edidname = strsep(&edidstr, ","))) {
281                 colon = strchr(edidname, ':');
282                 if (colon != NULL) {
283                         if (strncmp(connector_name, edidname, colon - edidname))
284                                 continue;
285                         edidname = colon + 1;
286                         break;
287                 }
288
289                 if (*edidname != '\0') /* corner case: multiple ',' */
290                         fallback = edidname;
291         }
292
293         if (!edidname) {
294                 if (!fallback) {
295                         kfree(fwstr);
296                         return 0;
297                 }
298                 edidname = fallback;
299         }
300
301         last = edidname + strlen(edidname) - 1;
302         if (*last == '\n')
303                 *last = '\0';
304
305         edid = edid_load(connector, edidname, connector_name);
306         kfree(fwstr);
307
308         if (IS_ERR_OR_NULL(edid))
309                 return 0;
310
311         drm_mode_connector_update_edid_property(connector, edid);
312         ret = drm_add_edid_modes(connector, edid);
313         drm_edid_to_eld(connector, edid);
314         kfree(edid);
315
316         return ret;
317 }