diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-08-04 08:50:25 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2010-08-09 14:24:28 -0400 |
commit | 32aad86fe88e7323d4fc5e9e423abcee0d55a03d (patch) | |
tree | e0cc3fd5d4fd9df21c8e480c13679f17ac81577b /drivers/gpu/drm/i915/intel_sdvo.c | |
parent | 615fb93f6d99cce2ab36dcf09986e321e17c356f (diff) |
drm/i915/sdvo: Propagate errors from reading/writing control bus.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 930 |
1 files changed, 379 insertions, 551 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index dca123527d5f..300f110fd180 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -47,6 +47,7 @@ | |||
47 | 47 | ||
48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) |
49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) |
50 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) | ||
50 | 51 | ||
51 | 52 | ||
52 | static char *tv_format_names[] = { | 53 | static char *tv_format_names[] = { |
@@ -189,10 +190,13 @@ static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector | |||
189 | 190 | ||
190 | static bool | 191 | static bool |
191 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); | 192 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); |
192 | static void | 193 | static bool |
193 | intel_sdvo_tv_create_property(struct drm_connector *connector, int type); | 194 | intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
194 | static void | 195 | struct intel_sdvo_connector *intel_sdvo_connector, |
195 | intel_sdvo_create_enhance_property(struct drm_connector *connector); | 196 | int type); |
197 | static bool | ||
198 | intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | ||
199 | struct intel_sdvo_connector *intel_sdvo_connector); | ||
196 | 200 | ||
197 | /** | 201 | /** |
198 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 202 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
@@ -231,13 +235,10 @@ static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) | |||
231 | } | 235 | } |
232 | } | 236 | } |
233 | 237 | ||
234 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, | 238 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) |
235 | u8 *ch) | ||
236 | { | 239 | { |
237 | u8 out_buf[2]; | 240 | u8 out_buf[2] = { addr, 0 }; |
238 | u8 buf[2]; | 241 | u8 buf[2]; |
239 | int ret; | ||
240 | |||
241 | struct i2c_msg msgs[] = { | 242 | struct i2c_msg msgs[] = { |
242 | { | 243 | { |
243 | .addr = intel_sdvo->slave_addr >> 1, | 244 | .addr = intel_sdvo->slave_addr >> 1, |
@@ -252,9 +253,7 @@ static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, | |||
252 | .buf = buf, | 253 | .buf = buf, |
253 | } | 254 | } |
254 | }; | 255 | }; |
255 | 256 | int ret; | |
256 | out_buf[0] = addr; | ||
257 | out_buf[1] = 0; | ||
258 | 257 | ||
259 | if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) | 258 | if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) |
260 | { | 259 | { |
@@ -266,10 +265,9 @@ static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, | |||
266 | return false; | 265 | return false; |
267 | } | 266 | } |
268 | 267 | ||
269 | static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, | 268 | static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch) |
270 | u8 ch) | ||
271 | { | 269 | { |
272 | u8 out_buf[2]; | 270 | u8 out_buf[2] = { addr, ch }; |
273 | struct i2c_msg msgs[] = { | 271 | struct i2c_msg msgs[] = { |
274 | { | 272 | { |
275 | .addr = intel_sdvo->slave_addr >> 1, | 273 | .addr = intel_sdvo->slave_addr >> 1, |
@@ -279,14 +277,7 @@ static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, | |||
279 | } | 277 | } |
280 | }; | 278 | }; |
281 | 279 | ||
282 | out_buf[0] = addr; | 280 | return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1; |
283 | out_buf[1] = ch; | ||
284 | |||
285 | if (i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1) | ||
286 | { | ||
287 | return true; | ||
288 | } | ||
289 | return false; | ||
290 | } | 281 | } |
291 | 282 | ||
292 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} | 283 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} |
@@ -390,7 +381,7 @@ static const struct _sdvo_cmd_name { | |||
390 | #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") | 381 | #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") |
391 | 382 | ||
392 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, | 383 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
393 | void *args, int args_len) | 384 | const void *args, int args_len) |
394 | { | 385 | { |
395 | int i; | 386 | int i; |
396 | 387 | ||
@@ -411,19 +402,20 @@ static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
411 | DRM_LOG_KMS("\n"); | 402 | DRM_LOG_KMS("\n"); |
412 | } | 403 | } |
413 | 404 | ||
414 | static void intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | 405 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
415 | void *args, int args_len) | 406 | const void *args, int args_len) |
416 | { | 407 | { |
417 | int i; | 408 | int i; |
418 | 409 | ||
419 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); | 410 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
420 | 411 | ||
421 | for (i = 0; i < args_len; i++) { | 412 | for (i = 0; i < args_len; i++) { |
422 | intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i, | 413 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i, |
423 | ((u8*)args)[i]); | 414 | ((u8*)args)[i])) |
415 | return false; | ||
424 | } | 416 | } |
425 | 417 | ||
426 | intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd); | 418 | return intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd); |
427 | } | 419 | } |
428 | 420 | ||
429 | static const char *cmd_status_names[] = { | 421 | static const char *cmd_status_names[] = { |
@@ -454,8 +446,8 @@ static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo, | |||
454 | DRM_LOG_KMS("\n"); | 446 | DRM_LOG_KMS("\n"); |
455 | } | 447 | } |
456 | 448 | ||
457 | static u8 intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | 449 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
458 | void *response, int response_len) | 450 | void *response, int response_len) |
459 | { | 451 | { |
460 | int i; | 452 | int i; |
461 | u8 status; | 453 | u8 status; |
@@ -464,24 +456,26 @@ static u8 intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, | |||
464 | while (retry--) { | 456 | while (retry--) { |
465 | /* Read the command response */ | 457 | /* Read the command response */ |
466 | for (i = 0; i < response_len; i++) { | 458 | for (i = 0; i < response_len; i++) { |
467 | intel_sdvo_read_byte(intel_sdvo, | 459 | if (!intel_sdvo_read_byte(intel_sdvo, |
468 | SDVO_I2C_RETURN_0 + i, | 460 | SDVO_I2C_RETURN_0 + i, |
469 | &((u8 *)response)[i]); | 461 | &((u8 *)response)[i])) |
462 | return false; | ||
470 | } | 463 | } |
471 | 464 | ||
472 | /* read the return status */ | 465 | /* read the return status */ |
473 | intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS, | 466 | if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS, |
474 | &status); | 467 | &status)) |
468 | return false; | ||
475 | 469 | ||
476 | intel_sdvo_debug_response(intel_sdvo, response, response_len, | 470 | intel_sdvo_debug_response(intel_sdvo, response, response_len, |
477 | status); | 471 | status); |
478 | if (status != SDVO_CMD_STATUS_PENDING) | 472 | if (status != SDVO_CMD_STATUS_PENDING) |
479 | return status; | 473 | break; |
480 | 474 | ||
481 | mdelay(50); | 475 | mdelay(50); |
482 | } | 476 | } |
483 | 477 | ||
484 | return status; | 478 | return status == SDVO_CMD_STATUS_SUCCESS; |
485 | } | 479 | } |
486 | 480 | ||
487 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | 481 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) |
@@ -553,23 +547,29 @@ static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, | |||
553 | return; | 547 | return; |
554 | } | 548 | } |
555 | 549 | ||
556 | static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo, bool target_0, bool target_1) | 550 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
557 | { | 551 | { |
558 | struct intel_sdvo_set_target_input_args targets = {0}; | 552 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) |
559 | u8 status; | 553 | return false; |
560 | |||
561 | if (target_0 && target_1) | ||
562 | return SDVO_CMD_STATUS_NOTSUPP; | ||
563 | 554 | ||
564 | if (target_1) | 555 | return intel_sdvo_read_response(intel_sdvo, NULL, 0); |
565 | targets.target_1 = 1; | 556 | } |
566 | 557 | ||
567 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_TARGET_INPUT, &targets, | 558 | static bool |
568 | sizeof(targets)); | 559 | intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len) |
560 | { | ||
561 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0)) | ||
562 | return false; | ||
569 | 563 | ||
570 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | 564 | return intel_sdvo_read_response(intel_sdvo, value, len); |
565 | } | ||
571 | 566 | ||
572 | return (status == SDVO_CMD_STATUS_SUCCESS); | 567 | static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo) |
568 | { | ||
569 | struct intel_sdvo_set_target_input_args targets = {0}; | ||
570 | return intel_sdvo_set_value(intel_sdvo, | ||
571 | SDVO_CMD_SET_TARGET_INPUT, | ||
572 | &targets, sizeof(targets)); | ||
573 | } | 573 | } |
574 | 574 | ||
575 | /** | 575 | /** |
@@ -581,11 +581,9 @@ static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo, bool targ | |||
581 | static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2) | 581 | static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2) |
582 | { | 582 | { |
583 | struct intel_sdvo_get_trained_inputs_response response; | 583 | struct intel_sdvo_get_trained_inputs_response response; |
584 | u8 status; | ||
585 | 584 | ||
586 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); | 585 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, |
587 | status = intel_sdvo_read_response(intel_sdvo, &response, sizeof(response)); | 586 | &response, sizeof(response))) |
588 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
589 | return false; | 587 | return false; |
590 | 588 | ||
591 | *input_1 = response.input0_trained; | 589 | *input_1 = response.input0_trained; |
@@ -596,18 +594,15 @@ static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *i | |||
596 | static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, | 594 | static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, |
597 | u16 outputs) | 595 | u16 outputs) |
598 | { | 596 | { |
599 | u8 status; | 597 | return intel_sdvo_set_value(intel_sdvo, |
600 | 598 | SDVO_CMD_SET_ACTIVE_OUTPUTS, | |
601 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, | 599 | &outputs, sizeof(outputs)); |
602 | sizeof(outputs)); | ||
603 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
604 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
605 | } | 600 | } |
606 | 601 | ||
607 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, | 602 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
608 | int mode) | 603 | int mode) |
609 | { | 604 | { |
610 | u8 status, state = SDVO_ENCODER_STATE_ON; | 605 | u8 state = SDVO_ENCODER_STATE_ON; |
611 | 606 | ||
612 | switch (mode) { | 607 | switch (mode) { |
613 | case DRM_MODE_DPMS_ON: | 608 | case DRM_MODE_DPMS_ON: |
@@ -624,11 +619,8 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, | |||
624 | break; | 619 | break; |
625 | } | 620 | } |
626 | 621 | ||
627 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, | 622 | return intel_sdvo_set_value(intel_sdvo, |
628 | sizeof(state)); | 623 | SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); |
629 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
630 | |||
631 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
632 | } | 624 | } |
633 | 625 | ||
634 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, | 626 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, |
@@ -636,51 +628,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo | |||
636 | int *clock_max) | 628 | int *clock_max) |
637 | { | 629 | { |
638 | struct intel_sdvo_pixel_clock_range clocks; | 630 | struct intel_sdvo_pixel_clock_range clocks; |
639 | u8 status; | ||
640 | |||
641 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
642 | NULL, 0); | ||
643 | 631 | ||
644 | status = intel_sdvo_read_response(intel_sdvo, &clocks, sizeof(clocks)); | 632 | if (!intel_sdvo_get_value(intel_sdvo, |
645 | 633 | SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | |
646 | if (status != SDVO_CMD_STATUS_SUCCESS) | 634 | &clocks, sizeof(clocks))) |
647 | return false; | 635 | return false; |
648 | 636 | ||
649 | /* Convert the values from units of 10 kHz to kHz. */ | 637 | /* Convert the values from units of 10 kHz to kHz. */ |
650 | *clock_min = clocks.min * 10; | 638 | *clock_min = clocks.min * 10; |
651 | *clock_max = clocks.max * 10; | 639 | *clock_max = clocks.max * 10; |
652 | |||
653 | return true; | 640 | return true; |
654 | } | 641 | } |
655 | 642 | ||
656 | static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo, | 643 | static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo, |
657 | u16 outputs) | 644 | u16 outputs) |
658 | { | 645 | { |
659 | u8 status; | 646 | return intel_sdvo_set_value(intel_sdvo, |
660 | 647 | SDVO_CMD_SET_TARGET_OUTPUT, | |
661 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, | 648 | &outputs, sizeof(outputs)); |
662 | sizeof(outputs)); | ||
663 | |||
664 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
665 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
666 | } | 649 | } |
667 | 650 | ||
668 | static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, | 651 | static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, |
669 | struct intel_sdvo_dtd *dtd) | 652 | struct intel_sdvo_dtd *dtd) |
670 | { | 653 | { |
671 | u8 status; | 654 | return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && |
672 | 655 | intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | |
673 | intel_sdvo_write_cmd(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)); | ||
674 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
675 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
676 | return false; | ||
677 | |||
678 | intel_sdvo_write_cmd(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | ||
679 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
680 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
681 | return false; | ||
682 | |||
683 | return true; | ||
684 | } | 656 | } |
685 | 657 | ||
686 | static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, | 658 | static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, |
@@ -704,7 +676,6 @@ intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, | |||
704 | uint16_t height) | 676 | uint16_t height) |
705 | { | 677 | { |
706 | struct intel_sdvo_preferred_input_timing_args args; | 678 | struct intel_sdvo_preferred_input_timing_args args; |
707 | uint8_t status; | ||
708 | 679 | ||
709 | memset(&args, 0, sizeof(args)); | 680 | memset(&args, 0, sizeof(args)); |
710 | args.clock = clock; | 681 | args.clock = clock; |
@@ -717,54 +688,27 @@ intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, | |||
717 | intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) | 688 | intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) |
718 | args.scaled = 1; | 689 | args.scaled = 1; |
719 | 690 | ||
720 | intel_sdvo_write_cmd(intel_sdvo, | 691 | return intel_sdvo_set_value(intel_sdvo, |
721 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 692 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
722 | &args, sizeof(args)); | 693 | &args, sizeof(args)); |
723 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
724 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
725 | return false; | ||
726 | |||
727 | return true; | ||
728 | } | 694 | } |
729 | 695 | ||
730 | static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo, | 696 | static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
731 | struct intel_sdvo_dtd *dtd) | 697 | struct intel_sdvo_dtd *dtd) |
732 | { | 698 | { |
733 | bool status; | 699 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, |
734 | 700 | &dtd->part1, sizeof(dtd->part1)) && | |
735 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, | 701 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, |
736 | NULL, 0); | 702 | &dtd->part2, sizeof(dtd->part2)); |
737 | |||
738 | status = intel_sdvo_read_response(intel_sdvo, &dtd->part1, | ||
739 | sizeof(dtd->part1)); | ||
740 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
741 | return false; | ||
742 | |||
743 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, | ||
744 | NULL, 0); | ||
745 | |||
746 | status = intel_sdvo_read_response(intel_sdvo, &dtd->part2, | ||
747 | sizeof(dtd->part2)); | ||
748 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
749 | return false; | ||
750 | |||
751 | return false; | ||
752 | } | 703 | } |
753 | 704 | ||
754 | static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val) | 705 | static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val) |
755 | { | 706 | { |
756 | u8 status; | 707 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); |
757 | |||
758 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); | ||
759 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
760 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
761 | return false; | ||
762 | |||
763 | return true; | ||
764 | } | 708 | } |
765 | 709 | ||
766 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | 710 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, |
767 | struct drm_display_mode *mode) | 711 | const struct drm_display_mode *mode) |
768 | { | 712 | { |
769 | uint16_t width, height; | 713 | uint16_t width, height; |
770 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; | 714 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
@@ -813,7 +757,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
813 | } | 757 | } |
814 | 758 | ||
815 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | 759 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, |
816 | struct intel_sdvo_dtd *dtd) | 760 | const struct intel_sdvo_dtd *dtd) |
817 | { | 761 | { |
818 | mode->hdisplay = dtd->part1.h_active; | 762 | mode->hdisplay = dtd->part1.h_active; |
819 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; | 763 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
@@ -848,38 +792,26 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | |||
848 | static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo, | 792 | static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo, |
849 | struct intel_sdvo_encode *encode) | 793 | struct intel_sdvo_encode *encode) |
850 | { | 794 | { |
851 | uint8_t status; | 795 | if (intel_sdvo_get_value(intel_sdvo, |
852 | 796 | SDVO_CMD_GET_SUPP_ENCODE, | |
853 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); | 797 | encode, sizeof(*encode))) |
854 | status = intel_sdvo_read_response(intel_sdvo, encode, sizeof(*encode)); | 798 | return true; |
855 | if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ | ||
856 | memset(encode, 0, sizeof(*encode)); | ||
857 | return false; | ||
858 | } | ||
859 | 799 | ||
860 | return true; | 800 | /* non-support means DVI */ |
801 | memset(encode, 0, sizeof(*encode)); | ||
802 | return false; | ||
861 | } | 803 | } |
862 | 804 | ||
863 | static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo, | 805 | static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo, |
864 | uint8_t mode) | 806 | uint8_t mode) |
865 | { | 807 | { |
866 | uint8_t status; | 808 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); |
867 | |||
868 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); | ||
869 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
870 | |||
871 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
872 | } | 809 | } |
873 | 810 | ||
874 | static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo, | 811 | static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo, |
875 | uint8_t mode) | 812 | uint8_t mode) |
876 | { | 813 | { |
877 | uint8_t status; | 814 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); |
878 | |||
879 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); | ||
880 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | ||
881 | |||
882 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
883 | } | 815 | } |
884 | 816 | ||
885 | #if 0 | 817 | #if 0 |
@@ -892,8 +824,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) | |||
892 | uint8_t buf[48]; | 824 | uint8_t buf[48]; |
893 | uint8_t *pos; | 825 | uint8_t *pos; |
894 | 826 | ||
895 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); | 827 | intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); |
896 | intel_sdvo_read_response(encoder, &av_split, 1); | ||
897 | 828 | ||
898 | for (i = 0; i <= av_split; i++) { | 829 | for (i = 0; i <= av_split; i++) { |
899 | set_buf_index[0] = i; set_buf_index[1] = 0; | 830 | set_buf_index[0] = i; set_buf_index[1] = 0; |
@@ -913,7 +844,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) | |||
913 | } | 844 | } |
914 | #endif | 845 | #endif |
915 | 846 | ||
916 | static void intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, | 847 | static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, |
917 | int index, | 848 | int index, |
918 | uint8_t *data, int8_t size, uint8_t tx_rate) | 849 | uint8_t *data, int8_t size, uint8_t tx_rate) |
919 | { | 850 | { |
@@ -922,15 +853,18 @@ static void intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, | |||
922 | set_buf_index[0] = index; | 853 | set_buf_index[0] = index; |
923 | set_buf_index[1] = 0; | 854 | set_buf_index[1] = 0; |
924 | 855 | ||
925 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, | 856 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, |
926 | set_buf_index, 2); | 857 | set_buf_index, 2)) |
858 | return false; | ||
927 | 859 | ||
928 | for (; size > 0; size -= 8) { | 860 | for (; size > 0; size -= 8) { |
929 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8); | 861 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8)) |
862 | return false; | ||
863 | |||
930 | data += 8; | 864 | data += 8; |
931 | } | 865 | } |
932 | 866 | ||
933 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); | 867 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); |
934 | } | 868 | } |
935 | 869 | ||
936 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) | 870 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) |
@@ -1005,7 +939,7 @@ struct dip_infoframe { | |||
1005 | } __attribute__ ((packed)) u; | 939 | } __attribute__ ((packed)) u; |
1006 | } __attribute__((packed)); | 940 | } __attribute__((packed)); |
1007 | 941 | ||
1008 | static void intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, | 942 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, |
1009 | struct drm_display_mode * mode) | 943 | struct drm_display_mode * mode) |
1010 | { | 944 | { |
1011 | struct dip_infoframe avi_if = { | 945 | struct dip_infoframe avi_if = { |
@@ -1016,17 +950,15 @@ static void intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, | |||
1016 | 950 | ||
1017 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, | 951 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, |
1018 | 4 + avi_if.len); | 952 | 4 + avi_if.len); |
1019 | intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if, | 953 | return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if, |
1020 | 4 + avi_if.len, | 954 | 4 + avi_if.len, |
1021 | SDVO_HBUF_TX_VSYNC); | 955 | SDVO_HBUF_TX_VSYNC); |
1022 | } | 956 | } |
1023 | 957 | ||
1024 | static void intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | 958 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
1025 | { | 959 | { |
1026 | |||
1027 | struct intel_sdvo_tv_format format; | 960 | struct intel_sdvo_tv_format format; |
1028 | uint32_t format_map, i; | 961 | uint32_t format_map, i; |
1029 | uint8_t status; | ||
1030 | 962 | ||
1031 | for (i = 0; i < TV_FORMAT_NUM; i++) | 963 | for (i = 0; i < TV_FORMAT_NUM; i++) |
1032 | if (tv_format_names[i] == intel_sdvo->tv_format_name) | 964 | if (tv_format_names[i] == intel_sdvo->tv_format_name) |
@@ -1034,113 +966,93 @@ static void intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) | |||
1034 | 966 | ||
1035 | format_map = 1 << i; | 967 | format_map = 1 << i; |
1036 | memset(&format, 0, sizeof(format)); | 968 | memset(&format, 0, sizeof(format)); |
1037 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 969 | memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); |
1038 | sizeof(format) : sizeof(format_map)); | ||
1039 | |||
1040 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_TV_FORMAT, &format, | ||
1041 | sizeof(format)); | ||
1042 | 970 | ||
1043 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | 971 | BUILD_BUG_ON(sizeof(format) != 6); |
1044 | if (status != SDVO_CMD_STATUS_SUCCESS) | 972 | return intel_sdvo_set_value(intel_sdvo, |
1045 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | 973 | SDVO_CMD_SET_TV_FORMAT, |
1046 | SDVO_NAME(intel_sdvo)); | 974 | &format, sizeof(format)); |
1047 | } | 975 | } |
1048 | 976 | ||
1049 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 977 | static bool |
1050 | struct drm_display_mode *mode, | 978 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
1051 | struct drm_display_mode *adjusted_mode) | 979 | struct drm_display_mode *mode) |
1052 | { | 980 | { |
1053 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 981 | struct intel_sdvo_dtd output_dtd; |
1054 | 982 | ||
1055 | if (intel_sdvo->is_tv) { | 983 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1056 | struct intel_sdvo_dtd output_dtd; | 984 | intel_sdvo->attached_output)) |
1057 | bool success; | 985 | return false; |
1058 | 986 | ||
1059 | /* We need to construct preferred input timings based on our | 987 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1060 | * output timings. To do that, we have to set the output | 988 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
1061 | * timings, even though this isn't really the right place in | 989 | return false; |
1062 | * the sequence to do it. Oh well. | ||
1063 | */ | ||
1064 | 990 | ||
991 | return true; | ||
992 | } | ||
993 | |||
994 | static bool | ||
995 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, | ||
996 | struct drm_display_mode *mode, | ||
997 | struct drm_display_mode *adjusted_mode) | ||
998 | { | ||
999 | struct intel_sdvo_dtd input_dtd; | ||
1065 | 1000 | ||
1066 | /* Set output timings */ | 1001 | /* Reset the input timing to the screen. Assume always input 0. */ |
1067 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1002 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1068 | intel_sdvo_set_target_output(intel_sdvo, | 1003 | return false; |
1069 | intel_sdvo->attached_output); | ||
1070 | intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); | ||
1071 | 1004 | ||
1072 | /* Set the input timing to the screen. Assume always input 0. */ | 1005 | if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, |
1073 | intel_sdvo_set_target_input(intel_sdvo, true, false); | 1006 | mode->clock / 10, |
1007 | mode->hdisplay, | ||
1008 | mode->vdisplay)) | ||
1009 | return false; | ||
1074 | 1010 | ||
1011 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, | ||
1012 | &input_dtd)) | ||
1013 | return false; | ||
1075 | 1014 | ||
1076 | success = intel_sdvo_create_preferred_input_timing(intel_sdvo, | 1015 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1077 | mode->clock / 10, | 1016 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; |
1078 | mode->hdisplay, | ||
1079 | mode->vdisplay); | ||
1080 | if (success) { | ||
1081 | struct intel_sdvo_dtd input_dtd; | ||
1082 | 1017 | ||
1083 | intel_sdvo_get_preferred_input_timing(intel_sdvo, | 1018 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
1084 | &input_dtd); | 1019 | mode->clock = adjusted_mode->clock; |
1085 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 1020 | return true; |
1086 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; | 1021 | } |
1087 | 1022 | ||
1088 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1023 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
1024 | struct drm_display_mode *mode, | ||
1025 | struct drm_display_mode *adjusted_mode) | ||
1026 | { | ||
1027 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1089 | 1028 | ||
1090 | mode->clock = adjusted_mode->clock; | 1029 | /* We need to construct preferred input timings based on our |
1030 | * output timings. To do that, we have to set the output | ||
1031 | * timings, even though this isn't really the right place in | ||
1032 | * the sequence to do it. Oh well. | ||
1033 | */ | ||
1034 | if (intel_sdvo->is_tv) { | ||
1035 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | ||
1036 | return false; | ||
1091 | 1037 | ||
1092 | adjusted_mode->clock *= | 1038 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) |
1093 | intel_sdvo_get_pixel_multiplier(mode); | ||
1094 | } else { | ||
1095 | return false; | 1039 | return false; |
1096 | } | ||
1097 | } else if (intel_sdvo->is_lvds) { | 1040 | } else if (intel_sdvo->is_lvds) { |
1098 | struct intel_sdvo_dtd output_dtd; | ||
1099 | bool success; | ||
1100 | |||
1101 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); | 1041 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); |
1102 | /* Set output timings */ | ||
1103 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1104 | intel_sdvo->sdvo_lvds_fixed_mode); | ||
1105 | |||
1106 | intel_sdvo_set_target_output(intel_sdvo, | ||
1107 | intel_sdvo->attached_output); | ||
1108 | intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); | ||
1109 | |||
1110 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1111 | intel_sdvo_set_target_input(intel_sdvo, true, false); | ||
1112 | |||
1113 | |||
1114 | success = intel_sdvo_create_preferred_input_timing( | ||
1115 | intel_sdvo, | ||
1116 | mode->clock / 10, | ||
1117 | mode->hdisplay, | ||
1118 | mode->vdisplay); | ||
1119 | |||
1120 | if (success) { | ||
1121 | struct intel_sdvo_dtd input_dtd; | ||
1122 | |||
1123 | intel_sdvo_get_preferred_input_timing(intel_sdvo, | ||
1124 | &input_dtd); | ||
1125 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1126 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1127 | 1042 | ||
1128 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1043 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1129 | 1044 | intel_sdvo->sdvo_lvds_fixed_mode)) | |
1130 | mode->clock = adjusted_mode->clock; | ||
1131 | |||
1132 | adjusted_mode->clock *= | ||
1133 | intel_sdvo_get_pixel_multiplier(mode); | ||
1134 | } else { | ||
1135 | return false; | 1045 | return false; |
1136 | } | ||
1137 | 1046 | ||
1138 | } else { | 1047 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) |
1139 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1048 | return false; |
1140 | * SDVO device will be told of the multiplier during mode_set. | ||
1141 | */ | ||
1142 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
1143 | } | 1049 | } |
1050 | |||
1051 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1052 | * SDVO device will be told of the multiplier during mode_set. | ||
1053 | */ | ||
1054 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
1055 | |||
1144 | return true; | 1056 | return true; |
1145 | } | 1057 | } |
1146 | 1058 | ||
@@ -1154,10 +1066,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1154 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1066 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1155 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1067 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1156 | u32 sdvox = 0; | 1068 | u32 sdvox = 0; |
1157 | int sdvo_pixel_multiply; | 1069 | int sdvo_pixel_multiply, rate; |
1158 | struct intel_sdvo_in_out_map in_out; | 1070 | struct intel_sdvo_in_out_map in_out; |
1159 | struct intel_sdvo_dtd input_dtd; | 1071 | struct intel_sdvo_dtd input_dtd; |
1160 | u8 status; | ||
1161 | 1072 | ||
1162 | if (!mode) | 1073 | if (!mode) |
1163 | return; | 1074 | return; |
@@ -1171,12 +1082,15 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1171 | in_out.in0 = intel_sdvo->attached_output; | 1082 | in_out.in0 = intel_sdvo->attached_output; |
1172 | in_out.in1 = 0; | 1083 | in_out.in1 = 0; |
1173 | 1084 | ||
1174 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_IN_OUT_MAP, | 1085 | if (!intel_sdvo_set_value(intel_sdvo, |
1175 | &in_out, sizeof(in_out)); | 1086 | SDVO_CMD_SET_IN_OUT_MAP, |
1176 | status = intel_sdvo_read_response(intel_sdvo, NULL, 0); | 1087 | &in_out, sizeof(in_out))) |
1088 | return; | ||
1177 | 1089 | ||
1178 | if (intel_sdvo->is_hdmi) { | 1090 | if (intel_sdvo->is_hdmi) { |
1179 | intel_sdvo_set_avi_infoframe(intel_sdvo, mode); | 1091 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) |
1092 | return; | ||
1093 | |||
1180 | sdvox |= SDVO_AUDIO_ENABLE; | 1094 | sdvox |= SDVO_AUDIO_ENABLE; |
1181 | } | 1095 | } |
1182 | 1096 | ||
@@ -1193,16 +1107,22 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1193 | */ | 1107 | */ |
1194 | if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) { | 1108 | if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) { |
1195 | /* Set the output timing to the screen */ | 1109 | /* Set the output timing to the screen */ |
1196 | intel_sdvo_set_target_output(intel_sdvo, | 1110 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1197 | intel_sdvo->attached_output); | 1111 | intel_sdvo->attached_output)) |
1198 | intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); | 1112 | return; |
1113 | |||
1114 | if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd)) | ||
1115 | return; | ||
1199 | } | 1116 | } |
1200 | 1117 | ||
1201 | /* Set the input timing to the screen. Assume always input 0. */ | 1118 | /* Set the input timing to the screen. Assume always input 0. */ |
1202 | intel_sdvo_set_target_input(intel_sdvo, true, false); | 1119 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1120 | return; | ||
1203 | 1121 | ||
1204 | if (intel_sdvo->is_tv) | 1122 | if (intel_sdvo->is_tv) { |
1205 | intel_sdvo_set_tv_format(intel_sdvo); | 1123 | if (!intel_sdvo_set_tv_format(intel_sdvo)) |
1124 | return; | ||
1125 | } | ||
1206 | 1126 | ||
1207 | /* We would like to use intel_sdvo_create_preferred_input_timing() to | 1127 | /* We would like to use intel_sdvo_create_preferred_input_timing() to |
1208 | * provide the device with a timing it can support, if it supports that | 1128 | * provide the device with a timing it can support, if it supports that |
@@ -1219,23 +1139,18 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1219 | intel_sdvo_set_input_timing(encoder, &input_dtd); | 1139 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
1220 | } | 1140 | } |
1221 | #else | 1141 | #else |
1222 | intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); | 1142 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
1143 | return; | ||
1223 | #endif | 1144 | #endif |
1224 | 1145 | ||
1225 | switch (intel_sdvo_get_pixel_multiplier(mode)) { | 1146 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); |
1226 | case 1: | 1147 | switch (sdvo_pixel_multiply) { |
1227 | intel_sdvo_set_clock_rate_mult(intel_sdvo, | 1148 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
1228 | SDVO_CLOCK_RATE_MULT_1X); | 1149 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
1229 | break; | 1150 | case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; |
1230 | case 2: | ||
1231 | intel_sdvo_set_clock_rate_mult(intel_sdvo, | ||
1232 | SDVO_CLOCK_RATE_MULT_2X); | ||
1233 | break; | ||
1234 | case 4: | ||
1235 | intel_sdvo_set_clock_rate_mult(intel_sdvo, | ||
1236 | SDVO_CLOCK_RATE_MULT_4X); | ||
1237 | break; | ||
1238 | } | 1151 | } |
1152 | if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate)) | ||
1153 | return; | ||
1239 | 1154 | ||
1240 | /* Set the SDVO control regs. */ | 1155 | /* Set the SDVO control regs. */ |
1241 | if (IS_I965G(dev)) { | 1156 | if (IS_I965G(dev)) { |
@@ -1259,7 +1174,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1259 | if (intel_crtc->pipe == 1) | 1174 | if (intel_crtc->pipe == 1) |
1260 | sdvox |= SDVO_PIPE_B_SELECT; | 1175 | sdvox |= SDVO_PIPE_B_SELECT; |
1261 | 1176 | ||
1262 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | ||
1263 | if (IS_I965G(dev)) { | 1177 | if (IS_I965G(dev)) { |
1264 | /* done in crtc_mode_set as the dpll_md reg must be written early */ | 1178 | /* done in crtc_mode_set as the dpll_md reg must be written early */ |
1265 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { | 1179 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
@@ -1302,10 +1216,7 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1302 | for (i = 0; i < 2; i++) | 1216 | for (i = 0; i < 2; i++) |
1303 | intel_wait_for_vblank(dev); | 1217 | intel_wait_for_vblank(dev); |
1304 | 1218 | ||
1305 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, | 1219 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); |
1306 | &input2); | ||
1307 | |||
1308 | |||
1309 | /* Warn if the device reported failure to sync. | 1220 | /* Warn if the device reported failure to sync. |
1310 | * A lot of SDVO devices fail to notify of sync, but it's | 1221 | * A lot of SDVO devices fail to notify of sync, but it's |
1311 | * a given it the status is a success, we succeeded. | 1222 | * a given it the status is a success, we succeeded. |
@@ -1353,14 +1264,7 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1353 | 1264 | ||
1354 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) | 1265 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) |
1355 | { | 1266 | { |
1356 | u8 status; | 1267 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps)); |
1357 | |||
1358 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); | ||
1359 | status = intel_sdvo_read_response(intel_sdvo, caps, sizeof(*caps)); | ||
1360 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1361 | return false; | ||
1362 | |||
1363 | return true; | ||
1364 | } | 1268 | } |
1365 | 1269 | ||
1366 | /* No use! */ | 1270 | /* No use! */ |
@@ -1403,13 +1307,8 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) | |||
1403 | 1307 | ||
1404 | intel_sdvo = to_intel_sdvo(connector); | 1308 | intel_sdvo = to_intel_sdvo(connector); |
1405 | 1309 | ||
1406 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | 1310 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
1407 | status = intel_sdvo_read_response(intel_sdvo, &response, 2); | 1311 | &response, 2) && response[0]; |
1408 | |||
1409 | if (response[0] !=0) | ||
1410 | return 1; | ||
1411 | |||
1412 | return 0; | ||
1413 | } | 1312 | } |
1414 | 1313 | ||
1415 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | 1314 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) |
@@ -1492,8 +1391,8 @@ static int | |||
1492 | intel_analog_is_connected(struct drm_device *dev) | 1391 | intel_analog_is_connected(struct drm_device *dev) |
1493 | { | 1392 | { |
1494 | struct drm_connector *analog_connector; | 1393 | struct drm_connector *analog_connector; |
1495 | analog_connector = intel_find_analog_connector(dev); | ||
1496 | 1394 | ||
1395 | analog_connector = intel_find_analog_connector(dev); | ||
1497 | if (!analog_connector) | 1396 | if (!analog_connector) |
1498 | return false; | 1397 | return false; |
1499 | 1398 | ||
@@ -1569,25 +1468,23 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1569 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1468 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1570 | { | 1469 | { |
1571 | uint16_t response; | 1470 | uint16_t response; |
1572 | u8 status; | ||
1573 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1471 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1574 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1472 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1575 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1473 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1576 | enum drm_connector_status ret; | 1474 | enum drm_connector_status ret; |
1577 | 1475 | ||
1578 | intel_sdvo_write_cmd(intel_sdvo, | 1476 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1579 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1477 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
1478 | return connector_status_unknown; | ||
1580 | if (intel_sdvo->is_tv) { | 1479 | if (intel_sdvo->is_tv) { |
1581 | /* add 30ms delay when the output type is SDVO-TV */ | 1480 | /* add 30ms delay when the output type is SDVO-TV */ |
1582 | mdelay(30); | 1481 | mdelay(30); |
1583 | } | 1482 | } |
1584 | status = intel_sdvo_read_response(intel_sdvo, &response, 2); | 1483 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1484 | return connector_status_unknown; | ||
1585 | 1485 | ||
1586 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1486 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
1587 | 1487 | ||
1588 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1589 | return connector_status_unknown; | ||
1590 | |||
1591 | if (response == 0) | 1488 | if (response == 0) |
1592 | return connector_status_disconnected; | 1489 | return connector_status_disconnected; |
1593 | 1490 | ||
@@ -1713,8 +1610,6 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1713 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1610 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1714 | uint32_t reply = 0, format_map = 0; | 1611 | uint32_t reply = 0, format_map = 0; |
1715 | int i; | 1612 | int i; |
1716 | uint8_t status; | ||
1717 | |||
1718 | 1613 | ||
1719 | /* Read the list of supported input resolutions for the selected TV | 1614 | /* Read the list of supported input resolutions for the selected TV |
1720 | * format. | 1615 | * format. |
@@ -1725,23 +1620,23 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1725 | 1620 | ||
1726 | format_map = (1 << i); | 1621 | format_map = (1 << i); |
1727 | memcpy(&tv_res, &format_map, | 1622 | memcpy(&tv_res, &format_map, |
1728 | sizeof(struct intel_sdvo_sdtv_resolution_request) > | 1623 | min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); |
1729 | sizeof(format_map) ? sizeof(format_map) : | ||
1730 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | ||
1731 | 1624 | ||
1732 | intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output); | 1625 | if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output)) |
1626 | return; | ||
1733 | 1627 | ||
1734 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1628 | BUILD_BUG_ON(sizeof(tv_res) != 3); |
1735 | &tv_res, sizeof(tv_res)); | 1629 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
1736 | status = intel_sdvo_read_response(intel_sdvo, &reply, 3); | 1630 | &tv_res, sizeof(tv_res))) |
1737 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1631 | return; |
1632 | if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) | ||
1738 | return; | 1633 | return; |
1739 | 1634 | ||
1740 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) | 1635 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) |
1741 | if (reply & (1 << i)) { | 1636 | if (reply & (1 << i)) { |
1742 | struct drm_display_mode *nmode; | 1637 | struct drm_display_mode *nmode; |
1743 | nmode = drm_mode_duplicate(connector->dev, | 1638 | nmode = drm_mode_duplicate(connector->dev, |
1744 | &sdvo_tv_modes[i]); | 1639 | &sdvo_tv_modes[i]); |
1745 | if (nmode) | 1640 | if (nmode) |
1746 | drm_mode_probed_add(connector, nmode); | 1641 | drm_mode_probed_add(connector, nmode); |
1747 | } | 1642 | } |
@@ -1798,9 +1693,7 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1798 | else | 1693 | else |
1799 | intel_sdvo_get_ddc_modes(connector); | 1694 | intel_sdvo_get_ddc_modes(connector); |
1800 | 1695 | ||
1801 | if (list_empty(&connector->probed_modes)) | 1696 | return !list_empty(&connector->probed_modes); |
1802 | return 0; | ||
1803 | return 1; | ||
1804 | } | 1697 | } |
1805 | 1698 | ||
1806 | static | 1699 | static |
@@ -1831,7 +1724,7 @@ void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | |||
1831 | if (intel_sdvo_connector->hue_property) | 1724 | if (intel_sdvo_connector->hue_property) |
1832 | drm_property_destroy(dev, intel_sdvo_connector->hue_property); | 1725 | drm_property_destroy(dev, intel_sdvo_connector->hue_property); |
1833 | } | 1726 | } |
1834 | if (IS_TV(intel_sdvo_connector) || IS_LVDS(intel_sdvo_connector)) { | 1727 | if (IS_TV_OR_LVDS(intel_sdvo_connector)) { |
1835 | if (intel_sdvo_connector->brightness_property) | 1728 | if (intel_sdvo_connector->brightness_property) |
1836 | drm_property_destroy(dev, | 1729 | drm_property_destroy(dev, |
1837 | intel_sdvo_connector->brightness_property); | 1730 | intel_sdvo_connector->brightness_property); |
@@ -1862,36 +1755,33 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1862 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 1755 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1863 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1756 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1864 | struct drm_crtc *crtc = encoder->crtc; | 1757 | struct drm_crtc *crtc = encoder->crtc; |
1865 | int ret = 0; | ||
1866 | bool changed = false; | 1758 | bool changed = false; |
1867 | uint8_t cmd, status; | ||
1868 | uint16_t temp_value; | 1759 | uint16_t temp_value; |
1760 | uint8_t cmd; | ||
1761 | int ret; | ||
1869 | 1762 | ||
1870 | ret = drm_connector_property_set_value(connector, property, val); | 1763 | ret = drm_connector_property_set_value(connector, property, val); |
1871 | if (ret < 0) | 1764 | if (ret) |
1872 | goto out; | 1765 | return ret; |
1873 | 1766 | ||
1874 | if (property == intel_sdvo_connector->tv_format_property) { | 1767 | if (property == intel_sdvo_connector->tv_format_property) { |
1875 | if (val >= TV_FORMAT_NUM) { | 1768 | if (val >= TV_FORMAT_NUM) |
1876 | ret = -EINVAL; | 1769 | return -EINVAL; |
1877 | goto out; | 1770 | |
1878 | } | ||
1879 | if (intel_sdvo->tv_format_name == | 1771 | if (intel_sdvo->tv_format_name == |
1880 | intel_sdvo_connector->tv_format_supported[val]) | 1772 | intel_sdvo_connector->tv_format_supported[val]) |
1881 | goto out; | 1773 | return 0; |
1882 | 1774 | ||
1883 | intel_sdvo->tv_format_name = intel_sdvo_connector->tv_format_supported[val]; | 1775 | intel_sdvo->tv_format_name = intel_sdvo_connector->tv_format_supported[val]; |
1884 | changed = true; | 1776 | changed = true; |
1885 | } | 1777 | } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { |
1886 | |||
1887 | if (IS_TV(intel_sdvo_connector) || IS_LVDS(intel_sdvo_connector)) { | ||
1888 | cmd = 0; | 1778 | cmd = 0; |
1889 | temp_value = val; | 1779 | temp_value = val; |
1890 | if (intel_sdvo_connector->left_property == property) { | 1780 | if (intel_sdvo_connector->left_property == property) { |
1891 | drm_connector_property_set_value(connector, | 1781 | drm_connector_property_set_value(connector, |
1892 | intel_sdvo_connector->right_property, val); | 1782 | intel_sdvo_connector->right_property, val); |
1893 | if (intel_sdvo_connector->left_margin == temp_value) | 1783 | if (intel_sdvo_connector->left_margin == temp_value) |
1894 | goto out; | 1784 | return 0; |
1895 | 1785 | ||
1896 | intel_sdvo_connector->left_margin = temp_value; | 1786 | intel_sdvo_connector->left_margin = temp_value; |
1897 | intel_sdvo_connector->right_margin = temp_value; | 1787 | intel_sdvo_connector->right_margin = temp_value; |
@@ -1902,7 +1792,7 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1902 | drm_connector_property_set_value(connector, | 1792 | drm_connector_property_set_value(connector, |
1903 | intel_sdvo_connector->left_property, val); | 1793 | intel_sdvo_connector->left_property, val); |
1904 | if (intel_sdvo_connector->right_margin == temp_value) | 1794 | if (intel_sdvo_connector->right_margin == temp_value) |
1905 | goto out; | 1795 | return 0; |
1906 | 1796 | ||
1907 | intel_sdvo_connector->left_margin = temp_value; | 1797 | intel_sdvo_connector->left_margin = temp_value; |
1908 | intel_sdvo_connector->right_margin = temp_value; | 1798 | intel_sdvo_connector->right_margin = temp_value; |
@@ -1913,7 +1803,7 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1913 | drm_connector_property_set_value(connector, | 1803 | drm_connector_property_set_value(connector, |
1914 | intel_sdvo_connector->bottom_property, val); | 1804 | intel_sdvo_connector->bottom_property, val); |
1915 | if (intel_sdvo_connector->top_margin == temp_value) | 1805 | if (intel_sdvo_connector->top_margin == temp_value) |
1916 | goto out; | 1806 | return 0; |
1917 | 1807 | ||
1918 | intel_sdvo_connector->top_margin = temp_value; | 1808 | intel_sdvo_connector->top_margin = temp_value; |
1919 | intel_sdvo_connector->bottom_margin = temp_value; | 1809 | intel_sdvo_connector->bottom_margin = temp_value; |
@@ -1924,7 +1814,8 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1924 | drm_connector_property_set_value(connector, | 1814 | drm_connector_property_set_value(connector, |
1925 | intel_sdvo_connector->top_property, val); | 1815 | intel_sdvo_connector->top_property, val); |
1926 | if (intel_sdvo_connector->bottom_margin == temp_value) | 1816 | if (intel_sdvo_connector->bottom_margin == temp_value) |
1927 | goto out; | 1817 | return 0; |
1818 | |||
1928 | intel_sdvo_connector->top_margin = temp_value; | 1819 | intel_sdvo_connector->top_margin = temp_value; |
1929 | intel_sdvo_connector->bottom_margin = temp_value; | 1820 | intel_sdvo_connector->bottom_margin = temp_value; |
1930 | temp_value = intel_sdvo_connector->max_vscan - | 1821 | temp_value = intel_sdvo_connector->max_vscan - |
@@ -1932,57 +1823,52 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1932 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1823 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
1933 | } else if (intel_sdvo_connector->hpos_property == property) { | 1824 | } else if (intel_sdvo_connector->hpos_property == property) { |
1934 | if (intel_sdvo_connector->cur_hpos == temp_value) | 1825 | if (intel_sdvo_connector->cur_hpos == temp_value) |
1935 | goto out; | 1826 | return 0; |
1936 | 1827 | ||
1937 | cmd = SDVO_CMD_SET_POSITION_H; | 1828 | cmd = SDVO_CMD_SET_POSITION_H; |
1938 | intel_sdvo_connector->cur_hpos = temp_value; | 1829 | intel_sdvo_connector->cur_hpos = temp_value; |
1939 | } else if (intel_sdvo_connector->vpos_property == property) { | 1830 | } else if (intel_sdvo_connector->vpos_property == property) { |
1940 | if (intel_sdvo_connector->cur_vpos == temp_value) | 1831 | if (intel_sdvo_connector->cur_vpos == temp_value) |
1941 | goto out; | 1832 | return 0; |
1942 | 1833 | ||
1943 | cmd = SDVO_CMD_SET_POSITION_V; | 1834 | cmd = SDVO_CMD_SET_POSITION_V; |
1944 | intel_sdvo_connector->cur_vpos = temp_value; | 1835 | intel_sdvo_connector->cur_vpos = temp_value; |
1945 | } else if (intel_sdvo_connector->saturation_property == property) { | 1836 | } else if (intel_sdvo_connector->saturation_property == property) { |
1946 | if (intel_sdvo_connector->cur_saturation == temp_value) | 1837 | if (intel_sdvo_connector->cur_saturation == temp_value) |
1947 | goto out; | 1838 | return 0; |
1948 | 1839 | ||
1949 | cmd = SDVO_CMD_SET_SATURATION; | 1840 | cmd = SDVO_CMD_SET_SATURATION; |
1950 | intel_sdvo_connector->cur_saturation = temp_value; | 1841 | intel_sdvo_connector->cur_saturation = temp_value; |
1951 | } else if (intel_sdvo_connector->contrast_property == property) { | 1842 | } else if (intel_sdvo_connector->contrast_property == property) { |
1952 | if (intel_sdvo_connector->cur_contrast == temp_value) | 1843 | if (intel_sdvo_connector->cur_contrast == temp_value) |
1953 | goto out; | 1844 | return 0; |
1954 | 1845 | ||
1955 | cmd = SDVO_CMD_SET_CONTRAST; | 1846 | cmd = SDVO_CMD_SET_CONTRAST; |
1956 | intel_sdvo_connector->cur_contrast = temp_value; | 1847 | intel_sdvo_connector->cur_contrast = temp_value; |
1957 | } else if (intel_sdvo_connector->hue_property == property) { | 1848 | } else if (intel_sdvo_connector->hue_property == property) { |
1958 | if (intel_sdvo_connector->cur_hue == temp_value) | 1849 | if (intel_sdvo_connector->cur_hue == temp_value) |
1959 | goto out; | 1850 | return 0; |
1960 | 1851 | ||
1961 | cmd = SDVO_CMD_SET_HUE; | 1852 | cmd = SDVO_CMD_SET_HUE; |
1962 | intel_sdvo_connector->cur_hue = temp_value; | 1853 | intel_sdvo_connector->cur_hue = temp_value; |
1963 | } else if (intel_sdvo_connector->brightness_property == property) { | 1854 | } else if (intel_sdvo_connector->brightness_property == property) { |
1964 | if (intel_sdvo_connector->cur_brightness == temp_value) | 1855 | if (intel_sdvo_connector->cur_brightness == temp_value) |
1965 | goto out; | 1856 | return 0; |
1966 | 1857 | ||
1967 | cmd = SDVO_CMD_SET_BRIGHTNESS; | 1858 | cmd = SDVO_CMD_SET_BRIGHTNESS; |
1968 | intel_sdvo_connector->cur_brightness = temp_value; | 1859 | intel_sdvo_connector->cur_brightness = temp_value; |
1969 | } | 1860 | } |
1970 | if (cmd) { | 1861 | if (cmd) { |
1971 | intel_sdvo_write_cmd(intel_sdvo, cmd, &temp_value, 2); | 1862 | if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2)) |
1972 | status = intel_sdvo_read_response(intel_sdvo, | ||
1973 | NULL, 0); | ||
1974 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
1975 | DRM_DEBUG_KMS("Incorrect SDVO command \n"); | ||
1976 | return -EINVAL; | 1863 | return -EINVAL; |
1977 | } | 1864 | |
1978 | changed = true; | 1865 | changed = true; |
1979 | } | 1866 | } |
1980 | } | 1867 | } |
1981 | if (changed && crtc) | 1868 | if (changed && crtc) |
1982 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1869 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, |
1983 | crtc->y, crtc->fb); | 1870 | crtc->y, crtc->fb); |
1984 | out: | 1871 | return 0; |
1985 | return ret; | ||
1986 | } | 1872 | } |
1987 | 1873 | ||
1988 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1874 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
@@ -2050,18 +1936,10 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
2050 | static bool | 1936 | static bool |
2051 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) | 1937 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) |
2052 | { | 1938 | { |
2053 | uint8_t status; | 1939 | return intel_sdvo_set_target_output(intel_sdvo, |
2054 | 1940 | device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1) && | |
2055 | if (device == 0) | 1941 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, |
2056 | intel_sdvo_set_target_output(intel_sdvo, SDVO_OUTPUT_TMDS0); | 1942 | &intel_sdvo->is_hdmi, 1); |
2057 | else | ||
2058 | intel_sdvo_set_target_output(intel_sdvo, SDVO_OUTPUT_TMDS1); | ||
2059 | |||
2060 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ENCODE, NULL, 0); | ||
2061 | status = intel_sdvo_read_response(intel_sdvo, &intel_sdvo->is_hdmi, 1); | ||
2062 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2063 | return false; | ||
2064 | return true; | ||
2065 | } | 1943 | } |
2066 | 1944 | ||
2067 | static struct intel_sdvo * | 1945 | static struct intel_sdvo * |
@@ -2076,7 +1954,7 @@ intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan) | |||
2076 | return intel_sdvo; | 1954 | return intel_sdvo; |
2077 | } | 1955 | } |
2078 | 1956 | ||
2079 | return NULL;; | 1957 | return NULL; |
2080 | } | 1958 | } |
2081 | 1959 | ||
2082 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | 1960 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, |
@@ -2141,8 +2019,8 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2141 | } | 2019 | } |
2142 | 2020 | ||
2143 | static void | 2021 | static void |
2144 | intel_sdvo_connector_create (struct drm_encoder *encoder, | 2022 | intel_sdvo_connector_init(struct drm_encoder *encoder, |
2145 | struct drm_connector *connector) | 2023 | struct drm_connector *connector) |
2146 | { | 2024 | { |
2147 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, | 2025 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, |
2148 | connector->connector_type); | 2026 | connector->connector_type); |
@@ -2195,7 +2073,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2195 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2073 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2196 | (1 << INTEL_ANALOG_CLONE_BIT)); | 2074 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2197 | 2075 | ||
2198 | intel_sdvo_connector_create(encoder, connector); | 2076 | intel_sdvo_connector_init(encoder, connector); |
2199 | 2077 | ||
2200 | return true; | 2078 | return true; |
2201 | } | 2079 | } |
@@ -2224,13 +2102,19 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) | |||
2224 | intel_sdvo->base.needs_tv_clock = true; | 2102 | intel_sdvo->base.needs_tv_clock = true; |
2225 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2103 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
2226 | 2104 | ||
2227 | intel_sdvo_connector_create(encoder, connector); | 2105 | intel_sdvo_connector_init(encoder, connector); |
2228 | 2106 | ||
2229 | intel_sdvo_tv_create_property(connector, type); | 2107 | if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) |
2108 | goto err; | ||
2230 | 2109 | ||
2231 | intel_sdvo_create_enhance_property(connector); | 2110 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2111 | goto err; | ||
2232 | 2112 | ||
2233 | return true; | 2113 | return true; |
2114 | |||
2115 | err: | ||
2116 | kfree(intel_sdvo_connector); | ||
2117 | return false; | ||
2234 | } | 2118 | } |
2235 | 2119 | ||
2236 | static bool | 2120 | static bool |
@@ -2262,7 +2146,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) | |||
2262 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2146 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2263 | (1 << INTEL_ANALOG_CLONE_BIT)); | 2147 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2264 | 2148 | ||
2265 | intel_sdvo_connector_create(encoder, connector); | 2149 | intel_sdvo_connector_init(encoder, connector); |
2266 | return true; | 2150 | return true; |
2267 | } | 2151 | } |
2268 | 2152 | ||
@@ -2296,9 +2180,15 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) | |||
2296 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | | 2180 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | |
2297 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); | 2181 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); |
2298 | 2182 | ||
2299 | intel_sdvo_connector_create(encoder, connector); | 2183 | intel_sdvo_connector_init(encoder, connector); |
2300 | intel_sdvo_create_enhance_property(connector); | 2184 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2301 | return true; | 2185 | goto err; |
2186 | |||
2187 | return true; | ||
2188 | |||
2189 | err: | ||
2190 | kfree(intel_sdvo_connector); | ||
2191 | return false; | ||
2302 | } | 2192 | } |
2303 | 2193 | ||
2304 | static bool | 2194 | static bool |
@@ -2358,29 +2248,26 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) | |||
2358 | return true; | 2248 | return true; |
2359 | } | 2249 | } |
2360 | 2250 | ||
2361 | static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type) | 2251 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
2252 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
2253 | int type) | ||
2362 | { | 2254 | { |
2363 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2255 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2364 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
2365 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | ||
2366 | struct intel_sdvo_tv_format format; | 2256 | struct intel_sdvo_tv_format format; |
2367 | uint32_t format_map, i; | 2257 | uint32_t format_map, i; |
2368 | uint8_t status; | ||
2369 | 2258 | ||
2370 | intel_sdvo_set_target_output(intel_sdvo, type); | 2259 | if (!intel_sdvo_set_target_output(intel_sdvo, type)) |
2260 | return false; | ||
2371 | 2261 | ||
2372 | intel_sdvo_write_cmd(intel_sdvo, | 2262 | if (!intel_sdvo_get_value(intel_sdvo, |
2373 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2263 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, |
2374 | status = intel_sdvo_read_response(intel_sdvo, | 2264 | &format, sizeof(format))) |
2375 | &format, sizeof(format)); | 2265 | return false; |
2376 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2377 | return; | ||
2378 | 2266 | ||
2379 | memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? | 2267 | memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); |
2380 | sizeof(format_map) : sizeof(format)); | ||
2381 | 2268 | ||
2382 | if (format_map == 0) | 2269 | if (format_map == 0) |
2383 | return; | 2270 | return false; |
2384 | 2271 | ||
2385 | intel_sdvo_connector->format_supported_num = 0; | 2272 | intel_sdvo_connector->format_supported_num = 0; |
2386 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | 2273 | for (i = 0 ; i < TV_FORMAT_NUM; i++) |
@@ -2392,9 +2279,8 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector, int t | |||
2392 | 2279 | ||
2393 | 2280 | ||
2394 | intel_sdvo_connector->tv_format_property = | 2281 | intel_sdvo_connector->tv_format_property = |
2395 | drm_property_create( | 2282 | drm_property_create(dev, DRM_MODE_PROP_ENUM, |
2396 | connector->dev, DRM_MODE_PROP_ENUM, | 2283 | "mode", intel_sdvo_connector->format_supported_num); |
2397 | "mode", intel_sdvo_connector->format_supported_num); | ||
2398 | 2284 | ||
2399 | for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) | 2285 | for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) |
2400 | drm_property_add_enum( | 2286 | drm_property_add_enum( |
@@ -2402,56 +2288,45 @@ static void intel_sdvo_tv_create_property(struct drm_connector *connector, int t | |||
2402 | i, intel_sdvo_connector->tv_format_supported[i]); | 2288 | i, intel_sdvo_connector->tv_format_supported[i]); |
2403 | 2289 | ||
2404 | intel_sdvo->tv_format_name = intel_sdvo_connector->tv_format_supported[0]; | 2290 | intel_sdvo->tv_format_name = intel_sdvo_connector->tv_format_supported[0]; |
2405 | drm_connector_attach_property( | 2291 | drm_connector_attach_property(&intel_sdvo_connector->base.base, |
2406 | connector, intel_sdvo_connector->tv_format_property, 0); | 2292 | intel_sdvo_connector->tv_format_property, 0); |
2293 | return true; | ||
2407 | 2294 | ||
2408 | } | 2295 | } |
2409 | 2296 | ||
2410 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2297 | static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, |
2298 | struct intel_sdvo_connector *intel_sdvo_connector) | ||
2411 | { | 2299 | { |
2412 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2300 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2413 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | 2301 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
2414 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | ||
2415 | struct intel_sdvo_enhancements_reply sdvo_data; | 2302 | struct intel_sdvo_enhancements_reply sdvo_data; |
2416 | struct drm_device *dev = connector->dev; | ||
2417 | uint8_t status; | ||
2418 | uint16_t response, data_value[2]; | 2303 | uint16_t response, data_value[2]; |
2419 | 2304 | ||
2420 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2305 | if (!intel_sdvo_get_value(intel_sdvo, |
2421 | NULL, 0); | 2306 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
2422 | status = intel_sdvo_read_response(intel_sdvo, &sdvo_data, | 2307 | &sdvo_data, sizeof(sdvo_data))) |
2423 | sizeof(sdvo_data)); | 2308 | return false; |
2424 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2309 | |
2425 | DRM_DEBUG_KMS(" incorrect response is returned\n"); | ||
2426 | return; | ||
2427 | } | ||
2428 | response = *((uint16_t *)&sdvo_data); | 2310 | response = *((uint16_t *)&sdvo_data); |
2429 | if (!response) { | 2311 | if (!response) { |
2430 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2312 | DRM_DEBUG_KMS("No enhancement is supported\n"); |
2431 | return; | 2313 | return true; |
2432 | } | 2314 | } |
2433 | if (IS_TV(intel_sdvo_connector)) { | 2315 | if (IS_TV(intel_sdvo_connector)) { |
2434 | /* when horizontal overscan is supported, Add the left/right | 2316 | /* when horizontal overscan is supported, Add the left/right |
2435 | * property | 2317 | * property |
2436 | */ | 2318 | */ |
2437 | if (sdvo_data.overscan_h) { | 2319 | if (sdvo_data.overscan_h) { |
2438 | intel_sdvo_write_cmd(intel_sdvo, | 2320 | if (!intel_sdvo_get_value(intel_sdvo, |
2439 | SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); | 2321 | SDVO_CMD_GET_MAX_OVERSCAN_H, |
2440 | status = intel_sdvo_read_response(intel_sdvo, | 2322 | &data_value, 4)) |
2441 | &data_value, 4); | 2323 | return false; |
2442 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2324 | |
2443 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2325 | if (!intel_sdvo_get_value(intel_sdvo, |
2444 | "h_overscan\n"); | 2326 | SDVO_CMD_GET_OVERSCAN_H, |
2445 | return; | 2327 | &response, 2)) |
2446 | } | 2328 | return false; |
2447 | intel_sdvo_write_cmd(intel_sdvo, | 2329 | |
2448 | SDVO_CMD_GET_OVERSCAN_H, NULL, 0); | ||
2449 | status = intel_sdvo_read_response(intel_sdvo, | ||
2450 | &response, 2); | ||
2451 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2452 | DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); | ||
2453 | return; | ||
2454 | } | ||
2455 | intel_sdvo_connector->max_hscan = data_value[0]; | 2330 | intel_sdvo_connector->max_hscan = data_value[0]; |
2456 | intel_sdvo_connector->left_margin = data_value[0] - response; | 2331 | intel_sdvo_connector->left_margin = data_value[0] - response; |
2457 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; | 2332 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; |
@@ -2476,23 +2351,16 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2476 | data_value[0], data_value[1], response); | 2351 | data_value[0], data_value[1], response); |
2477 | } | 2352 | } |
2478 | if (sdvo_data.overscan_v) { | 2353 | if (sdvo_data.overscan_v) { |
2479 | intel_sdvo_write_cmd(intel_sdvo, | 2354 | if (!intel_sdvo_get_value(intel_sdvo, |
2480 | SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); | 2355 | SDVO_CMD_GET_MAX_OVERSCAN_V, |
2481 | status = intel_sdvo_read_response(intel_sdvo, | 2356 | &data_value, 4)) |
2482 | &data_value, 4); | 2357 | return false; |
2483 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2358 | |
2484 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2359 | if (!intel_sdvo_get_value(intel_sdvo, |
2485 | "v_overscan\n"); | 2360 | SDVO_CMD_GET_OVERSCAN_V, |
2486 | return; | 2361 | &response, 2)) |
2487 | } | 2362 | return false; |
2488 | intel_sdvo_write_cmd(intel_sdvo, | 2363 | |
2489 | SDVO_CMD_GET_OVERSCAN_V, NULL, 0); | ||
2490 | status = intel_sdvo_read_response(intel_sdvo, | ||
2491 | &response, 2); | ||
2492 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2493 | DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); | ||
2494 | return; | ||
2495 | } | ||
2496 | intel_sdvo_connector->max_vscan = data_value[0]; | 2364 | intel_sdvo_connector->max_vscan = data_value[0]; |
2497 | intel_sdvo_connector->top_margin = data_value[0] - response; | 2365 | intel_sdvo_connector->top_margin = data_value[0] - response; |
2498 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; | 2366 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; |
@@ -2517,22 +2385,16 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2517 | data_value[0], data_value[1], response); | 2385 | data_value[0], data_value[1], response); |
2518 | } | 2386 | } |
2519 | if (sdvo_data.position_h) { | 2387 | if (sdvo_data.position_h) { |
2520 | intel_sdvo_write_cmd(intel_sdvo, | 2388 | if (!intel_sdvo_get_value(intel_sdvo, |
2521 | SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); | 2389 | SDVO_CMD_GET_MAX_POSITION_H, |
2522 | status = intel_sdvo_read_response(intel_sdvo, | 2390 | &data_value, 4)) |
2523 | &data_value, 4); | 2391 | return false; |
2524 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2392 | |
2525 | DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); | 2393 | if (!intel_sdvo_get_value(intel_sdvo, |
2526 | return; | 2394 | SDVO_CMD_GET_POSITION_H, |
2527 | } | 2395 | &response, 2)) |
2528 | intel_sdvo_write_cmd(intel_sdvo, | 2396 | return false; |
2529 | SDVO_CMD_GET_POSITION_H, NULL, 0); | 2397 | |
2530 | status = intel_sdvo_read_response(intel_sdvo, | ||
2531 | &response, 2); | ||
2532 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2533 | DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); | ||
2534 | return; | ||
2535 | } | ||
2536 | intel_sdvo_connector->max_hpos = data_value[0]; | 2398 | intel_sdvo_connector->max_hpos = data_value[0]; |
2537 | intel_sdvo_connector->cur_hpos = response; | 2399 | intel_sdvo_connector->cur_hpos = response; |
2538 | intel_sdvo_connector->hpos_property = | 2400 | intel_sdvo_connector->hpos_property = |
@@ -2548,22 +2410,16 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2548 | data_value[0], data_value[1], response); | 2410 | data_value[0], data_value[1], response); |
2549 | } | 2411 | } |
2550 | if (sdvo_data.position_v) { | 2412 | if (sdvo_data.position_v) { |
2551 | intel_sdvo_write_cmd(intel_sdvo, | 2413 | if (!intel_sdvo_get_value(intel_sdvo, |
2552 | SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); | 2414 | SDVO_CMD_GET_MAX_POSITION_V, |
2553 | status = intel_sdvo_read_response(intel_sdvo, | 2415 | &data_value, 4)) |
2554 | &data_value, 4); | 2416 | return false; |
2555 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2417 | |
2556 | DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); | 2418 | if (!intel_sdvo_get_value(intel_sdvo, |
2557 | return; | 2419 | SDVO_CMD_GET_POSITION_V, |
2558 | } | 2420 | &response, 2)) |
2559 | intel_sdvo_write_cmd(intel_sdvo, | 2421 | return false; |
2560 | SDVO_CMD_GET_POSITION_V, NULL, 0); | 2422 | |
2561 | status = intel_sdvo_read_response(intel_sdvo, | ||
2562 | &response, 2); | ||
2563 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2564 | DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); | ||
2565 | return; | ||
2566 | } | ||
2567 | intel_sdvo_connector->max_vpos = data_value[0]; | 2423 | intel_sdvo_connector->max_vpos = data_value[0]; |
2568 | intel_sdvo_connector->cur_vpos = response; | 2424 | intel_sdvo_connector->cur_vpos = response; |
2569 | intel_sdvo_connector->vpos_property = | 2425 | intel_sdvo_connector->vpos_property = |
@@ -2579,22 +2435,16 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2579 | data_value[0], data_value[1], response); | 2435 | data_value[0], data_value[1], response); |
2580 | } | 2436 | } |
2581 | if (sdvo_data.saturation) { | 2437 | if (sdvo_data.saturation) { |
2582 | intel_sdvo_write_cmd(intel_sdvo, | 2438 | if (!intel_sdvo_get_value(intel_sdvo, |
2583 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | 2439 | SDVO_CMD_GET_MAX_SATURATION, |
2584 | status = intel_sdvo_read_response(intel_sdvo, | 2440 | &data_value, 4)) |
2585 | &data_value, 4); | 2441 | return false; |
2586 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2442 | |
2587 | DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); | 2443 | if (!intel_sdvo_get_value(intel_sdvo, |
2588 | return; | 2444 | SDVO_CMD_GET_SATURATION, |
2589 | } | 2445 | &response, 2)) |
2590 | intel_sdvo_write_cmd(intel_sdvo, | 2446 | return false; |
2591 | SDVO_CMD_GET_SATURATION, NULL, 0); | 2447 | |
2592 | status = intel_sdvo_read_response(intel_sdvo, | ||
2593 | &response, 2); | ||
2594 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2595 | DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); | ||
2596 | return; | ||
2597 | } | ||
2598 | intel_sdvo_connector->max_saturation = data_value[0]; | 2448 | intel_sdvo_connector->max_saturation = data_value[0]; |
2599 | intel_sdvo_connector->cur_saturation = response; | 2449 | intel_sdvo_connector->cur_saturation = response; |
2600 | intel_sdvo_connector->saturation_property = | 2450 | intel_sdvo_connector->saturation_property = |
@@ -2611,22 +2461,14 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2611 | data_value[0], data_value[1], response); | 2461 | data_value[0], data_value[1], response); |
2612 | } | 2462 | } |
2613 | if (sdvo_data.contrast) { | 2463 | if (sdvo_data.contrast) { |
2614 | intel_sdvo_write_cmd(intel_sdvo, | 2464 | if (!intel_sdvo_get_value(intel_sdvo, |
2615 | SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); | 2465 | SDVO_CMD_GET_MAX_CONTRAST, &data_value, 4)) |
2616 | status = intel_sdvo_read_response(intel_sdvo, | 2466 | return false; |
2617 | &data_value, 4); | 2467 | |
2618 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2468 | if (!intel_sdvo_get_value(intel_sdvo, |
2619 | DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); | 2469 | SDVO_CMD_GET_CONTRAST, &response, 2)) |
2620 | return; | 2470 | return false; |
2621 | } | 2471 | |
2622 | intel_sdvo_write_cmd(intel_sdvo, | ||
2623 | SDVO_CMD_GET_CONTRAST, NULL, 0); | ||
2624 | status = intel_sdvo_read_response(intel_sdvo, | ||
2625 | &response, 2); | ||
2626 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2627 | DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); | ||
2628 | return; | ||
2629 | } | ||
2630 | intel_sdvo_connector->max_contrast = data_value[0]; | 2472 | intel_sdvo_connector->max_contrast = data_value[0]; |
2631 | intel_sdvo_connector->cur_contrast = response; | 2473 | intel_sdvo_connector->cur_contrast = response; |
2632 | intel_sdvo_connector->contrast_property = | 2474 | intel_sdvo_connector->contrast_property = |
@@ -2642,22 +2484,14 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2642 | data_value[0], data_value[1], response); | 2484 | data_value[0], data_value[1], response); |
2643 | } | 2485 | } |
2644 | if (sdvo_data.hue) { | 2486 | if (sdvo_data.hue) { |
2645 | intel_sdvo_write_cmd(intel_sdvo, | 2487 | if (!intel_sdvo_get_value(intel_sdvo, |
2646 | SDVO_CMD_GET_MAX_HUE, NULL, 0); | 2488 | SDVO_CMD_GET_MAX_HUE, &data_value, 4)) |
2647 | status = intel_sdvo_read_response(intel_sdvo, | 2489 | return false; |
2648 | &data_value, 4); | 2490 | |
2649 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2491 | if (!intel_sdvo_get_value(intel_sdvo, |
2650 | DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); | 2492 | SDVO_CMD_GET_HUE, &response, 2)) |
2651 | return; | 2493 | return false; |
2652 | } | 2494 | |
2653 | intel_sdvo_write_cmd(intel_sdvo, | ||
2654 | SDVO_CMD_GET_HUE, NULL, 0); | ||
2655 | status = intel_sdvo_read_response(intel_sdvo, | ||
2656 | &response, 2); | ||
2657 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2658 | DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); | ||
2659 | return; | ||
2660 | } | ||
2661 | intel_sdvo_connector->max_hue = data_value[0]; | 2495 | intel_sdvo_connector->max_hue = data_value[0]; |
2662 | intel_sdvo_connector->cur_hue = response; | 2496 | intel_sdvo_connector->cur_hue = response; |
2663 | intel_sdvo_connector->hue_property = | 2497 | intel_sdvo_connector->hue_property = |
@@ -2673,24 +2507,16 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2673 | data_value[0], data_value[1], response); | 2507 | data_value[0], data_value[1], response); |
2674 | } | 2508 | } |
2675 | } | 2509 | } |
2676 | if (IS_TV(intel_sdvo_connector) || IS_LVDS(intel_sdvo_connector)) { | 2510 | if (IS_TV_OR_LVDS(intel_sdvo_connector)) { |
2677 | if (sdvo_data.brightness) { | 2511 | if (sdvo_data.brightness) { |
2678 | intel_sdvo_write_cmd(intel_sdvo, | 2512 | if (!intel_sdvo_get_value(intel_sdvo, |
2679 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2513 | SDVO_CMD_GET_MAX_BRIGHTNESS, &data_value, 4)) |
2680 | status = intel_sdvo_read_response(intel_sdvo, | 2514 | return false; |
2681 | &data_value, 4); | 2515 | |
2682 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2516 | if (!intel_sdvo_get_value(intel_sdvo, |
2683 | DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); | 2517 | SDVO_CMD_GET_BRIGHTNESS, &response, 2)) |
2684 | return; | 2518 | return false; |
2685 | } | 2519 | |
2686 | intel_sdvo_write_cmd(intel_sdvo, | ||
2687 | SDVO_CMD_GET_BRIGHTNESS, NULL, 0); | ||
2688 | status = intel_sdvo_read_response(intel_sdvo, | ||
2689 | &response, 2); | ||
2690 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2691 | DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); | ||
2692 | return; | ||
2693 | } | ||
2694 | intel_sdvo_connector->max_brightness = data_value[0]; | 2520 | intel_sdvo_connector->max_brightness = data_value[0]; |
2695 | intel_sdvo_connector->cur_brightness = response; | 2521 | intel_sdvo_connector->cur_brightness = response; |
2696 | intel_sdvo_connector->brightness_property = | 2522 | intel_sdvo_connector->brightness_property = |
@@ -2707,7 +2533,7 @@ static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | |||
2707 | data_value[0], data_value[1], response); | 2533 | data_value[0], data_value[1], response); |
2708 | } | 2534 | } |
2709 | } | 2535 | } |
2710 | return; | 2536 | return true; |
2711 | } | 2537 | } |
2712 | 2538 | ||
2713 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2539 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
@@ -2773,8 +2599,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2773 | "SDVOC/VGA DDC BUS"); | 2599 | "SDVOC/VGA DDC BUS"); |
2774 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2600 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2775 | } | 2601 | } |
2776 | 2602 | if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL) | |
2777 | if (intel_encoder->ddc_bus == NULL) | ||
2778 | goto err_i2c; | 2603 | goto err_i2c; |
2779 | 2604 | ||
2780 | /* Wrap with our custom algo which switches to DDC mode */ | 2605 | /* Wrap with our custom algo which switches to DDC mode */ |
@@ -2785,24 +2610,26 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2785 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | 2610 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); |
2786 | 2611 | ||
2787 | /* In default case sdvo lvds is false */ | 2612 | /* In default case sdvo lvds is false */ |
2788 | intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps); | 2613 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2614 | goto err_enc; | ||
2789 | 2615 | ||
2790 | if (intel_sdvo_output_setup(intel_sdvo, | 2616 | if (intel_sdvo_output_setup(intel_sdvo, |
2791 | intel_sdvo->caps.output_flags) != true) { | 2617 | intel_sdvo->caps.output_flags) != true) { |
2792 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2618 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2793 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2619 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2794 | goto err_i2c; | 2620 | goto err_enc; |
2795 | } | 2621 | } |
2796 | 2622 | ||
2797 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); | 2623 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
2798 | 2624 | ||
2799 | /* Set the input timing to the screen. Assume always input 0. */ | 2625 | /* Set the input timing to the screen. Assume always input 0. */ |
2800 | intel_sdvo_set_target_input(intel_sdvo, true, false); | 2626 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
2801 | 2627 | goto err_enc; | |
2802 | intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | ||
2803 | &intel_sdvo->pixel_clock_min, | ||
2804 | &intel_sdvo->pixel_clock_max); | ||
2805 | 2628 | ||
2629 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | ||
2630 | &intel_sdvo->pixel_clock_min, | ||
2631 | &intel_sdvo->pixel_clock_max)) | ||
2632 | goto err_enc; | ||
2806 | 2633 | ||
2807 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2634 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
2808 | "clock range %dMHz - %dMHz, " | 2635 | "clock range %dMHz - %dMHz, " |
@@ -2820,9 +2647,10 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2820 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', | 2647 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', |
2821 | intel_sdvo->caps.output_flags & | 2648 | intel_sdvo->caps.output_flags & |
2822 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2649 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
2823 | |||
2824 | return true; | 2650 | return true; |
2825 | 2651 | ||
2652 | err_enc: | ||
2653 | drm_encoder_cleanup(&intel_encoder->enc); | ||
2826 | err_i2c: | 2654 | err_i2c: |
2827 | if (intel_sdvo->analog_ddc_bus != NULL) | 2655 | if (intel_sdvo->analog_ddc_bus != NULL) |
2828 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); | 2656 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |