diff options
Diffstat (limited to 'drivers/gpu')
52 files changed, 2715 insertions, 668 deletions
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index 325365f6d355..affa629589ac 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c | |||
@@ -85,11 +85,12 @@ again: | |||
85 | mutex_lock(&dev->struct_mutex); | 85 | mutex_lock(&dev->struct_mutex); |
86 | ret = idr_get_new_above(&dev->ctx_idr, NULL, | 86 | ret = idr_get_new_above(&dev->ctx_idr, NULL, |
87 | DRM_RESERVED_CONTEXTS, &new_id); | 87 | DRM_RESERVED_CONTEXTS, &new_id); |
88 | if (ret == -EAGAIN) { | ||
89 | mutex_unlock(&dev->struct_mutex); | ||
90 | goto again; | ||
91 | } | ||
92 | mutex_unlock(&dev->struct_mutex); | 88 | mutex_unlock(&dev->struct_mutex); |
89 | if (ret == -EAGAIN) | ||
90 | goto again; | ||
91 | else if (ret) | ||
92 | return ret; | ||
93 | |||
93 | return new_id; | 94 | return new_id; |
94 | } | 95 | } |
95 | 96 | ||
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index d3aaeb6ae236..a9ca1b80fc28 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -227,7 +227,7 @@ static int drm_mode_object_get(struct drm_device *dev, | |||
227 | again: | 227 | again: |
228 | if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { | 228 | if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) { |
229 | DRM_ERROR("Ran out memory getting a mode number\n"); | 229 | DRM_ERROR("Ran out memory getting a mode number\n"); |
230 | return -EINVAL; | 230 | return -ENOMEM; |
231 | } | 231 | } |
232 | 232 | ||
233 | mutex_lock(&dev->mode_config.idr_mutex); | 233 | mutex_lock(&dev->mode_config.idr_mutex); |
@@ -235,6 +235,8 @@ again: | |||
235 | mutex_unlock(&dev->mode_config.idr_mutex); | 235 | mutex_unlock(&dev->mode_config.idr_mutex); |
236 | if (ret == -EAGAIN) | 236 | if (ret == -EAGAIN) |
237 | goto again; | 237 | goto again; |
238 | else if (ret) | ||
239 | return ret; | ||
238 | 240 | ||
239 | obj->id = new_id; | 241 | obj->id = new_id; |
240 | obj->type = obj_type; | 242 | obj->type = obj_type; |
@@ -2185,6 +2187,47 @@ static int format_check(struct drm_mode_fb_cmd2 *r) | |||
2185 | } | 2187 | } |
2186 | } | 2188 | } |
2187 | 2189 | ||
2190 | static int framebuffer_check(struct drm_mode_fb_cmd2 *r) | ||
2191 | { | ||
2192 | int ret, hsub, vsub, num_planes, i; | ||
2193 | |||
2194 | ret = format_check(r); | ||
2195 | if (ret) { | ||
2196 | DRM_ERROR("bad framebuffer format 0x%08x\n", r->pixel_format); | ||
2197 | return ret; | ||
2198 | } | ||
2199 | |||
2200 | hsub = drm_format_horz_chroma_subsampling(r->pixel_format); | ||
2201 | vsub = drm_format_vert_chroma_subsampling(r->pixel_format); | ||
2202 | num_planes = drm_format_num_planes(r->pixel_format); | ||
2203 | |||
2204 | if (r->width == 0 || r->width % hsub) { | ||
2205 | DRM_ERROR("bad framebuffer width %u\n", r->height); | ||
2206 | return -EINVAL; | ||
2207 | } | ||
2208 | |||
2209 | if (r->height == 0 || r->height % vsub) { | ||
2210 | DRM_ERROR("bad framebuffer height %u\n", r->height); | ||
2211 | return -EINVAL; | ||
2212 | } | ||
2213 | |||
2214 | for (i = 0; i < num_planes; i++) { | ||
2215 | unsigned int width = r->width / (i != 0 ? hsub : 1); | ||
2216 | |||
2217 | if (!r->handles[i]) { | ||
2218 | DRM_ERROR("no buffer object handle for plane %d\n", i); | ||
2219 | return -EINVAL; | ||
2220 | } | ||
2221 | |||
2222 | if (r->pitches[i] < drm_format_plane_cpp(r->pixel_format, i) * width) { | ||
2223 | DRM_ERROR("bad pitch %u for plane %d\n", r->pitches[i], i); | ||
2224 | return -EINVAL; | ||
2225 | } | ||
2226 | } | ||
2227 | |||
2228 | return 0; | ||
2229 | } | ||
2230 | |||
2188 | /** | 2231 | /** |
2189 | * drm_mode_addfb2 - add an FB to the graphics configuration | 2232 | * drm_mode_addfb2 - add an FB to the graphics configuration |
2190 | * @inode: inode from the ioctl | 2233 | * @inode: inode from the ioctl |
@@ -2224,11 +2267,9 @@ int drm_mode_addfb2(struct drm_device *dev, | |||
2224 | return -EINVAL; | 2267 | return -EINVAL; |
2225 | } | 2268 | } |
2226 | 2269 | ||
2227 | ret = format_check(r); | 2270 | ret = framebuffer_check(r); |
2228 | if (ret) { | 2271 | if (ret) |
2229 | DRM_ERROR("bad framebuffer format 0x%08x\n", r->pixel_format); | ||
2230 | return ret; | 2272 | return ret; |
2231 | } | ||
2232 | 2273 | ||
2233 | mutex_lock(&dev->mode_config.mutex); | 2274 | mutex_lock(&dev->mode_config.mutex); |
2234 | 2275 | ||
@@ -3466,3 +3507,140 @@ void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, | |||
3466 | } | 3507 | } |
3467 | } | 3508 | } |
3468 | EXPORT_SYMBOL(drm_fb_get_bpp_depth); | 3509 | EXPORT_SYMBOL(drm_fb_get_bpp_depth); |
3510 | |||
3511 | /** | ||
3512 | * drm_format_num_planes - get the number of planes for format | ||
3513 | * @format: pixel format (DRM_FORMAT_*) | ||
3514 | * | ||
3515 | * RETURNS: | ||
3516 | * The number of planes used by the specified pixel format. | ||
3517 | */ | ||
3518 | int drm_format_num_planes(uint32_t format) | ||
3519 | { | ||
3520 | switch (format) { | ||
3521 | case DRM_FORMAT_YUV410: | ||
3522 | case DRM_FORMAT_YVU410: | ||
3523 | case DRM_FORMAT_YUV411: | ||
3524 | case DRM_FORMAT_YVU411: | ||
3525 | case DRM_FORMAT_YUV420: | ||
3526 | case DRM_FORMAT_YVU420: | ||
3527 | case DRM_FORMAT_YUV422: | ||
3528 | case DRM_FORMAT_YVU422: | ||
3529 | case DRM_FORMAT_YUV444: | ||
3530 | case DRM_FORMAT_YVU444: | ||
3531 | return 3; | ||
3532 | case DRM_FORMAT_NV12: | ||
3533 | case DRM_FORMAT_NV21: | ||
3534 | case DRM_FORMAT_NV16: | ||
3535 | case DRM_FORMAT_NV61: | ||
3536 | return 2; | ||
3537 | default: | ||
3538 | return 1; | ||
3539 | } | ||
3540 | } | ||
3541 | EXPORT_SYMBOL(drm_format_num_planes); | ||
3542 | |||
3543 | /** | ||
3544 | * drm_format_plane_cpp - determine the bytes per pixel value | ||
3545 | * @format: pixel format (DRM_FORMAT_*) | ||
3546 | * @plane: plane index | ||
3547 | * | ||
3548 | * RETURNS: | ||
3549 | * The bytes per pixel value for the specified plane. | ||
3550 | */ | ||
3551 | int drm_format_plane_cpp(uint32_t format, int plane) | ||
3552 | { | ||
3553 | unsigned int depth; | ||
3554 | int bpp; | ||
3555 | |||
3556 | if (plane >= drm_format_num_planes(format)) | ||
3557 | return 0; | ||
3558 | |||
3559 | switch (format) { | ||
3560 | case DRM_FORMAT_YUYV: | ||
3561 | case DRM_FORMAT_YVYU: | ||
3562 | case DRM_FORMAT_UYVY: | ||
3563 | case DRM_FORMAT_VYUY: | ||
3564 | return 2; | ||
3565 | case DRM_FORMAT_NV12: | ||
3566 | case DRM_FORMAT_NV21: | ||
3567 | case DRM_FORMAT_NV16: | ||
3568 | case DRM_FORMAT_NV61: | ||
3569 | return plane ? 2 : 1; | ||
3570 | case DRM_FORMAT_YUV410: | ||
3571 | case DRM_FORMAT_YVU410: | ||
3572 | case DRM_FORMAT_YUV411: | ||
3573 | case DRM_FORMAT_YVU411: | ||
3574 | case DRM_FORMAT_YUV420: | ||
3575 | case DRM_FORMAT_YVU420: | ||
3576 | case DRM_FORMAT_YUV422: | ||
3577 | case DRM_FORMAT_YVU422: | ||
3578 | case DRM_FORMAT_YUV444: | ||
3579 | case DRM_FORMAT_YVU444: | ||
3580 | return 1; | ||
3581 | default: | ||
3582 | drm_fb_get_bpp_depth(format, &depth, &bpp); | ||
3583 | return bpp >> 3; | ||
3584 | } | ||
3585 | } | ||
3586 | EXPORT_SYMBOL(drm_format_plane_cpp); | ||
3587 | |||
3588 | /** | ||
3589 | * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor | ||
3590 | * @format: pixel format (DRM_FORMAT_*) | ||
3591 | * | ||
3592 | * RETURNS: | ||
3593 | * The horizontal chroma subsampling factor for the | ||
3594 | * specified pixel format. | ||
3595 | */ | ||
3596 | int drm_format_horz_chroma_subsampling(uint32_t format) | ||
3597 | { | ||
3598 | switch (format) { | ||
3599 | case DRM_FORMAT_YUV411: | ||
3600 | case DRM_FORMAT_YVU411: | ||
3601 | case DRM_FORMAT_YUV410: | ||
3602 | case DRM_FORMAT_YVU410: | ||
3603 | return 4; | ||
3604 | case DRM_FORMAT_YUYV: | ||
3605 | case DRM_FORMAT_YVYU: | ||
3606 | case DRM_FORMAT_UYVY: | ||
3607 | case DRM_FORMAT_VYUY: | ||
3608 | case DRM_FORMAT_NV12: | ||
3609 | case DRM_FORMAT_NV21: | ||
3610 | case DRM_FORMAT_NV16: | ||
3611 | case DRM_FORMAT_NV61: | ||
3612 | case DRM_FORMAT_YUV422: | ||
3613 | case DRM_FORMAT_YVU422: | ||
3614 | case DRM_FORMAT_YUV420: | ||
3615 | case DRM_FORMAT_YVU420: | ||
3616 | return 2; | ||
3617 | default: | ||
3618 | return 1; | ||
3619 | } | ||
3620 | } | ||
3621 | EXPORT_SYMBOL(drm_format_horz_chroma_subsampling); | ||
3622 | |||
3623 | /** | ||
3624 | * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor | ||
3625 | * @format: pixel format (DRM_FORMAT_*) | ||
3626 | * | ||
3627 | * RETURNS: | ||
3628 | * The vertical chroma subsampling factor for the | ||
3629 | * specified pixel format. | ||
3630 | */ | ||
3631 | int drm_format_vert_chroma_subsampling(uint32_t format) | ||
3632 | { | ||
3633 | switch (format) { | ||
3634 | case DRM_FORMAT_YUV410: | ||
3635 | case DRM_FORMAT_YVU410: | ||
3636 | return 4; | ||
3637 | case DRM_FORMAT_YUV420: | ||
3638 | case DRM_FORMAT_YVU420: | ||
3639 | case DRM_FORMAT_NV12: | ||
3640 | case DRM_FORMAT_NV21: | ||
3641 | return 2; | ||
3642 | default: | ||
3643 | return 1; | ||
3644 | } | ||
3645 | } | ||
3646 | EXPORT_SYMBOL(drm_format_vert_chroma_subsampling); | ||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 81118893264c..974196ab7b22 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -1023,36 +1023,3 @@ void drm_helper_hpd_irq_event(struct drm_device *dev) | |||
1023 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); | 1023 | queue_delayed_work(system_nrt_wq, &dev->mode_config.output_poll_work, 0); |
1024 | } | 1024 | } |
1025 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); | 1025 | EXPORT_SYMBOL(drm_helper_hpd_irq_event); |
1026 | |||
1027 | |||
1028 | /** | ||
1029 | * drm_format_num_planes - get the number of planes for format | ||
1030 | * @format: pixel format (DRM_FORMAT_*) | ||
1031 | * | ||
1032 | * RETURNS: | ||
1033 | * The number of planes used by the specified pixel format. | ||
1034 | */ | ||
1035 | int drm_format_num_planes(uint32_t format) | ||
1036 | { | ||
1037 | switch (format) { | ||
1038 | case DRM_FORMAT_YUV410: | ||
1039 | case DRM_FORMAT_YVU410: | ||
1040 | case DRM_FORMAT_YUV411: | ||
1041 | case DRM_FORMAT_YVU411: | ||
1042 | case DRM_FORMAT_YUV420: | ||
1043 | case DRM_FORMAT_YVU420: | ||
1044 | case DRM_FORMAT_YUV422: | ||
1045 | case DRM_FORMAT_YVU422: | ||
1046 | case DRM_FORMAT_YUV444: | ||
1047 | case DRM_FORMAT_YVU444: | ||
1048 | return 3; | ||
1049 | case DRM_FORMAT_NV12: | ||
1050 | case DRM_FORMAT_NV21: | ||
1051 | case DRM_FORMAT_NV16: | ||
1052 | case DRM_FORMAT_NV61: | ||
1053 | return 2; | ||
1054 | default: | ||
1055 | return 1; | ||
1056 | } | ||
1057 | } | ||
1058 | EXPORT_SYMBOL(drm_format_num_planes); | ||
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 5a18b0df8285..608bddfc7e35 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -81,7 +81,7 @@ struct detailed_mode_closure { | |||
81 | #define LEVEL_CVT 3 | 81 | #define LEVEL_CVT 3 |
82 | 82 | ||
83 | static struct edid_quirk { | 83 | static struct edid_quirk { |
84 | char *vendor; | 84 | char vendor[4]; |
85 | int product_id; | 85 | int product_id; |
86 | u32 quirks; | 86 | u32 quirks; |
87 | } edid_quirk_list[] = { | 87 | } edid_quirk_list[] = { |
@@ -149,13 +149,13 @@ EXPORT_SYMBOL(drm_edid_header_is_valid); | |||
149 | * Sanity check the EDID block (base or extension). Return 0 if the block | 149 | * Sanity check the EDID block (base or extension). Return 0 if the block |
150 | * doesn't check out, or 1 if it's valid. | 150 | * doesn't check out, or 1 if it's valid. |
151 | */ | 151 | */ |
152 | bool drm_edid_block_valid(u8 *raw_edid) | 152 | bool drm_edid_block_valid(u8 *raw_edid, int block) |
153 | { | 153 | { |
154 | int i; | 154 | int i; |
155 | u8 csum = 0; | 155 | u8 csum = 0; |
156 | struct edid *edid = (struct edid *)raw_edid; | 156 | struct edid *edid = (struct edid *)raw_edid; |
157 | 157 | ||
158 | if (raw_edid[0] == 0x00) { | 158 | if (block == 0) { |
159 | int score = drm_edid_header_is_valid(raw_edid); | 159 | int score = drm_edid_header_is_valid(raw_edid); |
160 | if (score == 8) ; | 160 | if (score == 8) ; |
161 | else if (score >= 6) { | 161 | else if (score >= 6) { |
@@ -219,7 +219,7 @@ bool drm_edid_is_valid(struct edid *edid) | |||
219 | return false; | 219 | return false; |
220 | 220 | ||
221 | for (i = 0; i <= edid->extensions; i++) | 221 | for (i = 0; i <= edid->extensions; i++) |
222 | if (!drm_edid_block_valid(raw + i * EDID_LENGTH)) | 222 | if (!drm_edid_block_valid(raw + i * EDID_LENGTH, i)) |
223 | return false; | 223 | return false; |
224 | 224 | ||
225 | return true; | 225 | return true; |
@@ -299,7 +299,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) | |||
299 | for (i = 0; i < 4; i++) { | 299 | for (i = 0; i < 4; i++) { |
300 | if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH)) | 300 | if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH)) |
301 | goto out; | 301 | goto out; |
302 | if (drm_edid_block_valid(block)) | 302 | if (drm_edid_block_valid(block, 0)) |
303 | break; | 303 | break; |
304 | if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { | 304 | if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) { |
305 | connector->null_edid_counter++; | 305 | connector->null_edid_counter++; |
@@ -324,7 +324,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) | |||
324 | block + (valid_extensions + 1) * EDID_LENGTH, | 324 | block + (valid_extensions + 1) * EDID_LENGTH, |
325 | j, EDID_LENGTH)) | 325 | j, EDID_LENGTH)) |
326 | goto out; | 326 | goto out; |
327 | if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH)) { | 327 | if (drm_edid_block_valid(block + (valid_extensions + 1) * EDID_LENGTH, j)) { |
328 | valid_extensions++; | 328 | valid_extensions++; |
329 | break; | 329 | break; |
330 | } | 330 | } |
@@ -486,23 +486,47 @@ static void edid_fixup_preferred(struct drm_connector *connector, | |||
486 | preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; | 486 | preferred_mode->type |= DRM_MODE_TYPE_PREFERRED; |
487 | } | 487 | } |
488 | 488 | ||
489 | static bool | ||
490 | mode_is_rb(const struct drm_display_mode *mode) | ||
491 | { | ||
492 | return (mode->htotal - mode->hdisplay == 160) && | ||
493 | (mode->hsync_end - mode->hdisplay == 80) && | ||
494 | (mode->hsync_end - mode->hsync_start == 32) && | ||
495 | (mode->vsync_start - mode->vdisplay == 3); | ||
496 | } | ||
497 | |||
498 | /* | ||
499 | * drm_mode_find_dmt - Create a copy of a mode if present in DMT | ||
500 | * @dev: Device to duplicate against | ||
501 | * @hsize: Mode width | ||
502 | * @vsize: Mode height | ||
503 | * @fresh: Mode refresh rate | ||
504 | * @rb: Mode reduced-blanking-ness | ||
505 | * | ||
506 | * Walk the DMT mode list looking for a match for the given parameters. | ||
507 | * Return a newly allocated copy of the mode, or NULL if not found. | ||
508 | */ | ||
489 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, | 509 | struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, |
490 | int hsize, int vsize, int fresh) | 510 | int hsize, int vsize, int fresh, |
511 | bool rb) | ||
491 | { | 512 | { |
492 | struct drm_display_mode *mode = NULL; | ||
493 | int i; | 513 | int i; |
494 | 514 | ||
495 | for (i = 0; i < drm_num_dmt_modes; i++) { | 515 | for (i = 0; i < drm_num_dmt_modes; i++) { |
496 | const struct drm_display_mode *ptr = &drm_dmt_modes[i]; | 516 | const struct drm_display_mode *ptr = &drm_dmt_modes[i]; |
497 | if (hsize == ptr->hdisplay && | 517 | if (hsize != ptr->hdisplay) |
498 | vsize == ptr->vdisplay && | 518 | continue; |
499 | fresh == drm_mode_vrefresh(ptr)) { | 519 | if (vsize != ptr->vdisplay) |
500 | /* get the expected default mode */ | 520 | continue; |
501 | mode = drm_mode_duplicate(dev, ptr); | 521 | if (fresh != drm_mode_vrefresh(ptr)) |
502 | break; | 522 | continue; |
503 | } | 523 | if (rb != mode_is_rb(ptr)) |
524 | continue; | ||
525 | |||
526 | return drm_mode_duplicate(dev, ptr); | ||
504 | } | 527 | } |
505 | return mode; | 528 | |
529 | return NULL; | ||
506 | } | 530 | } |
507 | EXPORT_SYMBOL(drm_mode_find_dmt); | 531 | EXPORT_SYMBOL(drm_mode_find_dmt); |
508 | 532 | ||
@@ -731,10 +755,17 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, | |||
731 | } | 755 | } |
732 | 756 | ||
733 | /* check whether it can be found in default mode table */ | 757 | /* check whether it can be found in default mode table */ |
734 | mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate); | 758 | if (drm_monitor_supports_rb(edid)) { |
759 | mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, | ||
760 | true); | ||
761 | if (mode) | ||
762 | return mode; | ||
763 | } | ||
764 | mode = drm_mode_find_dmt(dev, hsize, vsize, vrefresh_rate, false); | ||
735 | if (mode) | 765 | if (mode) |
736 | return mode; | 766 | return mode; |
737 | 767 | ||
768 | /* okay, generate it */ | ||
738 | switch (timing_level) { | 769 | switch (timing_level) { |
739 | case LEVEL_DMT: | 770 | case LEVEL_DMT: |
740 | break; | 771 | break; |
@@ -748,6 +779,8 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, | |||
748 | * secondary GTF curve. Please don't do that. | 779 | * secondary GTF curve. Please don't do that. |
749 | */ | 780 | */ |
750 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); | 781 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
782 | if (!mode) | ||
783 | return NULL; | ||
751 | if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { | 784 | if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { |
752 | drm_mode_destroy(dev, mode); | 785 | drm_mode_destroy(dev, mode); |
753 | mode = drm_gtf_mode_complex(dev, hsize, vsize, | 786 | mode = drm_gtf_mode_complex(dev, hsize, vsize, |
@@ -909,15 +942,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
909 | } | 942 | } |
910 | 943 | ||
911 | static bool | 944 | static bool |
912 | mode_is_rb(const struct drm_display_mode *mode) | ||
913 | { | ||
914 | return (mode->htotal - mode->hdisplay == 160) && | ||
915 | (mode->hsync_end - mode->hdisplay == 80) && | ||
916 | (mode->hsync_end - mode->hsync_start == 32) && | ||
917 | (mode->vsync_start - mode->vdisplay == 3); | ||
918 | } | ||
919 | |||
920 | static bool | ||
921 | mode_in_hsync_range(const struct drm_display_mode *mode, | 945 | mode_in_hsync_range(const struct drm_display_mode *mode, |
922 | struct edid *edid, u8 *t) | 946 | struct edid *edid, u8 *t) |
923 | { | 947 | { |
@@ -994,12 +1018,8 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid, | |||
994 | return true; | 1018 | return true; |
995 | } | 1019 | } |
996 | 1020 | ||
997 | /* | ||
998 | * XXX If drm_dmt_modes ever regrows the CVT-R modes (and it will) this will | ||
999 | * need to account for them. | ||
1000 | */ | ||
1001 | static int | 1021 | static int |
1002 | drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, | 1022 | drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, |
1003 | struct detailed_timing *timing) | 1023 | struct detailed_timing *timing) |
1004 | { | 1024 | { |
1005 | int i, modes = 0; | 1025 | int i, modes = 0; |
@@ -1019,17 +1039,110 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, | |||
1019 | return modes; | 1039 | return modes; |
1020 | } | 1040 | } |
1021 | 1041 | ||
1042 | /* fix up 1366x768 mode from 1368x768; | ||
1043 | * GFT/CVT can't express 1366 width which isn't dividable by 8 | ||
1044 | */ | ||
1045 | static void fixup_mode_1366x768(struct drm_display_mode *mode) | ||
1046 | { | ||
1047 | if (mode->hdisplay == 1368 && mode->vdisplay == 768) { | ||
1048 | mode->hdisplay = 1366; | ||
1049 | mode->hsync_start--; | ||
1050 | mode->hsync_end--; | ||
1051 | drm_mode_set_name(mode); | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | static int | ||
1056 | drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, | ||
1057 | struct detailed_timing *timing) | ||
1058 | { | ||
1059 | int i, modes = 0; | ||
1060 | struct drm_display_mode *newmode; | ||
1061 | struct drm_device *dev = connector->dev; | ||
1062 | |||
1063 | for (i = 0; i < num_extra_modes; i++) { | ||
1064 | const struct minimode *m = &extra_modes[i]; | ||
1065 | newmode = drm_gtf_mode(dev, m->w, m->h, m->r, 0, 0); | ||
1066 | if (!newmode) | ||
1067 | return modes; | ||
1068 | |||
1069 | fixup_mode_1366x768(newmode); | ||
1070 | if (!mode_in_range(newmode, edid, timing)) { | ||
1071 | drm_mode_destroy(dev, newmode); | ||
1072 | continue; | ||
1073 | } | ||
1074 | |||
1075 | drm_mode_probed_add(connector, newmode); | ||
1076 | modes++; | ||
1077 | } | ||
1078 | |||
1079 | return modes; | ||
1080 | } | ||
1081 | |||
1082 | static int | ||
1083 | drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, | ||
1084 | struct detailed_timing *timing) | ||
1085 | { | ||
1086 | int i, modes = 0; | ||
1087 | struct drm_display_mode *newmode; | ||
1088 | struct drm_device *dev = connector->dev; | ||
1089 | bool rb = drm_monitor_supports_rb(edid); | ||
1090 | |||
1091 | for (i = 0; i < num_extra_modes; i++) { | ||
1092 | const struct minimode *m = &extra_modes[i]; | ||
1093 | newmode = drm_cvt_mode(dev, m->w, m->h, m->r, rb, 0, 0); | ||
1094 | if (!newmode) | ||
1095 | return modes; | ||
1096 | |||
1097 | fixup_mode_1366x768(newmode); | ||
1098 | if (!mode_in_range(newmode, edid, timing)) { | ||
1099 | drm_mode_destroy(dev, newmode); | ||
1100 | continue; | ||
1101 | } | ||
1102 | |||
1103 | drm_mode_probed_add(connector, newmode); | ||
1104 | modes++; | ||
1105 | } | ||
1106 | |||
1107 | return modes; | ||
1108 | } | ||
1109 | |||
1022 | static void | 1110 | static void |
1023 | do_inferred_modes(struct detailed_timing *timing, void *c) | 1111 | do_inferred_modes(struct detailed_timing *timing, void *c) |
1024 | { | 1112 | { |
1025 | struct detailed_mode_closure *closure = c; | 1113 | struct detailed_mode_closure *closure = c; |
1026 | struct detailed_non_pixel *data = &timing->data.other_data; | 1114 | struct detailed_non_pixel *data = &timing->data.other_data; |
1027 | int gtf = (closure->edid->features & DRM_EDID_FEATURE_DEFAULT_GTF); | 1115 | struct detailed_data_monitor_range *range = &data->data.range; |
1116 | |||
1117 | if (data->type != EDID_DETAIL_MONITOR_RANGE) | ||
1118 | return; | ||
1028 | 1119 | ||
1029 | if (gtf && data->type == EDID_DETAIL_MONITOR_RANGE) | 1120 | closure->modes += drm_dmt_modes_for_range(closure->connector, |
1121 | closure->edid, | ||
1122 | timing); | ||
1123 | |||
1124 | if (!version_greater(closure->edid, 1, 1)) | ||
1125 | return; /* GTF not defined yet */ | ||
1126 | |||
1127 | switch (range->flags) { | ||
1128 | case 0x02: /* secondary gtf, XXX could do more */ | ||
1129 | case 0x00: /* default gtf */ | ||
1030 | closure->modes += drm_gtf_modes_for_range(closure->connector, | 1130 | closure->modes += drm_gtf_modes_for_range(closure->connector, |
1031 | closure->edid, | 1131 | closure->edid, |
1032 | timing); | 1132 | timing); |
1133 | break; | ||
1134 | case 0x04: /* cvt, only in 1.4+ */ | ||
1135 | if (!version_greater(closure->edid, 1, 3)) | ||
1136 | break; | ||
1137 | |||
1138 | closure->modes += drm_cvt_modes_for_range(closure->connector, | ||
1139 | closure->edid, | ||
1140 | timing); | ||
1141 | break; | ||
1142 | case 0x01: /* just the ranges, no formula */ | ||
1143 | default: | ||
1144 | break; | ||
1145 | } | ||
1033 | } | 1146 | } |
1034 | 1147 | ||
1035 | static int | 1148 | static int |
@@ -1062,8 +1175,8 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing) | |||
1062 | mode = drm_mode_find_dmt(connector->dev, | 1175 | mode = drm_mode_find_dmt(connector->dev, |
1063 | est3_modes[m].w, | 1176 | est3_modes[m].w, |
1064 | est3_modes[m].h, | 1177 | est3_modes[m].h, |
1065 | est3_modes[m].r | 1178 | est3_modes[m].r, |
1066 | /*, est3_modes[m].rb */); | 1179 | est3_modes[m].rb); |
1067 | if (mode) { | 1180 | if (mode) { |
1068 | drm_mode_probed_add(connector, mode); | 1181 | drm_mode_probed_add(connector, mode); |
1069 | modes++; | 1182 | modes++; |
@@ -1312,6 +1425,8 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, | |||
1312 | #define VENDOR_BLOCK 0x03 | 1425 | #define VENDOR_BLOCK 0x03 |
1313 | #define SPEAKER_BLOCK 0x04 | 1426 | #define SPEAKER_BLOCK 0x04 |
1314 | #define EDID_BASIC_AUDIO (1 << 6) | 1427 | #define EDID_BASIC_AUDIO (1 << 6) |
1428 | #define EDID_CEA_YCRCB444 (1 << 5) | ||
1429 | #define EDID_CEA_YCRCB422 (1 << 4) | ||
1315 | 1430 | ||
1316 | /** | 1431 | /** |
1317 | * Search EDID for CEA extension block. | 1432 | * Search EDID for CEA extension block. |
@@ -1666,13 +1781,29 @@ static void drm_add_display_info(struct edid *edid, | |||
1666 | info->bpc = 0; | 1781 | info->bpc = 0; |
1667 | info->color_formats = 0; | 1782 | info->color_formats = 0; |
1668 | 1783 | ||
1669 | /* Only defined for 1.4 with digital displays */ | 1784 | if (edid->revision < 3) |
1670 | if (edid->revision < 4) | ||
1671 | return; | 1785 | return; |
1672 | 1786 | ||
1673 | if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) | 1787 | if (!(edid->input & DRM_EDID_INPUT_DIGITAL)) |
1674 | return; | 1788 | return; |
1675 | 1789 | ||
1790 | /* Get data from CEA blocks if present */ | ||
1791 | edid_ext = drm_find_cea_extension(edid); | ||
1792 | if (edid_ext) { | ||
1793 | info->cea_rev = edid_ext[1]; | ||
1794 | |||
1795 | /* The existence of a CEA block should imply RGB support */ | ||
1796 | info->color_formats = DRM_COLOR_FORMAT_RGB444; | ||
1797 | if (edid_ext[3] & EDID_CEA_YCRCB444) | ||
1798 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; | ||
1799 | if (edid_ext[3] & EDID_CEA_YCRCB422) | ||
1800 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; | ||
1801 | } | ||
1802 | |||
1803 | /* Only defined for 1.4 with digital displays */ | ||
1804 | if (edid->revision < 4) | ||
1805 | return; | ||
1806 | |||
1676 | switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { | 1807 | switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) { |
1677 | case DRM_EDID_DIGITAL_DEPTH_6: | 1808 | case DRM_EDID_DIGITAL_DEPTH_6: |
1678 | info->bpc = 6; | 1809 | info->bpc = 6; |
@@ -1698,18 +1829,11 @@ static void drm_add_display_info(struct edid *edid, | |||
1698 | break; | 1829 | break; |
1699 | } | 1830 | } |
1700 | 1831 | ||
1701 | info->color_formats = DRM_COLOR_FORMAT_RGB444; | 1832 | info->color_formats |= DRM_COLOR_FORMAT_RGB444; |
1702 | if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB444) | 1833 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB444) |
1703 | info->color_formats = DRM_COLOR_FORMAT_YCRCB444; | 1834 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB444; |
1704 | if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422) | 1835 | if (edid->features & DRM_EDID_FEATURE_RGB_YCRCB422) |
1705 | info->color_formats = DRM_COLOR_FORMAT_YCRCB422; | 1836 | info->color_formats |= DRM_COLOR_FORMAT_YCRCB422; |
1706 | |||
1707 | /* Get data from CEA blocks if present */ | ||
1708 | edid_ext = drm_find_cea_extension(edid); | ||
1709 | if (!edid_ext) | ||
1710 | return; | ||
1711 | |||
1712 | info->cea_rev = edid_ext[1]; | ||
1713 | } | 1837 | } |
1714 | 1838 | ||
1715 | /** | 1839 | /** |
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index da9acba2dd6c..48c927c37041 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c | |||
@@ -173,7 +173,7 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
173 | } | 173 | } |
174 | memcpy(edid, fwdata, fwsize); | 174 | memcpy(edid, fwdata, fwsize); |
175 | 175 | ||
176 | if (!drm_edid_block_valid(edid)) { | 176 | if (!drm_edid_block_valid(edid, 0)) { |
177 | DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ", | 177 | DRM_ERROR("Base block of EDID firmware \"%s\" is invalid ", |
178 | name); | 178 | name); |
179 | kfree(edid); | 179 | kfree(edid); |
@@ -185,7 +185,7 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
185 | if (i != valid_extensions + 1) | 185 | if (i != valid_extensions + 1) |
186 | memcpy(edid + (valid_extensions + 1) * EDID_LENGTH, | 186 | memcpy(edid + (valid_extensions + 1) * EDID_LENGTH, |
187 | edid + i * EDID_LENGTH, EDID_LENGTH); | 187 | edid + i * EDID_LENGTH, EDID_LENGTH); |
188 | if (drm_edid_block_valid(edid + i * EDID_LENGTH)) | 188 | if (drm_edid_block_valid(edid + i * EDID_LENGTH, i)) |
189 | valid_extensions++; | 189 | valid_extensions++; |
190 | } | 190 | } |
191 | 191 | ||
diff --git a/drivers/gpu/drm/drm_edid_modes.h b/drivers/gpu/drm/drm_edid_modes.h index a91ffb117220..ff98a7eb38dd 100644 --- a/drivers/gpu/drm/drm_edid_modes.h +++ b/drivers/gpu/drm/drm_edid_modes.h | |||
@@ -30,7 +30,6 @@ | |||
30 | /* | 30 | /* |
31 | * Autogenerated from the DMT spec. | 31 | * Autogenerated from the DMT spec. |
32 | * This table is copied from xfree86/modes/xf86EdidModes.c. | 32 | * This table is copied from xfree86/modes/xf86EdidModes.c. |
33 | * But the mode with Reduced blank feature is deleted. | ||
34 | */ | 33 | */ |
35 | static const struct drm_display_mode drm_dmt_modes[] = { | 34 | static const struct drm_display_mode drm_dmt_modes[] = { |
36 | /* 640x350@85Hz */ | 35 | /* 640x350@85Hz */ |
@@ -81,6 +80,10 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
81 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832, | 80 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 56250, 800, 832, |
82 | 896, 1048, 0, 600, 601, 604, 631, 0, | 81 | 896, 1048, 0, 600, 601, 604, 631, 0, |
83 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 82 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
83 | /* 800x600@120Hz RB */ | ||
84 | { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 73250, 800, 848, | ||
85 | 880, 960, 0, 600, 603, 607, 636, 0, | ||
86 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
84 | /* 848x480@60Hz */ | 87 | /* 848x480@60Hz */ |
85 | { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864, | 88 | { DRM_MODE("848x480", DRM_MODE_TYPE_DRIVER, 33750, 848, 864, |
86 | 976, 1088, 0, 480, 486, 494, 517, 0, | 89 | 976, 1088, 0, 480, 486, 494, 517, 0, |
@@ -106,10 +109,18 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
106 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072, | 109 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 94500, 1024, 1072, |
107 | 1168, 1376, 0, 768, 769, 772, 808, 0, | 110 | 1168, 1376, 0, 768, 769, 772, 808, 0, |
108 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 111 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
112 | /* 1024x768@120Hz RB */ | ||
113 | { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 115500, 1024, 1072, | ||
114 | 1104, 1184, 0, 768, 771, 775, 813, 0, | ||
115 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
109 | /* 1152x864@75Hz */ | 116 | /* 1152x864@75Hz */ |
110 | { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, | 117 | { DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216, |
111 | 1344, 1600, 0, 864, 865, 868, 900, 0, | 118 | 1344, 1600, 0, 864, 865, 868, 900, 0, |
112 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 119 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
120 | /* 1280x768@60Hz RB */ | ||
121 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 68250, 1280, 1328, | ||
122 | 1360, 1440, 0, 768, 771, 778, 790, 0, | ||
123 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
113 | /* 1280x768@60Hz */ | 124 | /* 1280x768@60Hz */ |
114 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, | 125 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344, |
115 | 1472, 1664, 0, 768, 771, 778, 798, 0, | 126 | 1472, 1664, 0, 768, 771, 778, 798, 0, |
@@ -122,6 +133,14 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
122 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360, | 133 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 117500, 1280, 1360, |
123 | 1496, 1712, 0, 768, 771, 778, 809, 0, | 134 | 1496, 1712, 0, 768, 771, 778, 809, 0, |
124 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 135 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
136 | /* 1280x768@120Hz RB */ | ||
137 | { DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 140250, 1280, 1328, | ||
138 | 1360, 1440, 0, 768, 771, 778, 813, 0, | ||
139 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
140 | /* 1280x800@60Hz RB */ | ||
141 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 71000, 1280, 1328, | ||
142 | 1360, 1440, 0, 800, 803, 809, 823, 0, | ||
143 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
125 | /* 1280x800@60Hz */ | 144 | /* 1280x800@60Hz */ |
126 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, | 145 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352, |
127 | 1480, 1680, 0, 800, 803, 809, 831, 0, | 146 | 1480, 1680, 0, 800, 803, 809, 831, 0, |
@@ -134,6 +153,10 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
134 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360, | 153 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 122500, 1280, 1360, |
135 | 1496, 1712, 0, 800, 803, 809, 843, 0, | 154 | 1496, 1712, 0, 800, 803, 809, 843, 0, |
136 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 155 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
156 | /* 1280x800@120Hz RB */ | ||
157 | { DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 146250, 1280, 1328, | ||
158 | 1360, 1440, 0, 800, 803, 809, 847, 0, | ||
159 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
137 | /* 1280x960@60Hz */ | 160 | /* 1280x960@60Hz */ |
138 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, | 161 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376, |
139 | 1488, 1800, 0, 960, 961, 964, 1000, 0, | 162 | 1488, 1800, 0, 960, 961, 964, 1000, 0, |
@@ -142,6 +165,10 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
142 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344, | 165 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1344, |
143 | 1504, 1728, 0, 960, 961, 964, 1011, 0, | 166 | 1504, 1728, 0, 960, 961, 964, 1011, 0, |
144 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 167 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
168 | /* 1280x960@120Hz RB */ | ||
169 | { DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 175500, 1280, 1328, | ||
170 | 1360, 1440, 0, 960, 963, 967, 1017, 0, | ||
171 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
145 | /* 1280x1024@60Hz */ | 172 | /* 1280x1024@60Hz */ |
146 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, | 173 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328, |
147 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, | 174 | 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, |
@@ -154,22 +181,42 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
154 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344, | 181 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 157500, 1280, 1344, |
155 | 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, | 182 | 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, |
156 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 183 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
184 | /* 1280x1024@120Hz RB */ | ||
185 | { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 187250, 1280, 1328, | ||
186 | 1360, 1440, 0, 1024, 1027, 1034, 1084, 0, | ||
187 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
157 | /* 1360x768@60Hz */ | 188 | /* 1360x768@60Hz */ |
158 | { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, | 189 | { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424, |
159 | 1536, 1792, 0, 768, 771, 777, 795, 0, | 190 | 1536, 1792, 0, 768, 771, 777, 795, 0, |
160 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 191 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
161 | /* 1440x1050@60Hz */ | 192 | /* 1360x768@120Hz RB */ |
193 | { DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 148250, 1360, 1408, | ||
194 | 1440, 1520, 0, 768, 771, 776, 813, 0, | ||
195 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
196 | /* 1400x1050@60Hz RB */ | ||
197 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 101000, 1400, 1448, | ||
198 | 1480, 1560, 0, 1050, 1053, 1057, 1080, 0, | ||
199 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
200 | /* 1400x1050@60Hz */ | ||
162 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, | 201 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488, |
163 | 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, | 202 | 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, |
164 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 203 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
165 | /* 1440x1050@75Hz */ | 204 | /* 1400x1050@75Hz */ |
166 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504, | 205 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 156000, 1400, 1504, |
167 | 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, | 206 | 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, |
168 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 207 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
169 | /* 1440x1050@85Hz */ | 208 | /* 1400x1050@85Hz */ |
170 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504, | 209 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 179500, 1400, 1504, |
171 | 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, | 210 | 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, |
172 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 211 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
212 | /* 1400x1050@120Hz RB */ | ||
213 | { DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 208000, 1400, 1448, | ||
214 | 1480, 1560, 0, 1050, 1053, 1057, 1112, 0, | ||
215 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
216 | /* 1440x900@60Hz RB */ | ||
217 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 88750, 1440, 1488, | ||
218 | 1520, 1600, 0, 900, 903, 909, 926, 0, | ||
219 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
173 | /* 1440x900@60Hz */ | 220 | /* 1440x900@60Hz */ |
174 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, | 221 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520, |
175 | 1672, 1904, 0, 900, 903, 909, 934, 0, | 222 | 1672, 1904, 0, 900, 903, 909, 934, 0, |
@@ -182,6 +229,10 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
182 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544, | 229 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 157000, 1440, 1544, |
183 | 1696, 1952, 0, 900, 903, 909, 948, 0, | 230 | 1696, 1952, 0, 900, 903, 909, 948, 0, |
184 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 231 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
232 | /* 1440x900@120Hz RB */ | ||
233 | { DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 182750, 1440, 1488, | ||
234 | 1520, 1600, 0, 900, 903, 909, 953, 0, | ||
235 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
185 | /* 1600x1200@60Hz */ | 236 | /* 1600x1200@60Hz */ |
186 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, | 237 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664, |
187 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, | 238 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, |
@@ -202,6 +253,14 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
202 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664, | 253 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 229500, 1600, 1664, |
203 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, | 254 | 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, |
204 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 255 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
256 | /* 1600x1200@120Hz RB */ | ||
257 | { DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 268250, 1600, 1648, | ||
258 | 1680, 1760, 0, 1200, 1203, 1207, 1271, 0, | ||
259 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
260 | /* 1680x1050@60Hz RB */ | ||
261 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 119000, 1680, 1728, | ||
262 | 1760, 1840, 0, 1050, 1053, 1059, 1080, 0, | ||
263 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
205 | /* 1680x1050@60Hz */ | 264 | /* 1680x1050@60Hz */ |
206 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, | 265 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784, |
207 | 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, | 266 | 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, |
@@ -214,15 +273,23 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
214 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808, | 273 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 214750, 1680, 1808, |
215 | 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, | 274 | 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, |
216 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 275 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
276 | /* 1680x1050@120Hz RB */ | ||
277 | { DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 245500, 1680, 1728, | ||
278 | 1760, 1840, 0, 1050, 1053, 1059, 1112, 0, | ||
279 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
217 | /* 1792x1344@60Hz */ | 280 | /* 1792x1344@60Hz */ |
218 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, | 281 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920, |
219 | 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, | 282 | 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, |
220 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 283 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
221 | /* 1729x1344@75Hz */ | 284 | /* 1792x1344@75Hz */ |
222 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888, | 285 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 261000, 1792, 1888, |
223 | 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, | 286 | 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, |
224 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 287 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
225 | /* 1853x1392@60Hz */ | 288 | /* 1792x1344@120Hz RB */ |
289 | { DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 333250, 1792, 1840, | ||
290 | 1872, 1952, 0, 1344, 1347, 1351, 1423, 0, | ||
291 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
292 | /* 1856x1392@60Hz */ | ||
226 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, | 293 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, |
227 | 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, | 294 | 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, |
228 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 295 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
@@ -230,6 +297,14 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
230 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984, | 297 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 288000, 1856, 1984, |
231 | 2208, 2560, 0, 1392, 1395, 1399, 1500, 0, | 298 | 2208, 2560, 0, 1392, 1395, 1399, 1500, 0, |
232 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 299 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
300 | /* 1856x1392@120Hz RB */ | ||
301 | { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 356500, 1856, 1904, | ||
302 | 1936, 2016, 0, 1392, 1395, 1399, 1474, 0, | ||
303 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
304 | /* 1920x1200@60Hz RB */ | ||
305 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 154000, 1920, 1968, | ||
306 | 2000, 2080, 0, 1200, 1203, 1209, 1235, 0, | ||
307 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
233 | /* 1920x1200@60Hz */ | 308 | /* 1920x1200@60Hz */ |
234 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, | 309 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, |
235 | 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, | 310 | 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, |
@@ -242,6 +317,10 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
242 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064, | 317 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 281250, 1920, 2064, |
243 | 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, | 318 | 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, |
244 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 319 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
320 | /* 1920x1200@120Hz RB */ | ||
321 | { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 317000, 1920, 1968, | ||
322 | 2000, 2080, 0, 1200, 1203, 1209, 1271, 0, | ||
323 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
245 | /* 1920x1440@60Hz */ | 324 | /* 1920x1440@60Hz */ |
246 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, | 325 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048, |
247 | 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, | 326 | 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, |
@@ -250,6 +329,14 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
250 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064, | 329 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2064, |
251 | 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, | 330 | 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, |
252 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 331 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
332 | /* 1920x1440@120Hz RB */ | ||
333 | { DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 380500, 1920, 1968, | ||
334 | 2000, 2080, 0, 1440, 1443, 1447, 1525, 0, | ||
335 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
336 | /* 2560x1600@60Hz RB */ | ||
337 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 268500, 2560, 2608, | ||
338 | 2640, 2720, 0, 1600, 1603, 1609, 1646, 0, | ||
339 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
253 | /* 2560x1600@60Hz */ | 340 | /* 2560x1600@60Hz */ |
254 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, | 341 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, |
255 | 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, | 342 | 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, |
@@ -262,6 +349,11 @@ static const struct drm_display_mode drm_dmt_modes[] = { | |||
262 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768, | 349 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 505250, 2560, 2768, |
263 | 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, | 350 | 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, |
264 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 351 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
352 | /* 2560x1600@120Hz RB */ | ||
353 | { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 552750, 2560, 2608, | ||
354 | 2640, 2720, 0, 1600, 1603, 1609, 1694, 0, | ||
355 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, | ||
356 | |||
265 | }; | 357 | }; |
266 | static const int drm_num_dmt_modes = | 358 | static const int drm_num_dmt_modes = |
267 | sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); | 359 | sizeof(drm_dmt_modes) / sizeof(struct drm_display_mode); |
@@ -320,12 +412,14 @@ static const struct drm_display_mode edid_est_modes[] = { | |||
320 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */ | 412 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1152x864@75Hz */ |
321 | }; | 413 | }; |
322 | 414 | ||
323 | static const struct { | 415 | struct minimode { |
324 | short w; | 416 | short w; |
325 | short h; | 417 | short h; |
326 | short r; | 418 | short r; |
327 | short rb; | 419 | short rb; |
328 | } est3_modes[] = { | 420 | }; |
421 | |||
422 | static const struct minimode est3_modes[] = { | ||
329 | /* byte 6 */ | 423 | /* byte 6 */ |
330 | { 640, 350, 85, 0 }, | 424 | { 640, 350, 85, 0 }, |
331 | { 640, 400, 85, 0 }, | 425 | { 640, 400, 85, 0 }, |
@@ -377,288 +471,304 @@ static const struct { | |||
377 | { 1920, 1440, 60, 0 }, | 471 | { 1920, 1440, 60, 0 }, |
378 | { 1920, 1440, 75, 0 }, | 472 | { 1920, 1440, 75, 0 }, |
379 | }; | 473 | }; |
380 | static const int num_est3_modes = sizeof(est3_modes) / sizeof(est3_modes[0]); | 474 | static const int num_est3_modes = ARRAY_SIZE(est3_modes); |
475 | |||
476 | static const struct minimode extra_modes[] = { | ||
477 | { 1024, 576, 60, 0 }, | ||
478 | { 1366, 768, 60, 0 }, | ||
479 | { 1600, 900, 60, 0 }, | ||
480 | { 1680, 945, 60, 0 }, | ||
481 | { 1920, 1080, 60, 0 }, | ||
482 | { 2048, 1152, 60, 0 }, | ||
483 | { 2048, 1536, 60, 0 }, | ||
484 | }; | ||
485 | static const int num_extra_modes = ARRAY_SIZE(extra_modes); | ||
381 | 486 | ||
382 | /* | 487 | /* |
383 | * Probably taken from CEA-861 spec. | 488 | * Probably taken from CEA-861 spec. |
384 | * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. | 489 | * This table is converted from xorg's hw/xfree86/modes/xf86EdidModes.c. |
385 | */ | 490 | */ |
386 | static const struct drm_display_mode edid_cea_modes[] = { | 491 | static const struct drm_display_mode edid_cea_modes[] = { |
387 | /* 640x480@60Hz */ | 492 | /* 1 - 640x480@60Hz */ |
388 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, | 493 | { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, |
389 | 752, 800, 0, 480, 490, 492, 525, 0, | 494 | 752, 800, 0, 480, 490, 492, 525, 0, |
390 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 495 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
391 | /* 720x480@60Hz */ | 496 | /* 2 - 720x480@60Hz */ |
392 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, | 497 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, |
393 | 798, 858, 0, 480, 489, 495, 525, 0, | 498 | 798, 858, 0, 480, 489, 495, 525, 0, |
394 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 499 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
395 | /* 720x480@60Hz */ | 500 | /* 3 - 720x480@60Hz */ |
396 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, | 501 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736, |
397 | 798, 858, 0, 480, 489, 495, 525, 0, | 502 | 798, 858, 0, 480, 489, 495, 525, 0, |
398 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 503 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
399 | /* 1280x720@60Hz */ | 504 | /* 4 - 1280x720@60Hz */ |
400 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390, | 505 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390, |
401 | 1430, 1650, 0, 720, 725, 730, 750, 0, | 506 | 1430, 1650, 0, 720, 725, 730, 750, 0, |
402 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 507 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
403 | /* 1920x1080i@60Hz */ | 508 | /* 5 - 1920x1080i@60Hz */ |
404 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, | 509 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, |
405 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, | 510 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, |
406 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | | 511 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
407 | DRM_MODE_FLAG_INTERLACE) }, | 512 | DRM_MODE_FLAG_INTERLACE) }, |
408 | /* 1440x480i@60Hz */ | 513 | /* 6 - 1440x480i@60Hz */ |
409 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, | 514 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
410 | 1602, 1716, 0, 480, 488, 494, 525, 0, | 515 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
411 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 516 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
412 | DRM_MODE_FLAG_INTERLACE) }, | 517 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
413 | /* 1440x480i@60Hz */ | 518 | /* 7 - 1440x480i@60Hz */ |
414 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, | 519 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
415 | 1602, 1716, 0, 480, 488, 494, 525, 0, | 520 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
416 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 521 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
417 | DRM_MODE_FLAG_INTERLACE) }, | 522 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
418 | /* 1440x240@60Hz */ | 523 | /* 8 - 1440x240@60Hz */ |
419 | { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, | 524 | { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
420 | 1602, 1716, 0, 240, 244, 247, 262, 0, | 525 | 1602, 1716, 0, 240, 244, 247, 262, 0, |
421 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 526 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
422 | /* 1440x240@60Hz */ | 527 | DRM_MODE_FLAG_DBLCLK) }, |
528 | /* 9 - 1440x240@60Hz */ | ||
423 | { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, | 529 | { DRM_MODE("1440x240", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1478, |
424 | 1602, 1716, 0, 240, 244, 247, 262, 0, | 530 | 1602, 1716, 0, 240, 244, 247, 262, 0, |
425 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 531 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
426 | /* 2880x480i@60Hz */ | 532 | DRM_MODE_FLAG_DBLCLK) }, |
533 | /* 10 - 2880x480i@60Hz */ | ||
427 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, | 534 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, |
428 | 3204, 3432, 0, 480, 488, 494, 525, 0, | 535 | 3204, 3432, 0, 480, 488, 494, 525, 0, |
429 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 536 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
430 | DRM_MODE_FLAG_INTERLACE) }, | 537 | DRM_MODE_FLAG_INTERLACE) }, |
431 | /* 2880x480i@60Hz */ | 538 | /* 11 - 2880x480i@60Hz */ |
432 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, | 539 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, |
433 | 3204, 3432, 0, 480, 488, 494, 525, 0, | 540 | 3204, 3432, 0, 480, 488, 494, 525, 0, |
434 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 541 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
435 | DRM_MODE_FLAG_INTERLACE) }, | 542 | DRM_MODE_FLAG_INTERLACE) }, |
436 | /* 2880x240@60Hz */ | 543 | /* 12 - 2880x240@60Hz */ |
437 | { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, | 544 | { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, |
438 | 3204, 3432, 0, 240, 244, 247, 262, 0, | 545 | 3204, 3432, 0, 240, 244, 247, 262, 0, |
439 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 546 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
440 | /* 2880x240@60Hz */ | 547 | /* 13 - 2880x240@60Hz */ |
441 | { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, | 548 | { DRM_MODE("2880x240", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2956, |
442 | 3204, 3432, 0, 240, 244, 247, 262, 0, | 549 | 3204, 3432, 0, 240, 244, 247, 262, 0, |
443 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 550 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
444 | /* 1440x480@60Hz */ | 551 | /* 14 - 1440x480@60Hz */ |
445 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, | 552 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, |
446 | 1596, 1716, 0, 480, 489, 495, 525, 0, | 553 | 1596, 1716, 0, 480, 489, 495, 525, 0, |
447 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 554 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
448 | /* 1440x480@60Hz */ | 555 | /* 15 - 1440x480@60Hz */ |
449 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, | 556 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1472, |
450 | 1596, 1716, 0, 480, 489, 495, 525, 0, | 557 | 1596, 1716, 0, 480, 489, 495, 525, 0, |
451 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 558 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
452 | /* 1920x1080@60Hz */ | 559 | /* 16 - 1920x1080@60Hz */ |
453 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, | 560 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, |
454 | 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, | 561 | 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, |
455 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 562 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
456 | /* 720x576@50Hz */ | 563 | /* 17 - 720x576@50Hz */ |
457 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, | 564 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, |
458 | 796, 864, 0, 576, 581, 586, 625, 0, | 565 | 796, 864, 0, 576, 581, 586, 625, 0, |
459 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 566 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
460 | /* 720x576@50Hz */ | 567 | /* 18 - 720x576@50Hz */ |
461 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, | 568 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, |
462 | 796, 864, 0, 576, 581, 586, 625, 0, | 569 | 796, 864, 0, 576, 581, 586, 625, 0, |
463 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 570 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
464 | /* 1280x720@50Hz */ | 571 | /* 19 - 1280x720@50Hz */ |
465 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720, | 572 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720, |
466 | 1760, 1980, 0, 720, 725, 730, 750, 0, | 573 | 1760, 1980, 0, 720, 725, 730, 750, 0, |
467 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 574 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
468 | /* 1920x1080i@50Hz */ | 575 | /* 20 - 1920x1080i@50Hz */ |
469 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, | 576 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, |
470 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, | 577 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, |
471 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | | 578 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
472 | DRM_MODE_FLAG_INTERLACE) }, | 579 | DRM_MODE_FLAG_INTERLACE) }, |
473 | /* 1440x576i@50Hz */ | 580 | /* 21 - 1440x576i@50Hz */ |
474 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, | 581 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
475 | 1590, 1728, 0, 576, 580, 586, 625, 0, | 582 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
476 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 583 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
477 | DRM_MODE_FLAG_INTERLACE) }, | 584 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
478 | /* 1440x576i@50Hz */ | 585 | /* 22 - 1440x576i@50Hz */ |
479 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, | 586 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
480 | 1590, 1728, 0, 576, 580, 586, 625, 0, | 587 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
481 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 588 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
482 | DRM_MODE_FLAG_INTERLACE) }, | 589 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
483 | /* 1440x288@50Hz */ | 590 | /* 23 - 1440x288@50Hz */ |
484 | { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, | 591 | { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
485 | 1590, 1728, 0, 288, 290, 293, 312, 0, | 592 | 1590, 1728, 0, 288, 290, 293, 312, 0, |
486 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 593 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
487 | /* 1440x288@50Hz */ | 594 | DRM_MODE_FLAG_DBLCLK) }, |
595 | /* 24 - 1440x288@50Hz */ | ||
488 | { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, | 596 | { DRM_MODE("1440x288", DRM_MODE_TYPE_DRIVER, 27000, 1440, 1464, |
489 | 1590, 1728, 0, 288, 290, 293, 312, 0, | 597 | 1590, 1728, 0, 288, 290, 293, 312, 0, |
490 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 598 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
491 | /* 2880x576i@50Hz */ | 599 | DRM_MODE_FLAG_DBLCLK) }, |
600 | /* 25 - 2880x576i@50Hz */ | ||
492 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, | 601 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, |
493 | 3180, 3456, 0, 576, 580, 586, 625, 0, | 602 | 3180, 3456, 0, 576, 580, 586, 625, 0, |
494 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 603 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
495 | DRM_MODE_FLAG_INTERLACE) }, | 604 | DRM_MODE_FLAG_INTERLACE) }, |
496 | /* 2880x576i@50Hz */ | 605 | /* 26 - 2880x576i@50Hz */ |
497 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, | 606 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, |
498 | 3180, 3456, 0, 576, 580, 586, 625, 0, | 607 | 3180, 3456, 0, 576, 580, 586, 625, 0, |
499 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 608 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
500 | DRM_MODE_FLAG_INTERLACE) }, | 609 | DRM_MODE_FLAG_INTERLACE) }, |
501 | /* 2880x288@50Hz */ | 610 | /* 27 - 2880x288@50Hz */ |
502 | { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, | 611 | { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, |
503 | 3180, 3456, 0, 288, 290, 293, 312, 0, | 612 | 3180, 3456, 0, 288, 290, 293, 312, 0, |
504 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 613 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
505 | /* 2880x288@50Hz */ | 614 | /* 28 - 2880x288@50Hz */ |
506 | { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, | 615 | { DRM_MODE("2880x288", DRM_MODE_TYPE_DRIVER, 54000, 2880, 2928, |
507 | 3180, 3456, 0, 288, 290, 293, 312, 0, | 616 | 3180, 3456, 0, 288, 290, 293, 312, 0, |
508 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 617 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
509 | /* 1440x576@50Hz */ | 618 | /* 29 - 1440x576@50Hz */ |
510 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, | 619 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, |
511 | 1592, 1728, 0, 576, 581, 586, 625, 0, | 620 | 1592, 1728, 0, 576, 581, 586, 625, 0, |
512 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 621 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
513 | /* 1440x576@50Hz */ | 622 | /* 30 - 1440x576@50Hz */ |
514 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, | 623 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, |
515 | 1592, 1728, 0, 576, 581, 586, 625, 0, | 624 | 1592, 1728, 0, 576, 581, 586, 625, 0, |
516 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 625 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
517 | /* 1920x1080@50Hz */ | 626 | /* 31 - 1920x1080@50Hz */ |
518 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, | 627 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, |
519 | 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, | 628 | 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, |
520 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 629 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
521 | /* 1920x1080@24Hz */ | 630 | /* 32 - 1920x1080@24Hz */ |
522 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558, | 631 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2558, |
523 | 2602, 2750, 0, 1080, 1084, 1089, 1125, 0, | 632 | 2602, 2750, 0, 1080, 1084, 1089, 1125, 0, |
524 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 633 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
525 | /* 1920x1080@25Hz */ | 634 | /* 33 - 1920x1080@25Hz */ |
526 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, | 635 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2448, |
527 | 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, | 636 | 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, |
528 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 637 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
529 | /* 1920x1080@30Hz */ | 638 | /* 34 - 1920x1080@30Hz */ |
530 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, | 639 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008, |
531 | 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, | 640 | 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, |
532 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 641 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
533 | /* 2880x480@60Hz */ | 642 | /* 35 - 2880x480@60Hz */ |
534 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, | 643 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, |
535 | 3192, 3432, 0, 480, 489, 495, 525, 0, | 644 | 3192, 3432, 0, 480, 489, 495, 525, 0, |
536 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 645 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
537 | /* 2880x480@60Hz */ | 646 | /* 36 - 2880x480@60Hz */ |
538 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, | 647 | { DRM_MODE("2880x480", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2944, |
539 | 3192, 3432, 0, 480, 489, 495, 525, 0, | 648 | 3192, 3432, 0, 480, 489, 495, 525, 0, |
540 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 649 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
541 | /* 2880x576@50Hz */ | 650 | /* 37 - 2880x576@50Hz */ |
542 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, | 651 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, |
543 | 3184, 3456, 0, 576, 581, 586, 625, 0, | 652 | 3184, 3456, 0, 576, 581, 586, 625, 0, |
544 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 653 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
545 | /* 2880x576@50Hz */ | 654 | /* 38 - 2880x576@50Hz */ |
546 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, | 655 | { DRM_MODE("2880x576", DRM_MODE_TYPE_DRIVER, 108000, 2880, 2928, |
547 | 3184, 3456, 0, 576, 581, 586, 625, 0, | 656 | 3184, 3456, 0, 576, 581, 586, 625, 0, |
548 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 657 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
549 | /* 1920x1080i@50Hz */ | 658 | /* 39 - 1920x1080i@50Hz */ |
550 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952, | 659 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 72000, 1920, 1952, |
551 | 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, | 660 | 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, |
552 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC | | 661 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC | |
553 | DRM_MODE_FLAG_INTERLACE) }, | 662 | DRM_MODE_FLAG_INTERLACE) }, |
554 | /* 1920x1080i@100Hz */ | 663 | /* 40 - 1920x1080i@100Hz */ |
555 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, | 664 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448, |
556 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, | 665 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, |
557 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | | 666 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
558 | DRM_MODE_FLAG_INTERLACE) }, | 667 | DRM_MODE_FLAG_INTERLACE) }, |
559 | /* 1280x720@100Hz */ | 668 | /* 41 - 1280x720@100Hz */ |
560 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720, | 669 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1720, |
561 | 1760, 1980, 0, 720, 725, 730, 750, 0, | 670 | 1760, 1980, 0, 720, 725, 730, 750, 0, |
562 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 671 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
563 | /* 720x576@100Hz */ | 672 | /* 42 - 720x576@100Hz */ |
564 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, | 673 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, |
565 | 796, 864, 0, 576, 581, 586, 625, 0, | 674 | 796, 864, 0, 576, 581, 586, 625, 0, |
566 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 675 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
567 | /* 720x576@100Hz */ | 676 | /* 43 - 720x576@100Hz */ |
568 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, | 677 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 54000, 720, 732, |
569 | 796, 864, 0, 576, 581, 586, 625, 0, | 678 | 796, 864, 0, 576, 581, 586, 625, 0, |
570 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 679 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
571 | /* 1440x576i@100Hz */ | 680 | /* 44 - 1440x576i@100Hz */ |
572 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, | 681 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, |
573 | 1590, 1728, 0, 576, 580, 586, 625, 0, | 682 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
574 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 683 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
575 | /* 1440x576i@100Hz */ | 684 | DRM_MODE_FLAG_DBLCLK) }, |
685 | /* 45 - 1440x576i@100Hz */ | ||
576 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, | 686 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1464, |
577 | 1590, 1728, 0, 576, 580, 586, 625, 0, | 687 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
578 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 688 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
579 | /* 1920x1080i@120Hz */ | 689 | DRM_MODE_FLAG_DBLCLK) }, |
690 | /* 46 - 1920x1080i@120Hz */ | ||
580 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, | 691 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, |
581 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, | 692 | 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, |
582 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | | 693 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC | |
583 | DRM_MODE_FLAG_INTERLACE) }, | 694 | DRM_MODE_FLAG_INTERLACE) }, |
584 | /* 1280x720@120Hz */ | 695 | /* 47 - 1280x720@120Hz */ |
585 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390, | 696 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 148500, 1280, 1390, |
586 | 1430, 1650, 0, 720, 725, 730, 750, 0, | 697 | 1430, 1650, 0, 720, 725, 730, 750, 0, |
587 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 698 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
588 | /* 720x480@120Hz */ | 699 | /* 48 - 720x480@120Hz */ |
589 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, | 700 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, |
590 | 798, 858, 0, 480, 489, 495, 525, 0, | 701 | 798, 858, 0, 480, 489, 495, 525, 0, |
591 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 702 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
592 | /* 720x480@120Hz */ | 703 | /* 49 - 720x480@120Hz */ |
593 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, | 704 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 54000, 720, 736, |
594 | 798, 858, 0, 480, 489, 495, 525, 0, | 705 | 798, 858, 0, 480, 489, 495, 525, 0, |
595 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 706 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
596 | /* 1440x480i@120Hz */ | 707 | /* 50 - 1440x480i@120Hz */ |
597 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, | 708 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, |
598 | 1602, 1716, 0, 480, 488, 494, 525, 0, | 709 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
599 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 710 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
600 | DRM_MODE_FLAG_INTERLACE) }, | 711 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
601 | /* 1440x480i@120Hz */ | 712 | /* 51 - 1440x480i@120Hz */ |
602 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, | 713 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 54000, 1440, 1478, |
603 | 1602, 1716, 0, 480, 488, 494, 525, 0, | 714 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
604 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 715 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
605 | DRM_MODE_FLAG_INTERLACE) }, | 716 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
606 | /* 720x576@200Hz */ | 717 | /* 52 - 720x576@200Hz */ |
607 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, | 718 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, |
608 | 796, 864, 0, 576, 581, 586, 625, 0, | 719 | 796, 864, 0, 576, 581, 586, 625, 0, |
609 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 720 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
610 | /* 720x576@200Hz */ | 721 | /* 53 - 720x576@200Hz */ |
611 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, | 722 | { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 108000, 720, 732, |
612 | 796, 864, 0, 576, 581, 586, 625, 0, | 723 | 796, 864, 0, 576, 581, 586, 625, 0, |
613 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 724 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
614 | /* 1440x576i@200Hz */ | 725 | /* 54 - 1440x576i@200Hz */ |
615 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, | 726 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, |
616 | 1590, 1728, 0, 576, 580, 586, 625, 0, | 727 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
617 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 728 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
618 | DRM_MODE_FLAG_INTERLACE) }, | 729 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
619 | /* 1440x576i@200Hz */ | 730 | /* 55 - 1440x576i@200Hz */ |
620 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, | 731 | { DRM_MODE("1440x576", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1464, |
621 | 1590, 1728, 0, 576, 580, 586, 625, 0, | 732 | 1590, 1728, 0, 576, 580, 586, 625, 0, |
622 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 733 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
623 | DRM_MODE_FLAG_INTERLACE) }, | 734 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
624 | /* 720x480@240Hz */ | 735 | /* 56 - 720x480@240Hz */ |
625 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, | 736 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, |
626 | 798, 858, 0, 480, 489, 495, 525, 0, | 737 | 798, 858, 0, 480, 489, 495, 525, 0, |
627 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 738 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
628 | /* 720x480@240Hz */ | 739 | /* 57 - 720x480@240Hz */ |
629 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, | 740 | { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 108000, 720, 736, |
630 | 798, 858, 0, 480, 489, 495, 525, 0, | 741 | 798, 858, 0, 480, 489, 495, 525, 0, |
631 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, | 742 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, |
632 | /* 1440x480i@240 */ | 743 | /* 58 - 1440x480i@240 */ |
633 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, | 744 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, |
634 | 1602, 1716, 0, 480, 488, 494, 525, 0, | 745 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
635 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 746 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
636 | DRM_MODE_FLAG_INTERLACE) }, | 747 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
637 | /* 1440x480i@240 */ | 748 | /* 59 - 1440x480i@240 */ |
638 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, | 749 | { DRM_MODE("1440x480", DRM_MODE_TYPE_DRIVER, 108000, 1440, 1478, |
639 | 1602, 1716, 0, 480, 488, 494, 525, 0, | 750 | 1602, 1716, 0, 480, 488, 494, 525, 0, |
640 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 751 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
641 | DRM_MODE_FLAG_INTERLACE) }, | 752 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK) }, |
642 | /* 1280x720@24Hz */ | 753 | /* 60 - 1280x720@24Hz */ |
643 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040, | 754 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 59400, 1280, 3040, |
644 | 3080, 3300, 0, 720, 725, 730, 750, 0, | 755 | 3080, 3300, 0, 720, 725, 730, 750, 0, |
645 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 756 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
646 | /* 1280x720@25Hz */ | 757 | /* 61 - 1280x720@25Hz */ |
647 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700, | 758 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3700, |
648 | 3740, 3960, 0, 720, 725, 730, 750, 0, | 759 | 3740, 3960, 0, 720, 725, 730, 750, 0, |
649 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 760 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
650 | /* 1280x720@30Hz */ | 761 | /* 62 - 1280x720@30Hz */ |
651 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040, | 762 | { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040, |
652 | 3080, 3300, 0, 720, 725, 730, 750, 0, | 763 | 3080, 3300, 0, 720, 725, 730, 750, 0, |
653 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 764 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
654 | /* 1920x1080@120Hz */ | 765 | /* 63 - 1920x1080@120Hz */ |
655 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008, | 766 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2008, |
656 | 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, | 767 | 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, |
657 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 768 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
658 | /* 1920x1080@100Hz */ | 769 | /* 64 - 1920x1080@100Hz */ |
659 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448, | 770 | { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 297000, 1920, 2448, |
660 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, | 771 | 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, |
661 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, | 772 | DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, |
662 | }; | 773 | }; |
663 | static const int drm_num_cea_modes = | 774 | static const int drm_num_cea_modes = ARRAY_SIZE(edid_cea_modes); |
664 | sizeof (edid_cea_modes) / sizeof (edid_cea_modes[0]); | ||
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a0d6e894d97c..6e19dd156be0 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -1083,7 +1083,7 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, | |||
1083 | 1083 | ||
1084 | /* try and find a 1024x768 mode on each connector */ | 1084 | /* try and find a 1024x768 mode on each connector */ |
1085 | can_clone = true; | 1085 | can_clone = true; |
1086 | dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60); | 1086 | dmt_mode = drm_mode_find_dmt(fb_helper->dev, 1024, 768, 60, false); |
1087 | 1087 | ||
1088 | for (i = 0; i < fb_helper->connector_count; i++) { | 1088 | for (i = 0; i < fb_helper->connector_count; i++) { |
1089 | 1089 | ||
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 83114b5e3cee..fc6ded8f318b 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -272,8 +272,7 @@ again: | |||
272 | spin_unlock(&file_priv->table_lock); | 272 | spin_unlock(&file_priv->table_lock); |
273 | if (ret == -EAGAIN) | 273 | if (ret == -EAGAIN) |
274 | goto again; | 274 | goto again; |
275 | 275 | else if (ret) | |
276 | if (ret != 0) | ||
277 | return ret; | 276 | return ret; |
278 | 277 | ||
279 | drm_gem_object_handle_reference(obj); | 278 | drm_gem_object_handle_reference(obj); |
@@ -456,8 +455,7 @@ again: | |||
456 | 455 | ||
457 | if (ret == -EAGAIN) | 456 | if (ret == -EAGAIN) |
458 | goto again; | 457 | goto again; |
459 | 458 | else if (ret) | |
460 | if (ret != 0) | ||
461 | goto err; | 459 | goto err; |
462 | 460 | ||
463 | /* Allocate a reference for the name table. */ | 461 | /* Allocate a reference for the name table. */ |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index aa454f80e109..ae1ccf1d5d96 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -122,11 +122,10 @@ again: | |||
122 | ret = idr_get_new_above(&drm_minors_idr, NULL, | 122 | ret = idr_get_new_above(&drm_minors_idr, NULL, |
123 | base, &new_id); | 123 | base, &new_id); |
124 | mutex_unlock(&dev->struct_mutex); | 124 | mutex_unlock(&dev->struct_mutex); |
125 | if (ret == -EAGAIN) { | 125 | if (ret == -EAGAIN) |
126 | goto again; | 126 | goto again; |
127 | } else if (ret) { | 127 | else if (ret) |
128 | return ret; | 128 | return ret; |
129 | } | ||
130 | 129 | ||
131 | if (new_id >= limit) { | 130 | if (new_id >= limit) { |
132 | idr_remove(&drm_minors_idr, new_id); | 131 | idr_remove(&drm_minors_idr, new_id); |
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index a54cc738926a..62f9b735459b 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c | |||
@@ -49,6 +49,9 @@ static void cdv_disable_vga(struct drm_device *dev) | |||
49 | static int cdv_output_init(struct drm_device *dev) | 49 | static int cdv_output_init(struct drm_device *dev) |
50 | { | 50 | { |
51 | struct drm_psb_private *dev_priv = dev->dev_private; | 51 | struct drm_psb_private *dev_priv = dev->dev_private; |
52 | |||
53 | drm_mode_create_scaling_mode_property(dev); | ||
54 | |||
52 | cdv_disable_vga(dev); | 55 | cdv_disable_vga(dev); |
53 | 56 | ||
54 | cdv_intel_crt_init(dev, &dev_priv->mode_dev); | 57 | cdv_intel_crt_init(dev, &dev_priv->mode_dev); |
@@ -238,6 +241,18 @@ static void cdv_init_pm(struct drm_device *dev) | |||
238 | dev_err(dev->dev, "GPU: power management timed out.\n"); | 241 | dev_err(dev->dev, "GPU: power management timed out.\n"); |
239 | } | 242 | } |
240 | 243 | ||
244 | static void cdv_errata(struct drm_device *dev) | ||
245 | { | ||
246 | /* Disable bonus launch. | ||
247 | * CPU and GPU competes for memory and display misses updates and flickers. | ||
248 | * Worst with dual core, dual displays. | ||
249 | * | ||
250 | * Fixes were done to Win 7 gfx driver to disable a feature called Bonus | ||
251 | * Launch to work around the issue, by degrading performance. | ||
252 | */ | ||
253 | CDV_MSG_WRITE32(3, 0x30, 0x08027108); | ||
254 | } | ||
255 | |||
241 | /** | 256 | /** |
242 | * cdv_save_display_registers - save registers lost on suspend | 257 | * cdv_save_display_registers - save registers lost on suspend |
243 | * @dev: our DRM device | 258 | * @dev: our DRM device |
@@ -355,7 +370,7 @@ static int cdv_restore_display_registers(struct drm_device *dev) | |||
355 | REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR); | 370 | REG_WRITE(PSB_INT_MASK_R, regs->cdv.saveIMR); |
356 | 371 | ||
357 | /* Fix arbitration bug */ | 372 | /* Fix arbitration bug */ |
358 | CDV_MSG_WRITE32(3, 0x30, 0x08027108); | 373 | cdv_errata(dev); |
359 | 374 | ||
360 | drm_mode_config_reset(dev); | 375 | drm_mode_config_reset(dev); |
361 | 376 | ||
@@ -447,13 +462,48 @@ static void cdv_get_core_freq(struct drm_device *dev) | |||
447 | } | 462 | } |
448 | } | 463 | } |
449 | 464 | ||
465 | static void cdv_hotplug_work_func(struct work_struct *work) | ||
466 | { | ||
467 | struct drm_psb_private *dev_priv = container_of(work, struct drm_psb_private, | ||
468 | hotplug_work); | ||
469 | struct drm_device *dev = dev_priv->dev; | ||
470 | |||
471 | /* Just fire off a uevent and let userspace tell us what to do */ | ||
472 | drm_helper_hpd_irq_event(dev); | ||
473 | } | ||
474 | |||
475 | /* The core driver has received a hotplug IRQ. We are in IRQ context | ||
476 | so extract the needed information and kick off queued processing */ | ||
477 | |||
478 | static int cdv_hotplug_event(struct drm_device *dev) | ||
479 | { | ||
480 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
481 | schedule_work(&dev_priv->hotplug_work); | ||
482 | REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); | ||
483 | return 1; | ||
484 | } | ||
485 | |||
486 | static void cdv_hotplug_enable(struct drm_device *dev, bool on) | ||
487 | { | ||
488 | if (on) { | ||
489 | u32 hotplug = REG_READ(PORT_HOTPLUG_EN); | ||
490 | hotplug |= HDMIB_HOTPLUG_INT_EN | HDMIC_HOTPLUG_INT_EN | | ||
491 | HDMID_HOTPLUG_INT_EN | CRT_HOTPLUG_INT_EN; | ||
492 | REG_WRITE(PORT_HOTPLUG_EN, hotplug); | ||
493 | } else { | ||
494 | REG_WRITE(PORT_HOTPLUG_EN, 0); | ||
495 | REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); | ||
496 | } | ||
497 | } | ||
498 | |||
450 | static int cdv_chip_setup(struct drm_device *dev) | 499 | static int cdv_chip_setup(struct drm_device *dev) |
451 | { | 500 | { |
501 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
502 | INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func); | ||
452 | cdv_get_core_freq(dev); | 503 | cdv_get_core_freq(dev); |
453 | gma_intel_opregion_init(dev); | 504 | gma_intel_opregion_init(dev); |
454 | psb_intel_init_bios(dev); | 505 | psb_intel_init_bios(dev); |
455 | REG_WRITE(PORT_HOTPLUG_EN, 0); | 506 | cdv_hotplug_enable(dev, false); |
456 | REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); | ||
457 | return 0; | 507 | return 0; |
458 | } | 508 | } |
459 | 509 | ||
@@ -464,13 +514,18 @@ const struct psb_ops cdv_chip_ops = { | |||
464 | .accel_2d = 0, | 514 | .accel_2d = 0, |
465 | .pipes = 2, | 515 | .pipes = 2, |
466 | .crtcs = 2, | 516 | .crtcs = 2, |
517 | .hdmi_mask = (1 << 0) | (1 << 1), | ||
518 | .lvds_mask = (1 << 1), | ||
467 | .sgx_offset = MRST_SGX_OFFSET, | 519 | .sgx_offset = MRST_SGX_OFFSET, |
468 | .chip_setup = cdv_chip_setup, | 520 | .chip_setup = cdv_chip_setup, |
521 | .errata = cdv_errata, | ||
469 | 522 | ||
470 | .crtc_helper = &cdv_intel_helper_funcs, | 523 | .crtc_helper = &cdv_intel_helper_funcs, |
471 | .crtc_funcs = &cdv_intel_crtc_funcs, | 524 | .crtc_funcs = &cdv_intel_crtc_funcs, |
472 | 525 | ||
473 | .output_init = cdv_output_init, | 526 | .output_init = cdv_output_init, |
527 | .hotplug = cdv_hotplug_event, | ||
528 | .hotplug_enable = cdv_hotplug_enable, | ||
474 | 529 | ||
475 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE | 530 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE |
476 | .backlight_init = cdv_backlight_init, | 531 | .backlight_init = cdv_backlight_init, |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c index a71a6cd95bdd..187422018601 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_crt.c +++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c | |||
@@ -67,8 +67,6 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
67 | static int cdv_intel_crt_mode_valid(struct drm_connector *connector, | 67 | static int cdv_intel_crt_mode_valid(struct drm_connector *connector, |
68 | struct drm_display_mode *mode) | 68 | struct drm_display_mode *mode) |
69 | { | 69 | { |
70 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
71 | int max_clock = 0; | ||
72 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 70 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
73 | return MODE_NO_DBLESCAN; | 71 | return MODE_NO_DBLESCAN; |
74 | 72 | ||
@@ -77,18 +75,9 @@ static int cdv_intel_crt_mode_valid(struct drm_connector *connector, | |||
77 | return MODE_CLOCK_LOW; | 75 | return MODE_CLOCK_LOW; |
78 | 76 | ||
79 | /* The max clock for CDV is 355 instead of 400 */ | 77 | /* The max clock for CDV is 355 instead of 400 */ |
80 | max_clock = 355000; | 78 | if (mode->clock > 355000) |
81 | if (mode->clock > max_clock) | ||
82 | return MODE_CLOCK_HIGH; | 79 | return MODE_CLOCK_HIGH; |
83 | 80 | ||
84 | if (mode->hdisplay > 1680 || mode->vdisplay > 1050) | ||
85 | return MODE_PANEL; | ||
86 | |||
87 | /* We assume worst case scenario of 32 bpp here, since we don't know */ | ||
88 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | ||
89 | dev_priv->vram_stolen_size) | ||
90 | return MODE_MEM; | ||
91 | |||
92 | return MODE_OK; | 81 | return MODE_OK; |
93 | } | 82 | } |
94 | 83 | ||
@@ -156,13 +145,7 @@ static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector, | |||
156 | struct drm_device *dev = connector->dev; | 145 | struct drm_device *dev = connector->dev; |
157 | u32 hotplug_en; | 146 | u32 hotplug_en; |
158 | int i, tries = 0, ret = false; | 147 | int i, tries = 0, ret = false; |
159 | u32 adpa_orig; | 148 | u32 orig; |
160 | |||
161 | /* disable the DAC when doing the hotplug detection */ | ||
162 | |||
163 | adpa_orig = REG_READ(ADPA); | ||
164 | |||
165 | REG_WRITE(ADPA, adpa_orig & ~(ADPA_DAC_ENABLE)); | ||
166 | 149 | ||
167 | /* | 150 | /* |
168 | * On a CDV thep, CRT detect sequence need to be done twice | 151 | * On a CDV thep, CRT detect sequence need to be done twice |
@@ -170,7 +153,7 @@ static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector, | |||
170 | */ | 153 | */ |
171 | tries = 2; | 154 | tries = 2; |
172 | 155 | ||
173 | hotplug_en = REG_READ(PORT_HOTPLUG_EN); | 156 | orig = hotplug_en = REG_READ(PORT_HOTPLUG_EN); |
174 | hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK); | 157 | hotplug_en &= ~(CRT_HOTPLUG_DETECT_MASK); |
175 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; | 158 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
176 | 159 | ||
@@ -195,8 +178,11 @@ static bool cdv_intel_crt_detect_hotplug(struct drm_connector *connector, | |||
195 | CRT_HOTPLUG_MONITOR_NONE) | 178 | CRT_HOTPLUG_MONITOR_NONE) |
196 | ret = true; | 179 | ret = true; |
197 | 180 | ||
198 | /* Restore the saved ADPA */ | 181 | /* clear the interrupt we just generated, if any */ |
199 | REG_WRITE(ADPA, adpa_orig); | 182 | REG_WRITE(PORT_HOTPLUG_STAT, CRT_HOTPLUG_INT_STATUS); |
183 | |||
184 | /* and put the bits back */ | ||
185 | REG_WRITE(PORT_HOTPLUG_EN, orig); | ||
200 | return ret; | 186 | return ret; |
201 | } | 187 | } |
202 | 188 | ||
diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index be8455919b33..2fab77854971 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c | |||
@@ -216,7 +216,7 @@ static void cdv_sb_reset(struct drm_device *dev) | |||
216 | */ | 216 | */ |
217 | static int | 217 | static int |
218 | cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | 218 | cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, |
219 | struct cdv_intel_clock_t *clock) | 219 | struct cdv_intel_clock_t *clock, bool is_lvds) |
220 | { | 220 | { |
221 | struct psb_intel_crtc *psb_crtc = | 221 | struct psb_intel_crtc *psb_crtc = |
222 | to_psb_intel_crtc(crtc); | 222 | to_psb_intel_crtc(crtc); |
@@ -224,14 +224,15 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
224 | u32 m, n_vco, p; | 224 | u32 m, n_vco, p; |
225 | int ret = 0; | 225 | int ret = 0; |
226 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 226 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
227 | int ref_sfr = (pipe == 0) ? SB_REF_DPLLA : SB_REF_DPLLB; | ||
227 | u32 ref_value; | 228 | u32 ref_value; |
229 | u32 lane_reg, lane_value; | ||
228 | 230 | ||
229 | cdv_sb_reset(dev); | 231 | cdv_sb_reset(dev); |
230 | 232 | ||
231 | if ((REG_READ(dpll_reg) & DPLL_SYNCLOCK_ENABLE) == 0) { | 233 | REG_WRITE(dpll_reg, DPLL_SYNCLOCK_ENABLE | DPLL_VGA_MODE_DIS); |
232 | DRM_ERROR("Attempting to set DPLL with refclk disabled\n"); | 234 | |
233 | return -EBUSY; | 235 | udelay(100); |
234 | } | ||
235 | 236 | ||
236 | /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */ | 237 | /* Follow the BIOS and write the REF/SFR Register. Hardcoded value */ |
237 | ref_value = 0x68A701; | 238 | ref_value = 0x68A701; |
@@ -241,6 +242,35 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
241 | /* We don't know what the other fields of these regs are, so | 242 | /* We don't know what the other fields of these regs are, so |
242 | * leave them in place. | 243 | * leave them in place. |
243 | */ | 244 | */ |
245 | /* | ||
246 | * The BIT 14:13 of 0x8010/0x8030 is used to select the ref clk | ||
247 | * for the pipe A/B. Display spec 1.06 has wrong definition. | ||
248 | * Correct definition is like below: | ||
249 | * | ||
250 | * refclka mean use clock from same PLL | ||
251 | * | ||
252 | * if DPLLA sets 01 and DPLLB sets 01, they use clock from their pll | ||
253 | * | ||
254 | * if DPLLA sets 01 and DPLLB sets 02, both use clk from DPLLA | ||
255 | * | ||
256 | */ | ||
257 | ret = cdv_sb_read(dev, ref_sfr, &ref_value); | ||
258 | if (ret) | ||
259 | return ret; | ||
260 | ref_value &= ~(REF_CLK_MASK); | ||
261 | |||
262 | /* use DPLL_A for pipeB on CRT/HDMI */ | ||
263 | if (pipe == 1 && !is_lvds) { | ||
264 | DRM_DEBUG_KMS("use DPLLA for pipe B\n"); | ||
265 | ref_value |= REF_CLK_DPLLA; | ||
266 | } else { | ||
267 | DRM_DEBUG_KMS("use their DPLL for pipe A/B\n"); | ||
268 | ref_value |= REF_CLK_DPLL; | ||
269 | } | ||
270 | ret = cdv_sb_write(dev, ref_sfr, ref_value); | ||
271 | if (ret) | ||
272 | return ret; | ||
273 | |||
244 | ret = cdv_sb_read(dev, SB_M(pipe), &m); | 274 | ret = cdv_sb_read(dev, SB_M(pipe), &m); |
245 | if (ret) | 275 | if (ret) |
246 | return ret; | 276 | return ret; |
@@ -307,36 +337,29 @@ cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, | |||
307 | if (ret) | 337 | if (ret) |
308 | return ret; | 338 | return ret; |
309 | 339 | ||
310 | /* always Program the Lane Register for the Pipe A*/ | 340 | lane_reg = PSB_LANE0; |
311 | if (pipe == 0) { | 341 | cdv_sb_read(dev, lane_reg, &lane_value); |
312 | /* Program the Lane0/1 for HDMI B */ | 342 | lane_value &= ~(LANE_PLL_MASK); |
313 | u32 lane_reg, lane_value; | 343 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); |
314 | 344 | cdv_sb_write(dev, lane_reg, lane_value); | |
315 | lane_reg = PSB_LANE0; | 345 | |
316 | cdv_sb_read(dev, lane_reg, &lane_value); | 346 | lane_reg = PSB_LANE1; |
317 | lane_value &= ~(LANE_PLL_MASK); | 347 | cdv_sb_read(dev, lane_reg, &lane_value); |
318 | lane_value |= LANE_PLL_ENABLE; | 348 | lane_value &= ~(LANE_PLL_MASK); |
319 | cdv_sb_write(dev, lane_reg, lane_value); | 349 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); |
320 | 350 | cdv_sb_write(dev, lane_reg, lane_value); | |
321 | lane_reg = PSB_LANE1; | 351 | |
322 | cdv_sb_read(dev, lane_reg, &lane_value); | 352 | lane_reg = PSB_LANE2; |
323 | lane_value &= ~(LANE_PLL_MASK); | 353 | cdv_sb_read(dev, lane_reg, &lane_value); |
324 | lane_value |= LANE_PLL_ENABLE; | 354 | lane_value &= ~(LANE_PLL_MASK); |
325 | cdv_sb_write(dev, lane_reg, lane_value); | 355 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); |
326 | 356 | cdv_sb_write(dev, lane_reg, lane_value); | |
327 | /* Program the Lane2/3 for HDMI C */ | 357 | |
328 | lane_reg = PSB_LANE2; | 358 | lane_reg = PSB_LANE3; |
329 | cdv_sb_read(dev, lane_reg, &lane_value); | 359 | cdv_sb_read(dev, lane_reg, &lane_value); |
330 | lane_value &= ~(LANE_PLL_MASK); | 360 | lane_value &= ~(LANE_PLL_MASK); |
331 | lane_value |= LANE_PLL_ENABLE; | 361 | lane_value |= LANE_PLL_ENABLE | LANE_PLL_PIPE(pipe); |
332 | cdv_sb_write(dev, lane_reg, lane_value); | 362 | cdv_sb_write(dev, lane_reg, lane_value); |
333 | |||
334 | lane_reg = PSB_LANE3; | ||
335 | cdv_sb_read(dev, lane_reg, &lane_value); | ||
336 | lane_value &= ~(LANE_PLL_MASK); | ||
337 | lane_value |= LANE_PLL_ENABLE; | ||
338 | cdv_sb_write(dev, lane_reg, lane_value); | ||
339 | } | ||
340 | 363 | ||
341 | return 0; | 364 | return 0; |
342 | } | 365 | } |
@@ -553,6 +576,200 @@ psb_intel_pipe_set_base_exit: | |||
553 | return ret; | 576 | return ret; |
554 | } | 577 | } |
555 | 578 | ||
579 | #define FIFO_PIPEA (1 << 0) | ||
580 | #define FIFO_PIPEB (1 << 1) | ||
581 | |||
582 | static bool cdv_intel_pipe_enabled(struct drm_device *dev, int pipe) | ||
583 | { | ||
584 | struct drm_crtc *crtc; | ||
585 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
586 | struct psb_intel_crtc *psb_intel_crtc = NULL; | ||
587 | |||
588 | crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | ||
589 | psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
590 | |||
591 | if (crtc->fb == NULL || !psb_intel_crtc->active) | ||
592 | return false; | ||
593 | return true; | ||
594 | } | ||
595 | |||
596 | static bool cdv_intel_single_pipe_active (struct drm_device *dev) | ||
597 | { | ||
598 | uint32_t pipe_enabled = 0; | ||
599 | |||
600 | if (cdv_intel_pipe_enabled(dev, 0)) | ||
601 | pipe_enabled |= FIFO_PIPEA; | ||
602 | |||
603 | if (cdv_intel_pipe_enabled(dev, 1)) | ||
604 | pipe_enabled |= FIFO_PIPEB; | ||
605 | |||
606 | |||
607 | DRM_DEBUG_KMS("pipe enabled %x\n", pipe_enabled); | ||
608 | |||
609 | if (pipe_enabled == FIFO_PIPEA || pipe_enabled == FIFO_PIPEB) | ||
610 | return true; | ||
611 | else | ||
612 | return false; | ||
613 | } | ||
614 | |||
615 | static bool is_pipeb_lvds(struct drm_device *dev, struct drm_crtc *crtc) | ||
616 | { | ||
617 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
618 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
619 | struct drm_connector *connector; | ||
620 | |||
621 | if (psb_intel_crtc->pipe != 1) | ||
622 | return false; | ||
623 | |||
624 | list_for_each_entry(connector, &mode_config->connector_list, head) { | ||
625 | struct psb_intel_encoder *psb_intel_encoder = | ||
626 | psb_intel_attached_encoder(connector); | ||
627 | |||
628 | if (!connector->encoder | ||
629 | || connector->encoder->crtc != crtc) | ||
630 | continue; | ||
631 | |||
632 | if (psb_intel_encoder->type == INTEL_OUTPUT_LVDS) | ||
633 | return true; | ||
634 | } | ||
635 | |||
636 | return false; | ||
637 | } | ||
638 | |||
639 | static void cdv_intel_disable_self_refresh (struct drm_device *dev) | ||
640 | { | ||
641 | if (REG_READ(FW_BLC_SELF) & FW_BLC_SELF_EN) { | ||
642 | |||
643 | /* Disable self-refresh before adjust WM */ | ||
644 | REG_WRITE(FW_BLC_SELF, (REG_READ(FW_BLC_SELF) & ~FW_BLC_SELF_EN)); | ||
645 | REG_READ(FW_BLC_SELF); | ||
646 | |||
647 | cdv_intel_wait_for_vblank(dev); | ||
648 | |||
649 | /* Cedarview workaround to write ovelay plane, which force to leave | ||
650 | * MAX_FIFO state. | ||
651 | */ | ||
652 | REG_WRITE(OV_OVADD, 0/*dev_priv->ovl_offset*/); | ||
653 | REG_READ(OV_OVADD); | ||
654 | |||
655 | cdv_intel_wait_for_vblank(dev); | ||
656 | } | ||
657 | |||
658 | } | ||
659 | |||
660 | static void cdv_intel_update_watermark (struct drm_device *dev, struct drm_crtc *crtc) | ||
661 | { | ||
662 | |||
663 | if (cdv_intel_single_pipe_active(dev)) { | ||
664 | u32 fw; | ||
665 | |||
666 | fw = REG_READ(DSPFW1); | ||
667 | fw &= ~DSP_FIFO_SR_WM_MASK; | ||
668 | fw |= (0x7e << DSP_FIFO_SR_WM_SHIFT); | ||
669 | fw &= ~CURSOR_B_FIFO_WM_MASK; | ||
670 | fw |= (0x4 << CURSOR_B_FIFO_WM_SHIFT); | ||
671 | REG_WRITE(DSPFW1, fw); | ||
672 | |||
673 | fw = REG_READ(DSPFW2); | ||
674 | fw &= ~CURSOR_A_FIFO_WM_MASK; | ||
675 | fw |= (0x6 << CURSOR_A_FIFO_WM_SHIFT); | ||
676 | fw &= ~DSP_PLANE_C_FIFO_WM_MASK; | ||
677 | fw |= (0x8 << DSP_PLANE_C_FIFO_WM_SHIFT); | ||
678 | REG_WRITE(DSPFW2, fw); | ||
679 | |||
680 | REG_WRITE(DSPFW3, 0x36000000); | ||
681 | |||
682 | /* ignore FW4 */ | ||
683 | |||
684 | if (is_pipeb_lvds(dev, crtc)) { | ||
685 | REG_WRITE(DSPFW5, 0x00040330); | ||
686 | } else { | ||
687 | fw = (3 << DSP_PLANE_B_FIFO_WM1_SHIFT) | | ||
688 | (4 << DSP_PLANE_A_FIFO_WM1_SHIFT) | | ||
689 | (3 << CURSOR_B_FIFO_WM1_SHIFT) | | ||
690 | (4 << CURSOR_FIFO_SR_WM1_SHIFT); | ||
691 | REG_WRITE(DSPFW5, fw); | ||
692 | } | ||
693 | |||
694 | REG_WRITE(DSPFW6, 0x10); | ||
695 | |||
696 | cdv_intel_wait_for_vblank(dev); | ||
697 | |||
698 | /* enable self-refresh for single pipe active */ | ||
699 | REG_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN); | ||
700 | REG_READ(FW_BLC_SELF); | ||
701 | cdv_intel_wait_for_vblank(dev); | ||
702 | |||
703 | } else { | ||
704 | |||
705 | /* HW team suggested values... */ | ||
706 | REG_WRITE(DSPFW1, 0x3f880808); | ||
707 | REG_WRITE(DSPFW2, 0x0b020202); | ||
708 | REG_WRITE(DSPFW3, 0x24000000); | ||
709 | REG_WRITE(DSPFW4, 0x08030202); | ||
710 | REG_WRITE(DSPFW5, 0x01010101); | ||
711 | REG_WRITE(DSPFW6, 0x1d0); | ||
712 | |||
713 | cdv_intel_wait_for_vblank(dev); | ||
714 | |||
715 | cdv_intel_disable_self_refresh(dev); | ||
716 | |||
717 | } | ||
718 | } | ||
719 | |||
720 | /** Loads the palette/gamma unit for the CRTC with the prepared values */ | ||
721 | static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) | ||
722 | { | ||
723 | struct drm_device *dev = crtc->dev; | ||
724 | struct drm_psb_private *dev_priv = | ||
725 | (struct drm_psb_private *)dev->dev_private; | ||
726 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
727 | int palreg = PALETTE_A; | ||
728 | int i; | ||
729 | |||
730 | /* The clocks have to be on to load the palette. */ | ||
731 | if (!crtc->enabled) | ||
732 | return; | ||
733 | |||
734 | switch (psb_intel_crtc->pipe) { | ||
735 | case 0: | ||
736 | break; | ||
737 | case 1: | ||
738 | palreg = PALETTE_B; | ||
739 | break; | ||
740 | case 2: | ||
741 | palreg = PALETTE_C; | ||
742 | break; | ||
743 | default: | ||
744 | dev_err(dev->dev, "Illegal Pipe Number.\n"); | ||
745 | return; | ||
746 | } | ||
747 | |||
748 | if (gma_power_begin(dev, false)) { | ||
749 | for (i = 0; i < 256; i++) { | ||
750 | REG_WRITE(palreg + 4 * i, | ||
751 | ((psb_intel_crtc->lut_r[i] + | ||
752 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
753 | ((psb_intel_crtc->lut_g[i] + | ||
754 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
755 | (psb_intel_crtc->lut_b[i] + | ||
756 | psb_intel_crtc->lut_adj[i])); | ||
757 | } | ||
758 | gma_power_end(dev); | ||
759 | } else { | ||
760 | for (i = 0; i < 256; i++) { | ||
761 | dev_priv->regs.psb.save_palette_a[i] = | ||
762 | ((psb_intel_crtc->lut_r[i] + | ||
763 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
764 | ((psb_intel_crtc->lut_g[i] + | ||
765 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
766 | (psb_intel_crtc->lut_b[i] + | ||
767 | psb_intel_crtc->lut_adj[i]); | ||
768 | } | ||
769 | |||
770 | } | ||
771 | } | ||
772 | |||
556 | /** | 773 | /** |
557 | * Sets the power management mode of the pipe and plane. | 774 | * Sets the power management mode of the pipe and plane. |
558 | * | 775 | * |
@@ -568,15 +785,23 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
568 | int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; | 785 | int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; |
569 | int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; | 786 | int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; |
570 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; | 787 | int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; |
788 | int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT; | ||
571 | u32 temp; | 789 | u32 temp; |
572 | 790 | ||
573 | /* XXX: When our outputs are all unaware of DPMS modes other than off | 791 | /* XXX: When our outputs are all unaware of DPMS modes other than off |
574 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | 792 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. |
575 | */ | 793 | */ |
794 | cdv_intel_disable_self_refresh(dev); | ||
795 | |||
576 | switch (mode) { | 796 | switch (mode) { |
577 | case DRM_MODE_DPMS_ON: | 797 | case DRM_MODE_DPMS_ON: |
578 | case DRM_MODE_DPMS_STANDBY: | 798 | case DRM_MODE_DPMS_STANDBY: |
579 | case DRM_MODE_DPMS_SUSPEND: | 799 | case DRM_MODE_DPMS_SUSPEND: |
800 | if (psb_intel_crtc->active) | ||
801 | return; | ||
802 | |||
803 | psb_intel_crtc->active = true; | ||
804 | |||
580 | /* Enable the DPLL */ | 805 | /* Enable the DPLL */ |
581 | temp = REG_READ(dpll_reg); | 806 | temp = REG_READ(dpll_reg); |
582 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 807 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
@@ -611,13 +836,26 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
611 | if ((temp & PIPEACONF_ENABLE) == 0) | 836 | if ((temp & PIPEACONF_ENABLE) == 0) |
612 | REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); | 837 | REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); |
613 | 838 | ||
614 | psb_intel_crtc_load_lut(crtc); | 839 | temp = REG_READ(pipestat_reg); |
840 | temp &= ~(0xFFFF); | ||
841 | temp |= PIPE_FIFO_UNDERRUN; | ||
842 | REG_WRITE(pipestat_reg, temp); | ||
843 | REG_READ(pipestat_reg); | ||
844 | |||
845 | cdv_intel_update_watermark(dev, crtc); | ||
846 | cdv_intel_crtc_load_lut(crtc); | ||
615 | 847 | ||
616 | /* Give the overlay scaler a chance to enable | 848 | /* Give the overlay scaler a chance to enable |
617 | * if it's on this pipe */ | 849 | * if it's on this pipe */ |
618 | /* psb_intel_crtc_dpms_video(crtc, true); TODO */ | 850 | /* psb_intel_crtc_dpms_video(crtc, true); TODO */ |
851 | psb_intel_crtc->crtc_enable = true; | ||
619 | break; | 852 | break; |
620 | case DRM_MODE_DPMS_OFF: | 853 | case DRM_MODE_DPMS_OFF: |
854 | if (!psb_intel_crtc->active) | ||
855 | return; | ||
856 | |||
857 | psb_intel_crtc->active = false; | ||
858 | |||
621 | /* Give the overlay scaler a chance to disable | 859 | /* Give the overlay scaler a chance to disable |
622 | * if it's on this pipe */ | 860 | * if it's on this pipe */ |
623 | /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ | 861 | /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */ |
@@ -627,6 +865,7 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
627 | 865 | ||
628 | /* Jim Bish - changed pipe/plane here as well. */ | 866 | /* Jim Bish - changed pipe/plane here as well. */ |
629 | 867 | ||
868 | drm_vblank_off(dev, pipe); | ||
630 | /* Wait for vblank for the disable to take effect */ | 869 | /* Wait for vblank for the disable to take effect */ |
631 | cdv_intel_wait_for_vblank(dev); | 870 | cdv_intel_wait_for_vblank(dev); |
632 | 871 | ||
@@ -660,6 +899,8 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
660 | 899 | ||
661 | /* Wait for the clocks to turn off. */ | 900 | /* Wait for the clocks to turn off. */ |
662 | udelay(150); | 901 | udelay(150); |
902 | cdv_intel_update_watermark(dev, crtc); | ||
903 | psb_intel_crtc->crtc_enable = false; | ||
663 | break; | 904 | break; |
664 | } | 905 | } |
665 | /*Set FIFO Watermarks*/ | 906 | /*Set FIFO Watermarks*/ |
@@ -709,6 +950,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
709 | struct drm_framebuffer *old_fb) | 950 | struct drm_framebuffer *old_fb) |
710 | { | 951 | { |
711 | struct drm_device *dev = crtc->dev; | 952 | struct drm_device *dev = crtc->dev; |
953 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
712 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | 954 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); |
713 | int pipe = psb_intel_crtc->pipe; | 955 | int pipe = psb_intel_crtc->pipe; |
714 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 956 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
@@ -757,13 +999,18 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
757 | } | 999 | } |
758 | } | 1000 | } |
759 | 1001 | ||
760 | refclk = 96000; | 1002 | if (dev_priv->dplla_96mhz) |
761 | 1003 | /* low-end sku, 96/100 mhz */ | |
762 | /* Hack selection about ref clk for CRT */ | 1004 | refclk = 96000; |
763 | /* Select 27MHz as the reference clk for HDMI */ | 1005 | else |
764 | if (is_crt || is_hdmi) | 1006 | /* high-end sku, 27/100 mhz */ |
765 | refclk = 27000; | 1007 | refclk = 27000; |
766 | 1008 | ||
1009 | if (is_lvds && dev_priv->lvds_use_ssc) { | ||
1010 | refclk = dev_priv->lvds_ssc_freq * 1000; | ||
1011 | DRM_DEBUG_KMS("Use SSC reference clock %d Mhz\n", dev_priv->lvds_ssc_freq); | ||
1012 | } | ||
1013 | |||
767 | drm_mode_debug_printmodeline(adjusted_mode); | 1014 | drm_mode_debug_printmodeline(adjusted_mode); |
768 | 1015 | ||
769 | ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, | 1016 | ok = cdv_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, |
@@ -779,14 +1026,13 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
779 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ | 1026 | /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ |
780 | dpll |= 3; | 1027 | dpll |= 3; |
781 | } | 1028 | } |
782 | dpll |= PLL_REF_INPUT_DREFCLK; | 1029 | /* dpll |= PLL_REF_INPUT_DREFCLK; */ |
783 | 1030 | ||
784 | dpll |= DPLL_SYNCLOCK_ENABLE; | 1031 | dpll |= DPLL_SYNCLOCK_ENABLE; |
785 | dpll |= DPLL_VGA_MODE_DIS; | 1032 | /* if (is_lvds) |
786 | if (is_lvds) | ||
787 | dpll |= DPLLB_MODE_LVDS; | 1033 | dpll |= DPLLB_MODE_LVDS; |
788 | else | 1034 | else |
789 | dpll |= DPLLB_MODE_DAC_SERIAL; | 1035 | dpll |= DPLLB_MODE_DAC_SERIAL; */ |
790 | /* dpll |= (2 << 11); */ | 1036 | /* dpll |= (2 << 11); */ |
791 | 1037 | ||
792 | /* setup pipeconf */ | 1038 | /* setup pipeconf */ |
@@ -806,7 +1052,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
806 | REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); | 1052 | REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); |
807 | REG_READ(dpll_reg); | 1053 | REG_READ(dpll_reg); |
808 | 1054 | ||
809 | cdv_dpll_set_clock_cdv(dev, crtc, &clock); | 1055 | cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds); |
810 | 1056 | ||
811 | udelay(150); | 1057 | udelay(150); |
812 | 1058 | ||
@@ -903,58 +1149,6 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, | |||
903 | return 0; | 1149 | return 0; |
904 | } | 1150 | } |
905 | 1151 | ||
906 | /** Loads the palette/gamma unit for the CRTC with the prepared values */ | ||
907 | static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) | ||
908 | { | ||
909 | struct drm_device *dev = crtc->dev; | ||
910 | struct drm_psb_private *dev_priv = | ||
911 | (struct drm_psb_private *)dev->dev_private; | ||
912 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); | ||
913 | int palreg = PALETTE_A; | ||
914 | int i; | ||
915 | |||
916 | /* The clocks have to be on to load the palette. */ | ||
917 | if (!crtc->enabled) | ||
918 | return; | ||
919 | |||
920 | switch (psb_intel_crtc->pipe) { | ||
921 | case 0: | ||
922 | break; | ||
923 | case 1: | ||
924 | palreg = PALETTE_B; | ||
925 | break; | ||
926 | case 2: | ||
927 | palreg = PALETTE_C; | ||
928 | break; | ||
929 | default: | ||
930 | dev_err(dev->dev, "Illegal Pipe Number.\n"); | ||
931 | return; | ||
932 | } | ||
933 | |||
934 | if (gma_power_begin(dev, false)) { | ||
935 | for (i = 0; i < 256; i++) { | ||
936 | REG_WRITE(palreg + 4 * i, | ||
937 | ((psb_intel_crtc->lut_r[i] + | ||
938 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
939 | ((psb_intel_crtc->lut_g[i] + | ||
940 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
941 | (psb_intel_crtc->lut_b[i] + | ||
942 | psb_intel_crtc->lut_adj[i])); | ||
943 | } | ||
944 | gma_power_end(dev); | ||
945 | } else { | ||
946 | for (i = 0; i < 256; i++) { | ||
947 | dev_priv->regs.psb.save_palette_a[i] = | ||
948 | ((psb_intel_crtc->lut_r[i] + | ||
949 | psb_intel_crtc->lut_adj[i]) << 16) | | ||
950 | ((psb_intel_crtc->lut_g[i] + | ||
951 | psb_intel_crtc->lut_adj[i]) << 8) | | ||
952 | (psb_intel_crtc->lut_b[i] + | ||
953 | psb_intel_crtc->lut_adj[i]); | ||
954 | } | ||
955 | |||
956 | } | ||
957 | } | ||
958 | 1152 | ||
959 | /** | 1153 | /** |
960 | * Save HW states of giving crtc | 1154 | * Save HW states of giving crtc |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index 8d5269555005..88b59d4a7b7f 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c | |||
@@ -242,8 +242,6 @@ static int cdv_hdmi_get_modes(struct drm_connector *connector) | |||
242 | static int cdv_hdmi_mode_valid(struct drm_connector *connector, | 242 | static int cdv_hdmi_mode_valid(struct drm_connector *connector, |
243 | struct drm_display_mode *mode) | 243 | struct drm_display_mode *mode) |
244 | { | 244 | { |
245 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
246 | |||
247 | if (mode->clock > 165000) | 245 | if (mode->clock > 165000) |
248 | return MODE_CLOCK_HIGH; | 246 | return MODE_CLOCK_HIGH; |
249 | if (mode->clock < 20000) | 247 | if (mode->clock < 20000) |
@@ -257,11 +255,6 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector, | |||
257 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | 255 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
258 | return MODE_NO_INTERLACE; | 256 | return MODE_NO_INTERLACE; |
259 | 257 | ||
260 | /* We assume worst case scenario of 32 bpp here, since we don't know */ | ||
261 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | ||
262 | dev_priv->vram_stolen_size) | ||
263 | return MODE_MEM; | ||
264 | |||
265 | return MODE_OK; | 258 | return MODE_OK; |
266 | } | 259 | } |
267 | 260 | ||
diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index 8359c1a3f45f..44a8353d92bf 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c | |||
@@ -356,6 +356,8 @@ static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder, | |||
356 | { | 356 | { |
357 | struct drm_device *dev = encoder->dev; | 357 | struct drm_device *dev = encoder->dev; |
358 | struct drm_psb_private *dev_priv = dev->dev_private; | 358 | struct drm_psb_private *dev_priv = dev->dev_private; |
359 | struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc( | ||
360 | encoder->crtc); | ||
359 | u32 pfit_control; | 361 | u32 pfit_control; |
360 | 362 | ||
361 | /* | 363 | /* |
@@ -377,6 +379,8 @@ static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder, | |||
377 | else | 379 | else |
378 | pfit_control = 0; | 380 | pfit_control = 0; |
379 | 381 | ||
382 | pfit_control |= psb_intel_crtc->pipe << PFIT_PIPE_SHIFT; | ||
383 | |||
380 | if (dev_priv->lvds_dither) | 384 | if (dev_priv->lvds_dither) |
381 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; | 385 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; |
382 | 386 | ||
@@ -556,6 +560,56 @@ const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { | |||
556 | .destroy = cdv_intel_lvds_enc_destroy, | 560 | .destroy = cdv_intel_lvds_enc_destroy, |
557 | }; | 561 | }; |
558 | 562 | ||
563 | /* | ||
564 | * Enumerate the child dev array parsed from VBT to check whether | ||
565 | * the LVDS is present. | ||
566 | * If it is present, return 1. | ||
567 | * If it is not present, return false. | ||
568 | * If no child dev is parsed from VBT, it assumes that the LVDS is present. | ||
569 | */ | ||
570 | static bool lvds_is_present_in_vbt(struct drm_device *dev, | ||
571 | u8 *i2c_pin) | ||
572 | { | ||
573 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
574 | int i; | ||
575 | |||
576 | if (!dev_priv->child_dev_num) | ||
577 | return true; | ||
578 | |||
579 | for (i = 0; i < dev_priv->child_dev_num; i++) { | ||
580 | struct child_device_config *child = dev_priv->child_dev + i; | ||
581 | |||
582 | /* If the device type is not LFP, continue. | ||
583 | * We have to check both the new identifiers as well as the | ||
584 | * old for compatibility with some BIOSes. | ||
585 | */ | ||
586 | if (child->device_type != DEVICE_TYPE_INT_LFP && | ||
587 | child->device_type != DEVICE_TYPE_LFP) | ||
588 | continue; | ||
589 | |||
590 | if (child->i2c_pin) | ||
591 | *i2c_pin = child->i2c_pin; | ||
592 | |||
593 | /* However, we cannot trust the BIOS writers to populate | ||
594 | * the VBT correctly. Since LVDS requires additional | ||
595 | * information from AIM blocks, a non-zero addin offset is | ||
596 | * a good indicator that the LVDS is actually present. | ||
597 | */ | ||
598 | if (child->addin_offset) | ||
599 | return true; | ||
600 | |||
601 | /* But even then some BIOS writers perform some black magic | ||
602 | * and instantiate the device without reference to any | ||
603 | * additional data. Trust that if the VBT was written into | ||
604 | * the OpRegion then they have validated the LVDS's existence. | ||
605 | */ | ||
606 | if (dev_priv->opregion.vbt) | ||
607 | return true; | ||
608 | } | ||
609 | |||
610 | return false; | ||
611 | } | ||
612 | |||
559 | /** | 613 | /** |
560 | * cdv_intel_lvds_init - setup LVDS connectors on this device | 614 | * cdv_intel_lvds_init - setup LVDS connectors on this device |
561 | * @dev: drm device | 615 | * @dev: drm device |
@@ -576,6 +630,13 @@ void cdv_intel_lvds_init(struct drm_device *dev, | |||
576 | struct drm_psb_private *dev_priv = dev->dev_private; | 630 | struct drm_psb_private *dev_priv = dev->dev_private; |
577 | u32 lvds; | 631 | u32 lvds; |
578 | int pipe; | 632 | int pipe; |
633 | u8 pin; | ||
634 | |||
635 | pin = GMBUS_PORT_PANEL; | ||
636 | if (!lvds_is_present_in_vbt(dev, &pin)) { | ||
637 | DRM_DEBUG_KMS("LVDS is not present in VBT\n"); | ||
638 | return; | ||
639 | } | ||
579 | 640 | ||
580 | psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), | 641 | psb_intel_encoder = kzalloc(sizeof(struct psb_intel_encoder), |
581 | GFP_KERNEL); | 642 | GFP_KERNEL); |
@@ -710,6 +771,19 @@ void cdv_intel_lvds_init(struct drm_device *dev, | |||
710 | goto failed_find; | 771 | goto failed_find; |
711 | } | 772 | } |
712 | 773 | ||
774 | /* setup PWM */ | ||
775 | { | ||
776 | u32 pwm; | ||
777 | |||
778 | pwm = REG_READ(BLC_PWM_CTL2); | ||
779 | if (pipe == 1) | ||
780 | pwm |= PWM_PIPE_B; | ||
781 | else | ||
782 | pwm &= ~PWM_PIPE_B; | ||
783 | pwm |= PWM_ENABLE; | ||
784 | REG_WRITE(BLC_PWM_CTL2, pwm); | ||
785 | } | ||
786 | |||
713 | out: | 787 | out: |
714 | drm_sysfs_connector_add(connector); | 788 | drm_sysfs_connector_add(connector); |
715 | return; | 789 | return; |
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 8ea202f1ba50..c9fe4bdeb681 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c | |||
@@ -543,9 +543,25 @@ static int psbfb_probe(struct drm_fb_helper *helper, | |||
543 | struct drm_fb_helper_surface_size *sizes) | 543 | struct drm_fb_helper_surface_size *sizes) |
544 | { | 544 | { |
545 | struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper; | 545 | struct psb_fbdev *psb_fbdev = (struct psb_fbdev *)helper; |
546 | struct drm_device *dev = psb_fbdev->psb_fb_helper.dev; | ||
547 | struct drm_psb_private *dev_priv = dev->dev_private; | ||
546 | int new_fb = 0; | 548 | int new_fb = 0; |
549 | int bytespp; | ||
547 | int ret; | 550 | int ret; |
548 | 551 | ||
552 | bytespp = sizes->surface_bpp / 8; | ||
553 | if (bytespp == 3) /* no 24bit packed */ | ||
554 | bytespp = 4; | ||
555 | |||
556 | /* If the mode will not fit in 32bit then switch to 16bit to get | ||
557 | a console on full resolution. The X mode setting server will | ||
558 | allocate its own 32bit GEM framebuffer */ | ||
559 | if (ALIGN(sizes->fb_width * bytespp, 64) * sizes->fb_height > | ||
560 | dev_priv->vram_stolen_size) { | ||
561 | sizes->surface_bpp = 16; | ||
562 | sizes->surface_depth = 16; | ||
563 | } | ||
564 | |||
549 | if (!helper->fb) { | 565 | if (!helper->fb) { |
550 | ret = psbfb_create(psb_fbdev, sizes); | 566 | ret = psbfb_create(psb_fbdev, sizes); |
551 | if (ret) | 567 | if (ret) |
@@ -732,10 +748,7 @@ static void psb_setup_outputs(struct drm_device *dev) | |||
732 | clone_mask = (1 << INTEL_OUTPUT_SDVO); | 748 | clone_mask = (1 << INTEL_OUTPUT_SDVO); |
733 | break; | 749 | break; |
734 | case INTEL_OUTPUT_LVDS: | 750 | case INTEL_OUTPUT_LVDS: |
735 | if (IS_MRST(dev)) | 751 | crtc_mask = dev_priv->ops->lvds_mask; |
736 | crtc_mask = (1 << 0); | ||
737 | else | ||
738 | crtc_mask = (1 << 1); | ||
739 | clone_mask = (1 << INTEL_OUTPUT_LVDS); | 752 | clone_mask = (1 << INTEL_OUTPUT_LVDS); |
740 | break; | 753 | break; |
741 | case INTEL_OUTPUT_MIPI: | 754 | case INTEL_OUTPUT_MIPI: |
@@ -747,10 +760,7 @@ static void psb_setup_outputs(struct drm_device *dev) | |||
747 | clone_mask = (1 << INTEL_OUTPUT_MIPI2); | 760 | clone_mask = (1 << INTEL_OUTPUT_MIPI2); |
748 | break; | 761 | break; |
749 | case INTEL_OUTPUT_HDMI: | 762 | case INTEL_OUTPUT_HDMI: |
750 | if (IS_MFLD(dev)) | 763 | crtc_mask = dev_priv->ops->hdmi_mask; |
751 | crtc_mask = (1 << 1); | ||
752 | else | ||
753 | crtc_mask = (1 << 0); | ||
754 | clone_mask = (1 << INTEL_OUTPUT_HDMI); | 764 | clone_mask = (1 << INTEL_OUTPUT_HDMI); |
755 | break; | 765 | break; |
756 | } | 766 | } |
@@ -786,6 +796,9 @@ void psb_modeset_init(struct drm_device *dev) | |||
786 | dev->mode_config.max_height = 2048; | 796 | dev->mode_config.max_height = 2048; |
787 | 797 | ||
788 | psb_setup_outputs(dev); | 798 | psb_setup_outputs(dev); |
799 | |||
800 | if (dev_priv->ops->errata) | ||
801 | dev_priv->ops->errata(dev); | ||
789 | } | 802 | } |
790 | 803 | ||
791 | void psb_modeset_cleanup(struct drm_device *dev) | 804 | void psb_modeset_cleanup(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 9fbb86868e2e..fc7d144bc2d3 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c | |||
@@ -124,6 +124,8 @@ static int psb_gem_create(struct drm_file *file, | |||
124 | dev_err(dev->dev, "GEM init failed for %lld\n", size); | 124 | dev_err(dev->dev, "GEM init failed for %lld\n", size); |
125 | return -ENOMEM; | 125 | return -ENOMEM; |
126 | } | 126 | } |
127 | /* Limit the object to 32bit mappings */ | ||
128 | mapping_set_gfp_mask(r->gem.filp->f_mapping, GFP_KERNEL | __GFP_DMA32); | ||
127 | /* Give the object a handle so we can carry it more easily */ | 129 | /* Give the object a handle so we can carry it more easily */ |
128 | ret = drm_gem_handle_create(file, &r->gem, &handle); | 130 | ret = drm_gem_handle_create(file, &r->gem, &handle); |
129 | if (ret) { | 131 | if (ret) { |
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index c6465b40090f..54e5c9e1e6fa 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c | |||
@@ -39,6 +39,10 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) | |||
39 | { | 39 | { |
40 | uint32_t mask = PSB_PTE_VALID; | 40 | uint32_t mask = PSB_PTE_VALID; |
41 | 41 | ||
42 | /* Ensure we explode rather than put an invalid low mapping of | ||
43 | a high mapping page into the gtt */ | ||
44 | BUG_ON(pfn & ~(0xFFFFFFFF >> PAGE_SHIFT)); | ||
45 | |||
42 | if (type & PSB_MMU_CACHED_MEMORY) | 46 | if (type & PSB_MMU_CACHED_MEMORY) |
43 | mask |= PSB_PTE_CACHED; | 47 | mask |= PSB_PTE_CACHED; |
44 | if (type & PSB_MMU_RO_MEMORY) | 48 | if (type & PSB_MMU_RO_MEMORY) |
@@ -93,7 +97,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) | |||
93 | pages = r->pages; | 97 | pages = r->pages; |
94 | 98 | ||
95 | /* Make sure changes are visible to the GPU */ | 99 | /* Make sure changes are visible to the GPU */ |
96 | set_pages_array_uc(pages, r->npage); | 100 | set_pages_array_wc(pages, r->npage); |
97 | 101 | ||
98 | /* Write our page entries into the GTT itself */ | 102 | /* Write our page entries into the GTT itself */ |
99 | for (i = r->roll; i < r->npage; i++) { | 103 | for (i = r->roll; i < r->npage; i++) { |
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index d4d0c5b8bf91..479e4497d26c 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include "psb_intel_reg.h" | 26 | #include "psb_intel_reg.h" |
27 | #include "intel_bios.h" | 27 | #include "intel_bios.h" |
28 | 28 | ||
29 | #define SLAVE_ADDR1 0x70 | ||
30 | #define SLAVE_ADDR2 0x72 | ||
29 | 31 | ||
30 | static void *find_section(struct bdb_header *bdb, int section_id) | 32 | static void *find_section(struct bdb_header *bdb, int section_id) |
31 | { | 33 | { |
@@ -52,6 +54,16 @@ static void *find_section(struct bdb_header *bdb, int section_id) | |||
52 | return NULL; | 54 | return NULL; |
53 | } | 55 | } |
54 | 56 | ||
57 | static u16 | ||
58 | get_blocksize(void *p) | ||
59 | { | ||
60 | u16 *block_ptr, block_size; | ||
61 | |||
62 | block_ptr = (u16 *)((char *)p - 2); | ||
63 | block_size = *block_ptr; | ||
64 | return block_size; | ||
65 | } | ||
66 | |||
55 | static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | 67 | static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, |
56 | struct lvds_dvo_timing *dvo_timing) | 68 | struct lvds_dvo_timing *dvo_timing) |
57 | { | 69 | { |
@@ -75,6 +87,16 @@ static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, | |||
75 | panel_fixed_mode->clock = dvo_timing->clock * 10; | 87 | panel_fixed_mode->clock = dvo_timing->clock * 10; |
76 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; | 88 | panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED; |
77 | 89 | ||
90 | if (dvo_timing->hsync_positive) | ||
91 | panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC; | ||
92 | else | ||
93 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
94 | |||
95 | if (dvo_timing->vsync_positive) | ||
96 | panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
97 | else | ||
98 | panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
99 | |||
78 | /* Some VBTs have bogus h/vtotal values */ | 100 | /* Some VBTs have bogus h/vtotal values */ |
79 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) | 101 | if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal) |
80 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; | 102 | panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1; |
@@ -217,6 +239,180 @@ static void parse_general_features(struct drm_psb_private *dev_priv, | |||
217 | } | 239 | } |
218 | } | 240 | } |
219 | 241 | ||
242 | static void | ||
243 | parse_sdvo_device_mapping(struct drm_psb_private *dev_priv, | ||
244 | struct bdb_header *bdb) | ||
245 | { | ||
246 | struct sdvo_device_mapping *p_mapping; | ||
247 | struct bdb_general_definitions *p_defs; | ||
248 | struct child_device_config *p_child; | ||
249 | int i, child_device_num, count; | ||
250 | u16 block_size; | ||
251 | |||
252 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
253 | if (!p_defs) { | ||
254 | DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n"); | ||
255 | return; | ||
256 | } | ||
257 | /* judge whether the size of child device meets the requirements. | ||
258 | * If the child device size obtained from general definition block | ||
259 | * is different with sizeof(struct child_device_config), skip the | ||
260 | * parsing of sdvo device info | ||
261 | */ | ||
262 | if (p_defs->child_dev_size != sizeof(*p_child)) { | ||
263 | /* different child dev size . Ignore it */ | ||
264 | DRM_DEBUG_KMS("different child size is found. Invalid.\n"); | ||
265 | return; | ||
266 | } | ||
267 | /* get the block size of general definitions */ | ||
268 | block_size = get_blocksize(p_defs); | ||
269 | /* get the number of child device */ | ||
270 | child_device_num = (block_size - sizeof(*p_defs)) / | ||
271 | sizeof(*p_child); | ||
272 | count = 0; | ||
273 | for (i = 0; i < child_device_num; i++) { | ||
274 | p_child = &(p_defs->devices[i]); | ||
275 | if (!p_child->device_type) { | ||
276 | /* skip the device block if device type is invalid */ | ||
277 | continue; | ||
278 | } | ||
279 | if (p_child->slave_addr != SLAVE_ADDR1 && | ||
280 | p_child->slave_addr != SLAVE_ADDR2) { | ||
281 | /* | ||
282 | * If the slave address is neither 0x70 nor 0x72, | ||
283 | * it is not a SDVO device. Skip it. | ||
284 | */ | ||
285 | continue; | ||
286 | } | ||
287 | if (p_child->dvo_port != DEVICE_PORT_DVOB && | ||
288 | p_child->dvo_port != DEVICE_PORT_DVOC) { | ||
289 | /* skip the incorrect SDVO port */ | ||
290 | DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n"); | ||
291 | continue; | ||
292 | } | ||
293 | DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on" | ||
294 | " %s port\n", | ||
295 | p_child->slave_addr, | ||
296 | (p_child->dvo_port == DEVICE_PORT_DVOB) ? | ||
297 | "SDVOB" : "SDVOC"); | ||
298 | p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]); | ||
299 | if (!p_mapping->initialized) { | ||
300 | p_mapping->dvo_port = p_child->dvo_port; | ||
301 | p_mapping->slave_addr = p_child->slave_addr; | ||
302 | p_mapping->dvo_wiring = p_child->dvo_wiring; | ||
303 | p_mapping->ddc_pin = p_child->ddc_pin; | ||
304 | p_mapping->i2c_pin = p_child->i2c_pin; | ||
305 | p_mapping->initialized = 1; | ||
306 | DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n", | ||
307 | p_mapping->dvo_port, | ||
308 | p_mapping->slave_addr, | ||
309 | p_mapping->dvo_wiring, | ||
310 | p_mapping->ddc_pin, | ||
311 | p_mapping->i2c_pin); | ||
312 | } else { | ||
313 | DRM_DEBUG_KMS("Maybe one SDVO port is shared by " | ||
314 | "two SDVO device.\n"); | ||
315 | } | ||
316 | if (p_child->slave2_addr) { | ||
317 | /* Maybe this is a SDVO device with multiple inputs */ | ||
318 | /* And the mapping info is not added */ | ||
319 | DRM_DEBUG_KMS("there exists the slave2_addr. Maybe this" | ||
320 | " is a SDVO device with multiple inputs.\n"); | ||
321 | } | ||
322 | count++; | ||
323 | } | ||
324 | |||
325 | if (!count) { | ||
326 | /* No SDVO device info is found */ | ||
327 | DRM_DEBUG_KMS("No SDVO device info is found in VBT\n"); | ||
328 | } | ||
329 | return; | ||
330 | } | ||
331 | |||
332 | |||
333 | static void | ||
334 | parse_driver_features(struct drm_psb_private *dev_priv, | ||
335 | struct bdb_header *bdb) | ||
336 | { | ||
337 | struct bdb_driver_features *driver; | ||
338 | |||
339 | driver = find_section(bdb, BDB_DRIVER_FEATURES); | ||
340 | if (!driver) | ||
341 | return; | ||
342 | |||
343 | /* This bit means to use 96Mhz for DPLL_A or not */ | ||
344 | if (driver->primary_lfp_id) | ||
345 | dev_priv->dplla_96mhz = true; | ||
346 | else | ||
347 | dev_priv->dplla_96mhz = false; | ||
348 | } | ||
349 | |||
350 | static void | ||
351 | parse_device_mapping(struct drm_psb_private *dev_priv, | ||
352 | struct bdb_header *bdb) | ||
353 | { | ||
354 | struct bdb_general_definitions *p_defs; | ||
355 | struct child_device_config *p_child, *child_dev_ptr; | ||
356 | int i, child_device_num, count; | ||
357 | u16 block_size; | ||
358 | |||
359 | p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); | ||
360 | if (!p_defs) { | ||
361 | DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n"); | ||
362 | return; | ||
363 | } | ||
364 | /* judge whether the size of child device meets the requirements. | ||
365 | * If the child device size obtained from general definition block | ||
366 | * is different with sizeof(struct child_device_config), skip the | ||
367 | * parsing of sdvo device info | ||
368 | */ | ||
369 | if (p_defs->child_dev_size != sizeof(*p_child)) { | ||
370 | /* different child dev size . Ignore it */ | ||
371 | DRM_DEBUG_KMS("different child size is found. Invalid.\n"); | ||
372 | return; | ||
373 | } | ||
374 | /* get the block size of general definitions */ | ||
375 | block_size = get_blocksize(p_defs); | ||
376 | /* get the number of child device */ | ||
377 | child_device_num = (block_size - sizeof(*p_defs)) / | ||
378 | sizeof(*p_child); | ||
379 | count = 0; | ||
380 | /* get the number of child devices that are present */ | ||
381 | for (i = 0; i < child_device_num; i++) { | ||
382 | p_child = &(p_defs->devices[i]); | ||
383 | if (!p_child->device_type) { | ||
384 | /* skip the device block if device type is invalid */ | ||
385 | continue; | ||
386 | } | ||
387 | count++; | ||
388 | } | ||
389 | if (!count) { | ||
390 | DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); | ||
391 | return; | ||
392 | } | ||
393 | dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); | ||
394 | if (!dev_priv->child_dev) { | ||
395 | DRM_DEBUG_KMS("No memory space for child devices\n"); | ||
396 | return; | ||
397 | } | ||
398 | |||
399 | dev_priv->child_dev_num = count; | ||
400 | count = 0; | ||
401 | for (i = 0; i < child_device_num; i++) { | ||
402 | p_child = &(p_defs->devices[i]); | ||
403 | if (!p_child->device_type) { | ||
404 | /* skip the device block if device type is invalid */ | ||
405 | continue; | ||
406 | } | ||
407 | child_dev_ptr = dev_priv->child_dev + count; | ||
408 | count++; | ||
409 | memcpy((void *)child_dev_ptr, (void *)p_child, | ||
410 | sizeof(*p_child)); | ||
411 | } | ||
412 | return; | ||
413 | } | ||
414 | |||
415 | |||
220 | /** | 416 | /** |
221 | * psb_intel_init_bios - initialize VBIOS settings & find VBT | 417 | * psb_intel_init_bios - initialize VBIOS settings & find VBT |
222 | * @dev: DRM device | 418 | * @dev: DRM device |
@@ -236,38 +432,54 @@ bool psb_intel_init_bios(struct drm_device *dev) | |||
236 | struct drm_psb_private *dev_priv = dev->dev_private; | 432 | struct drm_psb_private *dev_priv = dev->dev_private; |
237 | struct pci_dev *pdev = dev->pdev; | 433 | struct pci_dev *pdev = dev->pdev; |
238 | struct vbt_header *vbt = NULL; | 434 | struct vbt_header *vbt = NULL; |
239 | struct bdb_header *bdb; | 435 | struct bdb_header *bdb = NULL; |
240 | u8 __iomem *bios; | 436 | u8 __iomem *bios = NULL; |
241 | size_t size; | 437 | size_t size; |
242 | int i; | 438 | int i; |
243 | 439 | ||
244 | bios = pci_map_rom(pdev, &size); | 440 | /* XXX Should this validation be moved to intel_opregion.c? */ |
245 | if (!bios) | 441 | if (dev_priv->opregion.vbt) { |
246 | return -1; | 442 | struct vbt_header *vbt = dev_priv->opregion.vbt; |
443 | if (memcmp(vbt->signature, "$VBT", 4) == 0) { | ||
444 | DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n", | ||
445 | vbt->signature); | ||
446 | bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset); | ||
447 | } else | ||
448 | dev_priv->opregion.vbt = NULL; | ||
449 | } | ||
247 | 450 | ||
248 | /* Scour memory looking for the VBT signature */ | 451 | if (bdb == NULL) { |
249 | for (i = 0; i + 4 < size; i++) { | 452 | bios = pci_map_rom(pdev, &size); |
250 | if (!memcmp(bios + i, "$VBT", 4)) { | 453 | if (!bios) |
251 | vbt = (struct vbt_header *)(bios + i); | 454 | return -1; |
252 | break; | 455 | |
456 | /* Scour memory looking for the VBT signature */ | ||
457 | for (i = 0; i + 4 < size; i++) { | ||
458 | if (!memcmp(bios + i, "$VBT", 4)) { | ||
459 | vbt = (struct vbt_header *)(bios + i); | ||
460 | break; | ||
461 | } | ||
253 | } | 462 | } |
254 | } | ||
255 | 463 | ||
256 | if (!vbt) { | 464 | if (!vbt) { |
257 | dev_err(dev->dev, "VBT signature missing\n"); | 465 | dev_err(dev->dev, "VBT signature missing\n"); |
258 | pci_unmap_rom(pdev, bios); | 466 | pci_unmap_rom(pdev, bios); |
259 | return -1; | 467 | return -1; |
468 | } | ||
469 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | ||
260 | } | 470 | } |
261 | 471 | ||
262 | bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset); | 472 | /* Grab useful general dxefinitions */ |
263 | |||
264 | /* Grab useful general definitions */ | ||
265 | parse_general_features(dev_priv, bdb); | 473 | parse_general_features(dev_priv, bdb); |
474 | parse_driver_features(dev_priv, bdb); | ||
266 | parse_lfp_panel_data(dev_priv, bdb); | 475 | parse_lfp_panel_data(dev_priv, bdb); |
267 | parse_sdvo_panel_data(dev_priv, bdb); | 476 | parse_sdvo_panel_data(dev_priv, bdb); |
477 | parse_sdvo_device_mapping(dev_priv, bdb); | ||
478 | parse_device_mapping(dev_priv, bdb); | ||
268 | parse_backlight_data(dev_priv, bdb); | 479 | parse_backlight_data(dev_priv, bdb); |
269 | 480 | ||
270 | pci_unmap_rom(pdev, bios); | 481 | if (bios) |
482 | pci_unmap_rom(pdev, bios); | ||
271 | 483 | ||
272 | return 0; | 484 | return 0; |
273 | } | 485 | } |
diff --git a/drivers/gpu/drm/gma500/intel_bios.h b/drivers/gpu/drm/gma500/intel_bios.h index 70f1bf018183..0a738663eb5a 100644 --- a/drivers/gpu/drm/gma500/intel_bios.h +++ b/drivers/gpu/drm/gma500/intel_bios.h | |||
@@ -127,9 +127,93 @@ struct bdb_general_features { | |||
127 | /* bits 5 */ | 127 | /* bits 5 */ |
128 | u8 int_crt_support:1; | 128 | u8 int_crt_support:1; |
129 | u8 int_tv_support:1; | 129 | u8 int_tv_support:1; |
130 | u8 rsvd11:6; /* finish byte */ | 130 | u8 int_efp_support:1; |
131 | u8 dp_ssc_enb:1; /* PCH attached eDP supports SSC */ | ||
132 | u8 dp_ssc_freq:1; /* SSC freq for PCH attached eDP */ | ||
133 | u8 rsvd11:3; /* finish byte */ | ||
131 | } __attribute__((packed)); | 134 | } __attribute__((packed)); |
132 | 135 | ||
136 | /* pre-915 */ | ||
137 | #define GPIO_PIN_DVI_LVDS 0x03 /* "DVI/LVDS DDC GPIO pins" */ | ||
138 | #define GPIO_PIN_ADD_I2C 0x05 /* "ADDCARD I2C GPIO pins" */ | ||
139 | #define GPIO_PIN_ADD_DDC 0x04 /* "ADDCARD DDC GPIO pins" */ | ||
140 | #define GPIO_PIN_ADD_DDC_I2C 0x06 /* "ADDCARD DDC/I2C GPIO pins" */ | ||
141 | |||
142 | /* Pre 915 */ | ||
143 | #define DEVICE_TYPE_NONE 0x00 | ||
144 | #define DEVICE_TYPE_CRT 0x01 | ||
145 | #define DEVICE_TYPE_TV 0x09 | ||
146 | #define DEVICE_TYPE_EFP 0x12 | ||
147 | #define DEVICE_TYPE_LFP 0x22 | ||
148 | /* On 915+ */ | ||
149 | #define DEVICE_TYPE_CRT_DPMS 0x6001 | ||
150 | #define DEVICE_TYPE_CRT_DPMS_HOTPLUG 0x4001 | ||
151 | #define DEVICE_TYPE_TV_COMPOSITE 0x0209 | ||
152 | #define DEVICE_TYPE_TV_MACROVISION 0x0289 | ||
153 | #define DEVICE_TYPE_TV_RF_COMPOSITE 0x020c | ||
154 | #define DEVICE_TYPE_TV_SVIDEO_COMPOSITE 0x0609 | ||
155 | #define DEVICE_TYPE_TV_SCART 0x0209 | ||
156 | #define DEVICE_TYPE_TV_CODEC_HOTPLUG_PWR 0x6009 | ||
157 | #define DEVICE_TYPE_EFP_HOTPLUG_PWR 0x6012 | ||
158 | #define DEVICE_TYPE_EFP_DVI_HOTPLUG_PWR 0x6052 | ||
159 | #define DEVICE_TYPE_EFP_DVI_I 0x6053 | ||
160 | #define DEVICE_TYPE_EFP_DVI_D_DUAL 0x6152 | ||
161 | #define DEVICE_TYPE_EFP_DVI_D_HDCP 0x60d2 | ||
162 | #define DEVICE_TYPE_OPENLDI_HOTPLUG_PWR 0x6062 | ||
163 | #define DEVICE_TYPE_OPENLDI_DUALPIX 0x6162 | ||
164 | #define DEVICE_TYPE_LFP_PANELLINK 0x5012 | ||
165 | #define DEVICE_TYPE_LFP_CMOS_PWR 0x5042 | ||
166 | #define DEVICE_TYPE_LFP_LVDS_PWR 0x5062 | ||
167 | #define DEVICE_TYPE_LFP_LVDS_DUAL 0x5162 | ||
168 | #define DEVICE_TYPE_LFP_LVDS_DUAL_HDCP 0x51e2 | ||
169 | |||
170 | #define DEVICE_CFG_NONE 0x00 | ||
171 | #define DEVICE_CFG_12BIT_DVOB 0x01 | ||
172 | #define DEVICE_CFG_12BIT_DVOC 0x02 | ||
173 | #define DEVICE_CFG_24BIT_DVOBC 0x09 | ||
174 | #define DEVICE_CFG_24BIT_DVOCB 0x0a | ||
175 | #define DEVICE_CFG_DUAL_DVOB 0x11 | ||
176 | #define DEVICE_CFG_DUAL_DVOC 0x12 | ||
177 | #define DEVICE_CFG_DUAL_DVOBC 0x13 | ||
178 | #define DEVICE_CFG_DUAL_LINK_DVOBC 0x19 | ||
179 | #define DEVICE_CFG_DUAL_LINK_DVOCB 0x1a | ||
180 | |||
181 | #define DEVICE_WIRE_NONE 0x00 | ||
182 | #define DEVICE_WIRE_DVOB 0x01 | ||
183 | #define DEVICE_WIRE_DVOC 0x02 | ||
184 | #define DEVICE_WIRE_DVOBC 0x03 | ||
185 | #define DEVICE_WIRE_DVOBB 0x05 | ||
186 | #define DEVICE_WIRE_DVOCC 0x06 | ||
187 | #define DEVICE_WIRE_DVOB_MASTER 0x0d | ||
188 | #define DEVICE_WIRE_DVOC_MASTER 0x0e | ||
189 | |||
190 | #define DEVICE_PORT_DVOA 0x00 /* none on 845+ */ | ||
191 | #define DEVICE_PORT_DVOB 0x01 | ||
192 | #define DEVICE_PORT_DVOC 0x02 | ||
193 | |||
194 | struct child_device_config { | ||
195 | u16 handle; | ||
196 | u16 device_type; | ||
197 | u8 device_id[10]; /* ascii string */ | ||
198 | u16 addin_offset; | ||
199 | u8 dvo_port; /* See Device_PORT_* above */ | ||
200 | u8 i2c_pin; | ||
201 | u8 slave_addr; | ||
202 | u8 ddc_pin; | ||
203 | u16 edid_ptr; | ||
204 | u8 dvo_cfg; /* See DEVICE_CFG_* above */ | ||
205 | u8 dvo2_port; | ||
206 | u8 i2c2_pin; | ||
207 | u8 slave2_addr; | ||
208 | u8 ddc2_pin; | ||
209 | u8 capabilities; | ||
210 | u8 dvo_wiring;/* See DEVICE_WIRE_* above */ | ||
211 | u8 dvo2_wiring; | ||
212 | u16 extended_type; | ||
213 | u8 dvo_function; | ||
214 | } __attribute__((packed)); | ||
215 | |||
216 | |||
133 | struct bdb_general_definitions { | 217 | struct bdb_general_definitions { |
134 | /* DDC GPIO */ | 218 | /* DDC GPIO */ |
135 | u8 crt_ddc_gmbus_pin; | 219 | u8 crt_ddc_gmbus_pin; |
@@ -144,13 +228,18 @@ struct bdb_general_definitions { | |||
144 | u8 boot_display[2]; | 228 | u8 boot_display[2]; |
145 | u8 child_dev_size; | 229 | u8 child_dev_size; |
146 | 230 | ||
147 | /* device info */ | 231 | /* |
148 | u8 tv_or_lvds_info[33]; | 232 | * Device info: |
149 | u8 dev1[33]; | 233 | * If TV is present, it'll be at devices[0]. |
150 | u8 dev2[33]; | 234 | * LVDS will be next, either devices[0] or [1], if present. |
151 | u8 dev3[33]; | 235 | * On some platforms the number of device is 6. But could be as few as |
152 | u8 dev4[33]; | 236 | * 4 if both TV and LVDS are missing. |
153 | /* may be another device block here on some platforms */ | 237 | * And the device num is related with the size of general definition |
238 | * block. It is obtained by using the following formula: | ||
239 | * number = (block_size - sizeof(bdb_general_definitions))/ | ||
240 | * sizeof(child_device_config); | ||
241 | */ | ||
242 | struct child_device_config devices[0]; | ||
154 | }; | 243 | }; |
155 | 244 | ||
156 | struct bdb_lvds_options { | 245 | struct bdb_lvds_options { |
@@ -302,6 +391,45 @@ struct bdb_sdvo_lvds_options { | |||
302 | u8 panel_misc_bits_4; | 391 | u8 panel_misc_bits_4; |
303 | } __attribute__((packed)); | 392 | } __attribute__((packed)); |
304 | 393 | ||
394 | struct bdb_driver_features { | ||
395 | u8 boot_dev_algorithm:1; | ||
396 | u8 block_display_switch:1; | ||
397 | u8 allow_display_switch:1; | ||
398 | u8 hotplug_dvo:1; | ||
399 | u8 dual_view_zoom:1; | ||
400 | u8 int15h_hook:1; | ||
401 | u8 sprite_in_clone:1; | ||
402 | u8 primary_lfp_id:1; | ||
403 | |||
404 | u16 boot_mode_x; | ||
405 | u16 boot_mode_y; | ||
406 | u8 boot_mode_bpp; | ||
407 | u8 boot_mode_refresh; | ||
408 | |||
409 | u16 enable_lfp_primary:1; | ||
410 | u16 selective_mode_pruning:1; | ||
411 | u16 dual_frequency:1; | ||
412 | u16 render_clock_freq:1; /* 0: high freq; 1: low freq */ | ||
413 | u16 nt_clone_support:1; | ||
414 | u16 power_scheme_ui:1; /* 0: CUI; 1: 3rd party */ | ||
415 | u16 sprite_display_assign:1; /* 0: secondary; 1: primary */ | ||
416 | u16 cui_aspect_scaling:1; | ||
417 | u16 preserve_aspect_ratio:1; | ||
418 | u16 sdvo_device_power_down:1; | ||
419 | u16 crt_hotplug:1; | ||
420 | u16 lvds_config:2; | ||
421 | u16 tv_hotplug:1; | ||
422 | u16 hdmi_config:2; | ||
423 | |||
424 | u8 static_display:1; | ||
425 | u8 reserved2:7; | ||
426 | u16 legacy_crt_max_x; | ||
427 | u16 legacy_crt_max_y; | ||
428 | u8 legacy_crt_max_refresh; | ||
429 | |||
430 | u8 hdmi_termination; | ||
431 | u8 custom_vbt_version; | ||
432 | } __attribute__((packed)); | ||
305 | 433 | ||
306 | extern bool psb_intel_init_bios(struct drm_device *dev); | 434 | extern bool psb_intel_init_bios(struct drm_device *dev); |
307 | extern void psb_intel_destroy_bios(struct drm_device *dev); | 435 | extern void psb_intel_destroy_bios(struct drm_device *dev); |
@@ -427,4 +555,21 @@ extern void psb_intel_destroy_bios(struct drm_device *dev); | |||
427 | #define SWF14_APM_STANDBY 0x1 | 555 | #define SWF14_APM_STANDBY 0x1 |
428 | #define SWF14_APM_RESTORE 0x0 | 556 | #define SWF14_APM_RESTORE 0x0 |
429 | 557 | ||
558 | /* Add the device class for LFP, TV, HDMI */ | ||
559 | #define DEVICE_TYPE_INT_LFP 0x1022 | ||
560 | #define DEVICE_TYPE_INT_TV 0x1009 | ||
561 | #define DEVICE_TYPE_HDMI 0x60D2 | ||
562 | #define DEVICE_TYPE_DP 0x68C6 | ||
563 | #define DEVICE_TYPE_eDP 0x78C6 | ||
564 | |||
565 | /* define the DVO port for HDMI output type */ | ||
566 | #define DVO_B 1 | ||
567 | #define DVO_C 2 | ||
568 | #define DVO_D 3 | ||
569 | |||
570 | /* define the PORT for DP output type */ | ||
571 | #define PORT_IDPB 7 | ||
572 | #define PORT_IDPC 8 | ||
573 | #define PORT_IDPD 9 | ||
574 | |||
430 | #endif /* _I830_BIOS_H_ */ | 575 | #endif /* _I830_BIOS_H_ */ |
diff --git a/drivers/gpu/drm/gma500/intel_opregion.c b/drivers/gpu/drm/gma500/intel_opregion.c index d946bc1b17bf..7041f40affff 100644 --- a/drivers/gpu/drm/gma500/intel_opregion.c +++ b/drivers/gpu/drm/gma500/intel_opregion.c | |||
@@ -25,6 +25,22 @@ | |||
25 | 25 | ||
26 | #include "psb_drv.h" | 26 | #include "psb_drv.h" |
27 | 27 | ||
28 | #define PCI_ASLE 0xe4 | ||
29 | #define PCI_ASLS 0xfc | ||
30 | |||
31 | #define OPREGION_HEADER_OFFSET 0 | ||
32 | #define OPREGION_ACPI_OFFSET 0x100 | ||
33 | #define ACPI_CLID 0x01ac /* current lid state indicator */ | ||
34 | #define ACPI_CDCK 0x01b0 /* current docking state indicator */ | ||
35 | #define OPREGION_SWSCI_OFFSET 0x200 | ||
36 | #define OPREGION_ASLE_OFFSET 0x300 | ||
37 | #define OPREGION_VBT_OFFSET 0x400 | ||
38 | |||
39 | #define OPREGION_SIGNATURE "IntelGraphicsMem" | ||
40 | #define MBOX_ACPI (1<<0) | ||
41 | #define MBOX_SWSCI (1<<1) | ||
42 | #define MBOX_ASLE (1<<2) | ||
43 | |||
28 | struct opregion_header { | 44 | struct opregion_header { |
29 | u8 signature[16]; | 45 | u8 signature[16]; |
30 | u32 size; | 46 | u32 size; |
@@ -36,21 +52,94 @@ struct opregion_header { | |||
36 | u8 reserved[164]; | 52 | u8 reserved[164]; |
37 | } __packed; | 53 | } __packed; |
38 | 54 | ||
39 | struct opregion_apci { | 55 | /* OpRegion mailbox #1: public ACPI methods */ |
40 | /*FIXME: add it later*/ | 56 | struct opregion_acpi { |
41 | } __packed; | 57 | u32 drdy; /* driver readiness */ |
58 | u32 csts; /* notification status */ | ||
59 | u32 cevt; /* current event */ | ||
60 | u8 rsvd1[20]; | ||
61 | u32 didl[8]; /* supported display devices ID list */ | ||
62 | u32 cpdl[8]; /* currently presented display list */ | ||
63 | u32 cadl[8]; /* currently active display list */ | ||
64 | u32 nadl[8]; /* next active devices list */ | ||
65 | u32 aslp; /* ASL sleep time-out */ | ||
66 | u32 tidx; /* toggle table index */ | ||
67 | u32 chpd; /* current hotplug enable indicator */ | ||
68 | u32 clid; /* current lid state*/ | ||
69 | u32 cdck; /* current docking state */ | ||
70 | u32 sxsw; /* Sx state resume */ | ||
71 | u32 evts; /* ASL supported events */ | ||
72 | u32 cnot; /* current OS notification */ | ||
73 | u32 nrdy; /* driver status */ | ||
74 | u8 rsvd2[60]; | ||
75 | } __attribute__((packed)); | ||
42 | 76 | ||
77 | /* OpRegion mailbox #2: SWSCI */ | ||
43 | struct opregion_swsci { | 78 | struct opregion_swsci { |
44 | /*FIXME: add it later*/ | 79 | u32 scic; /* SWSCI command|status|data */ |
45 | } __packed; | 80 | u32 parm; /* command parameters */ |
81 | u32 dslp; /* driver sleep time-out */ | ||
82 | u8 rsvd[244]; | ||
83 | } __attribute__((packed)); | ||
46 | 84 | ||
47 | struct opregion_acpi { | 85 | /* OpRegion mailbox #3: ASLE */ |
48 | /*FIXME: add it later*/ | 86 | struct opregion_asle { |
49 | } __packed; | 87 | u32 ardy; /* driver readiness */ |
88 | u32 aslc; /* ASLE interrupt command */ | ||
89 | u32 tche; /* technology enabled indicator */ | ||
90 | u32 alsi; /* current ALS illuminance reading */ | ||
91 | u32 bclp; /* backlight brightness to set */ | ||
92 | u32 pfit; /* panel fitting state */ | ||
93 | u32 cblv; /* current brightness level */ | ||
94 | u16 bclm[20]; /* backlight level duty cycle mapping table */ | ||
95 | u32 cpfm; /* current panel fitting mode */ | ||
96 | u32 epfm; /* enabled panel fitting modes */ | ||
97 | u8 plut[74]; /* panel LUT and identifier */ | ||
98 | u32 pfmb; /* PWM freq and min brightness */ | ||
99 | u8 rsvd[102]; | ||
100 | } __attribute__((packed)); | ||
101 | |||
102 | /* ASLE irq request bits */ | ||
103 | #define ASLE_SET_ALS_ILLUM (1 << 0) | ||
104 | #define ASLE_SET_BACKLIGHT (1 << 1) | ||
105 | #define ASLE_SET_PFIT (1 << 2) | ||
106 | #define ASLE_SET_PWM_FREQ (1 << 3) | ||
107 | #define ASLE_REQ_MSK 0xf | ||
108 | |||
109 | /* response bits of ASLE irq request */ | ||
110 | #define ASLE_ALS_ILLUM_FAILED (1<<10) | ||
111 | #define ASLE_BACKLIGHT_FAILED (1<<12) | ||
112 | #define ASLE_PFIT_FAILED (1<<14) | ||
113 | #define ASLE_PWM_FREQ_FAILED (1<<16) | ||
114 | |||
115 | /* ASLE backlight brightness to set */ | ||
116 | #define ASLE_BCLP_VALID (1<<31) | ||
117 | #define ASLE_BCLP_MSK (~(1<<31)) | ||
118 | |||
119 | /* ASLE panel fitting request */ | ||
120 | #define ASLE_PFIT_VALID (1<<31) | ||
121 | #define ASLE_PFIT_CENTER (1<<0) | ||
122 | #define ASLE_PFIT_STRETCH_TEXT (1<<1) | ||
123 | #define ASLE_PFIT_STRETCH_GFX (1<<2) | ||
124 | |||
125 | /* PWM frequency and minimum brightness */ | ||
126 | #define ASLE_PFMB_BRIGHTNESS_MASK (0xff) | ||
127 | #define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) | ||
128 | #define ASLE_PFMB_PWM_MASK (0x7ffffe00) | ||
129 | #define ASLE_PFMB_PWM_VALID (1<<31) | ||
130 | |||
131 | #define ASLE_CBLV_VALID (1<<31) | ||
132 | |||
133 | #define ACPI_OTHER_OUTPUT (0<<8) | ||
134 | #define ACPI_VGA_OUTPUT (1<<8) | ||
135 | #define ACPI_TV_OUTPUT (2<<8) | ||
136 | #define ACPI_DIGITAL_OUTPUT (3<<8) | ||
137 | #define ACPI_LVDS_OUTPUT (4<<8) | ||
50 | 138 | ||
51 | int gma_intel_opregion_init(struct drm_device *dev) | 139 | int gma_intel_opregion_init(struct drm_device *dev) |
52 | { | 140 | { |
53 | struct drm_psb_private *dev_priv = dev->dev_private; | 141 | struct drm_psb_private *dev_priv = dev->dev_private; |
142 | struct psb_intel_opregion *opregion = &dev_priv->opregion; | ||
54 | u32 opregion_phy; | 143 | u32 opregion_phy; |
55 | void *base; | 144 | void *base; |
56 | u32 *lid_state; | 145 | u32 *lid_state; |
@@ -64,18 +153,26 @@ int gma_intel_opregion_init(struct drm_device *dev) | |||
64 | base = ioremap(opregion_phy, 8*1024); | 153 | base = ioremap(opregion_phy, 8*1024); |
65 | if (!base) | 154 | if (!base) |
66 | return -ENOMEM; | 155 | return -ENOMEM; |
156 | /* FIXME: should use _io ops - ditto on i915 */ | ||
157 | if (memcmp(base, OPREGION_SIGNATURE, 16)) { | ||
158 | DRM_ERROR("opregion signature mismatch\n"); | ||
159 | iounmap(base); | ||
160 | return -EINVAL; | ||
161 | } | ||
67 | 162 | ||
68 | lid_state = base + 0x01ac; | 163 | lid_state = base + 0x01ac; |
69 | 164 | ||
70 | dev_priv->lid_state = lid_state; | 165 | dev_priv->lid_state = lid_state; |
71 | dev_priv->lid_last_state = readl(lid_state); | 166 | dev_priv->lid_last_state = readl(lid_state); |
167 | opregion->header = base; | ||
168 | opregion->vbt = base + OPREGION_VBT_OFFSET; | ||
72 | return 0; | 169 | return 0; |
73 | } | 170 | } |
74 | 171 | ||
75 | int gma_intel_opregion_exit(struct drm_device *dev) | 172 | int gma_intel_opregion_exit(struct drm_device *dev) |
76 | { | 173 | { |
77 | struct drm_psb_private *dev_priv = dev->dev_private; | 174 | struct drm_psb_private *dev_priv = dev->dev_private; |
78 | if (dev_priv->lid_state) | 175 | if (dev_priv->opregion.header) |
79 | iounmap(dev_priv->lid_state); | 176 | iounmap(dev_priv->opregion.header); |
80 | return 0; | 177 | return 0; |
81 | } | 178 | } |
diff --git a/drivers/gpu/drm/gma500/mdfld_device.c b/drivers/gpu/drm/gma500/mdfld_device.c index af656787db0f..a0bd48cd92f4 100644 --- a/drivers/gpu/drm/gma500/mdfld_device.c +++ b/drivers/gpu/drm/gma500/mdfld_device.c | |||
@@ -672,6 +672,8 @@ const struct psb_ops mdfld_chip_ops = { | |||
672 | .accel_2d = 0, | 672 | .accel_2d = 0, |
673 | .pipes = 3, | 673 | .pipes = 3, |
674 | .crtcs = 3, | 674 | .crtcs = 3, |
675 | .lvds_mask = (1 << 1); | ||
676 | .hdmi_mask = (1 << 1); | ||
675 | .sgx_offset = MRST_SGX_OFFSET, | 677 | .sgx_offset = MRST_SGX_OFFSET, |
676 | 678 | ||
677 | .chip_setup = mid_chip_setup, | 679 | .chip_setup = mid_chip_setup, |
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 41d1924ea31e..4c5a1864adf4 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c | |||
@@ -487,6 +487,8 @@ const struct psb_ops oaktrail_chip_ops = { | |||
487 | .accel_2d = 1, | 487 | .accel_2d = 1, |
488 | .pipes = 2, | 488 | .pipes = 2, |
489 | .crtcs = 2, | 489 | .crtcs = 2, |
490 | .hdmi_mask = (1 << 0), | ||
491 | .lvds_mask = (1 << 0), | ||
490 | .sgx_offset = MRST_SGX_OFFSET, | 492 | .sgx_offset = MRST_SGX_OFFSET, |
491 | 493 | ||
492 | .chip_setup = oaktrail_chip_setup, | 494 | .chip_setup = oaktrail_chip_setup, |
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index f8b367b45f66..25956601191f 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c | |||
@@ -179,7 +179,6 @@ static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
179 | static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, | 179 | static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, |
180 | struct drm_display_mode *mode) | 180 | struct drm_display_mode *mode) |
181 | { | 181 | { |
182 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
183 | if (mode->clock > 165000) | 182 | if (mode->clock > 165000) |
184 | return MODE_CLOCK_HIGH; | 183 | return MODE_CLOCK_HIGH; |
185 | if (mode->clock < 20000) | 184 | if (mode->clock < 20000) |
@@ -188,11 +187,6 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, | |||
188 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 187 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
189 | return MODE_NO_DBLESCAN; | 188 | return MODE_NO_DBLESCAN; |
190 | 189 | ||
191 | /* We assume worst case scenario of 32 bpp here, since we don't know */ | ||
192 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | ||
193 | dev_priv->vram_stolen_size) | ||
194 | return MODE_MEM; | ||
195 | |||
196 | return MODE_OK; | 190 | return MODE_OK; |
197 | } | 191 | } |
198 | 192 | ||
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c index 95d163e4f1f4..34e6866a73b2 100644 --- a/drivers/gpu/drm/gma500/psb_device.c +++ b/drivers/gpu/drm/gma500/psb_device.c | |||
@@ -308,6 +308,8 @@ const struct psb_ops psb_chip_ops = { | |||
308 | .accel_2d = 1, | 308 | .accel_2d = 1, |
309 | .pipes = 2, | 309 | .pipes = 2, |
310 | .crtcs = 2, | 310 | .crtcs = 2, |
311 | .hdmi_mask = (1 << 0), | ||
312 | .lvds_mask = (1 << 1), | ||
311 | .sgx_offset = PSB_SGX_OFFSET, | 313 | .sgx_offset = PSB_SGX_OFFSET, |
312 | .chip_setup = psb_chip_setup, | 314 | .chip_setup = psb_chip_setup, |
313 | .chip_teardown = psb_chip_teardown, | 315 | .chip_teardown = psb_chip_teardown, |
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index c34adf9d910a..d5a6eab8227e 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c | |||
@@ -246,6 +246,7 @@ static int psb_driver_unload(struct drm_device *dev) | |||
246 | } | 246 | } |
247 | psb_gtt_takedown(dev); | 247 | psb_gtt_takedown(dev); |
248 | if (dev_priv->scratch_page) { | 248 | if (dev_priv->scratch_page) { |
249 | set_pages_wb(dev_priv->scratch_page, 1); | ||
249 | __free_page(dev_priv->scratch_page); | 250 | __free_page(dev_priv->scratch_page); |
250 | dev_priv->scratch_page = NULL; | 251 | dev_priv->scratch_page = NULL; |
251 | } | 252 | } |
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 40ce2c9bc2e4..d3528a694206 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h | |||
@@ -130,6 +130,7 @@ enum { | |||
130 | #define _PSB_VSYNC_PIPEA_FLAG (1<<7) | 130 | #define _PSB_VSYNC_PIPEA_FLAG (1<<7) |
131 | #define _MDFLD_MIPIA_FLAG (1<<16) | 131 | #define _MDFLD_MIPIA_FLAG (1<<16) |
132 | #define _MDFLD_MIPIC_FLAG (1<<17) | 132 | #define _MDFLD_MIPIC_FLAG (1<<17) |
133 | #define _PSB_IRQ_DISP_HOTSYNC (1<<17) | ||
133 | #define _PSB_IRQ_SGX_FLAG (1<<18) | 134 | #define _PSB_IRQ_SGX_FLAG (1<<18) |
134 | #define _PSB_IRQ_MSVDX_FLAG (1<<19) | 135 | #define _PSB_IRQ_MSVDX_FLAG (1<<19) |
135 | #define _LNC_IRQ_TOPAZ_FLAG (1<<20) | 136 | #define _LNC_IRQ_TOPAZ_FLAG (1<<20) |
@@ -257,6 +258,7 @@ struct psb_intel_opregion { | |||
257 | struct opregion_acpi *acpi; | 258 | struct opregion_acpi *acpi; |
258 | struct opregion_swsci *swsci; | 259 | struct opregion_swsci *swsci; |
259 | struct opregion_asle *asle; | 260 | struct opregion_asle *asle; |
261 | void *vbt; | ||
260 | int enabled; | 262 | int enabled; |
261 | }; | 263 | }; |
262 | 264 | ||
@@ -494,6 +496,9 @@ struct psb_ops; | |||
494 | struct drm_psb_private { | 496 | struct drm_psb_private { |
495 | struct drm_device *dev; | 497 | struct drm_device *dev; |
496 | const struct psb_ops *ops; | 498 | const struct psb_ops *ops; |
499 | |||
500 | struct child_device_config *child_dev; | ||
501 | int child_dev_num; | ||
497 | 502 | ||
498 | struct psb_gtt gtt; | 503 | struct psb_gtt gtt; |
499 | 504 | ||
@@ -621,6 +626,11 @@ struct drm_psb_private { | |||
621 | uint32_t msi_addr; | 626 | uint32_t msi_addr; |
622 | uint32_t msi_data; | 627 | uint32_t msi_data; |
623 | 628 | ||
629 | /* | ||
630 | * Hotplug handling | ||
631 | */ | ||
632 | |||
633 | struct work_struct hotplug_work; | ||
624 | 634 | ||
625 | /* | 635 | /* |
626 | * LID-Switch | 636 | * LID-Switch |
@@ -669,6 +679,8 @@ struct drm_psb_private { | |||
669 | u32 dspcntr[3]; | 679 | u32 dspcntr[3]; |
670 | 680 | ||
671 | int mdfld_panel_id; | 681 | int mdfld_panel_id; |
682 | |||
683 | bool dplla_96mhz; /* DPLL data from the VBT */ | ||
672 | }; | 684 | }; |
673 | 685 | ||
674 | 686 | ||
@@ -682,6 +694,8 @@ struct psb_ops { | |||
682 | int pipes; /* Number of output pipes */ | 694 | int pipes; /* Number of output pipes */ |
683 | int crtcs; /* Number of CRTCs */ | 695 | int crtcs; /* Number of CRTCs */ |
684 | int sgx_offset; /* Base offset of SGX device */ | 696 | int sgx_offset; /* Base offset of SGX device */ |
697 | int hdmi_mask; /* Mask of HDMI CRTCs */ | ||
698 | int lvds_mask; /* Mask of LVDS CRTCs */ | ||
685 | 699 | ||
686 | /* Sub functions */ | 700 | /* Sub functions */ |
687 | struct drm_crtc_helper_funcs const *crtc_helper; | 701 | struct drm_crtc_helper_funcs const *crtc_helper; |
@@ -690,9 +704,13 @@ struct psb_ops { | |||
690 | /* Setup hooks */ | 704 | /* Setup hooks */ |
691 | int (*chip_setup)(struct drm_device *dev); | 705 | int (*chip_setup)(struct drm_device *dev); |
692 | void (*chip_teardown)(struct drm_device *dev); | 706 | void (*chip_teardown)(struct drm_device *dev); |
707 | /* Optional helper caller after modeset */ | ||
708 | void (*errata)(struct drm_device *dev); | ||
693 | 709 | ||
694 | /* Display management hooks */ | 710 | /* Display management hooks */ |
695 | int (*output_init)(struct drm_device *dev); | 711 | int (*output_init)(struct drm_device *dev); |
712 | int (*hotplug)(struct drm_device *dev); | ||
713 | void (*hotplug_enable)(struct drm_device *dev, bool on); | ||
696 | /* Power management hooks */ | 714 | /* Power management hooks */ |
697 | void (*init_pm)(struct drm_device *dev); | 715 | void (*init_pm)(struct drm_device *dev); |
698 | int (*save_regs)(struct drm_device *dev); | 716 | int (*save_regs)(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h index f40535e56689..81852b48654c 100644 --- a/drivers/gpu/drm/gma500/psb_intel_drv.h +++ b/drivers/gpu/drm/gma500/psb_intel_drv.h | |||
@@ -193,6 +193,9 @@ struct psb_intel_crtc { | |||
193 | /*crtc mode setting flags*/ | 193 | /*crtc mode setting flags*/ |
194 | u32 mode_flags; | 194 | u32 mode_flags; |
195 | 195 | ||
196 | bool active; | ||
197 | bool crtc_enable; | ||
198 | |||
196 | /* Saved Crtc HW states */ | 199 | /* Saved Crtc HW states */ |
197 | struct psb_intel_crtc_state *crtc_state; | 200 | struct psb_intel_crtc_state *crtc_state; |
198 | }; | 201 | }; |
diff --git a/drivers/gpu/drm/gma500/psb_intel_reg.h b/drivers/gpu/drm/gma500/psb_intel_reg.h index e89d3a2e8fdc..519a9cd9ffbc 100644 --- a/drivers/gpu/drm/gma500/psb_intel_reg.h +++ b/drivers/gpu/drm/gma500/psb_intel_reg.h | |||
@@ -91,6 +91,9 @@ | |||
91 | 91 | ||
92 | #define BLC_PWM_CTL 0x61254 | 92 | #define BLC_PWM_CTL 0x61254 |
93 | #define BLC_PWM_CTL2 0x61250 | 93 | #define BLC_PWM_CTL2 0x61250 |
94 | #define PWM_ENABLE (1 << 31) | ||
95 | #define PWM_LEGACY_MODE (1 << 30) | ||
96 | #define PWM_PIPE_B (1 << 29) | ||
94 | #define BLC_PWM_CTL_C 0x62254 | 97 | #define BLC_PWM_CTL_C 0x62254 |
95 | #define BLC_PWM_CTL2_C 0x62250 | 98 | #define BLC_PWM_CTL2_C 0x62250 |
96 | #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) | 99 | #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) |
@@ -216,7 +219,7 @@ | |||
216 | #define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ | 219 | #define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */ |
217 | #define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ | 220 | #define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */ |
218 | #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ | 221 | #define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */ |
219 | #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ | 222 | #define DPLL_FPA0h1_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ |
220 | #define DPLL_LOCK (1 << 15) /* CDV */ | 223 | #define DPLL_LOCK (1 << 15) /* CDV */ |
221 | 224 | ||
222 | /* | 225 | /* |
@@ -343,6 +346,9 @@ | |||
343 | #define FP_M2_DIV_SHIFT 0 | 346 | #define FP_M2_DIV_SHIFT 0 |
344 | 347 | ||
345 | #define PORT_HOTPLUG_EN 0x61110 | 348 | #define PORT_HOTPLUG_EN 0x61110 |
349 | #define HDMIB_HOTPLUG_INT_EN (1 << 29) | ||
350 | #define HDMIC_HOTPLUG_INT_EN (1 << 28) | ||
351 | #define HDMID_HOTPLUG_INT_EN (1 << 27) | ||
346 | #define SDVOB_HOTPLUG_INT_EN (1 << 26) | 352 | #define SDVOB_HOTPLUG_INT_EN (1 << 26) |
347 | #define SDVOC_HOTPLUG_INT_EN (1 << 25) | 353 | #define SDVOC_HOTPLUG_INT_EN (1 << 25) |
348 | #define TV_HOTPLUG_INT_EN (1 << 18) | 354 | #define TV_HOTPLUG_INT_EN (1 << 18) |
@@ -505,6 +511,7 @@ | |||
505 | #define PIPE_VSYNC_ENABL (1UL << 25) | 511 | #define PIPE_VSYNC_ENABL (1UL << 25) |
506 | #define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) | 512 | #define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) |
507 | #define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27) | 513 | #define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27) |
514 | #define PIPE_FIFO_UNDERRUN (1UL << 31) | ||
508 | #define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \ | 515 | #define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \ |
509 | PIPE_HDMI_AUDIO_BUFFER_DONE) | 516 | PIPE_HDMI_AUDIO_BUFFER_DONE) |
510 | #define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) | 517 | #define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16)) |
@@ -569,12 +576,27 @@ struct dpst_guardband { | |||
569 | #define PIPE_PIXEL_MASK 0x00ffffff | 576 | #define PIPE_PIXEL_MASK 0x00ffffff |
570 | #define PIPE_PIXEL_SHIFT 0 | 577 | #define PIPE_PIXEL_SHIFT 0 |
571 | 578 | ||
579 | #define FW_BLC_SELF 0x20e0 | ||
580 | #define FW_BLC_SELF_EN (1<<15) | ||
581 | |||
572 | #define DSPARB 0x70030 | 582 | #define DSPARB 0x70030 |
573 | #define DSPFW1 0x70034 | 583 | #define DSPFW1 0x70034 |
584 | #define DSP_FIFO_SR_WM_MASK 0xFF800000 | ||
585 | #define DSP_FIFO_SR_WM_SHIFT 23 | ||
586 | #define CURSOR_B_FIFO_WM_MASK 0x003F0000 | ||
587 | #define CURSOR_B_FIFO_WM_SHIFT 16 | ||
574 | #define DSPFW2 0x70038 | 588 | #define DSPFW2 0x70038 |
589 | #define CURSOR_A_FIFO_WM_MASK 0x3F00 | ||
590 | #define CURSOR_A_FIFO_WM_SHIFT 8 | ||
591 | #define DSP_PLANE_C_FIFO_WM_MASK 0x7F | ||
592 | #define DSP_PLANE_C_FIFO_WM_SHIFT 0 | ||
575 | #define DSPFW3 0x7003c | 593 | #define DSPFW3 0x7003c |
576 | #define DSPFW4 0x70050 | 594 | #define DSPFW4 0x70050 |
577 | #define DSPFW5 0x70054 | 595 | #define DSPFW5 0x70054 |
596 | #define DSP_PLANE_B_FIFO_WM1_SHIFT 24 | ||
597 | #define DSP_PLANE_A_FIFO_WM1_SHIFT 16 | ||
598 | #define CURSOR_B_FIFO_WM1_SHIFT 8 | ||
599 | #define CURSOR_FIFO_SR_WM1_SHIFT 0 | ||
578 | #define DSPFW6 0x70058 | 600 | #define DSPFW6 0x70058 |
579 | #define DSPCHICKENBIT 0x70400 | 601 | #define DSPCHICKENBIT 0x70400 |
580 | #define DSPACNTR 0x70180 | 602 | #define DSPACNTR 0x70180 |
@@ -1290,6 +1312,15 @@ No status bits are changed. | |||
1290 | #define SB_N_CB_TUNE_MASK PSB_MASK(25, 24) | 1312 | #define SB_N_CB_TUNE_MASK PSB_MASK(25, 24) |
1291 | #define SB_N_CB_TUNE_SHIFT 24 | 1313 | #define SB_N_CB_TUNE_SHIFT 24 |
1292 | 1314 | ||
1315 | /* the bit 14:13 is used to select between the different reference clock for Pipe A/B */ | ||
1316 | #define SB_REF_DPLLA 0x8010 | ||
1317 | #define SB_REF_DPLLB 0x8030 | ||
1318 | #define REF_CLK_MASK (0x3 << 13) | ||
1319 | #define REF_CLK_CORE (0 << 13) | ||
1320 | #define REF_CLK_DPLL (1 << 13) | ||
1321 | #define REF_CLK_DPLLA (2 << 13) | ||
1322 | /* For the DPLL B, it will use the reference clk from DPLL A when using (2 << 13) */ | ||
1323 | |||
1293 | #define _SB_REF_A 0x8018 | 1324 | #define _SB_REF_A 0x8018 |
1294 | #define _SB_REF_B 0x8038 | 1325 | #define _SB_REF_B 0x8038 |
1295 | #define SB_REF_SFR(pipe) _PIPE(pipe, _SB_REF_A, _SB_REF_B) | 1326 | #define SB_REF_SFR(pipe) _PIPE(pipe, _SB_REF_A, _SB_REF_B) |
@@ -1313,6 +1344,7 @@ No status bits are changed. | |||
1313 | 1344 | ||
1314 | #define LANE_PLL_MASK (0x7 << 20) | 1345 | #define LANE_PLL_MASK (0x7 << 20) |
1315 | #define LANE_PLL_ENABLE (0x3 << 20) | 1346 | #define LANE_PLL_ENABLE (0x3 << 20) |
1347 | #define LANE_PLL_PIPE(p) (((p) == 0) ? (1 << 21) : (0 << 21)) | ||
1316 | 1348 | ||
1317 | 1349 | ||
1318 | #endif | 1350 | #endif |
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 36330cabcea2..958b4e2d4aed 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c | |||
@@ -1141,7 +1141,6 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1141 | static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, | 1141 | static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, |
1142 | struct drm_display_mode *mode) | 1142 | struct drm_display_mode *mode) |
1143 | { | 1143 | { |
1144 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
1145 | struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); | 1144 | struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); |
1146 | 1145 | ||
1147 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1146 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
@@ -1161,11 +1160,6 @@ static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1161 | return MODE_PANEL; | 1160 | return MODE_PANEL; |
1162 | } | 1161 | } |
1163 | 1162 | ||
1164 | /* We assume worst case scenario of 32 bpp here, since we don't know */ | ||
1165 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | ||
1166 | dev_priv->vram_stolen_size) | ||
1167 | return MODE_MEM; | ||
1168 | |||
1169 | return MODE_OK; | 1163 | return MODE_OK; |
1170 | } | 1164 | } |
1171 | 1165 | ||
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index 1869586457b1..2fcdffdc9063 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c | |||
@@ -199,11 +199,9 @@ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) | |||
199 | 199 | ||
200 | irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) | 200 | irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) |
201 | { | 201 | { |
202 | struct drm_device *dev = (struct drm_device *) arg; | 202 | struct drm_device *dev = arg; |
203 | struct drm_psb_private *dev_priv = | 203 | struct drm_psb_private *dev_priv = dev->dev_private; |
204 | (struct drm_psb_private *) dev->dev_private; | 204 | uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0; |
205 | |||
206 | uint32_t vdc_stat, dsp_int = 0, sgx_int = 0; | ||
207 | int handled = 0; | 205 | int handled = 0; |
208 | 206 | ||
209 | spin_lock(&dev_priv->irqmask_lock); | 207 | spin_lock(&dev_priv->irqmask_lock); |
@@ -220,6 +218,8 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) | |||
220 | 218 | ||
221 | if (vdc_stat & _PSB_IRQ_SGX_FLAG) | 219 | if (vdc_stat & _PSB_IRQ_SGX_FLAG) |
222 | sgx_int = 1; | 220 | sgx_int = 1; |
221 | if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC) | ||
222 | hotplug_int = 1; | ||
223 | 223 | ||
224 | vdc_stat &= dev_priv->vdc_irq_mask; | 224 | vdc_stat &= dev_priv->vdc_irq_mask; |
225 | spin_unlock(&dev_priv->irqmask_lock); | 225 | spin_unlock(&dev_priv->irqmask_lock); |
@@ -241,6 +241,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) | |||
241 | handled = 1; | 241 | handled = 1; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* Note: this bit has other meanings on some devices, so we will | ||
245 | need to address that later if it ever matters */ | ||
246 | if (hotplug_int && dev_priv->ops->hotplug) { | ||
247 | handled = dev_priv->ops->hotplug(dev); | ||
248 | REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); | ||
249 | } | ||
250 | |||
244 | PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); | 251 | PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R); |
245 | (void) PSB_RVDC32(PSB_INT_IDENTITY_R); | 252 | (void) PSB_RVDC32(PSB_INT_IDENTITY_R); |
246 | DRM_READMEMORYBARRIER(); | 253 | DRM_READMEMORYBARRIER(); |
@@ -273,6 +280,10 @@ void psb_irq_preinstall(struct drm_device *dev) | |||
273 | dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; | 280 | dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; |
274 | */ | 281 | */ |
275 | 282 | ||
283 | /* Revisit this area - want per device masks ? */ | ||
284 | if (dev_priv->ops->hotplug) | ||
285 | dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC; | ||
286 | |||
276 | /* This register is safe even if display island is off */ | 287 | /* This register is safe even if display island is off */ |
277 | PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); | 288 | PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); |
278 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); | 289 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); |
@@ -305,18 +316,23 @@ int psb_irq_postinstall(struct drm_device *dev) | |||
305 | else | 316 | else |
306 | psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); | 317 | psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE); |
307 | 318 | ||
319 | if (dev_priv->ops->hotplug_enable) | ||
320 | dev_priv->ops->hotplug_enable(dev, true); | ||
321 | |||
308 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); | 322 | spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); |
309 | return 0; | 323 | return 0; |
310 | } | 324 | } |
311 | 325 | ||
312 | void psb_irq_uninstall(struct drm_device *dev) | 326 | void psb_irq_uninstall(struct drm_device *dev) |
313 | { | 327 | { |
314 | struct drm_psb_private *dev_priv = | 328 | struct drm_psb_private *dev_priv = dev->dev_private; |
315 | (struct drm_psb_private *) dev->dev_private; | ||
316 | unsigned long irqflags; | 329 | unsigned long irqflags; |
317 | 330 | ||
318 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); | 331 | spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); |
319 | 332 | ||
333 | if (dev_priv->ops->hotplug_enable) | ||
334 | dev_priv->ops->hotplug_enable(dev, false); | ||
335 | |||
320 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); | 336 | PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); |
321 | 337 | ||
322 | if (dev->vblank_enabled[0]) | 338 | if (dev->vblank_enabled[0]) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index b5ff1f7b6f7e..2fab38f5a08e 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -588,8 +588,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
588 | if (encoder->crtc == crtc) { | 588 | if (encoder->crtc == crtc) { |
589 | radeon_encoder = to_radeon_encoder(encoder); | 589 | radeon_encoder = to_radeon_encoder(encoder); |
590 | connector = radeon_get_connector_for_encoder(encoder); | 590 | connector = radeon_get_connector_for_encoder(encoder); |
591 | /* if (connector && connector->display_info.bpc) | 591 | bpc = radeon_get_monitor_bpc(connector); |
592 | bpc = connector->display_info.bpc; */ | ||
593 | encoder_mode = atombios_get_encoder_mode(encoder); | 592 | encoder_mode = atombios_get_encoder_mode(encoder); |
594 | is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); | 593 | is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); |
595 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | 594 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
@@ -965,9 +964,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
965 | struct radeon_connector_atom_dig *dig_connector = | 964 | struct radeon_connector_atom_dig *dig_connector = |
966 | radeon_connector->con_priv; | 965 | radeon_connector->con_priv; |
967 | int dp_clock; | 966 | int dp_clock; |
968 | 967 | bpc = radeon_get_monitor_bpc(connector); | |
969 | /* if (connector->display_info.bpc) | ||
970 | bpc = connector->display_info.bpc; */ | ||
971 | 968 | ||
972 | switch (encoder_mode) { | 969 | switch (encoder_mode) { |
973 | case ATOM_ENCODER_MODE_DP_MST: | 970 | case ATOM_ENCODER_MODE_DP_MST: |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index c57d85664e77..cadbb107c803 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -405,13 +405,10 @@ static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE], | |||
405 | /* get bpc from the EDID */ | 405 | /* get bpc from the EDID */ |
406 | static int convert_bpc_to_bpp(int bpc) | 406 | static int convert_bpc_to_bpp(int bpc) |
407 | { | 407 | { |
408 | #if 0 | ||
409 | if (bpc == 0) | 408 | if (bpc == 0) |
410 | return 24; | 409 | return 24; |
411 | else | 410 | else |
412 | return bpc * 3; | 411 | return bpc * 3; |
413 | #endif | ||
414 | return 24; | ||
415 | } | 412 | } |
416 | 413 | ||
417 | /* get the max pix clock supported by the link rate and lane num */ | 414 | /* get the max pix clock supported by the link rate and lane num */ |
@@ -463,7 +460,7 @@ static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, | |||
463 | u8 dpcd[DP_DPCD_SIZE], | 460 | u8 dpcd[DP_DPCD_SIZE], |
464 | int pix_clock) | 461 | int pix_clock) |
465 | { | 462 | { |
466 | int bpp = convert_bpc_to_bpp(connector->display_info.bpc); | 463 | int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
467 | int max_link_rate = dp_get_max_link_rate(dpcd); | 464 | int max_link_rate = dp_get_max_link_rate(dpcd); |
468 | int max_lane_num = dp_get_max_lane_number(dpcd); | 465 | int max_lane_num = dp_get_max_lane_number(dpcd); |
469 | int lane_num; | 466 | int lane_num; |
@@ -482,7 +479,7 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, | |||
482 | u8 dpcd[DP_DPCD_SIZE], | 479 | u8 dpcd[DP_DPCD_SIZE], |
483 | int pix_clock) | 480 | int pix_clock) |
484 | { | 481 | { |
485 | int bpp = convert_bpc_to_bpp(connector->display_info.bpc); | 482 | int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
486 | int lane_num, max_pix_clock; | 483 | int lane_num, max_pix_clock; |
487 | 484 | ||
488 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 485 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 2d39f9977e00..b92a694caa0d 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -545,7 +545,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
545 | dp_clock = dig_connector->dp_clock; | 545 | dp_clock = dig_connector->dp_clock; |
546 | dp_lane_count = dig_connector->dp_lane_count; | 546 | dp_lane_count = dig_connector->dp_lane_count; |
547 | hpd_id = radeon_connector->hpd.hpd; | 547 | hpd_id = radeon_connector->hpd.hpd; |
548 | /* bpc = connector->display_info.bpc; */ | 548 | bpc = radeon_get_monitor_bpc(connector); |
549 | } | 549 | } |
550 | 550 | ||
551 | /* no dig encoder assigned */ | 551 | /* no dig encoder assigned */ |
@@ -1163,7 +1163,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
1163 | dp_lane_count = dig_connector->dp_lane_count; | 1163 | dp_lane_count = dig_connector->dp_lane_count; |
1164 | connector_object_id = | 1164 | connector_object_id = |
1165 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | 1165 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; |
1166 | /* bpc = connector->display_info.bpc; */ | 1166 | bpc = radeon_get_monitor_bpc(connector); |
1167 | } | 1167 | } |
1168 | 1168 | ||
1169 | memset(&args, 0, sizeof(args)); | 1169 | memset(&args, 0, sizeof(args)); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index cfa372cb1cb3..eed7acefb492 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2594,6 +2594,7 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2594 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 2594 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; |
2595 | u32 grbm_int_cntl = 0; | 2595 | u32 grbm_int_cntl = 0; |
2596 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | 2596 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; |
2597 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; | ||
2597 | 2598 | ||
2598 | if (!rdev->irq.installed) { | 2599 | if (!rdev->irq.installed) { |
2599 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 2600 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
@@ -2614,6 +2615,13 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2614 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | 2615 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; |
2615 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 2616 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; |
2616 | 2617 | ||
2618 | afmt1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2619 | afmt2 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2620 | afmt3 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2621 | afmt4 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2622 | afmt5 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2623 | afmt6 = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2624 | |||
2617 | if (rdev->family >= CHIP_CAYMAN) { | 2625 | if (rdev->family >= CHIP_CAYMAN) { |
2618 | /* enable CP interrupts on all rings */ | 2626 | /* enable CP interrupts on all rings */ |
2619 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 2627 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { |
@@ -2690,6 +2698,30 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2690 | DRM_DEBUG("evergreen_irq_set: hpd 6\n"); | 2698 | DRM_DEBUG("evergreen_irq_set: hpd 6\n"); |
2691 | hpd6 |= DC_HPDx_INT_EN; | 2699 | hpd6 |= DC_HPDx_INT_EN; |
2692 | } | 2700 | } |
2701 | if (rdev->irq.afmt[0]) { | ||
2702 | DRM_DEBUG("evergreen_irq_set: hdmi 0\n"); | ||
2703 | afmt1 |= AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2704 | } | ||
2705 | if (rdev->irq.afmt[1]) { | ||
2706 | DRM_DEBUG("evergreen_irq_set: hdmi 1\n"); | ||
2707 | afmt2 |= AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2708 | } | ||
2709 | if (rdev->irq.afmt[2]) { | ||
2710 | DRM_DEBUG("evergreen_irq_set: hdmi 2\n"); | ||
2711 | afmt3 |= AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2712 | } | ||
2713 | if (rdev->irq.afmt[3]) { | ||
2714 | DRM_DEBUG("evergreen_irq_set: hdmi 3\n"); | ||
2715 | afmt4 |= AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2716 | } | ||
2717 | if (rdev->irq.afmt[4]) { | ||
2718 | DRM_DEBUG("evergreen_irq_set: hdmi 4\n"); | ||
2719 | afmt5 |= AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2720 | } | ||
2721 | if (rdev->irq.afmt[5]) { | ||
2722 | DRM_DEBUG("evergreen_irq_set: hdmi 5\n"); | ||
2723 | afmt6 |= AFMT_AZ_FORMAT_WTRIG_MASK; | ||
2724 | } | ||
2693 | if (rdev->irq.gui_idle) { | 2725 | if (rdev->irq.gui_idle) { |
2694 | DRM_DEBUG("gui idle\n"); | 2726 | DRM_DEBUG("gui idle\n"); |
2695 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; | 2727 | grbm_int_cntl |= GUI_IDLE_INT_ENABLE; |
@@ -2732,6 +2764,13 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2732 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | 2764 | WREG32(DC_HPD5_INT_CONTROL, hpd5); |
2733 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | 2765 | WREG32(DC_HPD6_INT_CONTROL, hpd6); |
2734 | 2766 | ||
2767 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, afmt1); | ||
2768 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, afmt2); | ||
2769 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, afmt3); | ||
2770 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, afmt4); | ||
2771 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, afmt5); | ||
2772 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, afmt6); | ||
2773 | |||
2735 | return 0; | 2774 | return 0; |
2736 | } | 2775 | } |
2737 | 2776 | ||
@@ -2756,6 +2795,13 @@ static void evergreen_irq_ack(struct radeon_device *rdev) | |||
2756 | rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | 2795 | rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); |
2757 | } | 2796 | } |
2758 | 2797 | ||
2798 | rdev->irq.stat_regs.evergreen.afmt_status1 = RREG32(AFMT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
2799 | rdev->irq.stat_regs.evergreen.afmt_status2 = RREG32(AFMT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
2800 | rdev->irq.stat_regs.evergreen.afmt_status3 = RREG32(AFMT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
2801 | rdev->irq.stat_regs.evergreen.afmt_status4 = RREG32(AFMT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
2802 | rdev->irq.stat_regs.evergreen.afmt_status5 = RREG32(AFMT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
2803 | rdev->irq.stat_regs.evergreen.afmt_status6 = RREG32(AFMT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
2804 | |||
2759 | if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) | 2805 | if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) |
2760 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | 2806 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); |
2761 | if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) | 2807 | if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) |
@@ -2829,6 +2875,36 @@ static void evergreen_irq_ack(struct radeon_device *rdev) | |||
2829 | tmp |= DC_HPDx_INT_ACK; | 2875 | tmp |= DC_HPDx_INT_ACK; |
2830 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 2876 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
2831 | } | 2877 | } |
2878 | if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) { | ||
2879 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
2880 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; | ||
2881 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, tmp); | ||
2882 | } | ||
2883 | if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) { | ||
2884 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
2885 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; | ||
2886 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, tmp); | ||
2887 | } | ||
2888 | if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) { | ||
2889 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
2890 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; | ||
2891 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, tmp); | ||
2892 | } | ||
2893 | if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) { | ||
2894 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
2895 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; | ||
2896 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, tmp); | ||
2897 | } | ||
2898 | if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) { | ||
2899 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
2900 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; | ||
2901 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, tmp); | ||
2902 | } | ||
2903 | if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) { | ||
2904 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
2905 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; | ||
2906 | WREG32(AFMT_AUDIO_PACKET_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, tmp); | ||
2907 | } | ||
2832 | } | 2908 | } |
2833 | 2909 | ||
2834 | void evergreen_irq_disable(struct radeon_device *rdev) | 2910 | void evergreen_irq_disable(struct radeon_device *rdev) |
@@ -2878,6 +2954,7 @@ int evergreen_irq_process(struct radeon_device *rdev) | |||
2878 | u32 ring_index; | 2954 | u32 ring_index; |
2879 | unsigned long flags; | 2955 | unsigned long flags; |
2880 | bool queue_hotplug = false; | 2956 | bool queue_hotplug = false; |
2957 | bool queue_hdmi = false; | ||
2881 | 2958 | ||
2882 | if (!rdev->ih.enabled || rdev->shutdown) | 2959 | if (!rdev->ih.enabled || rdev->shutdown) |
2883 | return IRQ_NONE; | 2960 | return IRQ_NONE; |
@@ -3111,6 +3188,55 @@ restart_ih: | |||
3111 | break; | 3188 | break; |
3112 | } | 3189 | } |
3113 | break; | 3190 | break; |
3191 | case 44: /* hdmi */ | ||
3192 | switch (src_data) { | ||
3193 | case 0: | ||
3194 | if (rdev->irq.stat_regs.evergreen.afmt_status1 & AFMT_AZ_FORMAT_WTRIG) { | ||
3195 | rdev->irq.stat_regs.evergreen.afmt_status1 &= ~AFMT_AZ_FORMAT_WTRIG; | ||
3196 | queue_hdmi = true; | ||
3197 | DRM_DEBUG("IH: HDMI0\n"); | ||
3198 | } | ||
3199 | break; | ||
3200 | case 1: | ||
3201 | if (rdev->irq.stat_regs.evergreen.afmt_status2 & AFMT_AZ_FORMAT_WTRIG) { | ||
3202 | rdev->irq.stat_regs.evergreen.afmt_status2 &= ~AFMT_AZ_FORMAT_WTRIG; | ||
3203 | queue_hdmi = true; | ||
3204 | DRM_DEBUG("IH: HDMI1\n"); | ||
3205 | } | ||
3206 | break; | ||
3207 | case 2: | ||
3208 | if (rdev->irq.stat_regs.evergreen.afmt_status3 & AFMT_AZ_FORMAT_WTRIG) { | ||
3209 | rdev->irq.stat_regs.evergreen.afmt_status3 &= ~AFMT_AZ_FORMAT_WTRIG; | ||
3210 | queue_hdmi = true; | ||
3211 | DRM_DEBUG("IH: HDMI2\n"); | ||
3212 | } | ||
3213 | break; | ||
3214 | case 3: | ||
3215 | if (rdev->irq.stat_regs.evergreen.afmt_status4 & AFMT_AZ_FORMAT_WTRIG) { | ||
3216 | rdev->irq.stat_regs.evergreen.afmt_status4 &= ~AFMT_AZ_FORMAT_WTRIG; | ||
3217 | queue_hdmi = true; | ||
3218 | DRM_DEBUG("IH: HDMI3\n"); | ||
3219 | } | ||
3220 | break; | ||
3221 | case 4: | ||
3222 | if (rdev->irq.stat_regs.evergreen.afmt_status5 & AFMT_AZ_FORMAT_WTRIG) { | ||
3223 | rdev->irq.stat_regs.evergreen.afmt_status5 &= ~AFMT_AZ_FORMAT_WTRIG; | ||
3224 | queue_hdmi = true; | ||
3225 | DRM_DEBUG("IH: HDMI4\n"); | ||
3226 | } | ||
3227 | break; | ||
3228 | case 5: | ||
3229 | if (rdev->irq.stat_regs.evergreen.afmt_status6 & AFMT_AZ_FORMAT_WTRIG) { | ||
3230 | rdev->irq.stat_regs.evergreen.afmt_status6 &= ~AFMT_AZ_FORMAT_WTRIG; | ||
3231 | queue_hdmi = true; | ||
3232 | DRM_DEBUG("IH: HDMI5\n"); | ||
3233 | } | ||
3234 | break; | ||
3235 | default: | ||
3236 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
3237 | break; | ||
3238 | } | ||
3239 | break; | ||
3114 | case 176: /* CP_INT in ring buffer */ | 3240 | case 176: /* CP_INT in ring buffer */ |
3115 | case 177: /* CP_INT in IB1 */ | 3241 | case 177: /* CP_INT in IB1 */ |
3116 | case 178: /* CP_INT in IB2 */ | 3242 | case 178: /* CP_INT in IB2 */ |
@@ -3154,6 +3280,8 @@ restart_ih: | |||
3154 | goto restart_ih; | 3280 | goto restart_ih; |
3155 | if (queue_hotplug) | 3281 | if (queue_hotplug) |
3156 | schedule_work(&rdev->hotplug_work); | 3282 | schedule_work(&rdev->hotplug_work); |
3283 | if (queue_hdmi) | ||
3284 | schedule_work(&rdev->audio_work); | ||
3157 | rdev->ih.rptr = rptr; | 3285 | rdev->ih.rptr = rptr; |
3158 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3286 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
3159 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3287 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 96c10b3991aa..8beac1065025 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
@@ -232,6 +232,4 @@ | |||
232 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ | 232 | /* HDMI blocks at 0x7030, 0x7c30, 0x10830, 0x11430, 0x12030, 0x12c30 */ |
233 | #define EVERGREEN_HDMI_BASE 0x7030 | 233 | #define EVERGREEN_HDMI_BASE 0x7030 |
234 | 234 | ||
235 | #define EVERGREEN_HDMI_CONFIG_OFFSET 0xf0 | ||
236 | |||
237 | #endif | 235 | #endif |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b4eefc355f16..79130bfd1d6f 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -112,6 +112,226 @@ | |||
112 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 | 112 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 |
113 | #define CP_DEBUG 0xC1FC | 113 | #define CP_DEBUG 0xC1FC |
114 | 114 | ||
115 | /* Audio clocks */ | ||
116 | #define DCCG_AUDIO_DTO_SOURCE 0x05ac | ||
117 | # define DCCG_AUDIO_DTO0_SOURCE_SEL(x) ((x) << 0) /* crtc0 - crtc5 */ | ||
118 | # define DCCG_AUDIO_DTO_SEL (1 << 4) /* 0=dto0 1=dto1 */ | ||
119 | |||
120 | #define DCCG_AUDIO_DTO0_PHASE 0x05b0 | ||
121 | #define DCCG_AUDIO_DTO0_MODULE 0x05b4 | ||
122 | #define DCCG_AUDIO_DTO0_LOAD 0x05b8 | ||
123 | #define DCCG_AUDIO_DTO0_CNTL 0x05bc | ||
124 | |||
125 | #define DCCG_AUDIO_DTO1_PHASE 0x05c0 | ||
126 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 | ||
127 | #define DCCG_AUDIO_DTO1_LOAD 0x05c8 | ||
128 | #define DCCG_AUDIO_DTO1_CNTL 0x05cc | ||
129 | |||
130 | /* DCE 4.0 AFMT */ | ||
131 | #define HDMI_CONTROL 0x7030 | ||
132 | # define HDMI_KEEPOUT_MODE (1 << 0) | ||
133 | # define HDMI_PACKET_GEN_VERSION (1 << 4) /* 0 = r6xx compat */ | ||
134 | # define HDMI_ERROR_ACK (1 << 8) | ||
135 | # define HDMI_ERROR_MASK (1 << 9) | ||
136 | # define HDMI_DEEP_COLOR_ENABLE (1 << 24) | ||
137 | # define HDMI_DEEP_COLOR_DEPTH (((x) & 3) << 28) | ||
138 | # define HDMI_24BIT_DEEP_COLOR 0 | ||
139 | # define HDMI_30BIT_DEEP_COLOR 1 | ||
140 | # define HDMI_36BIT_DEEP_COLOR 2 | ||
141 | #define HDMI_STATUS 0x7034 | ||
142 | # define HDMI_ACTIVE_AVMUTE (1 << 0) | ||
143 | # define HDMI_AUDIO_PACKET_ERROR (1 << 16) | ||
144 | # define HDMI_VBI_PACKET_ERROR (1 << 20) | ||
145 | #define HDMI_AUDIO_PACKET_CONTROL 0x7038 | ||
146 | # define HDMI_AUDIO_DELAY_EN(x) (((x) & 3) << 4) | ||
147 | # define HDMI_AUDIO_PACKETS_PER_LINE(x) (((x) & 0x1f) << 16) | ||
148 | #define HDMI_ACR_PACKET_CONTROL 0x703c | ||
149 | # define HDMI_ACR_SEND (1 << 0) | ||
150 | # define HDMI_ACR_CONT (1 << 1) | ||
151 | # define HDMI_ACR_SELECT(x) (((x) & 3) << 4) | ||
152 | # define HDMI_ACR_HW 0 | ||
153 | # define HDMI_ACR_32 1 | ||
154 | # define HDMI_ACR_44 2 | ||
155 | # define HDMI_ACR_48 3 | ||
156 | # define HDMI_ACR_SOURCE (1 << 8) /* 0 - hw; 1 - cts value */ | ||
157 | # define HDMI_ACR_AUTO_SEND (1 << 12) | ||
158 | # define HDMI_ACR_N_MULTIPLE(x) (((x) & 7) << 16) | ||
159 | # define HDMI_ACR_X1 1 | ||
160 | # define HDMI_ACR_X2 2 | ||
161 | # define HDMI_ACR_X4 4 | ||
162 | # define HDMI_ACR_AUDIO_PRIORITY (1 << 31) | ||
163 | #define HDMI_VBI_PACKET_CONTROL 0x7040 | ||
164 | # define HDMI_NULL_SEND (1 << 0) | ||
165 | # define HDMI_GC_SEND (1 << 4) | ||
166 | # define HDMI_GC_CONT (1 << 5) /* 0 - once; 1 - every frame */ | ||
167 | #define HDMI_INFOFRAME_CONTROL0 0x7044 | ||
168 | # define HDMI_AVI_INFO_SEND (1 << 0) | ||
169 | # define HDMI_AVI_INFO_CONT (1 << 1) | ||
170 | # define HDMI_AUDIO_INFO_SEND (1 << 4) | ||
171 | # define HDMI_AUDIO_INFO_CONT (1 << 5) | ||
172 | # define HDMI_MPEG_INFO_SEND (1 << 8) | ||
173 | # define HDMI_MPEG_INFO_CONT (1 << 9) | ||
174 | #define HDMI_INFOFRAME_CONTROL1 0x7048 | ||
175 | # define HDMI_AVI_INFO_LINE(x) (((x) & 0x3f) << 0) | ||
176 | # define HDMI_AUDIO_INFO_LINE(x) (((x) & 0x3f) << 8) | ||
177 | # define HDMI_MPEG_INFO_LINE(x) (((x) & 0x3f) << 16) | ||
178 | #define HDMI_GENERIC_PACKET_CONTROL 0x704c | ||
179 | # define HDMI_GENERIC0_SEND (1 << 0) | ||
180 | # define HDMI_GENERIC0_CONT (1 << 1) | ||
181 | # define HDMI_GENERIC1_SEND (1 << 4) | ||
182 | # define HDMI_GENERIC1_CONT (1 << 5) | ||
183 | # define HDMI_GENERIC0_LINE(x) (((x) & 0x3f) << 16) | ||
184 | # define HDMI_GENERIC1_LINE(x) (((x) & 0x3f) << 24) | ||
185 | #define HDMI_GC 0x7058 | ||
186 | # define HDMI_GC_AVMUTE (1 << 0) | ||
187 | # define HDMI_GC_AVMUTE_CONT (1 << 2) | ||
188 | #define AFMT_AUDIO_PACKET_CONTROL2 0x705c | ||
189 | # define AFMT_AUDIO_LAYOUT_OVRD (1 << 0) | ||
190 | # define AFMT_AUDIO_LAYOUT_SELECT (1 << 1) | ||
191 | # define AFMT_60958_CS_SOURCE (1 << 4) | ||
192 | # define AFMT_AUDIO_CHANNEL_ENABLE(x) (((x) & 0xff) << 8) | ||
193 | # define AFMT_DP_AUDIO_STREAM_ID(x) (((x) & 0xff) << 16) | ||
194 | #define AFMT_AVI_INFO0 0x7084 | ||
195 | # define AFMT_AVI_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
196 | # define AFMT_AVI_INFO_S(x) (((x) & 3) << 8) | ||
197 | # define AFMT_AVI_INFO_B(x) (((x) & 3) << 10) | ||
198 | # define AFMT_AVI_INFO_A(x) (((x) & 1) << 12) | ||
199 | # define AFMT_AVI_INFO_Y(x) (((x) & 3) << 13) | ||
200 | # define AFMT_AVI_INFO_Y_RGB 0 | ||
201 | # define AFMT_AVI_INFO_Y_YCBCR422 1 | ||
202 | # define AFMT_AVI_INFO_Y_YCBCR444 2 | ||
203 | # define AFMT_AVI_INFO_Y_A_B_S(x) (((x) & 0xff) << 8) | ||
204 | # define AFMT_AVI_INFO_R(x) (((x) & 0xf) << 16) | ||
205 | # define AFMT_AVI_INFO_M(x) (((x) & 0x3) << 20) | ||
206 | # define AFMT_AVI_INFO_C(x) (((x) & 0x3) << 22) | ||
207 | # define AFMT_AVI_INFO_C_M_R(x) (((x) & 0xff) << 16) | ||
208 | # define AFMT_AVI_INFO_SC(x) (((x) & 0x3) << 24) | ||
209 | # define AFMT_AVI_INFO_Q(x) (((x) & 0x3) << 26) | ||
210 | # define AFMT_AVI_INFO_EC(x) (((x) & 0x3) << 28) | ||
211 | # define AFMT_AVI_INFO_ITC(x) (((x) & 0x1) << 31) | ||
212 | # define AFMT_AVI_INFO_ITC_EC_Q_SC(x) (((x) & 0xff) << 24) | ||
213 | #define AFMT_AVI_INFO1 0x7088 | ||
214 | # define AFMT_AVI_INFO_VIC(x) (((x) & 0x7f) << 0) /* don't use avi infoframe v1 */ | ||
215 | # define AFMT_AVI_INFO_PR(x) (((x) & 0xf) << 8) /* don't use avi infoframe v1 */ | ||
216 | # define AFMT_AVI_INFO_CN(x) (((x) & 0x3) << 12) | ||
217 | # define AFMT_AVI_INFO_YQ(x) (((x) & 0x3) << 14) | ||
218 | # define AFMT_AVI_INFO_TOP(x) (((x) & 0xffff) << 16) | ||
219 | #define AFMT_AVI_INFO2 0x708c | ||
220 | # define AFMT_AVI_INFO_BOTTOM(x) (((x) & 0xffff) << 0) | ||
221 | # define AFMT_AVI_INFO_LEFT(x) (((x) & 0xffff) << 16) | ||
222 | #define AFMT_AVI_INFO3 0x7090 | ||
223 | # define AFMT_AVI_INFO_RIGHT(x) (((x) & 0xffff) << 0) | ||
224 | # define AFMT_AVI_INFO_VERSION(x) (((x) & 3) << 24) | ||
225 | #define AFMT_MPEG_INFO0 0x7094 | ||
226 | # define AFMT_MPEG_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
227 | # define AFMT_MPEG_INFO_MB0(x) (((x) & 0xff) << 8) | ||
228 | # define AFMT_MPEG_INFO_MB1(x) (((x) & 0xff) << 16) | ||
229 | # define AFMT_MPEG_INFO_MB2(x) (((x) & 0xff) << 24) | ||
230 | #define AFMT_MPEG_INFO1 0x7098 | ||
231 | # define AFMT_MPEG_INFO_MB3(x) (((x) & 0xff) << 0) | ||
232 | # define AFMT_MPEG_INFO_MF(x) (((x) & 3) << 8) | ||
233 | # define AFMT_MPEG_INFO_FR(x) (((x) & 1) << 12) | ||
234 | #define AFMT_GENERIC0_HDR 0x709c | ||
235 | #define AFMT_GENERIC0_0 0x70a0 | ||
236 | #define AFMT_GENERIC0_1 0x70a4 | ||
237 | #define AFMT_GENERIC0_2 0x70a8 | ||
238 | #define AFMT_GENERIC0_3 0x70ac | ||
239 | #define AFMT_GENERIC0_4 0x70b0 | ||
240 | #define AFMT_GENERIC0_5 0x70b4 | ||
241 | #define AFMT_GENERIC0_6 0x70b8 | ||
242 | #define AFMT_GENERIC1_HDR 0x70bc | ||
243 | #define AFMT_GENERIC1_0 0x70c0 | ||
244 | #define AFMT_GENERIC1_1 0x70c4 | ||
245 | #define AFMT_GENERIC1_2 0x70c8 | ||
246 | #define AFMT_GENERIC1_3 0x70cc | ||
247 | #define AFMT_GENERIC1_4 0x70d0 | ||
248 | #define AFMT_GENERIC1_5 0x70d4 | ||
249 | #define AFMT_GENERIC1_6 0x70d8 | ||
250 | #define HDMI_ACR_32_0 0x70dc | ||
251 | # define HDMI_ACR_CTS_32(x) (((x) & 0xfffff) << 12) | ||
252 | #define HDMI_ACR_32_1 0x70e0 | ||
253 | # define HDMI_ACR_N_32(x) (((x) & 0xfffff) << 0) | ||
254 | #define HDMI_ACR_44_0 0x70e4 | ||
255 | # define HDMI_ACR_CTS_44(x) (((x) & 0xfffff) << 12) | ||
256 | #define HDMI_ACR_44_1 0x70e8 | ||
257 | # define HDMI_ACR_N_44(x) (((x) & 0xfffff) << 0) | ||
258 | #define HDMI_ACR_48_0 0x70ec | ||
259 | # define HDMI_ACR_CTS_48(x) (((x) & 0xfffff) << 12) | ||
260 | #define HDMI_ACR_48_1 0x70f0 | ||
261 | # define HDMI_ACR_N_48(x) (((x) & 0xfffff) << 0) | ||
262 | #define HDMI_ACR_STATUS_0 0x70f4 | ||
263 | #define HDMI_ACR_STATUS_1 0x70f8 | ||
264 | #define AFMT_AUDIO_INFO0 0x70fc | ||
265 | # define AFMT_AUDIO_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
266 | # define AFMT_AUDIO_INFO_CC(x) (((x) & 7) << 8) | ||
267 | # define AFMT_AUDIO_INFO_CT(x) (((x) & 0xf) << 11) | ||
268 | # define AFMT_AUDIO_INFO_CHECKSUM_OFFSET(x) (((x) & 0xff) << 16) | ||
269 | # define AFMT_AUDIO_INFO_CXT(x) (((x) & 0x1f) << 24) | ||
270 | #define AFMT_AUDIO_INFO1 0x7100 | ||
271 | # define AFMT_AUDIO_INFO_CA(x) (((x) & 0xff) << 0) | ||
272 | # define AFMT_AUDIO_INFO_LSV(x) (((x) & 0xf) << 11) | ||
273 | # define AFMT_AUDIO_INFO_DM_INH(x) (((x) & 1) << 15) | ||
274 | # define AFMT_AUDIO_INFO_DM_INH_LSV(x) (((x) & 0xff) << 8) | ||
275 | # define AFMT_AUDIO_INFO_LFEBPL(x) (((x) & 3) << 16) | ||
276 | #define AFMT_60958_0 0x7104 | ||
277 | # define AFMT_60958_CS_A(x) (((x) & 1) << 0) | ||
278 | # define AFMT_60958_CS_B(x) (((x) & 1) << 1) | ||
279 | # define AFMT_60958_CS_C(x) (((x) & 1) << 2) | ||
280 | # define AFMT_60958_CS_D(x) (((x) & 3) << 3) | ||
281 | # define AFMT_60958_CS_MODE(x) (((x) & 3) << 6) | ||
282 | # define AFMT_60958_CS_CATEGORY_CODE(x) (((x) & 0xff) << 8) | ||
283 | # define AFMT_60958_CS_SOURCE_NUMBER(x) (((x) & 0xf) << 16) | ||
284 | # define AFMT_60958_CS_CHANNEL_NUMBER_L(x) (((x) & 0xf) << 20) | ||
285 | # define AFMT_60958_CS_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 24) | ||
286 | # define AFMT_60958_CS_CLOCK_ACCURACY(x) (((x) & 3) << 28) | ||
287 | #define AFMT_60958_1 0x7108 | ||
288 | # define AFMT_60958_CS_WORD_LENGTH(x) (((x) & 0xf) << 0) | ||
289 | # define AFMT_60958_CS_ORIGINAL_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 4) | ||
290 | # define AFMT_60958_CS_VALID_L(x) (((x) & 1) << 16) | ||
291 | # define AFMT_60958_CS_VALID_R(x) (((x) & 1) << 18) | ||
292 | # define AFMT_60958_CS_CHANNEL_NUMBER_R(x) (((x) & 0xf) << 20) | ||
293 | #define AFMT_AUDIO_CRC_CONTROL 0x710c | ||
294 | # define AFMT_AUDIO_CRC_EN (1 << 0) | ||
295 | #define AFMT_RAMP_CONTROL0 0x7110 | ||
296 | # define AFMT_RAMP_MAX_COUNT(x) (((x) & 0xffffff) << 0) | ||
297 | # define AFMT_RAMP_DATA_SIGN (1 << 31) | ||
298 | #define AFMT_RAMP_CONTROL1 0x7114 | ||
299 | # define AFMT_RAMP_MIN_COUNT(x) (((x) & 0xffffff) << 0) | ||
300 | # define AFMT_AUDIO_TEST_CH_DISABLE(x) (((x) & 0xff) << 24) | ||
301 | #define AFMT_RAMP_CONTROL2 0x7118 | ||
302 | # define AFMT_RAMP_INC_COUNT(x) (((x) & 0xffffff) << 0) | ||
303 | #define AFMT_RAMP_CONTROL3 0x711c | ||
304 | # define AFMT_RAMP_DEC_COUNT(x) (((x) & 0xffffff) << 0) | ||
305 | #define AFMT_60958_2 0x7120 | ||
306 | # define AFMT_60958_CS_CHANNEL_NUMBER_2(x) (((x) & 0xf) << 0) | ||
307 | # define AFMT_60958_CS_CHANNEL_NUMBER_3(x) (((x) & 0xf) << 4) | ||
308 | # define AFMT_60958_CS_CHANNEL_NUMBER_4(x) (((x) & 0xf) << 8) | ||
309 | # define AFMT_60958_CS_CHANNEL_NUMBER_5(x) (((x) & 0xf) << 12) | ||
310 | # define AFMT_60958_CS_CHANNEL_NUMBER_6(x) (((x) & 0xf) << 16) | ||
311 | # define AFMT_60958_CS_CHANNEL_NUMBER_7(x) (((x) & 0xf) << 20) | ||
312 | #define AFMT_STATUS 0x7128 | ||
313 | # define AFMT_AUDIO_ENABLE (1 << 4) | ||
314 | # define AFMT_AUDIO_HBR_ENABLE (1 << 8) | ||
315 | # define AFMT_AZ_FORMAT_WTRIG (1 << 28) | ||
316 | # define AFMT_AZ_FORMAT_WTRIG_INT (1 << 29) | ||
317 | # define AFMT_AZ_AUDIO_ENABLE_CHG (1 << 30) | ||
318 | #define AFMT_AUDIO_PACKET_CONTROL 0x712c | ||
319 | # define AFMT_AUDIO_SAMPLE_SEND (1 << 0) | ||
320 | # define AFMT_RESET_FIFO_WHEN_AUDIO_DIS (1 << 11) /* set to 1 */ | ||
321 | # define AFMT_AUDIO_TEST_EN (1 << 12) | ||
322 | # define AFMT_AUDIO_CHANNEL_SWAP (1 << 24) | ||
323 | # define AFMT_60958_CS_UPDATE (1 << 26) | ||
324 | # define AFMT_AZ_AUDIO_ENABLE_CHG_MASK (1 << 27) | ||
325 | # define AFMT_AZ_FORMAT_WTRIG_MASK (1 << 28) | ||
326 | # define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29) | ||
327 | # define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30) | ||
328 | #define AFMT_VBI_PACKET_CONTROL 0x7130 | ||
329 | # define AFMT_GENERIC0_UPDATE (1 << 2) | ||
330 | #define AFMT_INFOFRAME_CONTROL0 0x7134 | ||
331 | # define AFMT_AUDIO_INFO_SOURCE (1 << 6) /* 0 - sound block; 1 - afmt regs */ | ||
332 | # define AFMT_AUDIO_INFO_UPDATE (1 << 7) | ||
333 | # define AFMT_MPEG_INFO_UPDATE (1 << 10) | ||
334 | #define AFMT_GENERIC0_7 0x7138 | ||
115 | 335 | ||
116 | #define GC_USER_SHADER_PIPE_CONFIG 0x8954 | 336 | #define GC_USER_SHADER_PIPE_CONFIG 0x8954 |
117 | #define INACTIVE_QD_PIPES(x) ((x) << 8) | 337 | #define INACTIVE_QD_PIPES(x) ((x) << 8) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 5b9b81c69b66..222245d0138a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2968,6 +2968,15 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) | |||
2968 | WREG32(DC_HPD5_INT_CONTROL, tmp); | 2968 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
2969 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; | 2969 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; |
2970 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 2970 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
2971 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
2972 | WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, tmp); | ||
2973 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
2974 | WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, tmp); | ||
2975 | } else { | ||
2976 | tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
2977 | WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp); | ||
2978 | tmp = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
2979 | WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, tmp); | ||
2971 | } | 2980 | } |
2972 | } else { | 2981 | } else { |
2973 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | 2982 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); |
@@ -2978,6 +2987,10 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) | |||
2978 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | 2987 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); |
2979 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | 2988 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; |
2980 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | 2989 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); |
2990 | tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
2991 | WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp); | ||
2992 | tmp = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
2993 | WREG32(HDMI1_AUDIO_PACKET_CONTROL, tmp); | ||
2981 | } | 2994 | } |
2982 | } | 2995 | } |
2983 | 2996 | ||
@@ -3074,7 +3087,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3074 | u32 mode_int = 0; | 3087 | u32 mode_int = 0; |
3075 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 3088 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
3076 | u32 grbm_int_cntl = 0; | 3089 | u32 grbm_int_cntl = 0; |
3077 | u32 hdmi1, hdmi2; | 3090 | u32 hdmi0, hdmi1; |
3078 | u32 d1grph = 0, d2grph = 0; | 3091 | u32 d1grph = 0, d2grph = 0; |
3079 | 3092 | ||
3080 | if (!rdev->irq.installed) { | 3093 | if (!rdev->irq.installed) { |
@@ -3089,9 +3102,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3089 | return 0; | 3102 | return 0; |
3090 | } | 3103 | } |
3091 | 3104 | ||
3092 | hdmi1 = RREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; | ||
3093 | if (ASIC_IS_DCE3(rdev)) { | 3105 | if (ASIC_IS_DCE3(rdev)) { |
3094 | hdmi2 = RREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; | ||
3095 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3106 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3096 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3107 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3097 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3108 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; |
@@ -3099,12 +3110,18 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3099 | if (ASIC_IS_DCE32(rdev)) { | 3110 | if (ASIC_IS_DCE32(rdev)) { |
3100 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3111 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3101 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3112 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3113 | hdmi0 = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
3114 | hdmi1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1) & ~AFMT_AZ_FORMAT_WTRIG_MASK; | ||
3115 | } else { | ||
3116 | hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
3117 | hdmi1 = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
3102 | } | 3118 | } |
3103 | } else { | 3119 | } else { |
3104 | hdmi2 = RREG32(R600_HDMI_BLOCK2 + R600_HDMI_CNTL) & ~R600_HDMI_INT_EN; | ||
3105 | hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3120 | hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3106 | hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3121 | hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3107 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; | 3122 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; |
3123 | hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
3124 | hdmi1 = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK; | ||
3108 | } | 3125 | } |
3109 | 3126 | ||
3110 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { | 3127 | if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) { |
@@ -3146,13 +3163,13 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3146 | DRM_DEBUG("r600_irq_set: hpd 6\n"); | 3163 | DRM_DEBUG("r600_irq_set: hpd 6\n"); |
3147 | hpd6 |= DC_HPDx_INT_EN; | 3164 | hpd6 |= DC_HPDx_INT_EN; |
3148 | } | 3165 | } |
3149 | if (rdev->irq.hdmi[0]) { | 3166 | if (rdev->irq.afmt[0]) { |
3150 | DRM_DEBUG("r600_irq_set: hdmi 1\n"); | 3167 | DRM_DEBUG("r600_irq_set: hdmi 0\n"); |
3151 | hdmi1 |= R600_HDMI_INT_EN; | 3168 | hdmi0 |= HDMI0_AZ_FORMAT_WTRIG_MASK; |
3152 | } | 3169 | } |
3153 | if (rdev->irq.hdmi[1]) { | 3170 | if (rdev->irq.afmt[1]) { |
3154 | DRM_DEBUG("r600_irq_set: hdmi 2\n"); | 3171 | DRM_DEBUG("r600_irq_set: hdmi 0\n"); |
3155 | hdmi2 |= R600_HDMI_INT_EN; | 3172 | hdmi1 |= HDMI0_AZ_FORMAT_WTRIG_MASK; |
3156 | } | 3173 | } |
3157 | if (rdev->irq.gui_idle) { | 3174 | if (rdev->irq.gui_idle) { |
3158 | DRM_DEBUG("gui idle\n"); | 3175 | DRM_DEBUG("gui idle\n"); |
@@ -3164,9 +3181,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3164 | WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); | 3181 | WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); |
3165 | WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); | 3182 | WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); |
3166 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 3183 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
3167 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); | ||
3168 | if (ASIC_IS_DCE3(rdev)) { | 3184 | if (ASIC_IS_DCE3(rdev)) { |
3169 | WREG32(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, hdmi2); | ||
3170 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 3185 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
3171 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | 3186 | WREG32(DC_HPD2_INT_CONTROL, hpd2); |
3172 | WREG32(DC_HPD3_INT_CONTROL, hpd3); | 3187 | WREG32(DC_HPD3_INT_CONTROL, hpd3); |
@@ -3174,12 +3189,18 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3174 | if (ASIC_IS_DCE32(rdev)) { | 3189 | if (ASIC_IS_DCE32(rdev)) { |
3175 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | 3190 | WREG32(DC_HPD5_INT_CONTROL, hpd5); |
3176 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | 3191 | WREG32(DC_HPD6_INT_CONTROL, hpd6); |
3192 | WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, hdmi0); | ||
3193 | WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, hdmi1); | ||
3194 | } else { | ||
3195 | WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0); | ||
3196 | WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, hdmi1); | ||
3177 | } | 3197 | } |
3178 | } else { | 3198 | } else { |
3179 | WREG32(R600_HDMI_BLOCK2 + R600_HDMI_CNTL, hdmi2); | ||
3180 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | 3199 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); |
3181 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | 3200 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); |
3182 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); | 3201 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); |
3202 | WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0); | ||
3203 | WREG32(HDMI1_AUDIO_PACKET_CONTROL, hdmi1); | ||
3183 | } | 3204 | } |
3184 | 3205 | ||
3185 | return 0; | 3206 | return 0; |
@@ -3193,10 +3214,19 @@ static void r600_irq_ack(struct radeon_device *rdev) | |||
3193 | rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | 3214 | rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); |
3194 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | 3215 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); |
3195 | rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | 3216 | rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); |
3217 | if (ASIC_IS_DCE32(rdev)) { | ||
3218 | rdev->irq.stat_regs.r600.hdmi0_status = RREG32(AFMT_STATUS + DCE3_HDMI_OFFSET0); | ||
3219 | rdev->irq.stat_regs.r600.hdmi1_status = RREG32(AFMT_STATUS + DCE3_HDMI_OFFSET1); | ||
3220 | } else { | ||
3221 | rdev->irq.stat_regs.r600.hdmi0_status = RREG32(HDMI0_STATUS); | ||
3222 | rdev->irq.stat_regs.r600.hdmi1_status = RREG32(DCE3_HDMI1_STATUS); | ||
3223 | } | ||
3196 | } else { | 3224 | } else { |
3197 | rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); | 3225 | rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
3198 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | 3226 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
3199 | rdev->irq.stat_regs.r600.disp_int_cont2 = 0; | 3227 | rdev->irq.stat_regs.r600.disp_int_cont2 = 0; |
3228 | rdev->irq.stat_regs.r600.hdmi0_status = RREG32(HDMI0_STATUS); | ||
3229 | rdev->irq.stat_regs.r600.hdmi1_status = RREG32(HDMI1_STATUS); | ||
3200 | } | 3230 | } |
3201 | rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); | 3231 | rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); |
3202 | rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); | 3232 | rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); |
@@ -3262,17 +3292,32 @@ static void r600_irq_ack(struct radeon_device *rdev) | |||
3262 | tmp |= DC_HPDx_INT_ACK; | 3292 | tmp |= DC_HPDx_INT_ACK; |
3263 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 3293 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
3264 | } | 3294 | } |
3265 | } | 3295 | if (rdev->irq.stat_regs.r600.hdmi0_status & AFMT_AZ_FORMAT_WTRIG) { |
3266 | if (RREG32(R600_HDMI_BLOCK1 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { | 3296 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0); |
3267 | WREG32_P(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); | 3297 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; |
3268 | } | 3298 | WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, tmp); |
3269 | if (ASIC_IS_DCE3(rdev)) { | 3299 | } |
3270 | if (RREG32(R600_HDMI_BLOCK3 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { | 3300 | if (rdev->irq.stat_regs.r600.hdmi1_status & AFMT_AZ_FORMAT_WTRIG) { |
3271 | WREG32_P(R600_HDMI_BLOCK3 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); | 3301 | tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1); |
3302 | tmp |= AFMT_AZ_FORMAT_WTRIG_ACK; | ||
3303 | WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, tmp); | ||
3272 | } | 3304 | } |
3273 | } else { | 3305 | } else { |
3274 | if (RREG32(R600_HDMI_BLOCK2 + R600_HDMI_STATUS) & R600_HDMI_INT_PENDING) { | 3306 | if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) { |
3275 | WREG32_P(R600_HDMI_BLOCK2 + R600_HDMI_CNTL, R600_HDMI_INT_ACK, ~R600_HDMI_INT_ACK); | 3307 | tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL); |
3308 | tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK; | ||
3309 | WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp); | ||
3310 | } | ||
3311 | if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) { | ||
3312 | if (ASIC_IS_DCE3(rdev)) { | ||
3313 | tmp = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL); | ||
3314 | tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK; | ||
3315 | WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, tmp); | ||
3316 | } else { | ||
3317 | tmp = RREG32(HDMI1_AUDIO_PACKET_CONTROL); | ||
3318 | tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK; | ||
3319 | WREG32(HDMI1_AUDIO_PACKET_CONTROL, tmp); | ||
3320 | } | ||
3276 | } | 3321 | } |
3277 | } | 3322 | } |
3278 | } | 3323 | } |
@@ -3348,6 +3393,7 @@ int r600_irq_process(struct radeon_device *rdev) | |||
3348 | u32 ring_index; | 3393 | u32 ring_index; |
3349 | unsigned long flags; | 3394 | unsigned long flags; |
3350 | bool queue_hotplug = false; | 3395 | bool queue_hotplug = false; |
3396 | bool queue_hdmi = false; | ||
3351 | 3397 | ||
3352 | if (!rdev->ih.enabled || rdev->shutdown) | 3398 | if (!rdev->ih.enabled || rdev->shutdown) |
3353 | return IRQ_NONE; | 3399 | return IRQ_NONE; |
@@ -3483,9 +3529,26 @@ restart_ih: | |||
3483 | break; | 3529 | break; |
3484 | } | 3530 | } |
3485 | break; | 3531 | break; |
3486 | case 21: /* HDMI */ | 3532 | case 21: /* hdmi */ |
3487 | DRM_DEBUG("IH: HDMI: 0x%x\n", src_data); | 3533 | switch (src_data) { |
3488 | r600_audio_schedule_polling(rdev); | 3534 | case 4: |
3535 | if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) { | ||
3536 | rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG; | ||
3537 | queue_hdmi = true; | ||
3538 | DRM_DEBUG("IH: HDMI0\n"); | ||
3539 | } | ||
3540 | break; | ||
3541 | case 5: | ||
3542 | if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) { | ||
3543 | rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG; | ||
3544 | queue_hdmi = true; | ||
3545 | DRM_DEBUG("IH: HDMI1\n"); | ||
3546 | } | ||
3547 | break; | ||
3548 | default: | ||
3549 | DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
3550 | break; | ||
3551 | } | ||
3489 | break; | 3552 | break; |
3490 | case 176: /* CP_INT in ring buffer */ | 3553 | case 176: /* CP_INT in ring buffer */ |
3491 | case 177: /* CP_INT in IB1 */ | 3554 | case 177: /* CP_INT in IB1 */ |
@@ -3517,6 +3580,8 @@ restart_ih: | |||
3517 | goto restart_ih; | 3580 | goto restart_ih; |
3518 | if (queue_hotplug) | 3581 | if (queue_hotplug) |
3519 | schedule_work(&rdev->hotplug_work); | 3582 | schedule_work(&rdev->hotplug_work); |
3583 | if (queue_hdmi) | ||
3584 | schedule_work(&rdev->audio_work); | ||
3520 | rdev->ih.rptr = rptr; | 3585 | rdev->ih.rptr = rptr; |
3521 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3586 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
3522 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3587 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index ba66f3093d46..b922a3cd90db 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -29,8 +29,6 @@ | |||
29 | #include "radeon_asic.h" | 29 | #include "radeon_asic.h" |
30 | #include "atom.h" | 30 | #include "atom.h" |
31 | 31 | ||
32 | #define AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */ | ||
33 | |||
34 | /* | 32 | /* |
35 | * check if the chipset is supported | 33 | * check if the chipset is supported |
36 | */ | 34 | */ |
@@ -106,20 +104,12 @@ uint8_t r600_audio_category_code(struct radeon_device *rdev) | |||
106 | } | 104 | } |
107 | 105 | ||
108 | /* | 106 | /* |
109 | * schedule next audio update event | ||
110 | */ | ||
111 | void r600_audio_schedule_polling(struct radeon_device *rdev) | ||
112 | { | ||
113 | mod_timer(&rdev->audio_timer, | ||
114 | jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL)); | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * update all hdmi interfaces with current audio parameters | 107 | * update all hdmi interfaces with current audio parameters |
119 | */ | 108 | */ |
120 | static void r600_audio_update_hdmi(unsigned long param) | 109 | void r600_audio_update_hdmi(struct work_struct *work) |
121 | { | 110 | { |
122 | struct radeon_device *rdev = (struct radeon_device *)param; | 111 | struct radeon_device *rdev = container_of(work, struct radeon_device, |
112 | audio_work); | ||
123 | struct drm_device *dev = rdev->ddev; | 113 | struct drm_device *dev = rdev->ddev; |
124 | 114 | ||
125 | int channels = r600_audio_channels(rdev); | 115 | int channels = r600_audio_channels(rdev); |
@@ -127,33 +117,27 @@ static void r600_audio_update_hdmi(unsigned long param) | |||
127 | int bps = r600_audio_bits_per_sample(rdev); | 117 | int bps = r600_audio_bits_per_sample(rdev); |
128 | uint8_t status_bits = r600_audio_status_bits(rdev); | 118 | uint8_t status_bits = r600_audio_status_bits(rdev); |
129 | uint8_t category_code = r600_audio_category_code(rdev); | 119 | uint8_t category_code = r600_audio_category_code(rdev); |
130 | |||
131 | struct drm_encoder *encoder; | 120 | struct drm_encoder *encoder; |
132 | int changes = 0, still_going = 0; | 121 | int changes = 0; |
133 | 122 | ||
134 | changes |= channels != rdev->audio_channels; | 123 | changes |= channels != rdev->audio.channels; |
135 | changes |= rate != rdev->audio_rate; | 124 | changes |= rate != rdev->audio.rate; |
136 | changes |= bps != rdev->audio_bits_per_sample; | 125 | changes |= bps != rdev->audio.bits_per_sample; |
137 | changes |= status_bits != rdev->audio_status_bits; | 126 | changes |= status_bits != rdev->audio.status_bits; |
138 | changes |= category_code != rdev->audio_category_code; | 127 | changes |= category_code != rdev->audio.category_code; |
139 | 128 | ||
140 | if (changes) { | 129 | if (changes) { |
141 | rdev->audio_channels = channels; | 130 | rdev->audio.channels = channels; |
142 | rdev->audio_rate = rate; | 131 | rdev->audio.rate = rate; |
143 | rdev->audio_bits_per_sample = bps; | 132 | rdev->audio.bits_per_sample = bps; |
144 | rdev->audio_status_bits = status_bits; | 133 | rdev->audio.status_bits = status_bits; |
145 | rdev->audio_category_code = category_code; | 134 | rdev->audio.category_code = category_code; |
146 | } | 135 | } |
147 | 136 | ||
148 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 137 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
149 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
150 | still_going |= radeon_encoder->audio_polling_active; | ||
151 | if (changes || r600_hdmi_buffer_status_changed(encoder)) | 138 | if (changes || r600_hdmi_buffer_status_changed(encoder)) |
152 | r600_hdmi_update_audio_settings(encoder); | 139 | r600_hdmi_update_audio_settings(encoder); |
153 | } | 140 | } |
154 | |||
155 | if (still_going) | ||
156 | r600_audio_schedule_polling(rdev); | ||
157 | } | 141 | } |
158 | 142 | ||
159 | /* | 143 | /* |
@@ -173,11 +157,11 @@ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) | |||
173 | WREG32_P(R600_AUDIO_ENABLE, | 157 | WREG32_P(R600_AUDIO_ENABLE, |
174 | enable ? 0x81000000 : 0x0, ~0x81000000); | 158 | enable ? 0x81000000 : 0x0, ~0x81000000); |
175 | } | 159 | } |
176 | rdev->audio_enabled = enable; | 160 | rdev->audio.enabled = enable; |
177 | } | 161 | } |
178 | 162 | ||
179 | /* | 163 | /* |
180 | * initialize the audio vars and register the update timer | 164 | * initialize the audio vars |
181 | */ | 165 | */ |
182 | int r600_audio_init(struct radeon_device *rdev) | 166 | int r600_audio_init(struct radeon_device *rdev) |
183 | { | 167 | { |
@@ -186,51 +170,16 @@ int r600_audio_init(struct radeon_device *rdev) | |||
186 | 170 | ||
187 | r600_audio_engine_enable(rdev, true); | 171 | r600_audio_engine_enable(rdev, true); |
188 | 172 | ||
189 | rdev->audio_channels = -1; | 173 | rdev->audio.channels = -1; |
190 | rdev->audio_rate = -1; | 174 | rdev->audio.rate = -1; |
191 | rdev->audio_bits_per_sample = -1; | 175 | rdev->audio.bits_per_sample = -1; |
192 | rdev->audio_status_bits = 0; | 176 | rdev->audio.status_bits = 0; |
193 | rdev->audio_category_code = 0; | 177 | rdev->audio.category_code = 0; |
194 | |||
195 | setup_timer( | ||
196 | &rdev->audio_timer, | ||
197 | r600_audio_update_hdmi, | ||
198 | (unsigned long)rdev); | ||
199 | 178 | ||
200 | return 0; | 179 | return 0; |
201 | } | 180 | } |
202 | 181 | ||
203 | /* | 182 | /* |
204 | * enable the polling timer, to check for status changes | ||
205 | */ | ||
206 | void r600_audio_enable_polling(struct drm_encoder *encoder) | ||
207 | { | ||
208 | struct drm_device *dev = encoder->dev; | ||
209 | struct radeon_device *rdev = dev->dev_private; | ||
210 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
211 | |||
212 | DRM_DEBUG("r600_audio_enable_polling: %d\n", | ||
213 | radeon_encoder->audio_polling_active); | ||
214 | if (radeon_encoder->audio_polling_active) | ||
215 | return; | ||
216 | |||
217 | radeon_encoder->audio_polling_active = 1; | ||
218 | if (rdev->audio_enabled) | ||
219 | mod_timer(&rdev->audio_timer, jiffies + 1); | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * disable the polling timer, so we get no more status updates | ||
224 | */ | ||
225 | void r600_audio_disable_polling(struct drm_encoder *encoder) | ||
226 | { | ||
227 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
228 | DRM_DEBUG("r600_audio_disable_polling: %d\n", | ||
229 | radeon_encoder->audio_polling_active); | ||
230 | radeon_encoder->audio_polling_active = 0; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * atach the audio codec to the clock source of the encoder | 183 | * atach the audio codec to the clock source of the encoder |
235 | */ | 184 | */ |
236 | void r600_audio_set_clock(struct drm_encoder *encoder, int clock) | 185 | void r600_audio_set_clock(struct drm_encoder *encoder, int clock) |
@@ -294,10 +243,8 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) | |||
294 | */ | 243 | */ |
295 | void r600_audio_fini(struct radeon_device *rdev) | 244 | void r600_audio_fini(struct radeon_device *rdev) |
296 | { | 245 | { |
297 | if (!rdev->audio_enabled) | 246 | if (!rdev->audio.enabled) |
298 | return; | 247 | return; |
299 | 248 | ||
300 | del_timer(&rdev->audio_timer); | ||
301 | |||
302 | r600_audio_engine_enable(rdev, false); | 249 | r600_audio_engine_enable(rdev, false); |
303 | } | 250 | } |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 0b5920671450..c6de0022c070 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "radeon_drm.h" | 27 | #include "radeon_drm.h" |
28 | #include "radeon.h" | 28 | #include "radeon.h" |
29 | #include "radeon_asic.h" | 29 | #include "radeon_asic.h" |
30 | #include "r600d.h" | ||
30 | #include "atom.h" | 31 | #include "atom.h" |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -108,20 +109,20 @@ static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock) | |||
108 | CTS = r600_hdmi_ACR[i].CTS_32kHz; | 109 | CTS = r600_hdmi_ACR[i].CTS_32kHz; |
109 | N = r600_hdmi_ACR[i].N_32kHz; | 110 | N = r600_hdmi_ACR[i].N_32kHz; |
110 | r600_hdmi_calc_CTS(clock, &CTS, N, 32000); | 111 | r600_hdmi_calc_CTS(clock, &CTS, N, 32000); |
111 | WREG32(offset+R600_HDMI_32kHz_CTS, CTS << 12); | 112 | WREG32(HDMI0_ACR_32_0 + offset, HDMI0_ACR_CTS_32(CTS)); |
112 | WREG32(offset+R600_HDMI_32kHz_N, N); | 113 | WREG32(HDMI0_ACR_32_1 + offset, N); |
113 | 114 | ||
114 | CTS = r600_hdmi_ACR[i].CTS_44_1kHz; | 115 | CTS = r600_hdmi_ACR[i].CTS_44_1kHz; |
115 | N = r600_hdmi_ACR[i].N_44_1kHz; | 116 | N = r600_hdmi_ACR[i].N_44_1kHz; |
116 | r600_hdmi_calc_CTS(clock, &CTS, N, 44100); | 117 | r600_hdmi_calc_CTS(clock, &CTS, N, 44100); |
117 | WREG32(offset+R600_HDMI_44_1kHz_CTS, CTS << 12); | 118 | WREG32(HDMI0_ACR_44_0 + offset, HDMI0_ACR_CTS_44(CTS)); |
118 | WREG32(offset+R600_HDMI_44_1kHz_N, N); | 119 | WREG32(HDMI0_ACR_44_1 + offset, N); |
119 | 120 | ||
120 | CTS = r600_hdmi_ACR[i].CTS_48kHz; | 121 | CTS = r600_hdmi_ACR[i].CTS_48kHz; |
121 | N = r600_hdmi_ACR[i].N_48kHz; | 122 | N = r600_hdmi_ACR[i].N_48kHz; |
122 | r600_hdmi_calc_CTS(clock, &CTS, N, 48000); | 123 | r600_hdmi_calc_CTS(clock, &CTS, N, 48000); |
123 | WREG32(offset+R600_HDMI_48kHz_CTS, CTS << 12); | 124 | WREG32(HDMI0_ACR_48_0 + offset, HDMI0_ACR_CTS_48(CTS)); |
124 | WREG32(offset+R600_HDMI_48kHz_N, N); | 125 | WREG32(HDMI0_ACR_48_1 + offset, N); |
125 | } | 126 | } |
126 | 127 | ||
127 | /* | 128 | /* |
@@ -204,13 +205,13 @@ static void r600_hdmi_videoinfoframe( | |||
204 | * workaround this issue. */ | 205 | * workaround this issue. */ |
205 | frame[0x0] += 2; | 206 | frame[0x0] += 2; |
206 | 207 | ||
207 | WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0, | 208 | WREG32(HDMI0_AVI_INFO0 + offset, |
208 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); | 209 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); |
209 | WREG32(offset+R600_HDMI_VIDEOINFOFRAME_1, | 210 | WREG32(HDMI0_AVI_INFO1 + offset, |
210 | frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24)); | 211 | frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24)); |
211 | WREG32(offset+R600_HDMI_VIDEOINFOFRAME_2, | 212 | WREG32(HDMI0_AVI_INFO2 + offset, |
212 | frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); | 213 | frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24)); |
213 | WREG32(offset+R600_HDMI_VIDEOINFOFRAME_3, | 214 | WREG32(HDMI0_AVI_INFO3 + offset, |
214 | frame[0xC] | (frame[0xD] << 8)); | 215 | frame[0xC] | (frame[0xD] << 8)); |
215 | } | 216 | } |
216 | 217 | ||
@@ -249,9 +250,9 @@ static void r600_hdmi_audioinfoframe( | |||
249 | 250 | ||
250 | r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame); | 251 | r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame); |
251 | 252 | ||
252 | WREG32(offset+R600_HDMI_AUDIOINFOFRAME_0, | 253 | WREG32(HDMI0_AUDIO_INFO0 + offset, |
253 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); | 254 | frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24)); |
254 | WREG32(offset+R600_HDMI_AUDIOINFOFRAME_1, | 255 | WREG32(HDMI0_AUDIO_INFO1 + offset, |
255 | frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24)); | 256 | frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24)); |
256 | } | 257 | } |
257 | 258 | ||
@@ -264,7 +265,7 @@ static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder) | |||
264 | struct radeon_device *rdev = dev->dev_private; | 265 | struct radeon_device *rdev = dev->dev_private; |
265 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; | 266 | uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; |
266 | 267 | ||
267 | return (RREG32(offset+R600_HDMI_STATUS) & 0x10) != 0; | 268 | return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0; |
268 | } | 269 | } |
269 | 270 | ||
270 | /* | 271 | /* |
@@ -275,7 +276,7 @@ int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder) | |||
275 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 276 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
276 | int status, result; | 277 | int status, result; |
277 | 278 | ||
278 | if (!radeon_encoder->hdmi_offset) | 279 | if (!radeon_encoder->hdmi_enabled) |
279 | return 0; | 280 | return 0; |
280 | 281 | ||
281 | status = r600_hdmi_is_audio_buffer_filled(encoder); | 282 | status = r600_hdmi_is_audio_buffer_filled(encoder); |
@@ -295,18 +296,18 @@ void r600_hdmi_audio_workaround(struct drm_encoder *encoder) | |||
295 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 296 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
296 | uint32_t offset = radeon_encoder->hdmi_offset; | 297 | uint32_t offset = radeon_encoder->hdmi_offset; |
297 | 298 | ||
298 | if (!offset) | 299 | if (!radeon_encoder->hdmi_enabled) |
299 | return; | 300 | return; |
300 | 301 | ||
301 | if (!radeon_encoder->hdmi_audio_workaround || | 302 | if (!radeon_encoder->hdmi_audio_workaround || |
302 | r600_hdmi_is_audio_buffer_filled(encoder)) { | 303 | r600_hdmi_is_audio_buffer_filled(encoder)) { |
303 | 304 | ||
304 | /* disable audio workaround */ | 305 | /* disable audio workaround */ |
305 | WREG32_P(offset+R600_HDMI_CNTL, 0x00000001, ~0x00001001); | 306 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x0001, ~0x1001); |
306 | 307 | ||
307 | } else { | 308 | } else { |
308 | /* enable audio workaround */ | 309 | /* enable audio workaround */ |
309 | WREG32_P(offset+R600_HDMI_CNTL, 0x00001001, ~0x00001001); | 310 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x1001, ~0x1001); |
310 | } | 311 | } |
311 | } | 312 | } |
312 | 313 | ||
@@ -323,34 +324,34 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
323 | if (ASIC_IS_DCE5(rdev)) | 324 | if (ASIC_IS_DCE5(rdev)) |
324 | return; | 325 | return; |
325 | 326 | ||
326 | if (!offset) | 327 | if (!to_radeon_encoder(encoder)->hdmi_enabled) |
327 | return; | 328 | return; |
328 | 329 | ||
329 | r600_audio_set_clock(encoder, mode->clock); | 330 | r600_audio_set_clock(encoder, mode->clock); |
330 | 331 | ||
331 | WREG32(offset+R600_HDMI_UNKNOWN_0, 0x1000); | 332 | WREG32(HDMI0_AUDIO_CRC_CONTROL + offset, 0x1000); |
332 | WREG32(offset+R600_HDMI_UNKNOWN_1, 0x0); | 333 | WREG32(HDMI0_GC + offset, 0x0); |
333 | WREG32(offset+R600_HDMI_UNKNOWN_2, 0x1000); | 334 | WREG32(HDMI0_ACR_PACKET_CONTROL + offset, 0x1000); |
334 | 335 | ||
335 | r600_hdmi_update_ACR(encoder, mode->clock); | 336 | r600_hdmi_update_ACR(encoder, mode->clock); |
336 | 337 | ||
337 | WREG32(offset+R600_HDMI_VIDEOCNTL, 0x13); | 338 | WREG32(HDMI0_INFOFRAME_CONTROL0 + offset, 0x13); |
338 | 339 | ||
339 | WREG32(offset+R600_HDMI_VERSION, 0x202); | 340 | WREG32(HDMI0_INFOFRAME_CONTROL1 + offset, 0x202); |
340 | 341 | ||
341 | r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0, | 342 | r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0, |
342 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); | 343 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); |
343 | 344 | ||
344 | /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ | 345 | /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ |
345 | WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF); | 346 | WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); |
346 | WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF); | 347 | WREG32(HDMI0_RAMP_CONTROL1 + offset, 0x007FFFFF); |
347 | WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001); | 348 | WREG32(HDMI0_RAMP_CONTROL2 + offset, 0x00000001); |
348 | WREG32(offset+R600_HDMI_AUDIO_DEBUG_3, 0x00000001); | 349 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); |
349 | 350 | ||
350 | r600_hdmi_audio_workaround(encoder); | 351 | r600_hdmi_audio_workaround(encoder); |
351 | 352 | ||
352 | /* audio packets per line, does anyone know how to calc this ? */ | 353 | /* audio packets per line, does anyone know how to calc this ? */ |
353 | WREG32_P(offset+R600_HDMI_CNTL, 0x00040000, ~0x001F0000); | 354 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, 0x00040000, ~0x001F0000); |
354 | } | 355 | } |
355 | 356 | ||
356 | /* | 357 | /* |
@@ -370,7 +371,7 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) | |||
370 | 371 | ||
371 | uint32_t iec; | 372 | uint32_t iec; |
372 | 373 | ||
373 | if (!offset) | 374 | if (!to_radeon_encoder(encoder)->hdmi_enabled) |
374 | return; | 375 | return; |
375 | 376 | ||
376 | DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n", | 377 | DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n", |
@@ -401,7 +402,7 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) | |||
401 | case 192000: iec |= 0xe << 24; break; | 402 | case 192000: iec |= 0xe << 24; break; |
402 | } | 403 | } |
403 | 404 | ||
404 | WREG32(offset+R600_HDMI_IEC60958_1, iec); | 405 | WREG32(HDMI0_60958_0 + offset, iec); |
405 | 406 | ||
406 | iec = 0; | 407 | iec = 0; |
407 | switch (bps) { | 408 | switch (bps) { |
@@ -412,49 +413,15 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) | |||
412 | if (status_bits & AUDIO_STATUS_V) | 413 | if (status_bits & AUDIO_STATUS_V) |
413 | iec |= 0x5 << 16; | 414 | iec |= 0x5 << 16; |
414 | 415 | ||
415 | WREG32_P(offset+R600_HDMI_IEC60958_2, iec, ~0x5000f); | 416 | WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f); |
416 | 417 | ||
417 | /* 0x021 or 0x031 sets the audio frame length */ | 418 | /* 0x021 or 0x031 sets the audio frame length */ |
418 | WREG32(offset+R600_HDMI_AUDIOCNTL, 0x31); | 419 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, 0x31); |
419 | r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0); | 420 | r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0); |
420 | 421 | ||
421 | r600_hdmi_audio_workaround(encoder); | 422 | r600_hdmi_audio_workaround(encoder); |
422 | } | 423 | } |
423 | 424 | ||
424 | static int r600_hdmi_find_free_block(struct drm_device *dev) | ||
425 | { | ||
426 | struct radeon_device *rdev = dev->dev_private; | ||
427 | struct drm_encoder *encoder; | ||
428 | struct radeon_encoder *radeon_encoder; | ||
429 | bool free_blocks[3] = { true, true, true }; | ||
430 | |||
431 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
432 | radeon_encoder = to_radeon_encoder(encoder); | ||
433 | switch (radeon_encoder->hdmi_offset) { | ||
434 | case R600_HDMI_BLOCK1: | ||
435 | free_blocks[0] = false; | ||
436 | break; | ||
437 | case R600_HDMI_BLOCK2: | ||
438 | free_blocks[1] = false; | ||
439 | break; | ||
440 | case R600_HDMI_BLOCK3: | ||
441 | free_blocks[2] = false; | ||
442 | break; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || | ||
447 | rdev->family == CHIP_RS740) { | ||
448 | return free_blocks[0] ? R600_HDMI_BLOCK1 : 0; | ||
449 | } else if (rdev->family >= CHIP_R600) { | ||
450 | if (free_blocks[0]) | ||
451 | return R600_HDMI_BLOCK1; | ||
452 | else if (free_blocks[1]) | ||
453 | return R600_HDMI_BLOCK2; | ||
454 | } | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static void r600_hdmi_assign_block(struct drm_encoder *encoder) | 425 | static void r600_hdmi_assign_block(struct drm_encoder *encoder) |
459 | { | 426 | { |
460 | struct drm_device *dev = encoder->dev; | 427 | struct drm_device *dev = encoder->dev; |
@@ -483,20 +450,24 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) | |||
483 | dev_err(rdev->dev, "Enabling HDMI on unknown dig\n"); | 450 | dev_err(rdev->dev, "Enabling HDMI on unknown dig\n"); |
484 | return; | 451 | return; |
485 | } | 452 | } |
486 | radeon_encoder->hdmi_offset = EVERGREEN_HDMI_BASE + | 453 | radeon_encoder->hdmi_offset = eg_offsets[dig->dig_encoder]; |
487 | eg_offsets[dig->dig_encoder]; | 454 | /* Temp hack for Evergreen until we split r600_hdmi.c |
488 | radeon_encoder->hdmi_config_offset = radeon_encoder->hdmi_offset | 455 | * Evergreen first block is 0x7030 instead of 0x7400. |
489 | + EVERGREEN_HDMI_CONFIG_OFFSET; | 456 | */ |
457 | radeon_encoder->hdmi_offset -= 0x3d0; | ||
490 | } else if (ASIC_IS_DCE3(rdev)) { | 458 | } else if (ASIC_IS_DCE3(rdev)) { |
491 | radeon_encoder->hdmi_offset = dig->dig_encoder ? | 459 | radeon_encoder->hdmi_offset = dig->dig_encoder ? |
492 | R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1; | 460 | DCE3_HDMI_OFFSET1 : DCE3_HDMI_OFFSET0; |
493 | if (ASIC_IS_DCE32(rdev)) | 461 | } else if (rdev->family >= CHIP_R600) { |
494 | radeon_encoder->hdmi_config_offset = dig->dig_encoder ? | 462 | /* 2 routable blocks, but using dig_encoder should be fine */ |
495 | R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; | 463 | radeon_encoder->hdmi_offset = dig->dig_encoder ? |
496 | } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 || | 464 | DCE2_HDMI_OFFSET1 : DCE2_HDMI_OFFSET0; |
497 | rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) { | 465 | } else if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || |
498 | radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); | 466 | rdev->family == CHIP_RS740) { |
467 | /* Only 1 routable block */ | ||
468 | radeon_encoder->hdmi_offset = DCE2_HDMI_OFFSET0; | ||
499 | } | 469 | } |
470 | radeon_encoder->hdmi_enabled = true; | ||
500 | } | 471 | } |
501 | 472 | ||
502 | /* | 473 | /* |
@@ -512,9 +483,9 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
512 | if (ASIC_IS_DCE5(rdev)) | 483 | if (ASIC_IS_DCE5(rdev)) |
513 | return; | 484 | return; |
514 | 485 | ||
515 | if (!radeon_encoder->hdmi_offset) { | 486 | if (!radeon_encoder->hdmi_enabled) { |
516 | r600_hdmi_assign_block(encoder); | 487 | r600_hdmi_assign_block(encoder); |
517 | if (!radeon_encoder->hdmi_offset) { | 488 | if (!radeon_encoder->hdmi_enabled) { |
518 | dev_warn(rdev->dev, "Could not find HDMI block for " | 489 | dev_warn(rdev->dev, "Could not find HDMI block for " |
519 | "0x%x encoder\n", radeon_encoder->encoder_id); | 490 | "0x%x encoder\n", radeon_encoder->encoder_id); |
520 | return; | 491 | return; |
@@ -525,9 +496,9 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
525 | if (ASIC_IS_DCE5(rdev)) { | 496 | if (ASIC_IS_DCE5(rdev)) { |
526 | /* TODO */ | 497 | /* TODO */ |
527 | } else if (ASIC_IS_DCE4(rdev)) { | 498 | } else if (ASIC_IS_DCE4(rdev)) { |
528 | WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0x1, ~0x1); | 499 | WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0x1, ~0x1); |
529 | } else if (ASIC_IS_DCE32(rdev)) { | 500 | } else if (ASIC_IS_DCE32(rdev)) { |
530 | WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1); | 501 | WREG32_P(AFMT_AUDIO_PACKET_CONTROL + radeon_encoder->hdmi_offset, 0x1, ~0x1); |
531 | } else if (ASIC_IS_DCE3(rdev)) { | 502 | } else if (ASIC_IS_DCE3(rdev)) { |
532 | /* TODO */ | 503 | /* TODO */ |
533 | } else if (rdev->family >= CHIP_R600) { | 504 | } else if (rdev->family >= CHIP_R600) { |
@@ -535,12 +506,12 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
535 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | 506 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
536 | WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN, | 507 | WREG32_P(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN, |
537 | ~AVIVO_TMDSA_CNTL_HDMI_EN); | 508 | ~AVIVO_TMDSA_CNTL_HDMI_EN); |
538 | WREG32(offset + R600_HDMI_ENABLE, 0x101); | 509 | WREG32(HDMI0_CONTROL + offset, 0x101); |
539 | break; | 510 | break; |
540 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | 511 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: |
541 | WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN, | 512 | WREG32_P(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN, |
542 | ~AVIVO_LVTMA_CNTL_HDMI_EN); | 513 | ~AVIVO_LVTMA_CNTL_HDMI_EN); |
543 | WREG32(offset + R600_HDMI_ENABLE, 0x105); | 514 | WREG32(HDMI0_CONTROL + offset, 0x105); |
544 | break; | 515 | break; |
545 | default: | 516 | default: |
546 | dev_err(rdev->dev, "Unknown HDMI output type\n"); | 517 | dev_err(rdev->dev, "Unknown HDMI output type\n"); |
@@ -548,19 +519,10 @@ void r600_hdmi_enable(struct drm_encoder *encoder) | |||
548 | } | 519 | } |
549 | } | 520 | } |
550 | 521 | ||
551 | if (rdev->irq.installed | 522 | if (rdev->irq.installed) { |
552 | && rdev->family != CHIP_RS600 | ||
553 | && rdev->family != CHIP_RS690 | ||
554 | && rdev->family != CHIP_RS740 | ||
555 | && !ASIC_IS_DCE4(rdev)) { | ||
556 | /* if irq is available use it */ | 523 | /* if irq is available use it */ |
557 | rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = true; | 524 | rdev->irq.afmt[offset == 0 ? 0 : 1] = true; |
558 | radeon_irq_set(rdev); | 525 | radeon_irq_set(rdev); |
559 | |||
560 | r600_audio_disable_polling(encoder); | ||
561 | } else { | ||
562 | /* if not fallback to polling */ | ||
563 | r600_audio_enable_polling(encoder); | ||
564 | } | 526 | } |
565 | 527 | ||
566 | DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 528 | DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
@@ -581,7 +543,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
581 | return; | 543 | return; |
582 | 544 | ||
583 | offset = radeon_encoder->hdmi_offset; | 545 | offset = radeon_encoder->hdmi_offset; |
584 | if (!offset) { | 546 | if (!radeon_encoder->hdmi_enabled) { |
585 | dev_err(rdev->dev, "Disabling not enabled HDMI\n"); | 547 | dev_err(rdev->dev, "Disabling not enabled HDMI\n"); |
586 | return; | 548 | return; |
587 | } | 549 | } |
@@ -590,29 +552,27 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
590 | offset, radeon_encoder->encoder_id); | 552 | offset, radeon_encoder->encoder_id); |
591 | 553 | ||
592 | /* disable irq */ | 554 | /* disable irq */ |
593 | rdev->irq.hdmi[offset == R600_HDMI_BLOCK1 ? 0 : 1] = false; | 555 | rdev->irq.afmt[offset == 0 ? 0 : 1] = false; |
594 | radeon_irq_set(rdev); | 556 | radeon_irq_set(rdev); |
595 | 557 | ||
596 | /* disable polling */ | ||
597 | r600_audio_disable_polling(encoder); | ||
598 | 558 | ||
599 | if (ASIC_IS_DCE5(rdev)) { | 559 | if (ASIC_IS_DCE5(rdev)) { |
600 | /* TODO */ | 560 | /* TODO */ |
601 | } else if (ASIC_IS_DCE4(rdev)) { | 561 | } else if (ASIC_IS_DCE4(rdev)) { |
602 | WREG32_P(radeon_encoder->hdmi_config_offset + 0xc, 0, ~0x1); | 562 | WREG32_P(0x74fc + radeon_encoder->hdmi_offset, 0, ~0x1); |
603 | } else if (ASIC_IS_DCE32(rdev)) { | 563 | } else if (ASIC_IS_DCE32(rdev)) { |
604 | WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1); | 564 | WREG32_P(AFMT_AUDIO_PACKET_CONTROL + radeon_encoder->hdmi_offset, 0, ~0x1); |
605 | } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { | 565 | } else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) { |
606 | switch (radeon_encoder->encoder_id) { | 566 | switch (radeon_encoder->encoder_id) { |
607 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | 567 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: |
608 | WREG32_P(AVIVO_TMDSA_CNTL, 0, | 568 | WREG32_P(AVIVO_TMDSA_CNTL, 0, |
609 | ~AVIVO_TMDSA_CNTL_HDMI_EN); | 569 | ~AVIVO_TMDSA_CNTL_HDMI_EN); |
610 | WREG32(offset + R600_HDMI_ENABLE, 0); | 570 | WREG32(HDMI0_CONTROL + offset, 0); |
611 | break; | 571 | break; |
612 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | 572 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: |
613 | WREG32_P(AVIVO_LVTMA_CNTL, 0, | 573 | WREG32_P(AVIVO_LVTMA_CNTL, 0, |
614 | ~AVIVO_LVTMA_CNTL_HDMI_EN); | 574 | ~AVIVO_LVTMA_CNTL_HDMI_EN); |
615 | WREG32(offset + R600_HDMI_ENABLE, 0); | 575 | WREG32(HDMI0_CONTROL + offset, 0); |
616 | break; | 576 | break; |
617 | default: | 577 | default: |
618 | dev_err(rdev->dev, "Unknown HDMI output type\n"); | 578 | dev_err(rdev->dev, "Unknown HDMI output type\n"); |
@@ -620,6 +580,6 @@ void r600_hdmi_disable(struct drm_encoder *encoder) | |||
620 | } | 580 | } |
621 | } | 581 | } |
622 | 582 | ||
583 | radeon_encoder->hdmi_enabled = false; | ||
623 | radeon_encoder->hdmi_offset = 0; | 584 | radeon_encoder->hdmi_offset = 0; |
624 | radeon_encoder->hdmi_config_offset = 0; | ||
625 | } | 585 | } |
diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h index f869897c7456..c44304ad8bda 100644 --- a/drivers/gpu/drm/radeon/r600_reg.h +++ b/drivers/gpu/drm/radeon/r600_reg.h | |||
@@ -156,45 +156,4 @@ | |||
156 | #define R600_AUDIO_PIN_WIDGET_CNTL 0x73d4 | 156 | #define R600_AUDIO_PIN_WIDGET_CNTL 0x73d4 |
157 | #define R600_AUDIO_STATUS_BITS 0x73d8 | 157 | #define R600_AUDIO_STATUS_BITS 0x73d8 |
158 | 158 | ||
159 | /* HDMI base register addresses */ | ||
160 | #define R600_HDMI_BLOCK1 0x7400 | ||
161 | #define R600_HDMI_BLOCK2 0x7700 | ||
162 | #define R600_HDMI_BLOCK3 0x7800 | ||
163 | |||
164 | /* HDMI registers */ | ||
165 | #define R600_HDMI_ENABLE 0x00 | ||
166 | #define R600_HDMI_STATUS 0x04 | ||
167 | # define R600_HDMI_INT_PENDING (1 << 29) | ||
168 | #define R600_HDMI_CNTL 0x08 | ||
169 | # define R600_HDMI_INT_EN (1 << 28) | ||
170 | # define R600_HDMI_INT_ACK (1 << 29) | ||
171 | #define R600_HDMI_UNKNOWN_0 0x0C | ||
172 | #define R600_HDMI_AUDIOCNTL 0x10 | ||
173 | #define R600_HDMI_VIDEOCNTL 0x14 | ||
174 | #define R600_HDMI_VERSION 0x18 | ||
175 | #define R600_HDMI_UNKNOWN_1 0x28 | ||
176 | #define R600_HDMI_VIDEOINFOFRAME_0 0x54 | ||
177 | #define R600_HDMI_VIDEOINFOFRAME_1 0x58 | ||
178 | #define R600_HDMI_VIDEOINFOFRAME_2 0x5c | ||
179 | #define R600_HDMI_VIDEOINFOFRAME_3 0x60 | ||
180 | #define R600_HDMI_32kHz_CTS 0xac | ||
181 | #define R600_HDMI_32kHz_N 0xb0 | ||
182 | #define R600_HDMI_44_1kHz_CTS 0xb4 | ||
183 | #define R600_HDMI_44_1kHz_N 0xb8 | ||
184 | #define R600_HDMI_48kHz_CTS 0xbc | ||
185 | #define R600_HDMI_48kHz_N 0xc0 | ||
186 | #define R600_HDMI_AUDIOINFOFRAME_0 0xcc | ||
187 | #define R600_HDMI_AUDIOINFOFRAME_1 0xd0 | ||
188 | #define R600_HDMI_IEC60958_1 0xd4 | ||
189 | #define R600_HDMI_IEC60958_2 0xd8 | ||
190 | #define R600_HDMI_UNKNOWN_2 0xdc | ||
191 | #define R600_HDMI_AUDIO_DEBUG_0 0xe0 | ||
192 | #define R600_HDMI_AUDIO_DEBUG_1 0xe4 | ||
193 | #define R600_HDMI_AUDIO_DEBUG_2 0xe8 | ||
194 | #define R600_HDMI_AUDIO_DEBUG_3 0xec | ||
195 | |||
196 | /* HDMI additional config base register addresses */ | ||
197 | #define R600_HDMI_CONFIG1 0x7600 | ||
198 | #define R600_HDMI_CONFIG2 0x7a00 | ||
199 | |||
200 | #endif | 159 | #endif |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 59f9c993cc31..a9652be93b66 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -824,6 +824,245 @@ | |||
824 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | 824 | # define TARGET_LINK_SPEED_MASK (0xf << 0) |
825 | # define SELECTABLE_DEEMPHASIS (1 << 6) | 825 | # define SELECTABLE_DEEMPHASIS (1 << 6) |
826 | 826 | ||
827 | /* Audio clocks */ | ||
828 | #define DCCG_AUDIO_DTO0_PHASE 0x0514 | ||
829 | #define DCCG_AUDIO_DTO0_MODULE 0x0518 | ||
830 | #define DCCG_AUDIO_DTO0_LOAD 0x051c | ||
831 | # define DTO_LOAD (1 << 31) | ||
832 | #define DCCG_AUDIO_DTO0_CNTL 0x0520 | ||
833 | |||
834 | #define DCCG_AUDIO_DTO1_PHASE 0x0524 | ||
835 | #define DCCG_AUDIO_DTO1_MODULE 0x0528 | ||
836 | #define DCCG_AUDIO_DTO1_LOAD 0x052c | ||
837 | #define DCCG_AUDIO_DTO1_CNTL 0x0530 | ||
838 | |||
839 | #define DCCG_AUDIO_DTO_SELECT 0x0534 | ||
840 | |||
841 | /* digital blocks */ | ||
842 | #define TMDSA_CNTL 0x7880 | ||
843 | # define TMDSA_HDMI_EN (1 << 2) | ||
844 | #define LVTMA_CNTL 0x7a80 | ||
845 | # define LVTMA_HDMI_EN (1 << 2) | ||
846 | #define DDIA_CNTL 0x7200 | ||
847 | # define DDIA_HDMI_EN (1 << 2) | ||
848 | #define DIG0_CNTL 0x75a0 | ||
849 | # define DIG_MODE(x) (((x) & 7) << 8) | ||
850 | # define DIG_MODE_DP 0 | ||
851 | # define DIG_MODE_LVDS 1 | ||
852 | # define DIG_MODE_TMDS_DVI 2 | ||
853 | # define DIG_MODE_TMDS_HDMI 3 | ||
854 | # define DIG_MODE_SDVO 4 | ||
855 | #define DIG1_CNTL 0x79a0 | ||
856 | |||
857 | /* rs6xx/rs740 and r6xx share the same HDMI blocks, however, rs6xx has only one | ||
858 | * instance of the blocks while r6xx has 2. DCE 3.0 cards are slightly | ||
859 | * different due to the new DIG blocks, but also have 2 instances. | ||
860 | * DCE 3.0 HDMI blocks are part of each DIG encoder. | ||
861 | */ | ||
862 | |||
863 | /* rs6xx/rs740/r6xx/dce3 */ | ||
864 | #define HDMI0_CONTROL 0x7400 | ||
865 | /* rs6xx/rs740/r6xx */ | ||
866 | # define HDMI0_ENABLE (1 << 0) | ||
867 | # define HDMI0_STREAM(x) (((x) & 3) << 2) | ||
868 | # define HDMI0_STREAM_TMDSA 0 | ||
869 | # define HDMI0_STREAM_LVTMA 1 | ||
870 | # define HDMI0_STREAM_DVOA 2 | ||
871 | # define HDMI0_STREAM_DDIA 3 | ||
872 | /* rs6xx/r6xx/dce3 */ | ||
873 | # define HDMI0_ERROR_ACK (1 << 8) | ||
874 | # define HDMI0_ERROR_MASK (1 << 9) | ||
875 | #define HDMI0_STATUS 0x7404 | ||
876 | # define HDMI0_ACTIVE_AVMUTE (1 << 0) | ||
877 | # define HDMI0_AUDIO_ENABLE (1 << 4) | ||
878 | # define HDMI0_AZ_FORMAT_WTRIG (1 << 28) | ||
879 | # define HDMI0_AZ_FORMAT_WTRIG_INT (1 << 29) | ||
880 | #define HDMI0_AUDIO_PACKET_CONTROL 0x7408 | ||
881 | # define HDMI0_AUDIO_SAMPLE_SEND (1 << 0) | ||
882 | # define HDMI0_AUDIO_DELAY_EN(x) (((x) & 3) << 4) | ||
883 | # define HDMI0_AUDIO_SEND_MAX_PACKETS (1 << 8) | ||
884 | # define HDMI0_AUDIO_TEST_EN (1 << 12) | ||
885 | # define HDMI0_AUDIO_PACKETS_PER_LINE(x) (((x) & 0x1f) << 16) | ||
886 | # define HDMI0_AUDIO_CHANNEL_SWAP (1 << 24) | ||
887 | # define HDMI0_60958_CS_UPDATE (1 << 26) | ||
888 | # define HDMI0_AZ_FORMAT_WTRIG_MASK (1 << 28) | ||
889 | # define HDMI0_AZ_FORMAT_WTRIG_ACK (1 << 29) | ||
890 | #define HDMI0_AUDIO_CRC_CONTROL 0x740c | ||
891 | # define HDMI0_AUDIO_CRC_EN (1 << 0) | ||
892 | #define HDMI0_VBI_PACKET_CONTROL 0x7410 | ||
893 | # define HDMI0_NULL_SEND (1 << 0) | ||
894 | # define HDMI0_GC_SEND (1 << 4) | ||
895 | # define HDMI0_GC_CONT (1 << 5) /* 0 - once; 1 - every frame */ | ||
896 | #define HDMI0_INFOFRAME_CONTROL0 0x7414 | ||
897 | # define HDMI0_AVI_INFO_SEND (1 << 0) | ||
898 | # define HDMI0_AVI_INFO_CONT (1 << 1) | ||
899 | # define HDMI0_AUDIO_INFO_SEND (1 << 4) | ||
900 | # define HDMI0_AUDIO_INFO_CONT (1 << 5) | ||
901 | # define HDMI0_AUDIO_INFO_SOURCE (1 << 6) /* 0 - sound block; 1 - hmdi regs */ | ||
902 | # define HDMI0_AUDIO_INFO_UPDATE (1 << 7) | ||
903 | # define HDMI0_MPEG_INFO_SEND (1 << 8) | ||
904 | # define HDMI0_MPEG_INFO_CONT (1 << 9) | ||
905 | # define HDMI0_MPEG_INFO_UPDATE (1 << 10) | ||
906 | #define HDMI0_INFOFRAME_CONTROL1 0x7418 | ||
907 | # define HDMI0_AVI_INFO_LINE(x) (((x) & 0x3f) << 0) | ||
908 | # define HDMI0_AUDIO_INFO_LINE(x) (((x) & 0x3f) << 8) | ||
909 | # define HDMI0_MPEG_INFO_LINE(x) (((x) & 0x3f) << 16) | ||
910 | #define HDMI0_GENERIC_PACKET_CONTROL 0x741c | ||
911 | # define HDMI0_GENERIC0_SEND (1 << 0) | ||
912 | # define HDMI0_GENERIC0_CONT (1 << 1) | ||
913 | # define HDMI0_GENERIC0_UPDATE (1 << 2) | ||
914 | # define HDMI0_GENERIC1_SEND (1 << 4) | ||
915 | # define HDMI0_GENERIC1_CONT (1 << 5) | ||
916 | # define HDMI0_GENERIC0_LINE(x) (((x) & 0x3f) << 16) | ||
917 | # define HDMI0_GENERIC1_LINE(x) (((x) & 0x3f) << 24) | ||
918 | #define HDMI0_GC 0x7428 | ||
919 | # define HDMI0_GC_AVMUTE (1 << 0) | ||
920 | #define HDMI0_AVI_INFO0 0x7454 | ||
921 | # define HDMI0_AVI_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
922 | # define HDMI0_AVI_INFO_S(x) (((x) & 3) << 8) | ||
923 | # define HDMI0_AVI_INFO_B(x) (((x) & 3) << 10) | ||
924 | # define HDMI0_AVI_INFO_A(x) (((x) & 1) << 12) | ||
925 | # define HDMI0_AVI_INFO_Y(x) (((x) & 3) << 13) | ||
926 | # define HDMI0_AVI_INFO_Y_RGB 0 | ||
927 | # define HDMI0_AVI_INFO_Y_YCBCR422 1 | ||
928 | # define HDMI0_AVI_INFO_Y_YCBCR444 2 | ||
929 | # define HDMI0_AVI_INFO_Y_A_B_S(x) (((x) & 0xff) << 8) | ||
930 | # define HDMI0_AVI_INFO_R(x) (((x) & 0xf) << 16) | ||
931 | # define HDMI0_AVI_INFO_M(x) (((x) & 0x3) << 20) | ||
932 | # define HDMI0_AVI_INFO_C(x) (((x) & 0x3) << 22) | ||
933 | # define HDMI0_AVI_INFO_C_M_R(x) (((x) & 0xff) << 16) | ||
934 | # define HDMI0_AVI_INFO_SC(x) (((x) & 0x3) << 24) | ||
935 | # define HDMI0_AVI_INFO_ITC_EC_Q_SC(x) (((x) & 0xff) << 24) | ||
936 | #define HDMI0_AVI_INFO1 0x7458 | ||
937 | # define HDMI0_AVI_INFO_VIC(x) (((x) & 0x7f) << 0) /* don't use avi infoframe v1 */ | ||
938 | # define HDMI0_AVI_INFO_PR(x) (((x) & 0xf) << 8) /* don't use avi infoframe v1 */ | ||
939 | # define HDMI0_AVI_INFO_TOP(x) (((x) & 0xffff) << 16) | ||
940 | #define HDMI0_AVI_INFO2 0x745c | ||
941 | # define HDMI0_AVI_INFO_BOTTOM(x) (((x) & 0xffff) << 0) | ||
942 | # define HDMI0_AVI_INFO_LEFT(x) (((x) & 0xffff) << 16) | ||
943 | #define HDMI0_AVI_INFO3 0x7460 | ||
944 | # define HDMI0_AVI_INFO_RIGHT(x) (((x) & 0xffff) << 0) | ||
945 | # define HDMI0_AVI_INFO_VERSION(x) (((x) & 3) << 24) | ||
946 | #define HDMI0_MPEG_INFO0 0x7464 | ||
947 | # define HDMI0_MPEG_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
948 | # define HDMI0_MPEG_INFO_MB0(x) (((x) & 0xff) << 8) | ||
949 | # define HDMI0_MPEG_INFO_MB1(x) (((x) & 0xff) << 16) | ||
950 | # define HDMI0_MPEG_INFO_MB2(x) (((x) & 0xff) << 24) | ||
951 | #define HDMI0_MPEG_INFO1 0x7468 | ||
952 | # define HDMI0_MPEG_INFO_MB3(x) (((x) & 0xff) << 0) | ||
953 | # define HDMI0_MPEG_INFO_MF(x) (((x) & 3) << 8) | ||
954 | # define HDMI0_MPEG_INFO_FR(x) (((x) & 1) << 12) | ||
955 | #define HDMI0_GENERIC0_HDR 0x746c | ||
956 | #define HDMI0_GENERIC0_0 0x7470 | ||
957 | #define HDMI0_GENERIC0_1 0x7474 | ||
958 | #define HDMI0_GENERIC0_2 0x7478 | ||
959 | #define HDMI0_GENERIC0_3 0x747c | ||
960 | #define HDMI0_GENERIC0_4 0x7480 | ||
961 | #define HDMI0_GENERIC0_5 0x7484 | ||
962 | #define HDMI0_GENERIC0_6 0x7488 | ||
963 | #define HDMI0_GENERIC1_HDR 0x748c | ||
964 | #define HDMI0_GENERIC1_0 0x7490 | ||
965 | #define HDMI0_GENERIC1_1 0x7494 | ||
966 | #define HDMI0_GENERIC1_2 0x7498 | ||
967 | #define HDMI0_GENERIC1_3 0x749c | ||
968 | #define HDMI0_GENERIC1_4 0x74a0 | ||
969 | #define HDMI0_GENERIC1_5 0x74a4 | ||
970 | #define HDMI0_GENERIC1_6 0x74a8 | ||
971 | #define HDMI0_ACR_32_0 0x74ac | ||
972 | # define HDMI0_ACR_CTS_32(x) (((x) & 0xfffff) << 12) | ||
973 | #define HDMI0_ACR_32_1 0x74b0 | ||
974 | # define HDMI0_ACR_N_32(x) (((x) & 0xfffff) << 0) | ||
975 | #define HDMI0_ACR_44_0 0x74b4 | ||
976 | # define HDMI0_ACR_CTS_44(x) (((x) & 0xfffff) << 12) | ||
977 | #define HDMI0_ACR_44_1 0x74b8 | ||
978 | # define HDMI0_ACR_N_44(x) (((x) & 0xfffff) << 0) | ||
979 | #define HDMI0_ACR_48_0 0x74bc | ||
980 | # define HDMI0_ACR_CTS_48(x) (((x) & 0xfffff) << 12) | ||
981 | #define HDMI0_ACR_48_1 0x74c0 | ||
982 | # define HDMI0_ACR_N_48(x) (((x) & 0xfffff) << 0) | ||
983 | #define HDMI0_ACR_STATUS_0 0x74c4 | ||
984 | #define HDMI0_ACR_STATUS_1 0x74c8 | ||
985 | #define HDMI0_AUDIO_INFO0 0x74cc | ||
986 | # define HDMI0_AUDIO_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
987 | # define HDMI0_AUDIO_INFO_CC(x) (((x) & 7) << 8) | ||
988 | #define HDMI0_AUDIO_INFO1 0x74d0 | ||
989 | # define HDMI0_AUDIO_INFO_CA(x) (((x) & 0xff) << 0) | ||
990 | # define HDMI0_AUDIO_INFO_LSV(x) (((x) & 0xf) << 11) | ||
991 | # define HDMI0_AUDIO_INFO_DM_INH(x) (((x) & 1) << 15) | ||
992 | # define HDMI0_AUDIO_INFO_DM_INH_LSV(x) (((x) & 0xff) << 8) | ||
993 | #define HDMI0_60958_0 0x74d4 | ||
994 | # define HDMI0_60958_CS_A(x) (((x) & 1) << 0) | ||
995 | # define HDMI0_60958_CS_B(x) (((x) & 1) << 1) | ||
996 | # define HDMI0_60958_CS_C(x) (((x) & 1) << 2) | ||
997 | # define HDMI0_60958_CS_D(x) (((x) & 3) << 3) | ||
998 | # define HDMI0_60958_CS_MODE(x) (((x) & 3) << 6) | ||
999 | # define HDMI0_60958_CS_CATEGORY_CODE(x) (((x) & 0xff) << 8) | ||
1000 | # define HDMI0_60958_CS_SOURCE_NUMBER(x) (((x) & 0xf) << 16) | ||
1001 | # define HDMI0_60958_CS_CHANNEL_NUMBER_L(x) (((x) & 0xf) << 20) | ||
1002 | # define HDMI0_60958_CS_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 24) | ||
1003 | # define HDMI0_60958_CS_CLOCK_ACCURACY(x) (((x) & 3) << 28) | ||
1004 | #define HDMI0_60958_1 0x74d8 | ||
1005 | # define HDMI0_60958_CS_WORD_LENGTH(x) (((x) & 0xf) << 0) | ||
1006 | # define HDMI0_60958_CS_ORIGINAL_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 4) | ||
1007 | # define HDMI0_60958_CS_VALID_L(x) (((x) & 1) << 16) | ||
1008 | # define HDMI0_60958_CS_VALID_R(x) (((x) & 1) << 18) | ||
1009 | # define HDMI0_60958_CS_CHANNEL_NUMBER_R(x) (((x) & 0xf) << 20) | ||
1010 | #define HDMI0_ACR_PACKET_CONTROL 0x74dc | ||
1011 | # define HDMI0_ACR_SEND (1 << 0) | ||
1012 | # define HDMI0_ACR_CONT (1 << 1) | ||
1013 | # define HDMI0_ACR_SELECT(x) (((x) & 3) << 4) | ||
1014 | # define HDMI0_ACR_HW 0 | ||
1015 | # define HDMI0_ACR_32 1 | ||
1016 | # define HDMI0_ACR_44 2 | ||
1017 | # define HDMI0_ACR_48 3 | ||
1018 | # define HDMI0_ACR_SOURCE (1 << 8) /* 0 - hw; 1 - cts value */ | ||
1019 | # define HDMI0_ACR_AUTO_SEND (1 << 12) | ||
1020 | #define HDMI0_RAMP_CONTROL0 0x74e0 | ||
1021 | # define HDMI0_RAMP_MAX_COUNT(x) (((x) & 0xffffff) << 0) | ||
1022 | #define HDMI0_RAMP_CONTROL1 0x74e4 | ||
1023 | # define HDMI0_RAMP_MIN_COUNT(x) (((x) & 0xffffff) << 0) | ||
1024 | #define HDMI0_RAMP_CONTROL2 0x74e8 | ||
1025 | # define HDMI0_RAMP_INC_COUNT(x) (((x) & 0xffffff) << 0) | ||
1026 | #define HDMI0_RAMP_CONTROL3 0x74ec | ||
1027 | # define HDMI0_RAMP_DEC_COUNT(x) (((x) & 0xffffff) << 0) | ||
1028 | /* HDMI0_60958_2 is r7xx only */ | ||
1029 | #define HDMI0_60958_2 0x74f0 | ||
1030 | # define HDMI0_60958_CS_CHANNEL_NUMBER_2(x) (((x) & 0xf) << 0) | ||
1031 | # define HDMI0_60958_CS_CHANNEL_NUMBER_3(x) (((x) & 0xf) << 4) | ||
1032 | # define HDMI0_60958_CS_CHANNEL_NUMBER_4(x) (((x) & 0xf) << 8) | ||
1033 | # define HDMI0_60958_CS_CHANNEL_NUMBER_5(x) (((x) & 0xf) << 12) | ||
1034 | # define HDMI0_60958_CS_CHANNEL_NUMBER_6(x) (((x) & 0xf) << 16) | ||
1035 | # define HDMI0_60958_CS_CHANNEL_NUMBER_7(x) (((x) & 0xf) << 20) | ||
1036 | /* r6xx only; second instance starts at 0x7700 */ | ||
1037 | #define HDMI1_CONTROL 0x7700 | ||
1038 | #define HDMI1_STATUS 0x7704 | ||
1039 | #define HDMI1_AUDIO_PACKET_CONTROL 0x7708 | ||
1040 | /* DCE3; second instance starts at 0x7800 NOT 0x7700 */ | ||
1041 | #define DCE3_HDMI1_CONTROL 0x7800 | ||
1042 | #define DCE3_HDMI1_STATUS 0x7804 | ||
1043 | #define DCE3_HDMI1_AUDIO_PACKET_CONTROL 0x7808 | ||
1044 | /* DCE3.2 (for interrupts) */ | ||
1045 | #define AFMT_STATUS 0x7600 | ||
1046 | # define AFMT_AUDIO_ENABLE (1 << 4) | ||
1047 | # define AFMT_AZ_FORMAT_WTRIG (1 << 28) | ||
1048 | # define AFMT_AZ_FORMAT_WTRIG_INT (1 << 29) | ||
1049 | # define AFMT_AZ_AUDIO_ENABLE_CHG (1 << 30) | ||
1050 | #define AFMT_AUDIO_PACKET_CONTROL 0x7604 | ||
1051 | # define AFMT_AUDIO_SAMPLE_SEND (1 << 0) | ||
1052 | # define AFMT_AUDIO_TEST_EN (1 << 12) | ||
1053 | # define AFMT_AUDIO_CHANNEL_SWAP (1 << 24) | ||
1054 | # define AFMT_60958_CS_UPDATE (1 << 26) | ||
1055 | # define AFMT_AZ_AUDIO_ENABLE_CHG_MASK (1 << 27) | ||
1056 | # define AFMT_AZ_FORMAT_WTRIG_MASK (1 << 28) | ||
1057 | # define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29) | ||
1058 | # define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30) | ||
1059 | |||
1060 | #define DCE2_HDMI_OFFSET0 (0x7400 - 0x7400) | ||
1061 | #define DCE2_HDMI_OFFSET1 (0x7700 - 0x7400) | ||
1062 | /* DCE3.2 second instance starts at 0x7800 */ | ||
1063 | #define DCE3_HDMI_OFFSET0 (0x7400 - 0x7400) | ||
1064 | #define DCE3_HDMI_OFFSET1 (0x7800 - 0x7400) | ||
1065 | |||
827 | /* | 1066 | /* |
828 | * PM4 | 1067 | * PM4 |
829 | */ | 1068 | */ |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 138b95216d8d..610acee74a3d 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -560,6 +560,7 @@ struct radeon_unpin_work { | |||
560 | 560 | ||
561 | struct r500_irq_stat_regs { | 561 | struct r500_irq_stat_regs { |
562 | u32 disp_int; | 562 | u32 disp_int; |
563 | u32 hdmi0_status; | ||
563 | }; | 564 | }; |
564 | 565 | ||
565 | struct r600_irq_stat_regs { | 566 | struct r600_irq_stat_regs { |
@@ -568,6 +569,8 @@ struct r600_irq_stat_regs { | |||
568 | u32 disp_int_cont2; | 569 | u32 disp_int_cont2; |
569 | u32 d1grph_int; | 570 | u32 d1grph_int; |
570 | u32 d2grph_int; | 571 | u32 d2grph_int; |
572 | u32 hdmi0_status; | ||
573 | u32 hdmi1_status; | ||
571 | }; | 574 | }; |
572 | 575 | ||
573 | struct evergreen_irq_stat_regs { | 576 | struct evergreen_irq_stat_regs { |
@@ -583,6 +586,12 @@ struct evergreen_irq_stat_regs { | |||
583 | u32 d4grph_int; | 586 | u32 d4grph_int; |
584 | u32 d5grph_int; | 587 | u32 d5grph_int; |
585 | u32 d6grph_int; | 588 | u32 d6grph_int; |
589 | u32 afmt_status1; | ||
590 | u32 afmt_status2; | ||
591 | u32 afmt_status3; | ||
592 | u32 afmt_status4; | ||
593 | u32 afmt_status5; | ||
594 | u32 afmt_status6; | ||
586 | }; | 595 | }; |
587 | 596 | ||
588 | union radeon_irq_stat_regs { | 597 | union radeon_irq_stat_regs { |
@@ -593,7 +602,7 @@ union radeon_irq_stat_regs { | |||
593 | 602 | ||
594 | #define RADEON_MAX_HPD_PINS 6 | 603 | #define RADEON_MAX_HPD_PINS 6 |
595 | #define RADEON_MAX_CRTCS 6 | 604 | #define RADEON_MAX_CRTCS 6 |
596 | #define RADEON_MAX_HDMI_BLOCKS 2 | 605 | #define RADEON_MAX_AFMT_BLOCKS 6 |
597 | 606 | ||
598 | struct radeon_irq { | 607 | struct radeon_irq { |
599 | bool installed; | 608 | bool installed; |
@@ -605,7 +614,7 @@ struct radeon_irq { | |||
605 | bool gui_idle; | 614 | bool gui_idle; |
606 | bool gui_idle_acked; | 615 | bool gui_idle_acked; |
607 | wait_queue_head_t idle_queue; | 616 | wait_queue_head_t idle_queue; |
608 | bool hdmi[RADEON_MAX_HDMI_BLOCKS]; | 617 | bool afmt[RADEON_MAX_AFMT_BLOCKS]; |
609 | spinlock_t sw_lock; | 618 | spinlock_t sw_lock; |
610 | int sw_refcount[RADEON_NUM_RINGS]; | 619 | int sw_refcount[RADEON_NUM_RINGS]; |
611 | union radeon_irq_stat_regs stat_regs; | 620 | union radeon_irq_stat_regs stat_regs; |
@@ -1105,6 +1114,15 @@ int radeon_pm_get_type_index(struct radeon_device *rdev, | |||
1105 | enum radeon_pm_state_type ps_type, | 1114 | enum radeon_pm_state_type ps_type, |
1106 | int instance); | 1115 | int instance); |
1107 | 1116 | ||
1117 | struct r600_audio { | ||
1118 | bool enabled; | ||
1119 | int channels; | ||
1120 | int rate; | ||
1121 | int bits_per_sample; | ||
1122 | u8 status_bits; | ||
1123 | u8 category_code; | ||
1124 | }; | ||
1125 | |||
1108 | /* | 1126 | /* |
1109 | * Benchmarking | 1127 | * Benchmarking |
1110 | */ | 1128 | */ |
@@ -1546,19 +1564,11 @@ struct radeon_device { | |||
1546 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1564 | struct r600_ih ih; /* r6/700 interrupt ring */ |
1547 | struct si_rlc rlc; | 1565 | struct si_rlc rlc; |
1548 | struct work_struct hotplug_work; | 1566 | struct work_struct hotplug_work; |
1567 | struct work_struct audio_work; | ||
1549 | int num_crtc; /* number of crtcs */ | 1568 | int num_crtc; /* number of crtcs */ |
1550 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ | 1569 | struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ |
1551 | struct mutex vram_mutex; | 1570 | struct mutex vram_mutex; |
1552 | 1571 | struct r600_audio audio; /* audio stuff */ | |
1553 | /* audio stuff */ | ||
1554 | bool audio_enabled; | ||
1555 | struct timer_list audio_timer; | ||
1556 | int audio_channels; | ||
1557 | int audio_rate; | ||
1558 | int audio_bits_per_sample; | ||
1559 | uint8_t audio_status_bits; | ||
1560 | uint8_t audio_category_code; | ||
1561 | |||
1562 | struct notifier_block acpi_nb; | 1572 | struct notifier_block acpi_nb; |
1563 | /* only one userspace can use Hyperz features or CMASK at a time */ | 1573 | /* only one userspace can use Hyperz features or CMASK at a time */ |
1564 | struct drm_file *hyperz_filp; | 1574 | struct drm_file *hyperz_filp; |
@@ -1828,6 +1838,8 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
1828 | struct radeon_vm *vm, | 1838 | struct radeon_vm *vm, |
1829 | struct radeon_bo *bo); | 1839 | struct radeon_bo *bo); |
1830 | 1840 | ||
1841 | /* audio */ | ||
1842 | void r600_audio_update_hdmi(struct work_struct *work); | ||
1831 | 1843 | ||
1832 | /* | 1844 | /* |
1833 | * R600 vram scratch functions | 1845 | * R600 vram scratch functions |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 3d9f9f1d8f90..b135bec649d1 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -369,9 +369,6 @@ int r600_audio_bits_per_sample(struct radeon_device *rdev); | |||
369 | int r600_audio_rate(struct radeon_device *rdev); | 369 | int r600_audio_rate(struct radeon_device *rdev); |
370 | uint8_t r600_audio_status_bits(struct radeon_device *rdev); | 370 | uint8_t r600_audio_status_bits(struct radeon_device *rdev); |
371 | uint8_t r600_audio_category_code(struct radeon_device *rdev); | 371 | uint8_t r600_audio_category_code(struct radeon_device *rdev); |
372 | void r600_audio_schedule_polling(struct radeon_device *rdev); | ||
373 | void r600_audio_enable_polling(struct drm_encoder *encoder); | ||
374 | void r600_audio_disable_polling(struct drm_encoder *encoder); | ||
375 | void r600_audio_fini(struct radeon_device *rdev); | 372 | void r600_audio_fini(struct radeon_device *rdev); |
376 | void r600_hdmi_init(struct drm_encoder *encoder); | 373 | void r600_hdmi_init(struct drm_encoder *encoder); |
377 | int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); | 374 | int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index bd05156edbdb..71fa389e10fe 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -84,6 +84,62 @@ static void radeon_property_change_mode(struct drm_encoder *encoder) | |||
84 | crtc->x, crtc->y, crtc->fb); | 84 | crtc->x, crtc->y, crtc->fb); |
85 | } | 85 | } |
86 | } | 86 | } |
87 | |||
88 | int radeon_get_monitor_bpc(struct drm_connector *connector) | ||
89 | { | ||
90 | struct drm_device *dev = connector->dev; | ||
91 | struct radeon_device *rdev = dev->dev_private; | ||
92 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
93 | struct radeon_connector_atom_dig *dig_connector; | ||
94 | int bpc = 8; | ||
95 | |||
96 | switch (connector->connector_type) { | ||
97 | case DRM_MODE_CONNECTOR_DVII: | ||
98 | case DRM_MODE_CONNECTOR_HDMIB: | ||
99 | if (radeon_connector->use_digital) { | ||
100 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
101 | if (connector->display_info.bpc) | ||
102 | bpc = connector->display_info.bpc; | ||
103 | } | ||
104 | } | ||
105 | break; | ||
106 | case DRM_MODE_CONNECTOR_DVID: | ||
107 | case DRM_MODE_CONNECTOR_HDMIA: | ||
108 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
109 | if (connector->display_info.bpc) | ||
110 | bpc = connector->display_info.bpc; | ||
111 | } | ||
112 | break; | ||
113 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
114 | dig_connector = radeon_connector->con_priv; | ||
115 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
116 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) || | ||
117 | drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
118 | if (connector->display_info.bpc) | ||
119 | bpc = connector->display_info.bpc; | ||
120 | } | ||
121 | break; | ||
122 | case DRM_MODE_CONNECTOR_eDP: | ||
123 | case DRM_MODE_CONNECTOR_LVDS: | ||
124 | if (connector->display_info.bpc) | ||
125 | bpc = connector->display_info.bpc; | ||
126 | else if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { | ||
127 | struct drm_connector_helper_funcs *connector_funcs = | ||
128 | connector->helper_private; | ||
129 | struct drm_encoder *encoder = connector_funcs->best_encoder(connector); | ||
130 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
131 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
132 | |||
133 | if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR) | ||
134 | bpc = 6; | ||
135 | else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR) | ||
136 | bpc = 8; | ||
137 | } | ||
138 | break; | ||
139 | } | ||
140 | return bpc; | ||
141 | } | ||
142 | |||
87 | static void | 143 | static void |
88 | radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) | 144 | radeon_connector_update_scratch_regs(struct drm_connector *connector, enum drm_connector_status status) |
89 | { | 145 | { |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 66d5fe1c8174..170f1718d92a 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -73,6 +73,7 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) | |||
73 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | 73 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
74 | rdev->irq.crtc_vblank_int[i] = false; | 74 | rdev->irq.crtc_vblank_int[i] = false; |
75 | rdev->irq.pflip[i] = false; | 75 | rdev->irq.pflip[i] = false; |
76 | rdev->irq.afmt[i] = false; | ||
76 | } | 77 | } |
77 | radeon_irq_set(rdev); | 78 | radeon_irq_set(rdev); |
78 | /* Clear bits */ | 79 | /* Clear bits */ |
@@ -108,6 +109,7 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) | |||
108 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { | 109 | for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
109 | rdev->irq.crtc_vblank_int[i] = false; | 110 | rdev->irq.crtc_vblank_int[i] = false; |
110 | rdev->irq.pflip[i] = false; | 111 | rdev->irq.pflip[i] = false; |
112 | rdev->irq.afmt[i] = false; | ||
111 | } | 113 | } |
112 | radeon_irq_set(rdev); | 114 | radeon_irq_set(rdev); |
113 | } | 115 | } |
@@ -164,6 +166,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
164 | int r = 0; | 166 | int r = 0; |
165 | 167 | ||
166 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); | 168 | INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
169 | INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); | ||
167 | 170 | ||
168 | spin_lock_init(&rdev->irq.sw_lock); | 171 | spin_lock_init(&rdev->irq.sw_lock); |
169 | for (i = 0; i < rdev->num_crtc; i++) | 172 | for (i = 0; i < rdev->num_crtc; i++) |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f7eb5d8b9fd3..0c3cdbd614d2 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -384,8 +384,8 @@ struct radeon_encoder { | |||
384 | struct drm_display_mode native_mode; | 384 | struct drm_display_mode native_mode; |
385 | void *enc_priv; | 385 | void *enc_priv; |
386 | int audio_polling_active; | 386 | int audio_polling_active; |
387 | bool hdmi_enabled; | ||
387 | int hdmi_offset; | 388 | int hdmi_offset; |
388 | int hdmi_config_offset; | ||
389 | int hdmi_audio_workaround; | 389 | int hdmi_audio_workaround; |
390 | int hdmi_buffer_status; | 390 | int hdmi_buffer_status; |
391 | bool is_ext_encoder; | 391 | bool is_ext_encoder; |
@@ -476,6 +476,7 @@ extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); | |||
476 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); | 476 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); |
477 | extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); | 477 | extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); |
478 | extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); | 478 | extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); |
479 | extern int radeon_get_monitor_bpc(struct drm_connector *connector); | ||
479 | 480 | ||
480 | extern void radeon_connector_hotplug(struct drm_connector *connector); | 481 | extern void radeon_connector_hotplug(struct drm_connector *connector); |
481 | extern int radeon_dp_mode_valid_helper(struct drm_connector *connector, | 482 | extern int radeon_dp_mode_valid_helper(struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index d25cf869d08d..10706c66b84b 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -553,6 +553,12 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
553 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); | 553 | ~S_007D08_DC_HOT_PLUG_DETECT1_INT_EN(1); |
554 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & | 554 | u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) & |
555 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | 555 | ~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); |
556 | u32 hdmi0; | ||
557 | if (ASIC_IS_DCE2(rdev)) | ||
558 | hdmi0 = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL) & | ||
559 | ~S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1); | ||
560 | else | ||
561 | hdmi0 = 0; | ||
556 | 562 | ||
557 | if (!rdev->irq.installed) { | 563 | if (!rdev->irq.installed) { |
558 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 564 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
@@ -579,10 +585,15 @@ int rs600_irq_set(struct radeon_device *rdev) | |||
579 | if (rdev->irq.hpd[1]) { | 585 | if (rdev->irq.hpd[1]) { |
580 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); | 586 | hpd2 |= S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1); |
581 | } | 587 | } |
588 | if (rdev->irq.afmt[0]) { | ||
589 | hdmi0 |= S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1); | ||
590 | } | ||
582 | WREG32(R_000040_GEN_INT_CNTL, tmp); | 591 | WREG32(R_000040_GEN_INT_CNTL, tmp); |
583 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); | 592 | WREG32(R_006540_DxMODE_INT_MASK, mode_int); |
584 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | 593 | WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); |
585 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | 594 | WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); |
595 | if (ASIC_IS_DCE2(rdev)) | ||
596 | WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0); | ||
586 | return 0; | 597 | return 0; |
587 | } | 598 | } |
588 | 599 | ||
@@ -622,6 +633,17 @@ static inline u32 rs600_irq_ack(struct radeon_device *rdev) | |||
622 | rdev->irq.stat_regs.r500.disp_int = 0; | 633 | rdev->irq.stat_regs.r500.disp_int = 0; |
623 | } | 634 | } |
624 | 635 | ||
636 | if (ASIC_IS_DCE2(rdev)) { | ||
637 | rdev->irq.stat_regs.r500.hdmi0_status = RREG32(R_007404_HDMI0_STATUS) & | ||
638 | S_007404_HDMI0_AZ_FORMAT_WTRIG(1); | ||
639 | if (G_007404_HDMI0_AZ_FORMAT_WTRIG(rdev->irq.stat_regs.r500.hdmi0_status)) { | ||
640 | tmp = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL); | ||
641 | tmp |= S_007408_HDMI0_AZ_FORMAT_WTRIG_ACK(1); | ||
642 | WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, tmp); | ||
643 | } | ||
644 | } else | ||
645 | rdev->irq.stat_regs.r500.hdmi0_status = 0; | ||
646 | |||
625 | if (irqs) { | 647 | if (irqs) { |
626 | WREG32(R_000044_GEN_INT_STATUS, irqs); | 648 | WREG32(R_000044_GEN_INT_STATUS, irqs); |
627 | } | 649 | } |
@@ -630,6 +652,9 @@ static inline u32 rs600_irq_ack(struct radeon_device *rdev) | |||
630 | 652 | ||
631 | void rs600_irq_disable(struct radeon_device *rdev) | 653 | void rs600_irq_disable(struct radeon_device *rdev) |
632 | { | 654 | { |
655 | u32 hdmi0 = RREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL) & | ||
656 | ~S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(1); | ||
657 | WREG32(R_007408_HDMI0_AUDIO_PACKET_CONTROL, hdmi0); | ||
633 | WREG32(R_000040_GEN_INT_CNTL, 0); | 658 | WREG32(R_000040_GEN_INT_CNTL, 0); |
634 | WREG32(R_006540_DxMODE_INT_MASK, 0); | 659 | WREG32(R_006540_DxMODE_INT_MASK, 0); |
635 | /* Wait and acknowledge irq */ | 660 | /* Wait and acknowledge irq */ |
@@ -641,15 +666,20 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
641 | { | 666 | { |
642 | u32 status, msi_rearm; | 667 | u32 status, msi_rearm; |
643 | bool queue_hotplug = false; | 668 | bool queue_hotplug = false; |
669 | bool queue_hdmi = false; | ||
644 | 670 | ||
645 | /* reset gui idle ack. the status bit is broken */ | 671 | /* reset gui idle ack. the status bit is broken */ |
646 | rdev->irq.gui_idle_acked = false; | 672 | rdev->irq.gui_idle_acked = false; |
647 | 673 | ||
648 | status = rs600_irq_ack(rdev); | 674 | status = rs600_irq_ack(rdev); |
649 | if (!status && !rdev->irq.stat_regs.r500.disp_int) { | 675 | if (!status && |
676 | !rdev->irq.stat_regs.r500.disp_int && | ||
677 | !rdev->irq.stat_regs.r500.hdmi0_status) { | ||
650 | return IRQ_NONE; | 678 | return IRQ_NONE; |
651 | } | 679 | } |
652 | while (status || rdev->irq.stat_regs.r500.disp_int) { | 680 | while (status || |
681 | rdev->irq.stat_regs.r500.disp_int || | ||
682 | rdev->irq.stat_regs.r500.hdmi0_status) { | ||
653 | /* SW interrupt */ | 683 | /* SW interrupt */ |
654 | if (G_000044_SW_INT(status)) { | 684 | if (G_000044_SW_INT(status)) { |
655 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); | 685 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
@@ -687,12 +717,18 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
687 | queue_hotplug = true; | 717 | queue_hotplug = true; |
688 | DRM_DEBUG("HPD2\n"); | 718 | DRM_DEBUG("HPD2\n"); |
689 | } | 719 | } |
720 | if (G_007404_HDMI0_AZ_FORMAT_WTRIG(rdev->irq.stat_regs.r500.hdmi0_status)) { | ||
721 | queue_hdmi = true; | ||
722 | DRM_DEBUG("HDMI0\n"); | ||
723 | } | ||
690 | status = rs600_irq_ack(rdev); | 724 | status = rs600_irq_ack(rdev); |
691 | } | 725 | } |
692 | /* reset gui idle ack. the status bit is broken */ | 726 | /* reset gui idle ack. the status bit is broken */ |
693 | rdev->irq.gui_idle_acked = false; | 727 | rdev->irq.gui_idle_acked = false; |
694 | if (queue_hotplug) | 728 | if (queue_hotplug) |
695 | schedule_work(&rdev->hotplug_work); | 729 | schedule_work(&rdev->hotplug_work); |
730 | if (queue_hdmi) | ||
731 | schedule_work(&rdev->audio_work); | ||
696 | if (rdev->msi_enabled) { | 732 | if (rdev->msi_enabled) { |
697 | switch (rdev->family) { | 733 | switch (rdev->family) { |
698 | case CHIP_RS600: | 734 | case CHIP_RS600: |
diff --git a/drivers/gpu/drm/radeon/rs600d.h b/drivers/gpu/drm/radeon/rs600d.h index a27c13ac47c3..f1f89414dc63 100644 --- a/drivers/gpu/drm/radeon/rs600d.h +++ b/drivers/gpu/drm/radeon/rs600d.h | |||
@@ -485,6 +485,20 @@ | |||
485 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) & 0x1) << 16) | 485 | #define S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) & 0x1) << 16) |
486 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) >> 16) & 0x1) | 486 | #define G_007D18_DC_HOT_PLUG_DETECT2_INT_EN(x) (((x) >> 16) & 0x1) |
487 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_EN 0xFFFEFFFF | 487 | #define C_007D18_DC_HOT_PLUG_DETECT2_INT_EN 0xFFFEFFFF |
488 | #define R_007404_HDMI0_STATUS 0x007404 | ||
489 | #define S_007404_HDMI0_AZ_FORMAT_WTRIG(x) (((x) & 0x1) << 28) | ||
490 | #define G_007404_HDMI0_AZ_FORMAT_WTRIG(x) (((x) >> 28) & 0x1) | ||
491 | #define C_007404_HDMI0_AZ_FORMAT_WTRIG 0xEFFFFFFF | ||
492 | #define S_007404_HDMI0_AZ_FORMAT_WTRIG_INT(x) (((x) & 0x1) << 29) | ||
493 | #define G_007404_HDMI0_AZ_FORMAT_WTRIG_INT(x) (((x) >> 29) & 0x1) | ||
494 | #define C_007404_HDMI0_AZ_FORMAT_WTRIG_INT 0xDFFFFFFF | ||
495 | #define R_007408_HDMI0_AUDIO_PACKET_CONTROL 0x007408 | ||
496 | #define S_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(x) (((x) & 0x1) << 28) | ||
497 | #define G_007408_HDMI0_AZ_FORMAT_WTRIG_MASK(x) (((x) >> 28) & 0x1) | ||
498 | #define C_007408_HDMI0_AZ_FORMAT_WTRIG_MASK 0xEFFFFFFF | ||
499 | #define S_007408_HDMI0_AZ_FORMAT_WTRIG_ACK(x) (((x) & 0x1) << 29) | ||
500 | #define G_007408_HDMI0_AZ_FORMAT_WTRIG_ACK(x) (((x) >> 29) & 0x1) | ||
501 | #define C_007408_HDMI0_AZ_FORMAT_WTRIG_ACK 0xDFFFFFFF | ||
488 | 502 | ||
489 | /* MC registers */ | 503 | /* MC registers */ |
490 | #define R_000000_MC_STATUS 0x000000 | 504 | #define R_000000_MC_STATUS 0x000000 |
diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 79fa588e9ed5..9c549f702f2f 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h | |||
@@ -353,6 +353,197 @@ | |||
353 | 353 | ||
354 | #define SRBM_STATUS 0x0E50 | 354 | #define SRBM_STATUS 0x0E50 |
355 | 355 | ||
356 | /* DCE 3.2 HDMI */ | ||
357 | #define HDMI_CONTROL 0x7400 | ||
358 | # define HDMI_KEEPOUT_MODE (1 << 0) | ||
359 | # define HDMI_PACKET_GEN_VERSION (1 << 4) /* 0 = r6xx compat */ | ||
360 | # define HDMI_ERROR_ACK (1 << 8) | ||
361 | # define HDMI_ERROR_MASK (1 << 9) | ||
362 | #define HDMI_STATUS 0x7404 | ||
363 | # define HDMI_ACTIVE_AVMUTE (1 << 0) | ||
364 | # define HDMI_AUDIO_PACKET_ERROR (1 << 16) | ||
365 | # define HDMI_VBI_PACKET_ERROR (1 << 20) | ||
366 | #define HDMI_AUDIO_PACKET_CONTROL 0x7408 | ||
367 | # define HDMI_AUDIO_DELAY_EN(x) (((x) & 3) << 4) | ||
368 | # define HDMI_AUDIO_PACKETS_PER_LINE(x) (((x) & 0x1f) << 16) | ||
369 | #define HDMI_ACR_PACKET_CONTROL 0x740c | ||
370 | # define HDMI_ACR_SEND (1 << 0) | ||
371 | # define HDMI_ACR_CONT (1 << 1) | ||
372 | # define HDMI_ACR_SELECT(x) (((x) & 3) << 4) | ||
373 | # define HDMI_ACR_HW 0 | ||
374 | # define HDMI_ACR_32 1 | ||
375 | # define HDMI_ACR_44 2 | ||
376 | # define HDMI_ACR_48 3 | ||
377 | # define HDMI_ACR_SOURCE (1 << 8) /* 0 - hw; 1 - cts value */ | ||
378 | # define HDMI_ACR_AUTO_SEND (1 << 12) | ||
379 | #define HDMI_VBI_PACKET_CONTROL 0x7410 | ||
380 | # define HDMI_NULL_SEND (1 << 0) | ||
381 | # define HDMI_GC_SEND (1 << 4) | ||
382 | # define HDMI_GC_CONT (1 << 5) /* 0 - once; 1 - every frame */ | ||
383 | #define HDMI_INFOFRAME_CONTROL0 0x7414 | ||
384 | # define HDMI_AVI_INFO_SEND (1 << 0) | ||
385 | # define HDMI_AVI_INFO_CONT (1 << 1) | ||
386 | # define HDMI_AUDIO_INFO_SEND (1 << 4) | ||
387 | # define HDMI_AUDIO_INFO_CONT (1 << 5) | ||
388 | # define HDMI_MPEG_INFO_SEND (1 << 8) | ||
389 | # define HDMI_MPEG_INFO_CONT (1 << 9) | ||
390 | #define HDMI_INFOFRAME_CONTROL1 0x7418 | ||
391 | # define HDMI_AVI_INFO_LINE(x) (((x) & 0x3f) << 0) | ||
392 | # define HDMI_AUDIO_INFO_LINE(x) (((x) & 0x3f) << 8) | ||
393 | # define HDMI_MPEG_INFO_LINE(x) (((x) & 0x3f) << 16) | ||
394 | #define HDMI_GENERIC_PACKET_CONTROL 0x741c | ||
395 | # define HDMI_GENERIC0_SEND (1 << 0) | ||
396 | # define HDMI_GENERIC0_CONT (1 << 1) | ||
397 | # define HDMI_GENERIC1_SEND (1 << 4) | ||
398 | # define HDMI_GENERIC1_CONT (1 << 5) | ||
399 | # define HDMI_GENERIC0_LINE(x) (((x) & 0x3f) << 16) | ||
400 | # define HDMI_GENERIC1_LINE(x) (((x) & 0x3f) << 24) | ||
401 | #define HDMI_GC 0x7428 | ||
402 | # define HDMI_GC_AVMUTE (1 << 0) | ||
403 | #define AFMT_AUDIO_PACKET_CONTROL2 0x742c | ||
404 | # define AFMT_AUDIO_LAYOUT_OVRD (1 << 0) | ||
405 | # define AFMT_AUDIO_LAYOUT_SELECT (1 << 1) | ||
406 | # define AFMT_60958_CS_SOURCE (1 << 4) | ||
407 | # define AFMT_AUDIO_CHANNEL_ENABLE(x) (((x) & 0xff) << 8) | ||
408 | # define AFMT_DP_AUDIO_STREAM_ID(x) (((x) & 0xff) << 16) | ||
409 | #define AFMT_AVI_INFO0 0x7454 | ||
410 | # define AFMT_AVI_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
411 | # define AFMT_AVI_INFO_S(x) (((x) & 3) << 8) | ||
412 | # define AFMT_AVI_INFO_B(x) (((x) & 3) << 10) | ||
413 | # define AFMT_AVI_INFO_A(x) (((x) & 1) << 12) | ||
414 | # define AFMT_AVI_INFO_Y(x) (((x) & 3) << 13) | ||
415 | # define AFMT_AVI_INFO_Y_RGB 0 | ||
416 | # define AFMT_AVI_INFO_Y_YCBCR422 1 | ||
417 | # define AFMT_AVI_INFO_Y_YCBCR444 2 | ||
418 | # define AFMT_AVI_INFO_Y_A_B_S(x) (((x) & 0xff) << 8) | ||
419 | # define AFMT_AVI_INFO_R(x) (((x) & 0xf) << 16) | ||
420 | # define AFMT_AVI_INFO_M(x) (((x) & 0x3) << 20) | ||
421 | # define AFMT_AVI_INFO_C(x) (((x) & 0x3) << 22) | ||
422 | # define AFMT_AVI_INFO_C_M_R(x) (((x) & 0xff) << 16) | ||
423 | # define AFMT_AVI_INFO_SC(x) (((x) & 0x3) << 24) | ||
424 | # define AFMT_AVI_INFO_Q(x) (((x) & 0x3) << 26) | ||
425 | # define AFMT_AVI_INFO_EC(x) (((x) & 0x3) << 28) | ||
426 | # define AFMT_AVI_INFO_ITC(x) (((x) & 0x1) << 31) | ||
427 | # define AFMT_AVI_INFO_ITC_EC_Q_SC(x) (((x) & 0xff) << 24) | ||
428 | #define AFMT_AVI_INFO1 0x7458 | ||
429 | # define AFMT_AVI_INFO_VIC(x) (((x) & 0x7f) << 0) /* don't use avi infoframe v1 */ | ||
430 | # define AFMT_AVI_INFO_PR(x) (((x) & 0xf) << 8) /* don't use avi infoframe v1 */ | ||
431 | # define AFMT_AVI_INFO_TOP(x) (((x) & 0xffff) << 16) | ||
432 | #define AFMT_AVI_INFO2 0x745c | ||
433 | # define AFMT_AVI_INFO_BOTTOM(x) (((x) & 0xffff) << 0) | ||
434 | # define AFMT_AVI_INFO_LEFT(x) (((x) & 0xffff) << 16) | ||
435 | #define AFMT_AVI_INFO3 0x7460 | ||
436 | # define AFMT_AVI_INFO_RIGHT(x) (((x) & 0xffff) << 0) | ||
437 | # define AFMT_AVI_INFO_VERSION(x) (((x) & 3) << 24) | ||
438 | #define AFMT_MPEG_INFO0 0x7464 | ||
439 | # define AFMT_MPEG_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
440 | # define AFMT_MPEG_INFO_MB0(x) (((x) & 0xff) << 8) | ||
441 | # define AFMT_MPEG_INFO_MB1(x) (((x) & 0xff) << 16) | ||
442 | # define AFMT_MPEG_INFO_MB2(x) (((x) & 0xff) << 24) | ||
443 | #define AFMT_MPEG_INFO1 0x7468 | ||
444 | # define AFMT_MPEG_INFO_MB3(x) (((x) & 0xff) << 0) | ||
445 | # define AFMT_MPEG_INFO_MF(x) (((x) & 3) << 8) | ||
446 | # define AFMT_MPEG_INFO_FR(x) (((x) & 1) << 12) | ||
447 | #define AFMT_GENERIC0_HDR 0x746c | ||
448 | #define AFMT_GENERIC0_0 0x7470 | ||
449 | #define AFMT_GENERIC0_1 0x7474 | ||
450 | #define AFMT_GENERIC0_2 0x7478 | ||
451 | #define AFMT_GENERIC0_3 0x747c | ||
452 | #define AFMT_GENERIC0_4 0x7480 | ||
453 | #define AFMT_GENERIC0_5 0x7484 | ||
454 | #define AFMT_GENERIC0_6 0x7488 | ||
455 | #define AFMT_GENERIC1_HDR 0x748c | ||
456 | #define AFMT_GENERIC1_0 0x7490 | ||
457 | #define AFMT_GENERIC1_1 0x7494 | ||
458 | #define AFMT_GENERIC1_2 0x7498 | ||
459 | #define AFMT_GENERIC1_3 0x749c | ||
460 | #define AFMT_GENERIC1_4 0x74a0 | ||
461 | #define AFMT_GENERIC1_5 0x74a4 | ||
462 | #define AFMT_GENERIC1_6 0x74a8 | ||
463 | #define HDMI_ACR_32_0 0x74ac | ||
464 | # define HDMI_ACR_CTS_32(x) (((x) & 0xfffff) << 12) | ||
465 | #define HDMI_ACR_32_1 0x74b0 | ||
466 | # define HDMI_ACR_N_32(x) (((x) & 0xfffff) << 0) | ||
467 | #define HDMI_ACR_44_0 0x74b4 | ||
468 | # define HDMI_ACR_CTS_44(x) (((x) & 0xfffff) << 12) | ||
469 | #define HDMI_ACR_44_1 0x74b8 | ||
470 | # define HDMI_ACR_N_44(x) (((x) & 0xfffff) << 0) | ||
471 | #define HDMI_ACR_48_0 0x74bc | ||
472 | # define HDMI_ACR_CTS_48(x) (((x) & 0xfffff) << 12) | ||
473 | #define HDMI_ACR_48_1 0x74c0 | ||
474 | # define HDMI_ACR_N_48(x) (((x) & 0xfffff) << 0) | ||
475 | #define HDMI_ACR_STATUS_0 0x74c4 | ||
476 | #define HDMI_ACR_STATUS_1 0x74c8 | ||
477 | #define AFMT_AUDIO_INFO0 0x74cc | ||
478 | # define AFMT_AUDIO_INFO_CHECKSUM(x) (((x) & 0xff) << 0) | ||
479 | # define AFMT_AUDIO_INFO_CC(x) (((x) & 7) << 8) | ||
480 | # define AFMT_AUDIO_INFO_CHECKSUM_OFFSET(x) (((x) & 0xff) << 16) | ||
481 | #define AFMT_AUDIO_INFO1 0x74d0 | ||
482 | # define AFMT_AUDIO_INFO_CA(x) (((x) & 0xff) << 0) | ||
483 | # define AFMT_AUDIO_INFO_LSV(x) (((x) & 0xf) << 11) | ||
484 | # define AFMT_AUDIO_INFO_DM_INH(x) (((x) & 1) << 15) | ||
485 | # define AFMT_AUDIO_INFO_DM_INH_LSV(x) (((x) & 0xff) << 8) | ||
486 | #define AFMT_60958_0 0x74d4 | ||
487 | # define AFMT_60958_CS_A(x) (((x) & 1) << 0) | ||
488 | # define AFMT_60958_CS_B(x) (((x) & 1) << 1) | ||
489 | # define AFMT_60958_CS_C(x) (((x) & 1) << 2) | ||
490 | # define AFMT_60958_CS_D(x) (((x) & 3) << 3) | ||
491 | # define AFMT_60958_CS_MODE(x) (((x) & 3) << 6) | ||
492 | # define AFMT_60958_CS_CATEGORY_CODE(x) (((x) & 0xff) << 8) | ||
493 | # define AFMT_60958_CS_SOURCE_NUMBER(x) (((x) & 0xf) << 16) | ||
494 | # define AFMT_60958_CS_CHANNEL_NUMBER_L(x) (((x) & 0xf) << 20) | ||
495 | # define AFMT_60958_CS_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 24) | ||
496 | # define AFMT_60958_CS_CLOCK_ACCURACY(x) (((x) & 3) << 28) | ||
497 | #define AFMT_60958_1 0x74d8 | ||
498 | # define AFMT_60958_CS_WORD_LENGTH(x) (((x) & 0xf) << 0) | ||
499 | # define AFMT_60958_CS_ORIGINAL_SAMPLING_FREQUENCY(x) (((x) & 0xf) << 4) | ||
500 | # define AFMT_60958_CS_VALID_L(x) (((x) & 1) << 16) | ||
501 | # define AFMT_60958_CS_VALID_R(x) (((x) & 1) << 18) | ||
502 | # define AFMT_60958_CS_CHANNEL_NUMBER_R(x) (((x) & 0xf) << 20) | ||
503 | #define AFMT_AUDIO_CRC_CONTROL 0x74dc | ||
504 | # define AFMT_AUDIO_CRC_EN (1 << 0) | ||
505 | #define AFMT_RAMP_CONTROL0 0x74e0 | ||
506 | # define AFMT_RAMP_MAX_COUNT(x) (((x) & 0xffffff) << 0) | ||
507 | # define AFMT_RAMP_DATA_SIGN (1 << 31) | ||
508 | #define AFMT_RAMP_CONTROL1 0x74e4 | ||
509 | # define AFMT_RAMP_MIN_COUNT(x) (((x) & 0xffffff) << 0) | ||
510 | # define AFMT_AUDIO_TEST_CH_DISABLE(x) (((x) & 0xff) << 24) | ||
511 | #define AFMT_RAMP_CONTROL2 0x74e8 | ||
512 | # define AFMT_RAMP_INC_COUNT(x) (((x) & 0xffffff) << 0) | ||
513 | #define AFMT_RAMP_CONTROL3 0x74ec | ||
514 | # define AFMT_RAMP_DEC_COUNT(x) (((x) & 0xffffff) << 0) | ||
515 | #define AFMT_60958_2 0x74f0 | ||
516 | # define AFMT_60958_CS_CHANNEL_NUMBER_2(x) (((x) & 0xf) << 0) | ||
517 | # define AFMT_60958_CS_CHANNEL_NUMBER_3(x) (((x) & 0xf) << 4) | ||
518 | # define AFMT_60958_CS_CHANNEL_NUMBER_4(x) (((x) & 0xf) << 8) | ||
519 | # define AFMT_60958_CS_CHANNEL_NUMBER_5(x) (((x) & 0xf) << 12) | ||
520 | # define AFMT_60958_CS_CHANNEL_NUMBER_6(x) (((x) & 0xf) << 16) | ||
521 | # define AFMT_60958_CS_CHANNEL_NUMBER_7(x) (((x) & 0xf) << 20) | ||
522 | #define AFMT_STATUS 0x7600 | ||
523 | # define AFMT_AUDIO_ENABLE (1 << 4) | ||
524 | # define AFMT_AZ_FORMAT_WTRIG (1 << 28) | ||
525 | # define AFMT_AZ_FORMAT_WTRIG_INT (1 << 29) | ||
526 | # define AFMT_AZ_AUDIO_ENABLE_CHG (1 << 30) | ||
527 | #define AFMT_AUDIO_PACKET_CONTROL 0x7604 | ||
528 | # define AFMT_AUDIO_SAMPLE_SEND (1 << 0) | ||
529 | # define AFMT_AUDIO_TEST_EN (1 << 12) | ||
530 | # define AFMT_AUDIO_CHANNEL_SWAP (1 << 24) | ||
531 | # define AFMT_60958_CS_UPDATE (1 << 26) | ||
532 | # define AFMT_AZ_AUDIO_ENABLE_CHG_MASK (1 << 27) | ||
533 | # define AFMT_AZ_FORMAT_WTRIG_MASK (1 << 28) | ||
534 | # define AFMT_AZ_FORMAT_WTRIG_ACK (1 << 29) | ||
535 | # define AFMT_AZ_AUDIO_ENABLE_CHG_ACK (1 << 30) | ||
536 | #define AFMT_VBI_PACKET_CONTROL 0x7608 | ||
537 | # define AFMT_GENERIC0_UPDATE (1 << 2) | ||
538 | #define AFMT_INFOFRAME_CONTROL0 0x760c | ||
539 | # define AFMT_AUDIO_INFO_SOURCE (1 << 6) /* 0 - sound block; 1 - hmdi regs */ | ||
540 | # define AFMT_AUDIO_INFO_UPDATE (1 << 7) | ||
541 | # define AFMT_MPEG_INFO_UPDATE (1 << 10) | ||
542 | #define AFMT_GENERIC0_7 0x7610 | ||
543 | /* second instance starts at 0x7800 */ | ||
544 | #define HDMI_OFFSET0 (0x7400 - 0x7400) | ||
545 | #define HDMI_OFFSET1 (0x7800 - 0x7400) | ||
546 | |||
356 | #define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 | 547 | #define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 |
357 | #define D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 | 548 | #define D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 |
358 | #define D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 | 549 | #define D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 |
diff --git a/drivers/gpu/vga/Kconfig b/drivers/gpu/vga/Kconfig index 96c83a9a76bb..f34838839b08 100644 --- a/drivers/gpu/vga/Kconfig +++ b/drivers/gpu/vga/Kconfig | |||
@@ -21,6 +21,7 @@ config VGA_SWITCHEROO | |||
21 | bool "Laptop Hybrid Graphics - GPU switching support" | 21 | bool "Laptop Hybrid Graphics - GPU switching support" |
22 | depends on X86 | 22 | depends on X86 |
23 | depends on ACPI | 23 | depends on ACPI |
24 | select VGA_ARB | ||
24 | help | 25 | help |
25 | Many laptops released in 2008/9/10 have two GPUs with a multiplexer | 26 | Many laptops released in 2008/9/10 have two GPUs with a multiplexer |
26 | to switch between them. This adds support for dynamic switching when | 27 | to switch between them. This adds support for dynamic switching when |
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 58434e804d91..9d830286f883 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
29 | #include <linux/vga_switcheroo.h> | 29 | #include <linux/vga_switcheroo.h> |
30 | 30 | ||
31 | #include <linux/vgaarb.h> | ||
32 | |||
31 | struct vga_switcheroo_client { | 33 | struct vga_switcheroo_client { |
32 | struct pci_dev *pdev; | 34 | struct pci_dev *pdev; |
33 | struct fb_info *fb_info; | 35 | struct fb_info *fb_info; |
@@ -122,7 +124,7 @@ int vga_switcheroo_register_client(struct pci_dev *pdev, | |||
122 | vgasr_priv.clients[index].reprobe = reprobe; | 124 | vgasr_priv.clients[index].reprobe = reprobe; |
123 | vgasr_priv.clients[index].can_switch = can_switch; | 125 | vgasr_priv.clients[index].can_switch = can_switch; |
124 | vgasr_priv.clients[index].id = -1; | 126 | vgasr_priv.clients[index].id = -1; |
125 | if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) | 127 | if (pdev == vga_default_device()) |
126 | vgasr_priv.clients[index].active = true; | 128 | vgasr_priv.clients[index].active = true; |
127 | 129 | ||
128 | vgasr_priv.registered_clients |= (1 << index); | 130 | vgasr_priv.registered_clients |= (1 << index); |
@@ -230,9 +232,8 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) | |||
230 | if (new_client->pwr_state == VGA_SWITCHEROO_OFF) | 232 | if (new_client->pwr_state == VGA_SWITCHEROO_OFF) |
231 | vga_switchon(new_client); | 233 | vga_switchon(new_client); |
232 | 234 | ||
233 | /* swap shadow resource to denote boot VGA device has changed so X starts on new device */ | 235 | vga_set_default_device(new_client->pdev); |
234 | active->pdev->resource[PCI_ROM_RESOURCE].flags &= ~IORESOURCE_ROM_SHADOW; | 236 | |
235 | new_client->pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; | ||
236 | return 0; | 237 | return 0; |
237 | } | 238 | } |
238 | 239 | ||
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index 111d956d8e7d..3df8fc0ec01a 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -136,6 +136,13 @@ struct pci_dev *vga_default_device(void) | |||
136 | { | 136 | { |
137 | return vga_default; | 137 | return vga_default; |
138 | } | 138 | } |
139 | |||
140 | EXPORT_SYMBOL_GPL(vga_default_device); | ||
141 | |||
142 | void vga_set_default_device(struct pci_dev *pdev) | ||
143 | { | ||
144 | vga_default = pdev; | ||
145 | } | ||
139 | #endif | 146 | #endif |
140 | 147 | ||
141 | static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) | 148 | static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) |
@@ -605,10 +612,12 @@ static bool vga_arbiter_del_pci_device(struct pci_dev *pdev) | |||
605 | goto bail; | 612 | goto bail; |
606 | } | 613 | } |
607 | 614 | ||
615 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
608 | if (vga_default == pdev) { | 616 | if (vga_default == pdev) { |
609 | pci_dev_put(vga_default); | 617 | pci_dev_put(vga_default); |
610 | vga_default = NULL; | 618 | vga_default = NULL; |
611 | } | 619 | } |
620 | #endif | ||
612 | 621 | ||
613 | if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) | 622 | if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) |
614 | vga_decode_count--; | 623 | vga_decode_count--; |