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 */ 24struct acpi_viat_table { 25 struct acpi_table_header header; 26 unsigned long vbios_addr; 27} __packed; 28 29static 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 40static 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 69static 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 106static 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 144static 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 188static 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 230static bool parse_vbios_backlight(struct desc_node *this, struct vbios_cmd *cmd) 231{ 232 return 0; 233} 234 235static 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 260static bool parse_vbios_header(struct desc_node *this, struct vbios_cmd *cmd) 261{ 262 return true; 263} 264 265static 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 280static 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 291static 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 309static 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 329static 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 341static 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 367static 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 382static 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 397u32 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 414u16 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 431u32 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 448enum 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 466u16 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 483u16 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 500u8 *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 521u32 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 538u32 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 555u32 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 572u32 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 589u32 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 606u32 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 623bool 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 640struct crtc_timing *get_crtc_timing(struct loongson_drm_device *ldev, u32 index) 641{ 642 return NULL; 643} 644 645u32 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 662u32 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 679struct 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 695u32 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 712enum 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 730enum 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 747u8 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 764enum 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 781bool 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 799static 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 826static 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 855bool 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 875success: 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 888void loongson_vbios_exit(struct loongson_drm_device *ldev) 889{ 890 free_desc_list(ldev); 891 kfree(ldev->vbios); 892} 893