1 /*
2 * Copyright (c) 2018 Loongson Technology Co., Ltd.
3 * Authors:
4 * Chen Zhu <zhuchen@loongson.cn>
5 * Yaling Fang <fangyaling@loongson.cn>
6 * Dandan Zhang <zhangdandan@loongson.cn>
7 * Huacai Chen <chenhc@lemote.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14 #include "loongson_drv.h"
15 #include "loongson_vbios.h"
16
17 #define VBIOS_START 0x1000
18 #define VBIOS_SIZE 0x40000
19 #define VBIOS_OFFSET 0x100000
20 #define VBIOS_DESC_OFFSET 0x6000
21 #define VBIOS_TITLE "Loongson-VBIOS"
22
23 /* VBIOS INFO ADDRESS TABLE */
24 struct acpi_viat_table {
25 struct acpi_table_header header;
26 unsigned long vbios_addr;
27 } __packed;
28
get_vbios_version(struct loongson_vbios *vbios)29 static u32 get_vbios_version(struct loongson_vbios *vbios)
30 {
31 u32 minor, major, version;
32
33 minor = vbios->version_minor;
34 major = vbios->version_major;
35 version = major * 10 + minor;
36
37 return version;
38 }
39
parse_vbios_i2c(struct desc_node *this, struct vbios_cmd *cmd)40 static bool parse_vbios_i2c(struct desc_node *this, struct vbios_cmd *cmd)
41 {
42 bool ret = true;
43 int i, num, size;
44 struct vbios_i2c *i2c;
45 struct vbios_i2c *vbios_i2c = NULL;
46 struct loongson_i2c *val = (struct loongson_i2c *)cmd->res;
47
48 size = this->desc->size;
49 vbios_i2c = kzalloc(size, GFP_KERNEL);
50 if (!vbios_i2c)
51 return false;
52
53 memset(vbios_i2c, 0xff, size);
54 memcpy(vbios_i2c, this->data, size);
55 num = size / sizeof(*vbios_i2c);
56
57 i2c = vbios_i2c;
58 for (i = 0; (i < num && i < DC_I2C_BUS_MAX); i++) {
59 val->i2c_id = (u32)i2c->id;
60 val->use = true;
61 val++;
62 i2c++;
63 }
64
65 kfree(vbios_i2c);
66 return ret;
67 }
68
parse_vbios_crtc(struct desc_node *this, struct vbios_cmd *cmd)69 static bool parse_vbios_crtc(struct desc_node *this, struct vbios_cmd *cmd)
70 {
71 bool ret = true;
72 u64 request = (u64)cmd->req;
73 u32 *val = (u32 *)cmd->res;
74 struct vbios_crtc crtc;
75
76 memset(&crtc, 0xff, sizeof(crtc));
77 memcpy(&crtc, this->data, min_t(u32, this->desc->size, sizeof(crtc)));
78
79 switch (request) {
80 case VBIOS_CRTC_ID:
81 *val = crtc.crtc_id;
82 break;
83 case VBIOS_CRTC_ENCODER_ID:
84 *val = crtc.encoder_id;
85 break;
86 case VBIOS_CRTC_MAX_FREQ:
87 *val = crtc.max_freq;
88 break;
89 case VBIOS_CRTC_MAX_WIDTH:
90 *val = crtc.max_width;
91 break;
92 case VBIOS_CRTC_MAX_HEIGHT:
93 *val = crtc.max_height;
94 break;
95 case VBIOS_CRTC_IS_VB_TIMING:
96 *val = crtc.is_vb_timing;
97 break;
98 default:
99 ret = false;
100 break;
101 }
102
103 return ret;
104 }
105
parse_vbios_encoder(struct desc_node *this, struct vbios_cmd *cmd)106 static bool parse_vbios_encoder(struct desc_node *this, struct vbios_cmd *cmd)
107 {
108 bool ret = true;
109 u64 request = (u64)cmd->req;
110 u32 *val = (u32 *)cmd->res;
111 struct vbios_encoder encoder;
112
113 memset(&encoder, 0xff, sizeof(encoder));
114 memcpy(&encoder, this->data,
115 min_t(u32, this->desc->size, sizeof(encoder)));
116
117 switch (request) {
118 case VBIOS_ENCODER_I2C_ID:
119 *val = encoder.i2c_id;
120 break;
121 case VBIOS_ENCODER_CONNECTOR_ID:
122 *val = encoder.connector_id;
123 break;
124 case VBIOS_ENCODER_TYPE:
125 *val = encoder.type;
126 break;
127 case VBIOS_ENCODER_CONFIG_TYPE:
128 *val = encoder.config_type;
129 break;
130 case VBIOS_ENCODER_CHIP:
131 *val = encoder.chip;
132 break;
133 case VBIOS_ENCODER_CHIP_ADDR:
134 *val = encoder.chip_addr;
135 break;
136 default:
137 ret = false;
138 break;
139 }
140
141 return ret;
142 }
143
parse_vbios_cfg_encoder(struct desc_node *this, struct vbios_cmd *cmd)144 static bool parse_vbios_cfg_encoder(struct desc_node *this,
145 struct vbios_cmd *cmd)
146 {
147 bool ret = true;
148 u64 request = (u64)cmd->req;
149 u32 *val = (u32 *)cmd->res;
150 struct cfg_encoder *cfg_encoder;
151 struct cfg_encoder *cfg;
152 struct vbios_cfg_encoder *vbios_cfg_encoder;
153 u32 num, size, i = 0;
154
155 vbios_cfg_encoder = (struct vbios_cfg_encoder *)this->data;
156 size = sizeof(struct vbios_cfg_encoder);
157 num = this->desc->size / size;
158
159 switch (request) {
160 case VBIOS_ENCODER_CONFIG_PARAM:
161 cfg_encoder = (struct cfg_encoder *)kzalloc(
162 sizeof(struct cfg_encoder) * num, GFP_KERNEL);
163 cfg = cfg_encoder;
164 for (i = 0; i < num; i++) {
165 cfg->reg_num = vbios_cfg_encoder->reg_num;
166 cfg->hdisplay = vbios_cfg_encoder->hdisplay;
167 cfg->vdisplay = vbios_cfg_encoder->vdisplay;
168 memcpy(&cfg->config_regs,
169 &vbios_cfg_encoder->config_regs,
170 sizeof(struct vbios_conf_reg) * 256);
171
172 cfg++;
173 vbios_cfg_encoder++;
174 }
175 cmd->res = (void *)cfg_encoder;
176 break;
177 case VBIOS_ENCODER_CONFIG_NUM:
178 *val = num;
179 break;
180 default:
181 ret = false;
182 break;
183 }
184
185 return ret;
186 }
187
parse_vbios_connector(struct desc_node *this, struct vbios_cmd *cmd)188 static bool parse_vbios_connector(struct desc_node *this, struct vbios_cmd *cmd)
189 {
190 bool ret = true;
191 u64 request = (u64)cmd->req;
192 u32 *val = (u32 *)cmd->res;
193 struct vbios_connector connector;
194
195 memset(&connector, 0xff, sizeof(connector));
196 memcpy(&connector, this->data,
197 min_t(u32, this->desc->size, sizeof(connector)));
198
199 switch (request) {
200 case VBIOS_CONNECTOR_I2C_ID:
201 *val = connector.i2c_id;
202 break;
203 case VBIOS_CONNECTOR_INTERNAL_EDID:
204 memcpy((u8 *)(ulong)val, connector.internal_edid,
205 EDID_LENGTH * 2);
206 break;
207 case VBIOS_CONNECTOR_TYPE:
208 *val = connector.type;
209 break;
210 case VBIOS_CONNECTOR_HOTPLUG:
211 *val = connector.hotplug;
212 break;
213 case VBIOS_CONNECTOR_EDID_METHOD:
214 *val = connector.edid_method;
215 break;
216 case VBIOS_CONNECTOR_IRQ_GPIO:
217 *val = connector.irq_gpio;
218 break;
219 case VBIOS_CONNECTOR_IRQ_PLACEMENT:
220 *val = connector.gpio_placement;
221 break;
222 default:
223 ret = false;
224 break;
225 }
226
227 return ret;
228 }
229
parse_vbios_backlight(struct desc_node *this, struct vbios_cmd *cmd)230 static bool parse_vbios_backlight(struct desc_node *this, struct vbios_cmd *cmd)
231 {
232 return 0;
233 }
234
parse_vbios_pwm(struct desc_node *this, struct vbios_cmd *cmd)235 static bool parse_vbios_pwm(struct desc_node *this, struct vbios_cmd *cmd)
236 {
237 bool ret = true;
238 u64 request = (u64)cmd->req;
239 u32 *val = (u32 *)cmd->res;
240 struct vbios_pwm *pwm = (struct vbios_pwm *)this->data;
241
242 switch (request) {
243 case VBIOS_PWM_ID:
244 *val = pwm->pwm;
245 break;
246 case VBIOS_PWM_PERIOD:
247 *val = pwm->peroid;
248 break;
249 case VBIOS_PWM_POLARITY:
250 *val = pwm->polarity;
251 break;
252 default:
253 ret = false;
254 break;
255 }
256
257 return ret;
258 }
259
parse_vbios_header(struct desc_node *this, struct vbios_cmd *cmd)260 static bool parse_vbios_header(struct desc_node *this, struct vbios_cmd *cmd)
261 {
262 return true;
263 }
264
parse_vbios_default(struct desc_node *this, struct vbios_cmd *cmd)265 static bool parse_vbios_default(struct desc_node *this, struct vbios_cmd *cmd)
266 {
267 struct vbios_desc *vb_desc;
268
269 vb_desc = this->desc;
270 DRM_WARN("Current descriptor[T-%d][V-%d] cannot be interprete.\n",
271 vb_desc->type, vb_desc->ver);
272 return false;
273 }
274
275 #define FUNC(t, v, f) \
276 { \
277 .type = t, .ver = v, .func = f, \
278 }
279
280 static struct desc_func tables[] = {
281 FUNC(desc_header, ver_v1, parse_vbios_header),
282 FUNC(desc_i2c, ver_v1, parse_vbios_i2c),
283 FUNC(desc_crtc, ver_v1, parse_vbios_crtc),
284 FUNC(desc_encoder, ver_v1, parse_vbios_encoder),
285 FUNC(desc_connector, ver_v1, parse_vbios_connector),
286 FUNC(desc_cfg_encoder, ver_v1, parse_vbios_cfg_encoder),
287 FUNC(desc_backlight, ver_v1, parse_vbios_backlight),
288 FUNC(desc_pwm, ver_v1, parse_vbios_pwm),
289 };
290
get_parse_func(struct vbios_desc *vb_desc)291 static inline parse_func *get_parse_func(struct vbios_desc *vb_desc)
292 {
293 int i;
294 u32 type = vb_desc->type;
295 u32 ver = vb_desc->ver;
296 parse_func *func = parse_vbios_default;
297 u32 tt_num = ARRAY_SIZE(tables);
298
299 for (i = 0; i < tt_num; i++) {
300 if ((tables[i].ver == ver) && (tables[i].type == type)) {
301 func = tables[i].func;
302 break;
303 }
304 }
305
306 return func;
307 }
308
insert_desc_list(struct loongson_drm_device *ldev, struct vbios_desc *vb_desc)309 static inline u32 insert_desc_list(struct loongson_drm_device *ldev,
310 struct vbios_desc *vb_desc)
311 {
312 struct desc_node *node;
313 parse_func *func = NULL;
314
315 WARN_ON(!ldev || !vb_desc);
316 node = (struct desc_node *)kzalloc(sizeof(*node), GFP_KERNEL);
317 if (!node)
318 return -ENOMEM;
319
320 func = get_parse_func(vb_desc);
321 node->parse = func;
322 node->desc = (void *)vb_desc;
323 node->data = ((u8 *)ldev->vbios + vb_desc->offset);
324 list_add_tail(&node->head, &ldev->desc_list);
325
326 return 0;
327 }
328
free_desc_list(struct loongson_drm_device *ldev)329 static inline void free_desc_list(struct loongson_drm_device *ldev)
330 {
331 struct desc_node *node, *tmp;
332
333 list_for_each_entry_safe (node, tmp, &ldev->desc_list, head) {
334 list_del(&node->head);
335 kfree(node);
336 }
337 }
338
339 #define DESC_LIST_MAX 1024
340
parse_vbios_desc(struct loongson_drm_device *ldev)341 static u32 parse_vbios_desc(struct loongson_drm_device *ldev)
342 {
343 u32 i, ret = 0;
344 struct vbios_desc *desc;
345 enum desc_type type = 0;
346 u8 *vbios = (u8 *)ldev->vbios;
347
348 WARN_ON(!vbios);
349
350 desc = (struct vbios_desc *)(vbios + VBIOS_DESC_OFFSET);
351 for (i = 0; i < DESC_LIST_MAX; i++) {
352 type = desc->type;
353 if (type == desc_max)
354 break;
355
356 ret = insert_desc_list(ldev, desc);
357 if (ret)
358 DRM_DEBUG_KMS("Parse T-%d V-%d failed[%d]\n", desc->ver,
359 desc->type, ret);
360
361 desc++;
362 }
363
364 return ret;
365 }
366
get_desc_node(struct loongson_drm_device *ldev, u16 type, u8 index)367 static inline struct desc_node *get_desc_node(struct loongson_drm_device *ldev,
368 u16 type, u8 index)
369 {
370 struct desc_node *node, *tmp;
371 struct vbios_desc *vb_desc;
372
373 list_for_each_entry_safe (node, tmp, &ldev->desc_list, head) {
374 vb_desc = node->desc;
375 if (vb_desc->type == type && vb_desc->index == index)
376 return node;
377 }
378
379 return NULL;
380 }
381
vbios_get_data(struct loongson_drm_device *ldev, struct vbios_cmd *cmd)382 static bool vbios_get_data(struct loongson_drm_device *ldev, struct vbios_cmd *cmd)
383 {
384 struct desc_node *node;
385
386 WARN_ON(!cmd);
387
388 node = get_desc_node(ldev, cmd->type, cmd->index);
389 if (node && node->parse)
390 return node->parse(node, cmd);
391
392 DRM_DEBUG_DRIVER("Failed to get node(%d,%d)\n", cmd->type, cmd->index);
393
394 return false;
395 }
396
get_connector_type(struct loongson_drm_device *ldev, u32 index)397 u32 get_connector_type(struct loongson_drm_device *ldev, u32 index)
398 {
399 u32 type = -1;
400 bool ret = false;
401 struct vbios_cmd vbt_cmd;
402
403 vbt_cmd.index = index;
404 vbt_cmd.type = desc_connector;
405 vbt_cmd.req = (void *)(ulong)VBIOS_CONNECTOR_TYPE;
406 vbt_cmd.res = (void *)(ulong)&type;
407 ret = vbios_get_data(ldev, &vbt_cmd);
408 if (!ret)
409 type = -1;
410
411 return type;
412 }
413
get_connector_i2cid(struct loongson_drm_device *ldev, u32 index)414 u16 get_connector_i2cid(struct loongson_drm_device *ldev, u32 index)
415 {
416 u16 i2c_id = -1;
417 bool ret = false;
418 struct vbios_cmd vbt_cmd;
419
420 vbt_cmd.index = index;
421 vbt_cmd.type = desc_connector;
422 vbt_cmd.req = (void *)(ulong)VBIOS_CONNECTOR_I2C_ID;
423 vbt_cmd.res = (void *)(ulong)&i2c_id;
424 ret = vbios_get_data(ldev, &vbt_cmd);
425 if (!ret)
426 i2c_id = -1;
427
428 return i2c_id;
429 }
430
get_connector_irq_gpio(struct loongson_drm_device *ldev, u32 index)431 u32 get_connector_irq_gpio(struct loongson_drm_device *ldev, u32 index)
432 {
433 int ret;
434 u32 irq_gpio;
435 struct vbios_cmd vbt_cmd;
436
437 vbt_cmd.index = index;
438 vbt_cmd.type = desc_connector;
439 vbt_cmd.req = (void *)(ulong)VBIOS_CONNECTOR_IRQ_GPIO;
440 vbt_cmd.res = (void *)(ulong)&irq_gpio;
441 ret = vbios_get_data(ldev, &vbt_cmd);
442 if (!ret)
443 return -1;
444
445 return irq_gpio;
446 }
447
get_connector_gpio_placement(struct loongson_drm_device *ldev, u32 index)448 enum gpio_placement get_connector_gpio_placement(struct loongson_drm_device *ldev,
449 u32 index)
450 {
451 int ret;
452 enum gpio_placement irq_placement;
453 struct vbios_cmd vbt_cmd;
454
455 vbt_cmd.index = index;
456 vbt_cmd.type = desc_connector;
457 vbt_cmd.req = (void *)(ulong)VBIOS_CONNECTOR_IRQ_PLACEMENT;
458 vbt_cmd.res = (void *)(ulong)&irq_placement;
459 ret = vbios_get_data(ldev, &vbt_cmd);
460 if (!ret)
461 return -1;
462
463 return irq_placement;
464 }
465
get_hotplug_mode(struct loongson_drm_device *ldev, u32 index)466 u16 get_hotplug_mode(struct loongson_drm_device *ldev, u32 index)
467 {
468 u16 mode = -1;
469 bool ret = false;
470 struct vbios_cmd vbt_cmd;
471
472 vbt_cmd.index = index;
473 vbt_cmd.type = desc_connector;
474 vbt_cmd.req = (void *)(ulong)VBIOS_CONNECTOR_HOTPLUG;
475 vbt_cmd.res = (void *)(ulong)&mode;
476 ret = vbios_get_data(ldev, &vbt_cmd);
477 if (!ret)
478 mode = -1;
479
480 return mode;
481 }
482
get_edid_method(struct loongson_drm_device *ldev, u32 index)483 u16 get_edid_method(struct loongson_drm_device *ldev, u32 index)
484 {
485 bool ret = false;
486 u16 method = via_null;
487 struct vbios_cmd vbt_cmd;
488
489 vbt_cmd.index = index;
490 vbt_cmd.type = desc_connector;
491 vbt_cmd.req = (void *)(ulong)VBIOS_CONNECTOR_EDID_METHOD;
492 vbt_cmd.res = (void *)(ulong)&method;
493 ret = vbios_get_data(ldev, &vbt_cmd);
494 if (!ret)
495 method = via_null;
496
497 return method;
498 }
499
get_vbios_edid(struct loongson_drm_device *ldev, u32 index)500 u8 *get_vbios_edid(struct loongson_drm_device *ldev, u32 index)
501 {
502 u8 *edid = NULL;
503 bool ret = false;
504 struct vbios_cmd vbt_cmd;
505
506 edid = kzalloc(sizeof(u8) * EDID_LENGTH * 2, GFP_KERNEL);
507 if (!edid)
508 return edid;
509
510 vbt_cmd.index = index;
511 vbt_cmd.type = desc_connector;
512 vbt_cmd.req = (void *)(ulong)VBIOS_CONNECTOR_INTERNAL_EDID;
513 vbt_cmd.res = (void *)(ulong)edid;
514 ret = vbios_get_data(ldev, &vbt_cmd);
515 if (!ret)
516 return NULL;
517
518 return edid;
519 }
520
get_vbios_pwm(struct loongson_drm_device *ldev, u32 index, u16 request)521 u32 get_vbios_pwm(struct loongson_drm_device *ldev, u32 index, u16 request)
522 {
523 u32 value = -1;
524 bool ret = false;
525 struct vbios_cmd vbt_cmd;
526
527 vbt_cmd.index = index;
528 vbt_cmd.type = desc_pwm;
529 vbt_cmd.req = (void *)(ulong)request;
530 vbt_cmd.res = (void *)(ulong)&value;
531 ret = vbios_get_data(ldev, &vbt_cmd);
532 if (!ret)
533 value = 0xffffffff;
534
535 return value;
536 }
537
get_crtc_id(struct loongson_drm_device *ldev, u32 index)538 u32 get_crtc_id(struct loongson_drm_device *ldev, u32 index)
539 {
540 u32 crtc_id = 0;
541 bool ret = false;
542 struct vbios_cmd vbt_cmd;
543
544 vbt_cmd.index = index;
545 vbt_cmd.type = desc_crtc;
546 vbt_cmd.req = (void *)(ulong)VBIOS_CRTC_ID;
547 vbt_cmd.res = (void *)(ulong)&crtc_id;
548 ret = vbios_get_data(ldev, &vbt_cmd);
549 if (!ret)
550 crtc_id = 0;
551
552 return crtc_id;
553 }
554
get_crtc_max_freq(struct loongson_drm_device *ldev, u32 index)555 u32 get_crtc_max_freq(struct loongson_drm_device *ldev, u32 index)
556 {
557 bool ret = false;
558 u32 max_freq = 0;
559 struct vbios_cmd vbt_cmd;
560
561 vbt_cmd.index = index;
562 vbt_cmd.type = desc_crtc;
563 vbt_cmd.req = (void *)(ulong)VBIOS_CRTC_MAX_FREQ;
564 vbt_cmd.res = (void *)(ulong)&max_freq;
565 ret = vbios_get_data(ldev, &vbt_cmd);
566 if (!ret)
567 max_freq = 0;
568
569 return max_freq;
570 }
571
get_crtc_max_width(struct loongson_drm_device *ldev, u32 index)572 u32 get_crtc_max_width(struct loongson_drm_device *ldev, u32 index)
573 {
574 bool ret = false;
575 u32 max_width = 0;
576 struct vbios_cmd vbt_cmd;
577
578 vbt_cmd.index = index;
579 vbt_cmd.type = desc_crtc;
580 vbt_cmd.req = (void *)(ulong)VBIOS_CRTC_MAX_WIDTH;
581 vbt_cmd.res = (void *)(ulong)&max_width;
582 ret = vbios_get_data(ldev, &vbt_cmd);
583 if (!ret)
584 max_width = LOONGSON_MAX_FB_WIDTH;
585
586 return max_width;
587 }
588
get_crtc_max_height(struct loongson_drm_device *ldev, u32 index)589 u32 get_crtc_max_height(struct loongson_drm_device *ldev, u32 index)
590 {
591 bool ret = false;
592 u32 max_height = 0;
593 struct vbios_cmd vbt_cmd;
594
595 vbt_cmd.index = index;
596 vbt_cmd.type = desc_crtc;
597 vbt_cmd.req = (void *)(ulong)VBIOS_CRTC_MAX_HEIGHT;
598 vbt_cmd.res = (void *)(ulong)&max_height;
599 ret = vbios_get_data(ldev, &vbt_cmd);
600 if (!ret)
601 max_height = LOONGSON_MAX_FB_HEIGHT;
602
603 return max_height;
604 }
605
get_crtc_encoder_id(struct loongson_drm_device *ldev, u32 index)606 u32 get_crtc_encoder_id(struct loongson_drm_device *ldev, u32 index)
607 {
608 bool ret = false;
609 u32 encoder_id = 0;
610 struct vbios_cmd vbt_cmd;
611
612 vbt_cmd.index = index;
613 vbt_cmd.type = desc_crtc;
614 vbt_cmd.req = (void *)(ulong)VBIOS_CRTC_ENCODER_ID;
615 vbt_cmd.res = (void *)(ulong)&encoder_id;
616 ret = vbios_get_data(ldev, &vbt_cmd);
617 if (!ret)
618 encoder_id = 0;
619
620 return encoder_id;
621 }
622
get_crtc_is_vb_timing(struct loongson_drm_device *ldev, u32 index)623 bool get_crtc_is_vb_timing(struct loongson_drm_device *ldev, u32 index)
624 {
625 bool ret = false;
626 bool vb_timing = false;
627 struct vbios_cmd vbt_cmd;
628
629 vbt_cmd.index = index;
630 vbt_cmd.type = desc_crtc;
631 vbt_cmd.req = (void *)(ulong)VBIOS_CRTC_IS_VB_TIMING;
632 vbt_cmd.res = (void *)(ulong)&vb_timing;
633 ret = vbios_get_data(ldev, &vbt_cmd);
634 if (!ret)
635 vb_timing = false;
636
637 return vb_timing;
638 }
639
get_crtc_timing(struct loongson_drm_device *ldev, u32 index)640 struct crtc_timing *get_crtc_timing(struct loongson_drm_device *ldev, u32 index)
641 {
642 return NULL;
643 }
644
get_encoder_connector_id(struct loongson_drm_device *ldev, u32 index)645 u32 get_encoder_connector_id(struct loongson_drm_device *ldev, u32 index)
646 {
647 bool ret = false;
648 u32 connector_id = 0;
649 struct vbios_cmd vbt_cmd;
650
651 vbt_cmd.index = index;
652 vbt_cmd.type = desc_encoder;
653 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_CONNECTOR_ID;
654 vbt_cmd.res = (void *)(ulong)&connector_id;
655 ret = vbios_get_data(ldev, &vbt_cmd);
656 if (!ret)
657 connector_id = 0;
658
659 return connector_id;
660 }
661
get_encoder_i2c_id(struct loongson_drm_device *ldev, u32 index)662 u32 get_encoder_i2c_id(struct loongson_drm_device *ldev, u32 index)
663 {
664 u32 i2c_id = 0;
665 bool ret = false;
666 struct vbios_cmd vbt_cmd;
667
668 vbt_cmd.index = index;
669 vbt_cmd.type = desc_encoder;
670 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_I2C_ID;
671 vbt_cmd.res = (void *)(ulong)&i2c_id;
672 ret = vbios_get_data(ldev, &vbt_cmd);
673 if (!ret)
674 i2c_id = 0;
675
676 return i2c_id;
677 }
678
get_encoder_config(struct loongson_drm_device *ldev, u32 index)679 struct cfg_encoder *get_encoder_config(struct loongson_drm_device *ldev, u32 index)
680 {
681 bool ret = false;
682 struct vbios_cmd vbt_cmd;
683 struct cfg_encoder *encoder_config = NULL;
684
685 vbt_cmd.index = index;
686 vbt_cmd.type = desc_cfg_encoder;
687 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_CONFIG_PARAM;
688 ret = vbios_get_data(ldev, &vbt_cmd);
689 if (ret)
690 encoder_config = (struct cfg_encoder *)vbt_cmd.res;
691
692 return encoder_config;
693 }
694
get_encoder_cfg_num(struct loongson_drm_device *ldev, u32 index)695 u32 get_encoder_cfg_num(struct loongson_drm_device *ldev, u32 index)
696 {
697 struct vbios_cmd vbt_cmd;
698 bool ret = false;
699 u32 cfg_num = 0;
700
701 vbt_cmd.index = index;
702 vbt_cmd.type = desc_cfg_encoder;
703 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_CONFIG_NUM;
704 vbt_cmd.res = (void *)(ulong)&cfg_num;
705 ret = vbios_get_data(ldev, &vbt_cmd);
706 if (!ret)
707 cfg_num = 0;
708
709 return cfg_num;
710 }
711
get_encoder_config_type(struct loongson_drm_device *ldev, u32 index)712 enum encoder_config get_encoder_config_type(struct loongson_drm_device *ldev,
713 u32 index)
714 {
715 bool ret = false;
716 enum encoder_config config_type = encoder_bios_config;
717 struct vbios_cmd vbt_cmd;
718
719 vbt_cmd.index = index;
720 vbt_cmd.type = desc_encoder;
721 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_CONFIG_TYPE;
722 vbt_cmd.res = (void *)(ulong)&config_type;
723 ret = vbios_get_data(ldev, &vbt_cmd);
724 if (!ret)
725 config_type = encoder_bios_config;
726
727 return config_type;
728 }
729
get_encoder_chip(struct loongson_drm_device *ldev, u32 index)730 enum encoder_object get_encoder_chip(struct loongson_drm_device *ldev, u32 index)
731 {
732 int ret;
733 enum encoder_object chip;
734 struct vbios_cmd vbt_cmd;
735
736 vbt_cmd.index = index;
737 vbt_cmd.type = desc_encoder;
738 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_CHIP;
739 vbt_cmd.res = (void *)(ulong)&chip;
740 ret = vbios_get_data(ldev, &vbt_cmd);
741 if (!ret)
742 return Unknown;
743
744 return chip;
745 }
746
get_encoder_chip_addr(struct loongson_drm_device *ldev, u32 index)747 u8 get_encoder_chip_addr(struct loongson_drm_device *ldev, u32 index)
748 {
749 int ret;
750 u8 chip_addr;
751 struct vbios_cmd vbt_cmd;
752
753 vbt_cmd.index = index;
754 vbt_cmd.type = desc_encoder;
755 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_CHIP_ADDR;
756 vbt_cmd.res = (void *)(ulong)&chip_addr;
757 ret = vbios_get_data(ldev, &vbt_cmd);
758 if (!ret)
759 return Unknown;
760
761 return chip_addr;
762 }
763
get_encoder_type(struct loongson_drm_device *ldev, u32 index)764 enum encoder_type get_encoder_type(struct loongson_drm_device *ldev, u32 index)
765 {
766 bool ret = false;
767 enum encoder_type type = encoder_dac;
768 struct vbios_cmd vbt_cmd;
769
770 vbt_cmd.index = index;
771 vbt_cmd.type = desc_encoder;
772 vbt_cmd.req = (void *)(ulong)VBIOS_ENCODER_TYPE;
773 vbt_cmd.res = (void *)(ulong)&type;
774 ret = vbios_get_data(ldev, &vbt_cmd);
775 if (!ret)
776 type = encoder_dac;
777
778 return type;
779 }
780
get_loongson_i2c(struct loongson_drm_device *ldev)781 bool get_loongson_i2c(struct loongson_drm_device *ldev)
782 {
783 bool ret = false;
784 struct vbios_cmd vbt_cmd;
785
786 vbt_cmd.index = 0;
787 vbt_cmd.type = desc_i2c;
788 vbt_cmd.res = (void *)&ldev->i2c_bus;
789 ret = vbios_get_data(ldev, &vbt_cmd);
790
791 if (!ret) {
792 ldev->i2c_bus[0].use = true;
793 ldev->i2c_bus[1].use = true;
794 }
795
796 return true;
797 }
798
get_vbios_from_acpi(struct loongson_drm_device *ldev)799 static void *get_vbios_from_acpi(struct loongson_drm_device *ldev)
800 {
801 void *vbios = NULL;
802 #ifdef CONFIG_ACPI
803 struct acpi_viat_table *viat;
804 struct acpi_table_header *hdr;
805
806 if (!ACPI_SUCCESS(acpi_get_table("VIAT", 1, &hdr)))
807 return NULL;
808
809 if (hdr->length != sizeof(struct acpi_viat_table)) {
810 DRM_WARN("ACPI VIAT table present but broken (length error)\n");
811 return NULL;
812 }
813
814 vbios = kmalloc(VBIOS_SIZE, GFP_KERNEL);
815 if (!vbios)
816 return NULL;
817
818 viat = (struct acpi_viat_table *)hdr;
819 memcpy(vbios, phys_to_virt(viat->vbios_addr), VBIOS_SIZE);
820
821 DRM_INFO("Get VBIOS from ACPI success!\n");
822 #endif
823 return vbios;
824 }
825
get_vbios_from_vram(struct loongson_drm_device *ldev)826 static void *get_vbios_from_vram(struct loongson_drm_device *ldev)
827 {
828 void *bios, *vbios = NULL;
829 u64 vram_base = pci_resource_start(ldev->gpu_pdev, 2);
830 u64 vram_size = pci_resource_len(ldev->gpu_pdev, 2);
831 u64 vbios_addr = vram_base + vram_size - VBIOS_OFFSET;
832
833 bios = ioremap(vbios_addr, VBIOS_SIZE);
834 if (!bios)
835 return NULL;
836
837 vbios = kmalloc(VBIOS_SIZE, GFP_KERNEL);
838 if (!vbios)
839 return NULL;
840
841 memcpy(vbios, bios, VBIOS_SIZE);
842
843 iounmap(bios);
844
845 if (memcmp(vbios, VBIOS_TITLE, strlen(VBIOS_TITLE))) {
846 kfree(vbios);
847 return NULL;
848 }
849
850 DRM_INFO("Get VBIOS from VRAM success!\n");
851
852 return vbios;
853 }
854
loongson_vbios_init(struct loongson_drm_device *ldev)855 bool loongson_vbios_init(struct loongson_drm_device *ldev)
856 {
857 void *vbios = NULL;
858 struct loongson_vbios *header;
859
860 vbios = get_vbios_from_vram(ldev);
861 if (vbios)
862 goto success;
863
864 vbios = get_vbios_from_acpi(ldev);
865 if (vbios)
866 goto success;
867
868 vbios = kzalloc(256 * 1024, GFP_KERNEL);
869 if (!vbios)
870 return false;
871
872 header = vbios;
873 header->crtc_num = 2;
874
875 success:
876 header = ldev->vbios = vbios;
877 ldev->num_crtc = header->crtc_num;
878
879 DRM_INFO("Loongson VBIOS version %d.%d\n", header->version_major,
880 header->version_minor);
881
882 INIT_LIST_HEAD(&ldev->desc_list);
883 parse_vbios_desc(ldev);
884
885 return true;
886 }
887
loongson_vbios_exit(struct loongson_drm_device *ldev)888 void loongson_vbios_exit(struct loongson_drm_device *ldev)
889 {
890 free_desc_list(ldev);
891 kfree(ldev->vbios);
892 }
893