diff options
Diffstat (limited to 'drivers/gpu')
117 files changed, 1172 insertions, 1122 deletions
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 19ada0bbe319..9dc0fd5c1ea4 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c | |||
@@ -1104,8 +1104,8 @@ static u32 copy_cursor_image(u8 *src, u8 *dst, int width, int height) | |||
1104 | srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; | 1104 | srcdata32[1].ul = *((u32 *)(srcxor + 4)) & 0xf0f0f0f0; |
1105 | data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); | 1105 | data32.b[0] = srcdata32[0].b[1] | (srcdata32[0].b[0] >> 4); |
1106 | data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); | 1106 | data32.b[1] = srcdata32[0].b[3] | (srcdata32[0].b[2] >> 4); |
1107 | data32.b[2] = srcdata32[0].b[1] | (srcdata32[1].b[0] >> 4); | 1107 | data32.b[2] = srcdata32[1].b[1] | (srcdata32[1].b[0] >> 4); |
1108 | data32.b[3] = srcdata32[0].b[3] | (srcdata32[1].b[2] >> 4); | 1108 | data32.b[3] = srcdata32[1].b[3] | (srcdata32[1].b[2] >> 4); |
1109 | 1109 | ||
1110 | writel(data32.ul, dstxor); | 1110 | writel(data32.ul, dstxor); |
1111 | csum += data32.ul; | 1111 | csum += data32.ul; |
diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 9d7346b92653..6b7efcf363d6 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c | |||
@@ -250,6 +250,7 @@ static void bochs_connector_init(struct drm_device *dev) | |||
250 | DRM_MODE_CONNECTOR_VIRTUAL); | 250 | DRM_MODE_CONNECTOR_VIRTUAL); |
251 | drm_connector_helper_add(connector, | 251 | drm_connector_helper_add(connector, |
252 | &bochs_connector_connector_helper_funcs); | 252 | &bochs_connector_connector_helper_funcs); |
253 | drm_connector_register(connector); | ||
253 | } | 254 | } |
254 | 255 | ||
255 | 256 | ||
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index e1c5c3222129..c7c5a9d91fa0 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c | |||
@@ -555,6 +555,7 @@ static struct drm_connector *cirrus_vga_init(struct drm_device *dev) | |||
555 | 555 | ||
556 | drm_connector_helper_add(connector, &cirrus_vga_connector_helper_funcs); | 556 | drm_connector_helper_add(connector, &cirrus_vga_connector_helper_funcs); |
557 | 557 | ||
558 | drm_connector_register(connector); | ||
558 | return connector; | 559 | return connector; |
559 | } | 560 | } |
560 | 561 | ||
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index b3adf1445020..070f913d2dba 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c | |||
@@ -682,7 +682,7 @@ static int build_allocate_payload(struct drm_dp_sideband_msg_tx *msg, int port_n | |||
682 | static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr, | 682 | static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr, |
683 | struct drm_dp_vcpi *vcpi) | 683 | struct drm_dp_vcpi *vcpi) |
684 | { | 684 | { |
685 | int ret; | 685 | int ret, vcpi_ret; |
686 | 686 | ||
687 | mutex_lock(&mgr->payload_lock); | 687 | mutex_lock(&mgr->payload_lock); |
688 | ret = find_first_zero_bit(&mgr->payload_mask, mgr->max_payloads + 1); | 688 | ret = find_first_zero_bit(&mgr->payload_mask, mgr->max_payloads + 1); |
@@ -692,8 +692,16 @@ static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr, | |||
692 | goto out_unlock; | 692 | goto out_unlock; |
693 | } | 693 | } |
694 | 694 | ||
695 | vcpi_ret = find_first_zero_bit(&mgr->vcpi_mask, mgr->max_payloads + 1); | ||
696 | if (vcpi_ret > mgr->max_payloads) { | ||
697 | ret = -EINVAL; | ||
698 | DRM_DEBUG_KMS("out of vcpi ids %d\n", ret); | ||
699 | goto out_unlock; | ||
700 | } | ||
701 | |||
695 | set_bit(ret, &mgr->payload_mask); | 702 | set_bit(ret, &mgr->payload_mask); |
696 | vcpi->vcpi = ret; | 703 | set_bit(vcpi_ret, &mgr->vcpi_mask); |
704 | vcpi->vcpi = vcpi_ret + 1; | ||
697 | mgr->proposed_vcpis[ret - 1] = vcpi; | 705 | mgr->proposed_vcpis[ret - 1] = vcpi; |
698 | out_unlock: | 706 | out_unlock: |
699 | mutex_unlock(&mgr->payload_lock); | 707 | mutex_unlock(&mgr->payload_lock); |
@@ -701,15 +709,23 @@ out_unlock: | |||
701 | } | 709 | } |
702 | 710 | ||
703 | static void drm_dp_mst_put_payload_id(struct drm_dp_mst_topology_mgr *mgr, | 711 | static void drm_dp_mst_put_payload_id(struct drm_dp_mst_topology_mgr *mgr, |
704 | int id) | 712 | int vcpi) |
705 | { | 713 | { |
706 | if (id == 0) | 714 | int i; |
715 | if (vcpi == 0) | ||
707 | return; | 716 | return; |
708 | 717 | ||
709 | mutex_lock(&mgr->payload_lock); | 718 | mutex_lock(&mgr->payload_lock); |
710 | DRM_DEBUG_KMS("putting payload %d\n", id); | 719 | DRM_DEBUG_KMS("putting payload %d\n", vcpi); |
711 | clear_bit(id, &mgr->payload_mask); | 720 | clear_bit(vcpi - 1, &mgr->vcpi_mask); |
712 | mgr->proposed_vcpis[id - 1] = NULL; | 721 | |
722 | for (i = 0; i < mgr->max_payloads; i++) { | ||
723 | if (mgr->proposed_vcpis[i]) | ||
724 | if (mgr->proposed_vcpis[i]->vcpi == vcpi) { | ||
725 | mgr->proposed_vcpis[i] = NULL; | ||
726 | clear_bit(i + 1, &mgr->payload_mask); | ||
727 | } | ||
728 | } | ||
713 | mutex_unlock(&mgr->payload_lock); | 729 | mutex_unlock(&mgr->payload_lock); |
714 | } | 730 | } |
715 | 731 | ||
@@ -1563,7 +1579,7 @@ static int drm_dp_destroy_payload_step1(struct drm_dp_mst_topology_mgr *mgr, | |||
1563 | } | 1579 | } |
1564 | 1580 | ||
1565 | drm_dp_dpcd_write_payload(mgr, id, payload); | 1581 | drm_dp_dpcd_write_payload(mgr, id, payload); |
1566 | payload->payload_state = 0; | 1582 | payload->payload_state = DP_PAYLOAD_DELETE_LOCAL; |
1567 | return 0; | 1583 | return 0; |
1568 | } | 1584 | } |
1569 | 1585 | ||
@@ -1590,7 +1606,7 @@ static int drm_dp_destroy_payload_step2(struct drm_dp_mst_topology_mgr *mgr, | |||
1590 | */ | 1606 | */ |
1591 | int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) | 1607 | int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) |
1592 | { | 1608 | { |
1593 | int i; | 1609 | int i, j; |
1594 | int cur_slots = 1; | 1610 | int cur_slots = 1; |
1595 | struct drm_dp_payload req_payload; | 1611 | struct drm_dp_payload req_payload; |
1596 | struct drm_dp_mst_port *port; | 1612 | struct drm_dp_mst_port *port; |
@@ -1607,26 +1623,46 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) | |||
1607 | port = NULL; | 1623 | port = NULL; |
1608 | req_payload.num_slots = 0; | 1624 | req_payload.num_slots = 0; |
1609 | } | 1625 | } |
1626 | |||
1627 | if (mgr->payloads[i].start_slot != req_payload.start_slot) { | ||
1628 | mgr->payloads[i].start_slot = req_payload.start_slot; | ||
1629 | } | ||
1610 | /* work out what is required to happen with this payload */ | 1630 | /* work out what is required to happen with this payload */ |
1611 | if (mgr->payloads[i].start_slot != req_payload.start_slot || | 1631 | if (mgr->payloads[i].num_slots != req_payload.num_slots) { |
1612 | mgr->payloads[i].num_slots != req_payload.num_slots) { | ||
1613 | 1632 | ||
1614 | /* need to push an update for this payload */ | 1633 | /* need to push an update for this payload */ |
1615 | if (req_payload.num_slots) { | 1634 | if (req_payload.num_slots) { |
1616 | drm_dp_create_payload_step1(mgr, i + 1, &req_payload); | 1635 | drm_dp_create_payload_step1(mgr, mgr->proposed_vcpis[i]->vcpi, &req_payload); |
1617 | mgr->payloads[i].num_slots = req_payload.num_slots; | 1636 | mgr->payloads[i].num_slots = req_payload.num_slots; |
1618 | } else if (mgr->payloads[i].num_slots) { | 1637 | } else if (mgr->payloads[i].num_slots) { |
1619 | mgr->payloads[i].num_slots = 0; | 1638 | mgr->payloads[i].num_slots = 0; |
1620 | drm_dp_destroy_payload_step1(mgr, port, i + 1, &mgr->payloads[i]); | 1639 | drm_dp_destroy_payload_step1(mgr, port, port->vcpi.vcpi, &mgr->payloads[i]); |
1621 | req_payload.payload_state = mgr->payloads[i].payload_state; | 1640 | req_payload.payload_state = mgr->payloads[i].payload_state; |
1622 | } else | 1641 | mgr->payloads[i].start_slot = 0; |
1623 | req_payload.payload_state = 0; | 1642 | } |
1624 | |||
1625 | mgr->payloads[i].start_slot = req_payload.start_slot; | ||
1626 | mgr->payloads[i].payload_state = req_payload.payload_state; | 1643 | mgr->payloads[i].payload_state = req_payload.payload_state; |
1627 | } | 1644 | } |
1628 | cur_slots += req_payload.num_slots; | 1645 | cur_slots += req_payload.num_slots; |
1629 | } | 1646 | } |
1647 | |||
1648 | for (i = 0; i < mgr->max_payloads; i++) { | ||
1649 | if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) { | ||
1650 | DRM_DEBUG_KMS("removing payload %d\n", i); | ||
1651 | for (j = i; j < mgr->max_payloads - 1; j++) { | ||
1652 | memcpy(&mgr->payloads[j], &mgr->payloads[j + 1], sizeof(struct drm_dp_payload)); | ||
1653 | mgr->proposed_vcpis[j] = mgr->proposed_vcpis[j + 1]; | ||
1654 | if (mgr->proposed_vcpis[j] && mgr->proposed_vcpis[j]->num_slots) { | ||
1655 | set_bit(j + 1, &mgr->payload_mask); | ||
1656 | } else { | ||
1657 | clear_bit(j + 1, &mgr->payload_mask); | ||
1658 | } | ||
1659 | } | ||
1660 | memset(&mgr->payloads[mgr->max_payloads - 1], 0, sizeof(struct drm_dp_payload)); | ||
1661 | mgr->proposed_vcpis[mgr->max_payloads - 1] = NULL; | ||
1662 | clear_bit(mgr->max_payloads, &mgr->payload_mask); | ||
1663 | |||
1664 | } | ||
1665 | } | ||
1630 | mutex_unlock(&mgr->payload_lock); | 1666 | mutex_unlock(&mgr->payload_lock); |
1631 | 1667 | ||
1632 | return 0; | 1668 | return 0; |
@@ -1657,9 +1693,9 @@ int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr) | |||
1657 | 1693 | ||
1658 | DRM_DEBUG_KMS("payload %d %d\n", i, mgr->payloads[i].payload_state); | 1694 | DRM_DEBUG_KMS("payload %d %d\n", i, mgr->payloads[i].payload_state); |
1659 | if (mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL) { | 1695 | if (mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL) { |
1660 | ret = drm_dp_create_payload_step2(mgr, port, i + 1, &mgr->payloads[i]); | 1696 | ret = drm_dp_create_payload_step2(mgr, port, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]); |
1661 | } else if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) { | 1697 | } else if (mgr->payloads[i].payload_state == DP_PAYLOAD_DELETE_LOCAL) { |
1662 | ret = drm_dp_destroy_payload_step2(mgr, i + 1, &mgr->payloads[i]); | 1698 | ret = drm_dp_destroy_payload_step2(mgr, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]); |
1663 | } | 1699 | } |
1664 | if (ret) { | 1700 | if (ret) { |
1665 | mutex_unlock(&mgr->payload_lock); | 1701 | mutex_unlock(&mgr->payload_lock); |
@@ -1861,6 +1897,7 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms | |||
1861 | memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload)); | 1897 | memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload)); |
1862 | mgr->payload_mask = 0; | 1898 | mgr->payload_mask = 0; |
1863 | set_bit(0, &mgr->payload_mask); | 1899 | set_bit(0, &mgr->payload_mask); |
1900 | mgr->vcpi_mask = 0; | ||
1864 | } | 1901 | } |
1865 | 1902 | ||
1866 | out_unlock: | 1903 | out_unlock: |
@@ -2475,7 +2512,7 @@ void drm_dp_mst_dump_topology(struct seq_file *m, | |||
2475 | mutex_unlock(&mgr->lock); | 2512 | mutex_unlock(&mgr->lock); |
2476 | 2513 | ||
2477 | mutex_lock(&mgr->payload_lock); | 2514 | mutex_lock(&mgr->payload_lock); |
2478 | seq_printf(m, "vcpi: %lx\n", mgr->payload_mask); | 2515 | seq_printf(m, "vcpi: %lx %lx\n", mgr->payload_mask, mgr->vcpi_mask); |
2479 | 2516 | ||
2480 | for (i = 0; i < mgr->max_payloads; i++) { | 2517 | for (i = 0; i < mgr->max_payloads; i++) { |
2481 | if (mgr->proposed_vcpis[i]) { | 2518 | if (mgr->proposed_vcpis[i]) { |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8889f8ec50ab..bc3da32d4585 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -595,7 +595,7 @@ struct drm_device *drm_dev_alloc(struct drm_driver *driver, | |||
595 | goto err_ht; | 595 | goto err_ht; |
596 | } | 596 | } |
597 | 597 | ||
598 | if (driver->driver_features & DRIVER_GEM) { | 598 | if (drm_core_check_feature(dev, DRIVER_GEM)) { |
599 | ret = drm_gem_init(dev); | 599 | ret = drm_gem_init(dev); |
600 | if (ret) { | 600 | if (ret) { |
601 | DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n"); | 601 | DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n"); |
@@ -625,7 +625,7 @@ static void drm_dev_release(struct kref *ref) | |||
625 | { | 625 | { |
626 | struct drm_device *dev = container_of(ref, struct drm_device, ref); | 626 | struct drm_device *dev = container_of(ref, struct drm_device, ref); |
627 | 627 | ||
628 | if (dev->driver->driver_features & DRIVER_GEM) | 628 | if (drm_core_check_feature(dev, DRIVER_GEM)) |
629 | drm_gem_destroy(dev); | 629 | drm_gem_destroy(dev); |
630 | 630 | ||
631 | drm_legacy_ctxbitmap_cleanup(dev); | 631 | drm_legacy_ctxbitmap_cleanup(dev); |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 1bdbfd0e0033..3bf999134bcc 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -841,13 +841,13 @@ static const struct drm_display_mode edid_cea_modes[] = { | |||
841 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, | 841 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, |
842 | 795, 864, 0, 576, 580, 586, 625, 0, | 842 | 795, 864, 0, 576, 580, 586, 625, 0, |
843 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 843 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
844 | DRM_MODE_FLAG_DBLCLK), | 844 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
845 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, | 845 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, |
846 | /* 45 - 720(1440)x576i@100Hz */ | 846 | /* 45 - 720(1440)x576i@100Hz */ |
847 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, | 847 | { DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 27000, 720, 732, |
848 | 795, 864, 0, 576, 580, 586, 625, 0, | 848 | 795, 864, 0, 576, 580, 586, 625, 0, |
849 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | | 849 | DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | |
850 | DRM_MODE_FLAG_DBLCLK), | 850 | DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), |
851 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, | 851 | .vrefresh = 100, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, |
852 | /* 46 - 1920x1080i@120Hz */ | 852 | /* 46 - 1920x1080i@120Hz */ |
853 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, | 853 | { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 3e6694633f42..ed7bc68f7e87 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -171,7 +171,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) | |||
171 | init_waitqueue_head(&priv->event_wait); | 171 | init_waitqueue_head(&priv->event_wait); |
172 | priv->event_space = 4096; /* set aside 4k for event buffer */ | 172 | priv->event_space = 4096; /* set aside 4k for event buffer */ |
173 | 173 | ||
174 | if (dev->driver->driver_features & DRIVER_GEM) | 174 | if (drm_core_check_feature(dev, DRIVER_GEM)) |
175 | drm_gem_open(dev, priv); | 175 | drm_gem_open(dev, priv); |
176 | 176 | ||
177 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | 177 | if (drm_core_check_feature(dev, DRIVER_PRIME)) |
@@ -256,7 +256,7 @@ out_close: | |||
256 | out_prime_destroy: | 256 | out_prime_destroy: |
257 | if (drm_core_check_feature(dev, DRIVER_PRIME)) | 257 | if (drm_core_check_feature(dev, DRIVER_PRIME)) |
258 | drm_prime_destroy_file_private(&priv->prime); | 258 | drm_prime_destroy_file_private(&priv->prime); |
259 | if (dev->driver->driver_features & DRIVER_GEM) | 259 | if (drm_core_check_feature(dev, DRIVER_GEM)) |
260 | drm_gem_release(dev, priv); | 260 | drm_gem_release(dev, priv); |
261 | put_pid(priv->pid); | 261 | put_pid(priv->pid); |
262 | kfree(priv); | 262 | kfree(priv); |
@@ -408,10 +408,10 @@ int drm_release(struct inode *inode, struct file *filp) | |||
408 | 408 | ||
409 | drm_events_release(file_priv); | 409 | drm_events_release(file_priv); |
410 | 410 | ||
411 | if (dev->driver->driver_features & DRIVER_MODESET) | 411 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
412 | drm_fb_release(file_priv); | 412 | drm_fb_release(file_priv); |
413 | 413 | ||
414 | if (dev->driver->driver_features & DRIVER_GEM) | 414 | if (drm_core_check_feature(dev, DRIVER_GEM)) |
415 | drm_gem_release(dev, file_priv); | 415 | drm_gem_release(dev, file_priv); |
416 | 416 | ||
417 | drm_legacy_ctxbitmap_flush(dev, file_priv); | 417 | drm_legacy_ctxbitmap_flush(dev, file_priv); |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index cd45e45e2cce..f6ca51259fa3 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -581,7 +581,7 @@ drm_gem_close_ioctl(struct drm_device *dev, void *data, | |||
581 | struct drm_gem_close *args = data; | 581 | struct drm_gem_close *args = data; |
582 | int ret; | 582 | int ret; |
583 | 583 | ||
584 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 584 | if (!drm_core_check_feature(dev, DRIVER_GEM)) |
585 | return -ENODEV; | 585 | return -ENODEV; |
586 | 586 | ||
587 | ret = drm_gem_handle_delete(file_priv, args->handle); | 587 | ret = drm_gem_handle_delete(file_priv, args->handle); |
@@ -608,7 +608,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data, | |||
608 | struct drm_gem_object *obj; | 608 | struct drm_gem_object *obj; |
609 | int ret; | 609 | int ret; |
610 | 610 | ||
611 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 611 | if (!drm_core_check_feature(dev, DRIVER_GEM)) |
612 | return -ENODEV; | 612 | return -ENODEV; |
613 | 613 | ||
614 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 614 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
@@ -661,7 +661,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data, | |||
661 | int ret; | 661 | int ret; |
662 | u32 handle; | 662 | u32 handle; |
663 | 663 | ||
664 | if (!(dev->driver->driver_features & DRIVER_GEM)) | 664 | if (!drm_core_check_feature(dev, DRIVER_GEM)) |
665 | return -ENODEV; | 665 | return -ENODEV; |
666 | 666 | ||
667 | mutex_lock(&dev->object_name_lock); | 667 | mutex_lock(&dev->object_name_lock); |
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 8749fc06570e..474e4d12a2d8 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c | |||
@@ -35,7 +35,7 @@ | |||
35 | * of extra utility/tracking out of our acquire-ctx. This is provided | 35 | * of extra utility/tracking out of our acquire-ctx. This is provided |
36 | * by drm_modeset_lock / drm_modeset_acquire_ctx. | 36 | * by drm_modeset_lock / drm_modeset_acquire_ctx. |
37 | * | 37 | * |
38 | * For basic principles of ww_mutex, see: Documentation/ww-mutex-design.txt | 38 | * For basic principles of ww_mutex, see: Documentation/locking/ww-mutex-design.txt |
39 | * | 39 | * |
40 | * The basic usage pattern is to: | 40 | * The basic usage pattern is to: |
41 | * | 41 | * |
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index c45856bcc8b9..593b657d3e59 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c | |||
@@ -709,11 +709,13 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring) | |||
709 | BUG_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count)); | 709 | BUG_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count)); |
710 | BUG_ON(!validate_regs_sorted(ring)); | 710 | BUG_ON(!validate_regs_sorted(ring)); |
711 | 711 | ||
712 | ret = init_hash_table(ring, cmd_tables, cmd_table_count); | 712 | if (hash_empty(ring->cmd_hash)) { |
713 | if (ret) { | 713 | ret = init_hash_table(ring, cmd_tables, cmd_table_count); |
714 | DRM_ERROR("CMD: cmd_parser_init failed!\n"); | 714 | if (ret) { |
715 | fini_hash_table(ring); | 715 | DRM_ERROR("CMD: cmd_parser_init failed!\n"); |
716 | return ret; | 716 | fini_hash_table(ring); |
717 | return ret; | ||
718 | } | ||
717 | } | 719 | } |
718 | 720 | ||
719 | ring->needs_cmd_parser = true; | 721 | ring->needs_cmd_parser = true; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 2cbc85f3b237..063b44817e08 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -3826,7 +3826,6 @@ i915_drop_caches_set(void *data, u64 val) | |||
3826 | { | 3826 | { |
3827 | struct drm_device *dev = data; | 3827 | struct drm_device *dev = data; |
3828 | struct drm_i915_private *dev_priv = dev->dev_private; | 3828 | struct drm_i915_private *dev_priv = dev->dev_private; |
3829 | struct drm_i915_gem_object *obj, *next; | ||
3830 | int ret; | 3829 | int ret; |
3831 | 3830 | ||
3832 | DRM_DEBUG("Dropping caches: 0x%08llx\n", val); | 3831 | DRM_DEBUG("Dropping caches: 0x%08llx\n", val); |
@@ -3846,36 +3845,11 @@ i915_drop_caches_set(void *data, u64 val) | |||
3846 | if (val & (DROP_RETIRE | DROP_ACTIVE)) | 3845 | if (val & (DROP_RETIRE | DROP_ACTIVE)) |
3847 | i915_gem_retire_requests(dev); | 3846 | i915_gem_retire_requests(dev); |
3848 | 3847 | ||
3849 | if (val & DROP_BOUND) { | 3848 | if (val & DROP_BOUND) |
3850 | list_for_each_entry_safe(obj, next, &dev_priv->mm.bound_list, | 3849 | i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_BOUND); |
3851 | global_list) { | ||
3852 | struct i915_vma *vma, *v; | ||
3853 | 3850 | ||
3854 | ret = 0; | 3851 | if (val & DROP_UNBOUND) |
3855 | drm_gem_object_reference(&obj->base); | 3852 | i915_gem_shrink(dev_priv, LONG_MAX, I915_SHRINK_UNBOUND); |
3856 | list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) { | ||
3857 | if (vma->pin_count) | ||
3858 | continue; | ||
3859 | |||
3860 | ret = i915_vma_unbind(vma); | ||
3861 | if (ret) | ||
3862 | break; | ||
3863 | } | ||
3864 | drm_gem_object_unreference(&obj->base); | ||
3865 | if (ret) | ||
3866 | goto unlock; | ||
3867 | } | ||
3868 | } | ||
3869 | |||
3870 | if (val & DROP_UNBOUND) { | ||
3871 | list_for_each_entry_safe(obj, next, &dev_priv->mm.unbound_list, | ||
3872 | global_list) | ||
3873 | if (obj->pages_pin_count == 0) { | ||
3874 | ret = i915_gem_object_put_pages(obj); | ||
3875 | if (ret) | ||
3876 | goto unlock; | ||
3877 | } | ||
3878 | } | ||
3879 | 3853 | ||
3880 | unlock: | 3854 | unlock: |
3881 | mutex_unlock(&dev->struct_mutex); | 3855 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3870c7359a16..055d5e7fbf12 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -871,8 +871,6 @@ int i915_reset(struct drm_device *dev) | |||
871 | */ | 871 | */ |
872 | if (INTEL_INFO(dev)->gen > 5) | 872 | if (INTEL_INFO(dev)->gen > 5) |
873 | intel_reset_gt_powersave(dev); | 873 | intel_reset_gt_powersave(dev); |
874 | |||
875 | intel_hpd_init(dev); | ||
876 | } else { | 874 | } else { |
877 | mutex_unlock(&dev->struct_mutex); | 875 | mutex_unlock(&dev->struct_mutex); |
878 | } | 876 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 19c0dd8e255e..16a6f6d187a1 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -946,23 +946,6 @@ struct intel_rps_ei { | |||
946 | u32 media_c0; | 946 | u32 media_c0; |
947 | }; | 947 | }; |
948 | 948 | ||
949 | struct intel_rps_bdw_cal { | ||
950 | u32 it_threshold_pct; /* interrupt, in percentage */ | ||
951 | u32 eval_interval; /* evaluation interval, in us */ | ||
952 | u32 last_ts; | ||
953 | u32 last_c0; | ||
954 | bool is_up; | ||
955 | }; | ||
956 | |||
957 | struct intel_rps_bdw_turbo { | ||
958 | struct intel_rps_bdw_cal up; | ||
959 | struct intel_rps_bdw_cal down; | ||
960 | struct timer_list flip_timer; | ||
961 | u32 timeout; | ||
962 | atomic_t flip_received; | ||
963 | struct work_struct work_max_freq; | ||
964 | }; | ||
965 | |||
966 | struct intel_gen6_power_mgmt { | 949 | struct intel_gen6_power_mgmt { |
967 | /* work and pm_iir are protected by dev_priv->irq_lock */ | 950 | /* work and pm_iir are protected by dev_priv->irq_lock */ |
968 | struct work_struct work; | 951 | struct work_struct work; |
@@ -996,9 +979,6 @@ struct intel_gen6_power_mgmt { | |||
996 | bool enabled; | 979 | bool enabled; |
997 | struct delayed_work delayed_resume_work; | 980 | struct delayed_work delayed_resume_work; |
998 | 981 | ||
999 | bool is_bdw_sw_turbo; /* Switch of BDW software turbo */ | ||
1000 | struct intel_rps_bdw_turbo sw_turbo; /* Calculate RP interrupt timing */ | ||
1001 | |||
1002 | /* manual wa residency calculations */ | 982 | /* manual wa residency calculations */ |
1003 | struct intel_rps_ei up_ei, down_ei; | 983 | struct intel_rps_ei up_ei, down_ei; |
1004 | 984 | ||
@@ -2369,6 +2349,12 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, | |||
2369 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, | 2349 | int i915_gem_wait_ioctl(struct drm_device *dev, void *data, |
2370 | struct drm_file *file_priv); | 2350 | struct drm_file *file_priv); |
2371 | void i915_gem_load(struct drm_device *dev); | 2351 | void i915_gem_load(struct drm_device *dev); |
2352 | unsigned long i915_gem_shrink(struct drm_i915_private *dev_priv, | ||
2353 | long target, | ||
2354 | unsigned flags); | ||
2355 | #define I915_SHRINK_PURGEABLE 0x1 | ||
2356 | #define I915_SHRINK_UNBOUND 0x2 | ||
2357 | #define I915_SHRINK_BOUND 0x4 | ||
2372 | void *i915_gem_object_alloc(struct drm_device *dev); | 2358 | void *i915_gem_object_alloc(struct drm_device *dev); |
2373 | void i915_gem_object_free(struct drm_i915_gem_object *obj); | 2359 | void i915_gem_object_free(struct drm_i915_gem_object *obj); |
2374 | void i915_gem_object_init(struct drm_i915_gem_object *obj, | 2360 | void i915_gem_object_init(struct drm_i915_gem_object *obj, |
@@ -2823,8 +2809,6 @@ extern void intel_disable_fbc(struct drm_device *dev); | |||
2823 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | 2809 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); |
2824 | extern void intel_init_pch_refclk(struct drm_device *dev); | 2810 | extern void intel_init_pch_refclk(struct drm_device *dev); |
2825 | extern void gen6_set_rps(struct drm_device *dev, u8 val); | 2811 | extern void gen6_set_rps(struct drm_device *dev, u8 val); |
2826 | extern void bdw_software_turbo(struct drm_device *dev); | ||
2827 | extern void gen8_flip_interrupt(struct drm_device *dev); | ||
2828 | extern void valleyview_set_rps(struct drm_device *dev, u8 val); | 2812 | extern void valleyview_set_rps(struct drm_device *dev, u8 val); |
2829 | extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, | 2813 | extern void intel_set_memory_cxsr(struct drm_i915_private *dev_priv, |
2830 | bool enable); | 2814 | bool enable); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4ca3a6dcf10b..28f91df2604d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -60,7 +60,6 @@ static unsigned long i915_gem_shrinker_scan(struct shrinker *shrinker, | |||
60 | static int i915_gem_shrinker_oom(struct notifier_block *nb, | 60 | static int i915_gem_shrinker_oom(struct notifier_block *nb, |
61 | unsigned long event, | 61 | unsigned long event, |
62 | void *ptr); | 62 | void *ptr); |
63 | static unsigned long i915_gem_purge(struct drm_i915_private *dev_priv, long target); | ||
64 | static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); | 63 | static unsigned long i915_gem_shrink_all(struct drm_i915_private *dev_priv); |
65 | 64 | ||
66 | static bool cpu_cache_is_coherent(struct drm_device *dev, | 65 | static bool cpu_cache_is_coherent(struct drm_device *dev, |
@@ -1741,7 +1740,11 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj) | |||
1741 | * offsets on purgeable objects by truncating it and marking it purged, | 1740 | * offsets on purgeable objects by truncating it and marking it purged, |
1742 | * which prevents userspace from ever using that object again. | 1741 | * which prevents userspace from ever using that object again. |
1743 | */ | 1742 | */ |
1744 | i915_gem_purge(dev_priv, obj->base.size >> PAGE_SHIFT); | 1743 | i915_gem_shrink(dev_priv, |
1744 | obj->base.size >> PAGE_SHIFT, | ||
1745 | I915_SHRINK_BOUND | | ||
1746 | I915_SHRINK_UNBOUND | | ||
1747 | I915_SHRINK_PURGEABLE); | ||
1745 | ret = drm_gem_create_mmap_offset(&obj->base); | 1748 | ret = drm_gem_create_mmap_offset(&obj->base); |
1746 | if (ret != -ENOSPC) | 1749 | if (ret != -ENOSPC) |
1747 | goto out; | 1750 | goto out; |
@@ -1938,12 +1941,11 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) | |||
1938 | return 0; | 1941 | return 0; |
1939 | } | 1942 | } |
1940 | 1943 | ||
1941 | static unsigned long | 1944 | unsigned long |
1942 | __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, | 1945 | i915_gem_shrink(struct drm_i915_private *dev_priv, |
1943 | bool purgeable_only) | 1946 | long target, unsigned flags) |
1944 | { | 1947 | { |
1945 | struct list_head still_in_list; | 1948 | const bool purgeable_only = flags & I915_SHRINK_PURGEABLE; |
1946 | struct drm_i915_gem_object *obj; | ||
1947 | unsigned long count = 0; | 1949 | unsigned long count = 0; |
1948 | 1950 | ||
1949 | /* | 1951 | /* |
@@ -1965,62 +1967,68 @@ __i915_gem_shrink(struct drm_i915_private *dev_priv, long target, | |||
1965 | * dev->struct_mutex and so we won't ever be able to observe an | 1967 | * dev->struct_mutex and so we won't ever be able to observe an |
1966 | * object on the bound_list with a reference count equals 0. | 1968 | * object on the bound_list with a reference count equals 0. |
1967 | */ | 1969 | */ |
1968 | INIT_LIST_HEAD(&still_in_list); | 1970 | if (flags & I915_SHRINK_UNBOUND) { |
1969 | while (count < target && !list_empty(&dev_priv->mm.unbound_list)) { | 1971 | struct list_head still_in_list; |
1970 | obj = list_first_entry(&dev_priv->mm.unbound_list, | ||
1971 | typeof(*obj), global_list); | ||
1972 | list_move_tail(&obj->global_list, &still_in_list); | ||
1973 | 1972 | ||
1974 | if (!i915_gem_object_is_purgeable(obj) && purgeable_only) | 1973 | INIT_LIST_HEAD(&still_in_list); |
1975 | continue; | 1974 | while (count < target && !list_empty(&dev_priv->mm.unbound_list)) { |
1975 | struct drm_i915_gem_object *obj; | ||
1976 | 1976 | ||
1977 | drm_gem_object_reference(&obj->base); | 1977 | obj = list_first_entry(&dev_priv->mm.unbound_list, |
1978 | typeof(*obj), global_list); | ||
1979 | list_move_tail(&obj->global_list, &still_in_list); | ||
1978 | 1980 | ||
1979 | if (i915_gem_object_put_pages(obj) == 0) | 1981 | if (!i915_gem_object_is_purgeable(obj) && purgeable_only) |
1980 | count += obj->base.size >> PAGE_SHIFT; | 1982 | continue; |
1983 | |||
1984 | drm_gem_object_reference(&obj->base); | ||
1981 | 1985 | ||
1982 | drm_gem_object_unreference(&obj->base); | 1986 | if (i915_gem_object_put_pages(obj) == 0) |
1987 | count += obj->base.size >> PAGE_SHIFT; | ||
1988 | |||
1989 | drm_gem_object_unreference(&obj->base); | ||
1990 | } | ||
1991 | list_splice(&still_in_list, &dev_priv->mm.unbound_list); | ||
1983 | } | 1992 | } |
1984 | list_splice(&still_in_list, &dev_priv->mm.unbound_list); | ||
1985 | 1993 | ||
1986 | INIT_LIST_HEAD(&still_in_list); | 1994 | if (flags & I915_SHRINK_BOUND) { |
1987 | while (count < target && !list_empty(&dev_priv->mm.bound_list)) { | 1995 | struct list_head still_in_list; |
1988 | struct i915_vma *vma, *v; | ||
1989 | 1996 | ||
1990 | obj = list_first_entry(&dev_priv->mm.bound_list, | 1997 | INIT_LIST_HEAD(&still_in_list); |
1991 | typeof(*obj), global_list); | 1998 | while (count < target && !list_empty(&dev_priv->mm.bound_list)) { |
1992 | list_move_tail(&obj->global_list, &still_in_list); | 1999 | struct drm_i915_gem_object *obj; |
2000 | struct i915_vma *vma, *v; | ||
1993 | 2001 | ||
1994 | if (!i915_gem_object_is_purgeable(obj) && purgeable_only) | 2002 | obj = list_first_entry(&dev_priv->mm.bound_list, |
1995 | continue; | 2003 | typeof(*obj), global_list); |
2004 | list_move_tail(&obj->global_list, &still_in_list); | ||
1996 | 2005 | ||
1997 | drm_gem_object_reference(&obj->base); | 2006 | if (!i915_gem_object_is_purgeable(obj) && purgeable_only) |
2007 | continue; | ||
1998 | 2008 | ||
1999 | list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) | 2009 | drm_gem_object_reference(&obj->base); |
2000 | if (i915_vma_unbind(vma)) | ||
2001 | break; | ||
2002 | 2010 | ||
2003 | if (i915_gem_object_put_pages(obj) == 0) | 2011 | list_for_each_entry_safe(vma, v, &obj->vma_list, vma_link) |
2004 | count += obj->base.size >> PAGE_SHIFT; | 2012 | if (i915_vma_unbind(vma)) |
2013 | break; | ||
2014 | |||
2015 | if (i915_gem_object_put_pages(obj) == 0) | ||
2016 | count += obj->base.size >> PAGE_SHIFT; | ||
2005 | 2017 | ||
2006 | drm_gem_object_unreference(&obj->base); | 2018 | drm_gem_object_unreference(&obj->base); |
2019 | } | ||
2020 | list_splice(&still_in_list, &dev_priv->mm.bound_list); | ||
2007 | } | 2021 | } |
2008 | list_splice(&still_in_list, &dev_priv->mm.bound_list); | ||
2009 | 2022 | ||
2010 | return count; | 2023 | return count; |
2011 | } | 2024 | } |
2012 | 2025 | ||
2013 | static unsigned long | 2026 | static unsigned long |
2014 | i915_gem_purge(struct drm_i915_private *dev_priv, long target) | ||
2015 | { | ||
2016 | return __i915_gem_shrink(dev_priv, target, true); | ||
2017 | } | ||
2018 | |||
2019 | static unsigned long | ||
2020 | i915_gem_shrink_all(struct drm_i915_private *dev_priv) | 2027 | i915_gem_shrink_all(struct drm_i915_private *dev_priv) |
2021 | { | 2028 | { |
2022 | i915_gem_evict_everything(dev_priv->dev); | 2029 | i915_gem_evict_everything(dev_priv->dev); |
2023 | return __i915_gem_shrink(dev_priv, LONG_MAX, false); | 2030 | return i915_gem_shrink(dev_priv, LONG_MAX, |
2031 | I915_SHRINK_BOUND | I915_SHRINK_UNBOUND); | ||
2024 | } | 2032 | } |
2025 | 2033 | ||
2026 | static int | 2034 | static int |
@@ -2067,7 +2075,11 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) | |||
2067 | for (i = 0; i < page_count; i++) { | 2075 | for (i = 0; i < page_count; i++) { |
2068 | page = shmem_read_mapping_page_gfp(mapping, i, gfp); | 2076 | page = shmem_read_mapping_page_gfp(mapping, i, gfp); |
2069 | if (IS_ERR(page)) { | 2077 | if (IS_ERR(page)) { |
2070 | i915_gem_purge(dev_priv, page_count); | 2078 | i915_gem_shrink(dev_priv, |
2079 | page_count, | ||
2080 | I915_SHRINK_BOUND | | ||
2081 | I915_SHRINK_UNBOUND | | ||
2082 | I915_SHRINK_PURGEABLE); | ||
2071 | page = shmem_read_mapping_page_gfp(mapping, i, gfp); | 2083 | page = shmem_read_mapping_page_gfp(mapping, i, gfp); |
2072 | } | 2084 | } |
2073 | if (IS_ERR(page)) { | 2085 | if (IS_ERR(page)) { |
@@ -2944,6 +2956,9 @@ int i915_vma_unbind(struct i915_vma *vma) | |||
2944 | * cause memory corruption through use-after-free. | 2956 | * cause memory corruption through use-after-free. |
2945 | */ | 2957 | */ |
2946 | 2958 | ||
2959 | /* Throw away the active reference before moving to the unbound list */ | ||
2960 | i915_gem_object_retire(obj); | ||
2961 | |||
2947 | if (i915_is_ggtt(vma->vm)) { | 2962 | if (i915_is_ggtt(vma->vm)) { |
2948 | i915_gem_object_finish_gtt(obj); | 2963 | i915_gem_object_finish_gtt(obj); |
2949 | 2964 | ||
@@ -3336,17 +3351,20 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj) | |||
3336 | return 0; | 3351 | return 0; |
3337 | } | 3352 | } |
3338 | 3353 | ||
3339 | static bool i915_gem_valid_gtt_space(struct drm_device *dev, | 3354 | static bool i915_gem_valid_gtt_space(struct i915_vma *vma, |
3340 | struct drm_mm_node *gtt_space, | ||
3341 | unsigned long cache_level) | 3355 | unsigned long cache_level) |
3342 | { | 3356 | { |
3357 | struct drm_mm_node *gtt_space = &vma->node; | ||
3343 | struct drm_mm_node *other; | 3358 | struct drm_mm_node *other; |
3344 | 3359 | ||
3345 | /* On non-LLC machines we have to be careful when putting differing | 3360 | /* |
3346 | * types of snoopable memory together to avoid the prefetcher | 3361 | * On some machines we have to be careful when putting differing types |
3347 | * crossing memory domains and dying. | 3362 | * of snoopable memory together to avoid the prefetcher crossing memory |
3363 | * domains and dying. During vm initialisation, we decide whether or not | ||
3364 | * these constraints apply and set the drm_mm.color_adjust | ||
3365 | * appropriately. | ||
3348 | */ | 3366 | */ |
3349 | if (HAS_LLC(dev)) | 3367 | if (vma->vm->mm.color_adjust == NULL) |
3350 | return true; | 3368 | return true; |
3351 | 3369 | ||
3352 | if (!drm_mm_node_allocated(gtt_space)) | 3370 | if (!drm_mm_node_allocated(gtt_space)) |
@@ -3484,8 +3502,7 @@ search_free: | |||
3484 | 3502 | ||
3485 | goto err_free_vma; | 3503 | goto err_free_vma; |
3486 | } | 3504 | } |
3487 | if (WARN_ON(!i915_gem_valid_gtt_space(dev, &vma->node, | 3505 | if (WARN_ON(!i915_gem_valid_gtt_space(vma, obj->cache_level))) { |
3488 | obj->cache_level))) { | ||
3489 | ret = -EINVAL; | 3506 | ret = -EINVAL; |
3490 | goto err_remove_node; | 3507 | goto err_remove_node; |
3491 | } | 3508 | } |
@@ -3695,7 +3712,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
3695 | } | 3712 | } |
3696 | 3713 | ||
3697 | list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) { | 3714 | list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) { |
3698 | if (!i915_gem_valid_gtt_space(dev, &vma->node, cache_level)) { | 3715 | if (!i915_gem_valid_gtt_space(vma, cache_level)) { |
3699 | ret = i915_vma_unbind(vma); | 3716 | ret = i915_vma_unbind(vma); |
3700 | if (ret) | 3717 | if (ret) |
3701 | return ret; | 3718 | return ret; |
@@ -5261,11 +5278,16 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) | |||
5261 | if (!i915_gem_shrinker_lock(dev, &unlock)) | 5278 | if (!i915_gem_shrinker_lock(dev, &unlock)) |
5262 | return SHRINK_STOP; | 5279 | return SHRINK_STOP; |
5263 | 5280 | ||
5264 | freed = i915_gem_purge(dev_priv, sc->nr_to_scan); | 5281 | freed = i915_gem_shrink(dev_priv, |
5282 | sc->nr_to_scan, | ||
5283 | I915_SHRINK_BOUND | | ||
5284 | I915_SHRINK_UNBOUND | | ||
5285 | I915_SHRINK_PURGEABLE); | ||
5265 | if (freed < sc->nr_to_scan) | 5286 | if (freed < sc->nr_to_scan) |
5266 | freed += __i915_gem_shrink(dev_priv, | 5287 | freed += i915_gem_shrink(dev_priv, |
5267 | sc->nr_to_scan - freed, | 5288 | sc->nr_to_scan - freed, |
5268 | false); | 5289 | I915_SHRINK_BOUND | |
5290 | I915_SHRINK_UNBOUND); | ||
5269 | if (unlock) | 5291 | if (unlock) |
5270 | mutex_unlock(&dev->struct_mutex); | 5292 | mutex_unlock(&dev->struct_mutex); |
5271 | 5293 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index bbf4b12d842e..886ff2ee7a28 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -243,7 +243,7 @@ int | |||
243 | i915_gem_evict_everything(struct drm_device *dev) | 243 | i915_gem_evict_everything(struct drm_device *dev) |
244 | { | 244 | { |
245 | struct drm_i915_private *dev_priv = dev->dev_private; | 245 | struct drm_i915_private *dev_priv = dev->dev_private; |
246 | struct i915_address_space *vm; | 246 | struct i915_address_space *vm, *v; |
247 | bool lists_empty = true; | 247 | bool lists_empty = true; |
248 | int ret; | 248 | int ret; |
249 | 249 | ||
@@ -270,7 +270,7 @@ i915_gem_evict_everything(struct drm_device *dev) | |||
270 | i915_gem_retire_requests(dev); | 270 | i915_gem_retire_requests(dev); |
271 | 271 | ||
272 | /* Having flushed everything, unbind() should never raise an error */ | 272 | /* Having flushed everything, unbind() should never raise an error */ |
273 | list_for_each_entry(vm, &dev_priv->vm_list, global_link) | 273 | list_for_each_entry_safe(vm, v, &dev_priv->vm_list, global_link) |
274 | WARN_ON(i915_gem_evict_vm(vm, false)); | 274 | WARN_ON(i915_gem_evict_vm(vm, false)); |
275 | 275 | ||
276 | return 0; | 276 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6f410cfb0510..b672b843fd5e 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -1273,6 +1273,16 @@ void i915_check_and_clear_faults(struct drm_device *dev) | |||
1273 | POSTING_READ(RING_FAULT_REG(&dev_priv->ring[RCS])); | 1273 | POSTING_READ(RING_FAULT_REG(&dev_priv->ring[RCS])); |
1274 | } | 1274 | } |
1275 | 1275 | ||
1276 | static void i915_ggtt_flush(struct drm_i915_private *dev_priv) | ||
1277 | { | ||
1278 | if (INTEL_INFO(dev_priv->dev)->gen < 6) { | ||
1279 | intel_gtt_chipset_flush(); | ||
1280 | } else { | ||
1281 | I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN); | ||
1282 | POSTING_READ(GFX_FLSH_CNTL_GEN6); | ||
1283 | } | ||
1284 | } | ||
1285 | |||
1276 | void i915_gem_suspend_gtt_mappings(struct drm_device *dev) | 1286 | void i915_gem_suspend_gtt_mappings(struct drm_device *dev) |
1277 | { | 1287 | { |
1278 | struct drm_i915_private *dev_priv = dev->dev_private; | 1288 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -1289,6 +1299,8 @@ void i915_gem_suspend_gtt_mappings(struct drm_device *dev) | |||
1289 | dev_priv->gtt.base.start, | 1299 | dev_priv->gtt.base.start, |
1290 | dev_priv->gtt.base.total, | 1300 | dev_priv->gtt.base.total, |
1291 | true); | 1301 | true); |
1302 | |||
1303 | i915_ggtt_flush(dev_priv); | ||
1292 | } | 1304 | } |
1293 | 1305 | ||
1294 | void i915_gem_restore_gtt_mappings(struct drm_device *dev) | 1306 | void i915_gem_restore_gtt_mappings(struct drm_device *dev) |
@@ -1341,7 +1353,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) | |||
1341 | gen6_write_pdes(container_of(vm, struct i915_hw_ppgtt, base)); | 1353 | gen6_write_pdes(container_of(vm, struct i915_hw_ppgtt, base)); |
1342 | } | 1354 | } |
1343 | 1355 | ||
1344 | i915_gem_chipset_flush(dev); | 1356 | i915_ggtt_flush(dev_priv); |
1345 | } | 1357 | } |
1346 | 1358 | ||
1347 | int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | 1359 | int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) |
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 21c025a209c0..85fda6b803e4 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
@@ -289,6 +289,7 @@ void i915_gem_cleanup_stolen(struct drm_device *dev) | |||
289 | int i915_gem_init_stolen(struct drm_device *dev) | 289 | int i915_gem_init_stolen(struct drm_device *dev) |
290 | { | 290 | { |
291 | struct drm_i915_private *dev_priv = dev->dev_private; | 291 | struct drm_i915_private *dev_priv = dev->dev_private; |
292 | u32 tmp; | ||
292 | int bios_reserved = 0; | 293 | int bios_reserved = 0; |
293 | 294 | ||
294 | #ifdef CONFIG_INTEL_IOMMU | 295 | #ifdef CONFIG_INTEL_IOMMU |
@@ -308,8 +309,16 @@ int i915_gem_init_stolen(struct drm_device *dev) | |||
308 | DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n", | 309 | DRM_DEBUG_KMS("found %zd bytes of stolen memory at %08lx\n", |
309 | dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base); | 310 | dev_priv->gtt.stolen_size, dev_priv->mm.stolen_base); |
310 | 311 | ||
311 | if (IS_VALLEYVIEW(dev)) | 312 | if (INTEL_INFO(dev)->gen >= 8) { |
312 | bios_reserved = 1024*1024; /* top 1M on VLV/BYT */ | 313 | tmp = I915_READ(GEN7_BIOS_RESERVED); |
314 | tmp >>= GEN8_BIOS_RESERVED_SHIFT; | ||
315 | tmp &= GEN8_BIOS_RESERVED_MASK; | ||
316 | bios_reserved = (1024*1024) << tmp; | ||
317 | } else if (IS_GEN7(dev)) { | ||
318 | tmp = I915_READ(GEN7_BIOS_RESERVED); | ||
319 | bios_reserved = tmp & GEN7_BIOS_RESERVED_256K ? | ||
320 | 256*1024 : 1024*1024; | ||
321 | } | ||
313 | 322 | ||
314 | if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size)) | 323 | if (WARN_ON(bios_reserved > dev_priv->gtt.stolen_size)) |
315 | return 0; | 324 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index d38413997379..d182058383a9 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c | |||
@@ -293,15 +293,23 @@ i915_gem_userptr_release__mmu_notifier(struct drm_i915_gem_object *obj) | |||
293 | static struct i915_mmu_notifier * | 293 | static struct i915_mmu_notifier * |
294 | i915_mmu_notifier_find(struct i915_mm_struct *mm) | 294 | i915_mmu_notifier_find(struct i915_mm_struct *mm) |
295 | { | 295 | { |
296 | if (mm->mn == NULL) { | 296 | struct i915_mmu_notifier *mn = mm->mn; |
297 | down_write(&mm->mm->mmap_sem); | 297 | |
298 | mutex_lock(&to_i915(mm->dev)->mm_lock); | 298 | mn = mm->mn; |
299 | if (mm->mn == NULL) | 299 | if (mn) |
300 | mm->mn = i915_mmu_notifier_create(mm->mm); | 300 | return mn; |
301 | mutex_unlock(&to_i915(mm->dev)->mm_lock); | 301 | |
302 | up_write(&mm->mm->mmap_sem); | 302 | down_write(&mm->mm->mmap_sem); |
303 | mutex_lock(&to_i915(mm->dev)->mm_lock); | ||
304 | if ((mn = mm->mn) == NULL) { | ||
305 | mn = i915_mmu_notifier_create(mm->mm); | ||
306 | if (!IS_ERR(mn)) | ||
307 | mm->mn = mn; | ||
303 | } | 308 | } |
304 | return mm->mn; | 309 | mutex_unlock(&to_i915(mm->dev)->mm_lock); |
310 | up_write(&mm->mm->mmap_sem); | ||
311 | |||
312 | return mn; | ||
305 | } | 313 | } |
306 | 314 | ||
307 | static int | 315 | static int |
@@ -681,16 +689,15 @@ i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) | |||
681 | static void | 689 | static void |
682 | i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) | 690 | i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj) |
683 | { | 691 | { |
684 | struct scatterlist *sg; | 692 | struct sg_page_iter sg_iter; |
685 | int i; | ||
686 | 693 | ||
687 | BUG_ON(obj->userptr.work != NULL); | 694 | BUG_ON(obj->userptr.work != NULL); |
688 | 695 | ||
689 | if (obj->madv != I915_MADV_WILLNEED) | 696 | if (obj->madv != I915_MADV_WILLNEED) |
690 | obj->dirty = 0; | 697 | obj->dirty = 0; |
691 | 698 | ||
692 | for_each_sg(obj->pages->sgl, sg, obj->pages->nents, i) { | 699 | for_each_sg_page(obj->pages->sgl, &sg_iter, obj->pages->nents, 0) { |
693 | struct page *page = sg_page(sg); | 700 | struct page *page = sg_page_iter_page(&sg_iter); |
694 | 701 | ||
695 | if (obj->dirty) | 702 | if (obj->dirty) |
696 | set_page_dirty(page); | 703 | set_page_dirty(page); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c96ddc953531..f66392b6e287 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1711,7 +1711,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, | |||
1711 | #define HPD_STORM_DETECT_PERIOD 1000 | 1711 | #define HPD_STORM_DETECT_PERIOD 1000 |
1712 | #define HPD_STORM_THRESHOLD 5 | 1712 | #define HPD_STORM_THRESHOLD 5 |
1713 | 1713 | ||
1714 | static int ilk_port_to_hotplug_shift(enum port port) | 1714 | static int pch_port_to_hotplug_shift(enum port port) |
1715 | { | 1715 | { |
1716 | switch (port) { | 1716 | switch (port) { |
1717 | case PORT_A: | 1717 | case PORT_A: |
@@ -1727,7 +1727,7 @@ static int ilk_port_to_hotplug_shift(enum port port) | |||
1727 | } | 1727 | } |
1728 | } | 1728 | } |
1729 | 1729 | ||
1730 | static int g4x_port_to_hotplug_shift(enum port port) | 1730 | static int i915_port_to_hotplug_shift(enum port port) |
1731 | { | 1731 | { |
1732 | switch (port) { | 1732 | switch (port) { |
1733 | case PORT_A: | 1733 | case PORT_A: |
@@ -1785,12 +1785,12 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, | |||
1785 | if (port && dev_priv->hpd_irq_port[port]) { | 1785 | if (port && dev_priv->hpd_irq_port[port]) { |
1786 | bool long_hpd; | 1786 | bool long_hpd; |
1787 | 1787 | ||
1788 | if (IS_G4X(dev)) { | 1788 | if (HAS_PCH_SPLIT(dev)) { |
1789 | dig_shift = g4x_port_to_hotplug_shift(port); | 1789 | dig_shift = pch_port_to_hotplug_shift(port); |
1790 | long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; | ||
1791 | } else { | ||
1792 | dig_shift = ilk_port_to_hotplug_shift(port); | ||
1793 | long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; | 1790 | long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; |
1791 | } else { | ||
1792 | dig_shift = i915_port_to_hotplug_shift(port); | ||
1793 | long_hpd = (hotplug_trigger >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; | ||
1794 | } | 1794 | } |
1795 | 1795 | ||
1796 | DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", | 1796 | DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", |
@@ -1979,27 +1979,6 @@ static void i9xx_pipe_crc_irq_handler(struct drm_device *dev, enum pipe pipe) | |||
1979 | res1, res2); | 1979 | res1, res2); |
1980 | } | 1980 | } |
1981 | 1981 | ||
1982 | void gen8_flip_interrupt(struct drm_device *dev) | ||
1983 | { | ||
1984 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1985 | |||
1986 | if (!dev_priv->rps.is_bdw_sw_turbo) | ||
1987 | return; | ||
1988 | |||
1989 | if(atomic_read(&dev_priv->rps.sw_turbo.flip_received)) { | ||
1990 | mod_timer(&dev_priv->rps.sw_turbo.flip_timer, | ||
1991 | usecs_to_jiffies(dev_priv->rps.sw_turbo.timeout) + jiffies); | ||
1992 | } | ||
1993 | else { | ||
1994 | dev_priv->rps.sw_turbo.flip_timer.expires = | ||
1995 | usecs_to_jiffies(dev_priv->rps.sw_turbo.timeout) + jiffies; | ||
1996 | add_timer(&dev_priv->rps.sw_turbo.flip_timer); | ||
1997 | atomic_set(&dev_priv->rps.sw_turbo.flip_received, true); | ||
1998 | } | ||
1999 | |||
2000 | bdw_software_turbo(dev); | ||
2001 | } | ||
2002 | |||
2003 | /* The RPS events need forcewake, so we add them to a work queue and mask their | 1982 | /* The RPS events need forcewake, so we add them to a work queue and mask their |
2004 | * IMR bits until the work is done. Other interrupts can be processed without | 1983 | * IMR bits until the work is done. Other interrupts can be processed without |
2005 | * the work queue. */ | 1984 | * the work queue. */ |
@@ -3479,12 +3458,13 @@ static void gen8_irq_reset(struct drm_device *dev) | |||
3479 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) | 3458 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv) |
3480 | { | 3459 | { |
3481 | unsigned long irqflags; | 3460 | unsigned long irqflags; |
3461 | uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; | ||
3482 | 3462 | ||
3483 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); | 3463 | spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
3484 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B], | 3464 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, dev_priv->de_irq_mask[PIPE_B], |
3485 | ~dev_priv->de_irq_mask[PIPE_B]); | 3465 | ~dev_priv->de_irq_mask[PIPE_B] | extra_ier); |
3486 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C], | 3466 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, dev_priv->de_irq_mask[PIPE_C], |
3487 | ~dev_priv->de_irq_mask[PIPE_C]); | 3467 | ~dev_priv->de_irq_mask[PIPE_C] | extra_ier); |
3488 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 3468 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
3489 | } | 3469 | } |
3490 | 3470 | ||
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 139f490d464d..c91cb2033cc5 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c | |||
@@ -67,12 +67,12 @@ module_param_named(powersave, i915.powersave, int, 0600); | |||
67 | MODULE_PARM_DESC(powersave, | 67 | MODULE_PARM_DESC(powersave, |
68 | "Enable powersavings, fbc, downclocking, etc. (default: true)"); | 68 | "Enable powersavings, fbc, downclocking, etc. (default: true)"); |
69 | 69 | ||
70 | module_param_named(semaphores, i915.semaphores, int, 0400); | 70 | module_param_named_unsafe(semaphores, i915.semaphores, int, 0400); |
71 | MODULE_PARM_DESC(semaphores, | 71 | MODULE_PARM_DESC(semaphores, |
72 | "Use semaphores for inter-ring sync " | 72 | "Use semaphores for inter-ring sync " |
73 | "(default: -1 (use per-chip defaults))"); | 73 | "(default: -1 (use per-chip defaults))"); |
74 | 74 | ||
75 | module_param_named(enable_rc6, i915.enable_rc6, int, 0400); | 75 | module_param_named_unsafe(enable_rc6, i915.enable_rc6, int, 0400); |
76 | MODULE_PARM_DESC(enable_rc6, | 76 | MODULE_PARM_DESC(enable_rc6, |
77 | "Enable power-saving render C-state 6. " | 77 | "Enable power-saving render C-state 6. " |
78 | "Different stages can be selected via bitmask values " | 78 | "Different stages can be selected via bitmask values " |
@@ -80,7 +80,7 @@ MODULE_PARM_DESC(enable_rc6, | |||
80 | "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " | 80 | "For example, 3 would enable rc6 and deep rc6, and 7 would enable everything. " |
81 | "default: -1 (use per-chip default)"); | 81 | "default: -1 (use per-chip default)"); |
82 | 82 | ||
83 | module_param_named(enable_fbc, i915.enable_fbc, int, 0600); | 83 | module_param_named_unsafe(enable_fbc, i915.enable_fbc, int, 0600); |
84 | MODULE_PARM_DESC(enable_fbc, | 84 | MODULE_PARM_DESC(enable_fbc, |
85 | "Enable frame buffer compression for power savings " | 85 | "Enable frame buffer compression for power savings " |
86 | "(default: -1 (use per-chip default))"); | 86 | "(default: -1 (use per-chip default))"); |
@@ -114,7 +114,7 @@ MODULE_PARM_DESC(enable_hangcheck, | |||
114 | "WARNING: Disabling this can cause system wide hangs. " | 114 | "WARNING: Disabling this can cause system wide hangs. " |
115 | "(default: true)"); | 115 | "(default: true)"); |
116 | 116 | ||
117 | module_param_named(enable_ppgtt, i915.enable_ppgtt, int, 0400); | 117 | module_param_named_unsafe(enable_ppgtt, i915.enable_ppgtt, int, 0400); |
118 | MODULE_PARM_DESC(enable_ppgtt, | 118 | MODULE_PARM_DESC(enable_ppgtt, |
119 | "Override PPGTT usage. " | 119 | "Override PPGTT usage. " |
120 | "(-1=auto [default], 0=disabled, 1=aliasing, 2=full)"); | 120 | "(-1=auto [default], 0=disabled, 1=aliasing, 2=full)"); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b65bdfc23ccb..c01e5f31430e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -143,6 +143,14 @@ | |||
143 | #define GAB_CTL 0x24000 | 143 | #define GAB_CTL 0x24000 |
144 | #define GAB_CTL_CONT_AFTER_PAGEFAULT (1<<8) | 144 | #define GAB_CTL_CONT_AFTER_PAGEFAULT (1<<8) |
145 | 145 | ||
146 | #define GEN7_BIOS_RESERVED 0x1082C0 | ||
147 | #define GEN7_BIOS_RESERVED_1M (0 << 5) | ||
148 | #define GEN7_BIOS_RESERVED_256K (1 << 5) | ||
149 | #define GEN8_BIOS_RESERVED_SHIFT 7 | ||
150 | #define GEN7_BIOS_RESERVED_MASK 0x1 | ||
151 | #define GEN8_BIOS_RESERVED_MASK 0x3 | ||
152 | |||
153 | |||
146 | /* VGA stuff */ | 154 | /* VGA stuff */ |
147 | 155 | ||
148 | #define VGA_ST01_MDA 0x3ba | 156 | #define VGA_ST01_MDA 0x3ba |
@@ -2435,6 +2443,7 @@ enum punit_power_well { | |||
2435 | #define _PIPEASRC 0x6001c | 2443 | #define _PIPEASRC 0x6001c |
2436 | #define _BCLRPAT_A 0x60020 | 2444 | #define _BCLRPAT_A 0x60020 |
2437 | #define _VSYNCSHIFT_A 0x60028 | 2445 | #define _VSYNCSHIFT_A 0x60028 |
2446 | #define _PIPE_MULT_A 0x6002c | ||
2438 | 2447 | ||
2439 | /* Pipe B timing regs */ | 2448 | /* Pipe B timing regs */ |
2440 | #define _HTOTAL_B 0x61000 | 2449 | #define _HTOTAL_B 0x61000 |
@@ -2446,6 +2455,7 @@ enum punit_power_well { | |||
2446 | #define _PIPEBSRC 0x6101c | 2455 | #define _PIPEBSRC 0x6101c |
2447 | #define _BCLRPAT_B 0x61020 | 2456 | #define _BCLRPAT_B 0x61020 |
2448 | #define _VSYNCSHIFT_B 0x61028 | 2457 | #define _VSYNCSHIFT_B 0x61028 |
2458 | #define _PIPE_MULT_B 0x6102c | ||
2449 | 2459 | ||
2450 | #define TRANSCODER_A_OFFSET 0x60000 | 2460 | #define TRANSCODER_A_OFFSET 0x60000 |
2451 | #define TRANSCODER_B_OFFSET 0x61000 | 2461 | #define TRANSCODER_B_OFFSET 0x61000 |
@@ -2466,6 +2476,7 @@ enum punit_power_well { | |||
2466 | #define BCLRPAT(trans) _TRANSCODER2(trans, _BCLRPAT_A) | 2476 | #define BCLRPAT(trans) _TRANSCODER2(trans, _BCLRPAT_A) |
2467 | #define VSYNCSHIFT(trans) _TRANSCODER2(trans, _VSYNCSHIFT_A) | 2477 | #define VSYNCSHIFT(trans) _TRANSCODER2(trans, _VSYNCSHIFT_A) |
2468 | #define PIPESRC(trans) _TRANSCODER2(trans, _PIPEASRC) | 2478 | #define PIPESRC(trans) _TRANSCODER2(trans, _PIPEASRC) |
2479 | #define PIPE_MULT(trans) _TRANSCODER2(trans, _PIPE_MULT_A) | ||
2469 | 2480 | ||
2470 | /* HSW+ eDP PSR registers */ | 2481 | /* HSW+ eDP PSR registers */ |
2471 | #define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800) | 2482 | #define EDP_PSR_BASE(dev) (IS_HASWELL(dev) ? 0x64800 : 0x6f800) |
@@ -5577,10 +5588,6 @@ enum punit_power_well { | |||
5577 | #define GEN8_UCGCTL6 0x9430 | 5588 | #define GEN8_UCGCTL6 0x9430 |
5578 | #define GEN8_SDEUNIT_CLOCK_GATE_DISABLE (1<<14) | 5589 | #define GEN8_SDEUNIT_CLOCK_GATE_DISABLE (1<<14) |
5579 | 5590 | ||
5580 | #define TIMESTAMP_CTR 0x44070 | ||
5581 | #define FREQ_1_28_US(us) (((us) * 100) >> 7) | ||
5582 | #define MCHBAR_PCU_C0 (MCHBAR_MIRROR_BASE_SNB + 0x5960) | ||
5583 | |||
5584 | #define GEN6_GFXPAUSE 0xA000 | 5591 | #define GEN6_GFXPAUSE 0xA000 |
5585 | #define GEN6_RPNSWREQ 0xA008 | 5592 | #define GEN6_RPNSWREQ 0xA008 |
5586 | #define GEN6_TURBO_DISABLE (1<<31) | 5593 | #define GEN6_TURBO_DISABLE (1<<31) |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b3e579b4428e..a4bd90f36a03 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -946,7 +946,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, | |||
946 | DRM_DEBUG_KMS("Analog port %c is also DP or TMDS compatible\n", | 946 | DRM_DEBUG_KMS("Analog port %c is also DP or TMDS compatible\n", |
947 | port_name(port)); | 947 | port_name(port)); |
948 | if (is_dvi && (port == PORT_A || port == PORT_E)) | 948 | if (is_dvi && (port == PORT_A || port == PORT_E)) |
949 | DRM_DEBUG_KMS("Port %c is TMDS compabile\n", port_name(port)); | 949 | DRM_DEBUG_KMS("Port %c is TMDS compatible\n", port_name(port)); |
950 | if (!is_dvi && !is_dp && !is_crt) | 950 | if (!is_dvi && !is_dp && !is_crt) |
951 | DRM_DEBUG_KMS("Port %c is not DP/TMDS/CRT compatible\n", | 951 | DRM_DEBUG_KMS("Port %c is not DP/TMDS/CRT compatible\n", |
952 | port_name(port)); | 952 | port_name(port)); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1386086ec245..c9e220963a78 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -73,9 +73,6 @@ static const uint32_t intel_cursor_formats[] = { | |||
73 | DRM_FORMAT_ARGB8888, | 73 | DRM_FORMAT_ARGB8888, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | #define DIV_ROUND_CLOSEST_ULL(ll, d) \ | ||
77 | ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | ||
78 | |||
79 | static void intel_increase_pllclock(struct drm_device *dev, | 76 | static void intel_increase_pllclock(struct drm_device *dev, |
80 | enum pipe pipe); | 77 | enum pipe pipe); |
81 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); | 78 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); |
@@ -1612,6 +1609,18 @@ static void chv_enable_pll(struct intel_crtc *crtc) | |||
1612 | mutex_unlock(&dev_priv->dpio_lock); | 1609 | mutex_unlock(&dev_priv->dpio_lock); |
1613 | } | 1610 | } |
1614 | 1611 | ||
1612 | static int intel_num_dvo_pipes(struct drm_device *dev) | ||
1613 | { | ||
1614 | struct intel_crtc *crtc; | ||
1615 | int count = 0; | ||
1616 | |||
1617 | for_each_intel_crtc(dev, crtc) | ||
1618 | count += crtc->active && | ||
1619 | intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO); | ||
1620 | |||
1621 | return count; | ||
1622 | } | ||
1623 | |||
1615 | static void i9xx_enable_pll(struct intel_crtc *crtc) | 1624 | static void i9xx_enable_pll(struct intel_crtc *crtc) |
1616 | { | 1625 | { |
1617 | struct drm_device *dev = crtc->base.dev; | 1626 | struct drm_device *dev = crtc->base.dev; |
@@ -1628,7 +1637,18 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) | |||
1628 | if (IS_MOBILE(dev) && !IS_I830(dev)) | 1637 | if (IS_MOBILE(dev) && !IS_I830(dev)) |
1629 | assert_panel_unlocked(dev_priv, crtc->pipe); | 1638 | assert_panel_unlocked(dev_priv, crtc->pipe); |
1630 | 1639 | ||
1631 | I915_WRITE(reg, dpll); | 1640 | /* Enable DVO 2x clock on both PLLs if necessary */ |
1641 | if (IS_I830(dev) && intel_num_dvo_pipes(dev) > 0) { | ||
1642 | /* | ||
1643 | * It appears to be important that we don't enable this | ||
1644 | * for the current pipe before otherwise configuring the | ||
1645 | * PLL. No idea how this should be handled if multiple | ||
1646 | * DVO outputs are enabled simultaneosly. | ||
1647 | */ | ||
1648 | dpll |= DPLL_DVO_2X_MODE; | ||
1649 | I915_WRITE(DPLL(!crtc->pipe), | ||
1650 | I915_READ(DPLL(!crtc->pipe)) | DPLL_DVO_2X_MODE); | ||
1651 | } | ||
1632 | 1652 | ||
1633 | /* Wait for the clocks to stabilize. */ | 1653 | /* Wait for the clocks to stabilize. */ |
1634 | POSTING_READ(reg); | 1654 | POSTING_READ(reg); |
@@ -1667,8 +1687,22 @@ static void i9xx_enable_pll(struct intel_crtc *crtc) | |||
1667 | * | 1687 | * |
1668 | * Note! This is for pre-ILK only. | 1688 | * Note! This is for pre-ILK only. |
1669 | */ | 1689 | */ |
1670 | static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) | 1690 | static void i9xx_disable_pll(struct intel_crtc *crtc) |
1671 | { | 1691 | { |
1692 | struct drm_device *dev = crtc->base.dev; | ||
1693 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1694 | enum pipe pipe = crtc->pipe; | ||
1695 | |||
1696 | /* Disable DVO 2x clock on both PLLs if necessary */ | ||
1697 | if (IS_I830(dev) && | ||
1698 | intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO) && | ||
1699 | intel_num_dvo_pipes(dev) == 1) { | ||
1700 | I915_WRITE(DPLL(PIPE_B), | ||
1701 | I915_READ(DPLL(PIPE_B)) & ~DPLL_DVO_2X_MODE); | ||
1702 | I915_WRITE(DPLL(PIPE_A), | ||
1703 | I915_READ(DPLL(PIPE_A)) & ~DPLL_DVO_2X_MODE); | ||
1704 | } | ||
1705 | |||
1672 | /* Don't disable pipe or pipe PLLs if needed */ | 1706 | /* Don't disable pipe or pipe PLLs if needed */ |
1673 | if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || | 1707 | if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) || |
1674 | (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) | 1708 | (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)) |
@@ -4185,6 +4219,11 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) | |||
4185 | 4219 | ||
4186 | intel_set_pipe_timings(intel_crtc); | 4220 | intel_set_pipe_timings(intel_crtc); |
4187 | 4221 | ||
4222 | if (intel_crtc->config.cpu_transcoder != TRANSCODER_EDP) { | ||
4223 | I915_WRITE(PIPE_MULT(intel_crtc->config.cpu_transcoder), | ||
4224 | intel_crtc->config.pixel_multiplier - 1); | ||
4225 | } | ||
4226 | |||
4188 | if (intel_crtc->config.has_pch_encoder) { | 4227 | if (intel_crtc->config.has_pch_encoder) { |
4189 | intel_cpu_transcoder_set_m_n(intel_crtc, | 4228 | intel_cpu_transcoder_set_m_n(intel_crtc, |
4190 | &intel_crtc->config.fdi_m_n, NULL); | 4229 | &intel_crtc->config.fdi_m_n, NULL); |
@@ -4941,7 +4980,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) | |||
4941 | else if (IS_VALLEYVIEW(dev)) | 4980 | else if (IS_VALLEYVIEW(dev)) |
4942 | vlv_disable_pll(dev_priv, pipe); | 4981 | vlv_disable_pll(dev_priv, pipe); |
4943 | else | 4982 | else |
4944 | i9xx_disable_pll(dev_priv, pipe); | 4983 | i9xx_disable_pll(intel_crtc); |
4945 | } | 4984 | } |
4946 | 4985 | ||
4947 | if (!IS_GEN2(dev)) | 4986 | if (!IS_GEN2(dev)) |
@@ -5945,7 +5984,7 @@ static void i8xx_update_pll(struct intel_crtc *crtc, | |||
5945 | dpll |= PLL_P2_DIVIDE_BY_4; | 5984 | dpll |= PLL_P2_DIVIDE_BY_4; |
5946 | } | 5985 | } |
5947 | 5986 | ||
5948 | if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO)) | 5987 | if (!IS_I830(dev) && intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DVO)) |
5949 | dpll |= DPLL_DVO_2X_MODE; | 5988 | dpll |= DPLL_DVO_2X_MODE; |
5950 | 5989 | ||
5951 | if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && | 5990 | if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) && |
@@ -6451,6 +6490,14 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, | |||
6451 | } | 6490 | } |
6452 | pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(crtc->pipe)); | 6491 | pipe_config->dpll_hw_state.dpll = I915_READ(DPLL(crtc->pipe)); |
6453 | if (!IS_VALLEYVIEW(dev)) { | 6492 | if (!IS_VALLEYVIEW(dev)) { |
6493 | /* | ||
6494 | * DPLL_DVO_2X_MODE must be enabled for both DPLLs | ||
6495 | * on 830. Filter it out here so that we don't | ||
6496 | * report errors due to that. | ||
6497 | */ | ||
6498 | if (IS_I830(dev)) | ||
6499 | pipe_config->dpll_hw_state.dpll &= ~DPLL_DVO_2X_MODE; | ||
6500 | |||
6454 | pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(crtc->pipe)); | 6501 | pipe_config->dpll_hw_state.fp0 = I915_READ(FP0(crtc->pipe)); |
6455 | pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(crtc->pipe)); | 6502 | pipe_config->dpll_hw_state.fp1 = I915_READ(FP1(crtc->pipe)); |
6456 | } else { | 6503 | } else { |
@@ -7845,7 +7892,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc, | |||
7845 | pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && | 7892 | pipe_config->ips_enabled = hsw_crtc_supports_ips(crtc) && |
7846 | (I915_READ(IPS_CTL) & IPS_ENABLE); | 7893 | (I915_READ(IPS_CTL) & IPS_ENABLE); |
7847 | 7894 | ||
7848 | pipe_config->pixel_multiplier = 1; | 7895 | if (pipe_config->cpu_transcoder != TRANSCODER_EDP) { |
7896 | pipe_config->pixel_multiplier = | ||
7897 | I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1; | ||
7898 | } else { | ||
7899 | pipe_config->pixel_multiplier = 1; | ||
7900 | } | ||
7849 | 7901 | ||
7850 | return true; | 7902 | return true; |
7851 | } | 7903 | } |
@@ -9881,9 +9933,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
9881 | unsigned long flags; | 9933 | unsigned long flags; |
9882 | int ret; | 9934 | int ret; |
9883 | 9935 | ||
9884 | //trigger software GT busyness calculation | ||
9885 | gen8_flip_interrupt(dev); | ||
9886 | |||
9887 | /* | 9936 | /* |
9888 | * drm_mode_page_flip_ioctl() should already catch this, but double | 9937 | * drm_mode_page_flip_ioctl() should already catch this, but double |
9889 | * check to be safe. In the future we may enable pageflipping from | 9938 | * check to be safe. In the future we may enable pageflipping from |
@@ -10039,8 +10088,11 @@ free_work: | |||
10039 | out_hang: | 10088 | out_hang: |
10040 | intel_crtc_wait_for_pending_flips(crtc); | 10089 | intel_crtc_wait_for_pending_flips(crtc); |
10041 | ret = intel_pipe_set_base(crtc, crtc->x, crtc->y, fb); | 10090 | ret = intel_pipe_set_base(crtc, crtc->x, crtc->y, fb); |
10042 | if (ret == 0 && event) | 10091 | if (ret == 0 && event) { |
10092 | spin_lock_irqsave(&dev->event_lock, flags); | ||
10043 | drm_send_vblank_event(dev, pipe, event); | 10093 | drm_send_vblank_event(dev, pipe, event); |
10094 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
10095 | } | ||
10044 | } | 10096 | } |
10045 | return ret; | 10097 | return ret; |
10046 | } | 10098 | } |
@@ -12302,27 +12354,36 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
12302 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | 12354 | if (I915_READ(PCH_DP_D) & DP_DETECTED) |
12303 | intel_dp_init(dev, PCH_DP_D, PORT_D); | 12355 | intel_dp_init(dev, PCH_DP_D, PORT_D); |
12304 | } else if (IS_VALLEYVIEW(dev)) { | 12356 | } else if (IS_VALLEYVIEW(dev)) { |
12305 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) { | 12357 | /* |
12358 | * The DP_DETECTED bit is the latched state of the DDC | ||
12359 | * SDA pin at boot. However since eDP doesn't require DDC | ||
12360 | * (no way to plug in a DP->HDMI dongle) the DDC pins for | ||
12361 | * eDP ports may have been muxed to an alternate function. | ||
12362 | * Thus we can't rely on the DP_DETECTED bit alone to detect | ||
12363 | * eDP ports. Consult the VBT as well as DP_DETECTED to | ||
12364 | * detect eDP ports. | ||
12365 | */ | ||
12366 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIB) & SDVO_DETECTED) | ||
12306 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, | 12367 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIB, |
12307 | PORT_B); | 12368 | PORT_B); |
12308 | if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED) | 12369 | if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED || |
12309 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); | 12370 | intel_dp_is_edp(dev, PORT_B)) |
12310 | } | 12371 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B); |
12311 | 12372 | ||
12312 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) { | 12373 | if (I915_READ(VLV_DISPLAY_BASE + GEN4_HDMIC) & SDVO_DETECTED) |
12313 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, | 12374 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + GEN4_HDMIC, |
12314 | PORT_C); | 12375 | PORT_C); |
12315 | if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED) | 12376 | if (I915_READ(VLV_DISPLAY_BASE + DP_C) & DP_DETECTED || |
12316 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); | 12377 | intel_dp_is_edp(dev, PORT_C)) |
12317 | } | 12378 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_C, PORT_C); |
12318 | 12379 | ||
12319 | if (IS_CHERRYVIEW(dev)) { | 12380 | if (IS_CHERRYVIEW(dev)) { |
12320 | if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) { | 12381 | if (I915_READ(VLV_DISPLAY_BASE + CHV_HDMID) & SDVO_DETECTED) |
12321 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID, | 12382 | intel_hdmi_init(dev, VLV_DISPLAY_BASE + CHV_HDMID, |
12322 | PORT_D); | 12383 | PORT_D); |
12323 | if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED) | 12384 | /* eDP not supported on port D, so don't check VBT */ |
12324 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D); | 12385 | if (I915_READ(VLV_DISPLAY_BASE + DP_D) & DP_DETECTED) |
12325 | } | 12386 | intel_dp_init(dev, VLV_DISPLAY_BASE + DP_D, PORT_D); |
12326 | } | 12387 | } |
12327 | 12388 | ||
12328 | intel_dsi_init(dev); | 12389 | intel_dsi_init(dev); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2a26774ddb68..f6a3fdd5589e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1068,23 +1068,15 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
1068 | bpp = dev_priv->vbt.edp_bpp; | 1068 | bpp = dev_priv->vbt.edp_bpp; |
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | if (IS_BROADWELL(dev)) { | 1071 | /* |
1072 | /* Yes, it's an ugly hack. */ | 1072 | * Use the maximum clock and number of lanes the eDP panel |
1073 | min_lane_count = max_lane_count; | 1073 | * advertizes being capable of. The panels are generally |
1074 | DRM_DEBUG_KMS("forcing lane count to max (%u) on BDW\n", | 1074 | * designed to support only a single clock and lane |
1075 | min_lane_count); | 1075 | * configuration, and typically these values correspond to the |
1076 | } else if (dev_priv->vbt.edp_lanes) { | 1076 | * native resolution of the panel. |
1077 | min_lane_count = min(dev_priv->vbt.edp_lanes, | 1077 | */ |
1078 | max_lane_count); | 1078 | min_lane_count = max_lane_count; |
1079 | DRM_DEBUG_KMS("using min %u lanes per VBT\n", | 1079 | min_clock = max_clock; |
1080 | min_lane_count); | ||
1081 | } | ||
1082 | |||
1083 | if (dev_priv->vbt.edp_rate) { | ||
1084 | min_clock = min(dev_priv->vbt.edp_rate >> 3, max_clock); | ||
1085 | DRM_DEBUG_KMS("using min %02x link bw per VBT\n", | ||
1086 | bws[min_clock]); | ||
1087 | } | ||
1088 | } | 1080 | } |
1089 | 1081 | ||
1090 | for (; bpp >= 6*3; bpp -= 2*3) { | 1082 | for (; bpp >= 6*3; bpp -= 2*3) { |
@@ -1915,6 +1907,10 @@ static void intel_dp_get_config(struct intel_encoder *encoder, | |||
1915 | 1907 | ||
1916 | pipe_config->adjusted_mode.flags |= flags; | 1908 | pipe_config->adjusted_mode.flags |= flags; |
1917 | 1909 | ||
1910 | if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) && | ||
1911 | tmp & DP_COLOR_RANGE_16_235) | ||
1912 | pipe_config->limited_color_range = true; | ||
1913 | |||
1918 | pipe_config->has_dp_encoder = true; | 1914 | pipe_config->has_dp_encoder = true; |
1919 | 1915 | ||
1920 | intel_dp_get_m_n(crtc, pipe_config); | 1916 | intel_dp_get_m_n(crtc, pipe_config); |
@@ -3732,7 +3728,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) | |||
3732 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && | 3728 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && |
3733 | intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { | 3729 | intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { |
3734 | intel_dp->use_tps3 = true; | 3730 | intel_dp->use_tps3 = true; |
3735 | DRM_DEBUG_KMS("Displayport TPS3 supported"); | 3731 | DRM_DEBUG_KMS("Displayport TPS3 supported\n"); |
3736 | } else | 3732 | } else |
3737 | intel_dp->use_tps3 = false; | 3733 | intel_dp->use_tps3 = false; |
3738 | 3734 | ||
@@ -3808,21 +3804,21 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) | |||
3808 | u8 buf[1]; | 3804 | u8 buf[1]; |
3809 | 3805 | ||
3810 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, buf) < 0) | 3806 | if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, buf) < 0) |
3811 | return -EAGAIN; | 3807 | return -EIO; |
3812 | 3808 | ||
3813 | if (!(buf[0] & DP_TEST_CRC_SUPPORTED)) | 3809 | if (!(buf[0] & DP_TEST_CRC_SUPPORTED)) |
3814 | return -ENOTTY; | 3810 | return -ENOTTY; |
3815 | 3811 | ||
3816 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, | 3812 | if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, |
3817 | DP_TEST_SINK_START) < 0) | 3813 | DP_TEST_SINK_START) < 0) |
3818 | return -EAGAIN; | 3814 | return -EIO; |
3819 | 3815 | ||
3820 | /* Wait 2 vblanks to be sure we will have the correct CRC value */ | 3816 | /* Wait 2 vblanks to be sure we will have the correct CRC value */ |
3821 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 3817 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
3822 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 3818 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
3823 | 3819 | ||
3824 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) | 3820 | if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) |
3825 | return -EAGAIN; | 3821 | return -EIO; |
3826 | 3822 | ||
3827 | drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, 0); | 3823 | drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, 0); |
3828 | return 0; | 3824 | return 0; |
@@ -4395,7 +4391,7 @@ intel_dp_connector_destroy(struct drm_connector *connector) | |||
4395 | { | 4391 | { |
4396 | struct intel_connector *intel_connector = to_intel_connector(connector); | 4392 | struct intel_connector *intel_connector = to_intel_connector(connector); |
4397 | 4393 | ||
4398 | intel_dp_unset_edid(intel_attached_dp(connector)); | 4394 | kfree(intel_connector->detect_edid); |
4399 | 4395 | ||
4400 | if (!IS_ERR_OR_NULL(intel_connector->edid)) | 4396 | if (!IS_ERR_OR_NULL(intel_connector->edid)) |
4401 | kfree(intel_connector->edid); | 4397 | kfree(intel_connector->edid); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 07ce04683c30..ba715229a540 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -35,6 +35,9 @@ | |||
35 | #include <drm/drm_fb_helper.h> | 35 | #include <drm/drm_fb_helper.h> |
36 | #include <drm/drm_dp_mst_helper.h> | 36 | #include <drm/drm_dp_mst_helper.h> |
37 | 37 | ||
38 | #define DIV_ROUND_CLOSEST_ULL(ll, d) \ | ||
39 | ({ unsigned long long _tmp = (ll)+(d)/2; do_div(_tmp, d); _tmp; }) | ||
40 | |||
38 | /** | 41 | /** |
39 | * _wait_for - magic (register) wait macro | 42 | * _wait_for - magic (register) wait macro |
40 | * | 43 | * |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index c5861736b4b0..29ec1535992d 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -712,7 +712,8 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, | |||
712 | struct intel_crtc_config *pipe_config) | 712 | struct intel_crtc_config *pipe_config) |
713 | { | 713 | { |
714 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | 714 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
715 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 715 | struct drm_device *dev = encoder->base.dev; |
716 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
716 | u32 tmp, flags = 0; | 717 | u32 tmp, flags = 0; |
717 | int dotclock; | 718 | int dotclock; |
718 | 719 | ||
@@ -731,9 +732,13 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder, | |||
731 | if (tmp & HDMI_MODE_SELECT_HDMI) | 732 | if (tmp & HDMI_MODE_SELECT_HDMI) |
732 | pipe_config->has_hdmi_sink = true; | 733 | pipe_config->has_hdmi_sink = true; |
733 | 734 | ||
734 | if (tmp & HDMI_MODE_SELECT_HDMI) | 735 | if (tmp & SDVO_AUDIO_ENABLE) |
735 | pipe_config->has_audio = true; | 736 | pipe_config->has_audio = true; |
736 | 737 | ||
738 | if (!HAS_PCH_SPLIT(dev) && | ||
739 | tmp & HDMI_COLOR_RANGE_16_235) | ||
740 | pipe_config->limited_color_range = true; | ||
741 | |||
737 | pipe_config->adjusted_mode.flags |= flags; | 742 | pipe_config->adjusted_mode.flags |= flags; |
738 | 743 | ||
739 | if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc) | 744 | if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc) |
@@ -1501,7 +1506,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) | |||
1501 | 1506 | ||
1502 | static void intel_hdmi_destroy(struct drm_connector *connector) | 1507 | static void intel_hdmi_destroy(struct drm_connector *connector) |
1503 | { | 1508 | { |
1504 | intel_hdmi_unset_edid(connector); | 1509 | kfree(to_intel_connector(connector)->detect_edid); |
1505 | drm_connector_cleanup(connector); | 1510 | drm_connector_cleanup(connector); |
1506 | kfree(connector); | 1511 | kfree(connector); |
1507 | } | 1512 | } |
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index bd1b28d99920..bafd38b5703e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c | |||
@@ -300,8 +300,18 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, | |||
300 | * Instead, we do the runtime_pm_get/put when creating/destroying requests. | 300 | * Instead, we do the runtime_pm_get/put when creating/destroying requests. |
301 | */ | 301 | */ |
302 | spin_lock_irqsave(&dev_priv->uncore.lock, flags); | 302 | spin_lock_irqsave(&dev_priv->uncore.lock, flags); |
303 | if (dev_priv->uncore.forcewake_count++ == 0) | 303 | if (IS_CHERRYVIEW(dev_priv->dev)) { |
304 | dev_priv->uncore.funcs.force_wake_get(dev_priv, FORCEWAKE_ALL); | 304 | if (dev_priv->uncore.fw_rendercount++ == 0) |
305 | dev_priv->uncore.funcs.force_wake_get(dev_priv, | ||
306 | FORCEWAKE_RENDER); | ||
307 | if (dev_priv->uncore.fw_mediacount++ == 0) | ||
308 | dev_priv->uncore.funcs.force_wake_get(dev_priv, | ||
309 | FORCEWAKE_MEDIA); | ||
310 | } else { | ||
311 | if (dev_priv->uncore.forcewake_count++ == 0) | ||
312 | dev_priv->uncore.funcs.force_wake_get(dev_priv, | ||
313 | FORCEWAKE_ALL); | ||
314 | } | ||
305 | spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); | 315 | spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); |
306 | 316 | ||
307 | I915_WRITE(RING_ELSP(ring), desc[1]); | 317 | I915_WRITE(RING_ELSP(ring), desc[1]); |
@@ -315,8 +325,19 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, | |||
315 | 325 | ||
316 | /* Release Force Wakeup (see the big comment above). */ | 326 | /* Release Force Wakeup (see the big comment above). */ |
317 | spin_lock_irqsave(&dev_priv->uncore.lock, flags); | 327 | spin_lock_irqsave(&dev_priv->uncore.lock, flags); |
318 | if (--dev_priv->uncore.forcewake_count == 0) | 328 | if (IS_CHERRYVIEW(dev_priv->dev)) { |
319 | dev_priv->uncore.funcs.force_wake_put(dev_priv, FORCEWAKE_ALL); | 329 | if (--dev_priv->uncore.fw_rendercount == 0) |
330 | dev_priv->uncore.funcs.force_wake_put(dev_priv, | ||
331 | FORCEWAKE_RENDER); | ||
332 | if (--dev_priv->uncore.fw_mediacount == 0) | ||
333 | dev_priv->uncore.funcs.force_wake_put(dev_priv, | ||
334 | FORCEWAKE_MEDIA); | ||
335 | } else { | ||
336 | if (--dev_priv->uncore.forcewake_count == 0) | ||
337 | dev_priv->uncore.funcs.force_wake_put(dev_priv, | ||
338 | FORCEWAKE_ALL); | ||
339 | } | ||
340 | |||
320 | spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); | 341 | spin_unlock_irqrestore(&dev_priv->uncore.lock, flags); |
321 | } | 342 | } |
322 | 343 | ||
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index ca52ad2ae7d1..d8de1d5140a7 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
@@ -396,6 +396,16 @@ int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state) | |||
396 | return -EINVAL; | 396 | return -EINVAL; |
397 | } | 397 | } |
398 | 398 | ||
399 | /* | ||
400 | * If the vendor backlight interface is not in use and ACPI backlight interface | ||
401 | * is broken, do not bother processing backlight change requests from firmware. | ||
402 | */ | ||
403 | static bool should_ignore_backlight_request(void) | ||
404 | { | ||
405 | return acpi_video_backlight_support() && | ||
406 | !acpi_video_verify_backlight_support(); | ||
407 | } | ||
408 | |||
399 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 409 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
400 | { | 410 | { |
401 | struct drm_i915_private *dev_priv = dev->dev_private; | 411 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -404,11 +414,7 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | |||
404 | 414 | ||
405 | DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); | 415 | DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); |
406 | 416 | ||
407 | /* | 417 | if (should_ignore_backlight_request()) { |
408 | * If the acpi_video interface is not supposed to be used, don't | ||
409 | * bother processing backlight level change requests from firmware. | ||
410 | */ | ||
411 | if (!acpi_video_verify_backlight_support()) { | ||
412 | DRM_DEBUG_KMS("opregion backlight request ignored\n"); | 418 | DRM_DEBUG_KMS("opregion backlight request ignored\n"); |
413 | return 0; | 419 | return 0; |
414 | } | 420 | } |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 18784470a760..0e018cb49147 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -419,9 +419,8 @@ static uint32_t scale(uint32_t source_val, | |||
419 | source_val = clamp(source_val, source_min, source_max); | 419 | source_val = clamp(source_val, source_min, source_max); |
420 | 420 | ||
421 | /* avoid overflows */ | 421 | /* avoid overflows */ |
422 | target_val = (uint64_t)(source_val - source_min) * | 422 | target_val = DIV_ROUND_CLOSEST_ULL((uint64_t)(source_val - source_min) * |
423 | (target_max - target_min); | 423 | (target_max - target_min), source_max - source_min); |
424 | do_div(target_val, source_max - source_min); | ||
425 | target_val += target_min; | 424 | target_val += target_min; |
426 | 425 | ||
427 | return target_val; | 426 | return target_val; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 45f71e6dc544..c27b6140bfd1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -1070,6 +1070,17 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz, | |||
1070 | wm_size = wm->max_wm; | 1070 | wm_size = wm->max_wm; |
1071 | if (wm_size <= 0) | 1071 | if (wm_size <= 0) |
1072 | wm_size = wm->default_wm; | 1072 | wm_size = wm->default_wm; |
1073 | |||
1074 | /* | ||
1075 | * Bspec seems to indicate that the value shouldn't be lower than | ||
1076 | * 'burst size + 1'. Certainly 830 is quite unhappy with low values. | ||
1077 | * Lets go for 8 which is the burst size since certain platforms | ||
1078 | * already use a hardcoded 8 (which is what the spec says should be | ||
1079 | * done). | ||
1080 | */ | ||
1081 | if (wm_size <= 8) | ||
1082 | wm_size = 8; | ||
1083 | |||
1073 | return wm_size; | 1084 | return wm_size; |
1074 | } | 1085 | } |
1075 | 1086 | ||
@@ -2274,6 +2285,7 @@ int ilk_wm_max_level(const struct drm_device *dev) | |||
2274 | else | 2285 | else |
2275 | return 2; | 2286 | return 2; |
2276 | } | 2287 | } |
2288 | |||
2277 | static void intel_print_wm_latency(struct drm_device *dev, | 2289 | static void intel_print_wm_latency(struct drm_device *dev, |
2278 | const char *name, | 2290 | const char *name, |
2279 | const uint16_t wm[5]) | 2291 | const uint16_t wm[5]) |
@@ -3242,9 +3254,6 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val) | |||
3242 | { | 3254 | { |
3243 | int new_power; | 3255 | int new_power; |
3244 | 3256 | ||
3245 | if (dev_priv->rps.is_bdw_sw_turbo) | ||
3246 | return; | ||
3247 | |||
3248 | new_power = dev_priv->rps.power; | 3257 | new_power = dev_priv->rps.power; |
3249 | switch (dev_priv->rps.power) { | 3258 | switch (dev_priv->rps.power) { |
3250 | case LOW_POWER: | 3259 | case LOW_POWER: |
@@ -3452,11 +3461,8 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv) | |||
3452 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); | 3461 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
3453 | else if (IS_VALLEYVIEW(dev)) | 3462 | else if (IS_VALLEYVIEW(dev)) |
3454 | vlv_set_rps_idle(dev_priv); | 3463 | vlv_set_rps_idle(dev_priv); |
3455 | else if (!dev_priv->rps.is_bdw_sw_turbo | 3464 | else |
3456 | || atomic_read(&dev_priv->rps.sw_turbo.flip_received)){ | ||
3457 | gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); | 3465 | gen6_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit); |
3458 | } | ||
3459 | |||
3460 | dev_priv->rps.last_adj = 0; | 3466 | dev_priv->rps.last_adj = 0; |
3461 | } | 3467 | } |
3462 | mutex_unlock(&dev_priv->rps.hw_lock); | 3468 | mutex_unlock(&dev_priv->rps.hw_lock); |
@@ -3470,11 +3476,8 @@ void gen6_rps_boost(struct drm_i915_private *dev_priv) | |||
3470 | if (dev_priv->rps.enabled) { | 3476 | if (dev_priv->rps.enabled) { |
3471 | if (IS_VALLEYVIEW(dev)) | 3477 | if (IS_VALLEYVIEW(dev)) |
3472 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); | 3478 | valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); |
3473 | else if (!dev_priv->rps.is_bdw_sw_turbo | 3479 | else |
3474 | || atomic_read(&dev_priv->rps.sw_turbo.flip_received)){ | ||
3475 | gen6_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); | 3480 | gen6_set_rps(dev_priv->dev, dev_priv->rps.max_freq_softlimit); |
3476 | } | ||
3477 | |||
3478 | dev_priv->rps.last_adj = 0; | 3481 | dev_priv->rps.last_adj = 0; |
3479 | } | 3482 | } |
3480 | mutex_unlock(&dev_priv->rps.hw_lock); | 3483 | mutex_unlock(&dev_priv->rps.hw_lock); |
@@ -3488,17 +3491,18 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) | |||
3488 | WARN_ON(val > dev_priv->rps.max_freq_softlimit); | 3491 | WARN_ON(val > dev_priv->rps.max_freq_softlimit); |
3489 | WARN_ON(val < dev_priv->rps.min_freq_softlimit); | 3492 | WARN_ON(val < dev_priv->rps.min_freq_softlimit); |
3490 | 3493 | ||
3491 | DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", | ||
3492 | vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), | ||
3493 | dev_priv->rps.cur_freq, | ||
3494 | vlv_gpu_freq(dev_priv, val), val); | ||
3495 | |||
3496 | if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), | 3494 | if (WARN_ONCE(IS_CHERRYVIEW(dev) && (val & 1), |
3497 | "Odd GPU freq value\n")) | 3495 | "Odd GPU freq value\n")) |
3498 | val &= ~1; | 3496 | val &= ~1; |
3499 | 3497 | ||
3500 | if (val != dev_priv->rps.cur_freq) | 3498 | if (val != dev_priv->rps.cur_freq) { |
3499 | DRM_DEBUG_DRIVER("GPU freq request from %d MHz (%u) to %d MHz (%u)\n", | ||
3500 | vlv_gpu_freq(dev_priv, dev_priv->rps.cur_freq), | ||
3501 | dev_priv->rps.cur_freq, | ||
3502 | vlv_gpu_freq(dev_priv, val), val); | ||
3503 | |||
3501 | vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); | 3504 | vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ, val); |
3505 | } | ||
3502 | 3506 | ||
3503 | I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); | 3507 | I915_WRITE(GEN6_PMINTRMSK, gen6_rps_pm_mask(dev_priv, val)); |
3504 | 3508 | ||
@@ -3509,26 +3513,21 @@ void valleyview_set_rps(struct drm_device *dev, u8 val) | |||
3509 | static void gen8_disable_rps_interrupts(struct drm_device *dev) | 3513 | static void gen8_disable_rps_interrupts(struct drm_device *dev) |
3510 | { | 3514 | { |
3511 | struct drm_i915_private *dev_priv = dev->dev_private; | 3515 | struct drm_i915_private *dev_priv = dev->dev_private; |
3512 | if (IS_BROADWELL(dev) && dev_priv->rps.is_bdw_sw_turbo){ | ||
3513 | if (atomic_read(&dev_priv->rps.sw_turbo.flip_received)) | ||
3514 | del_timer(&dev_priv->rps.sw_turbo.flip_timer); | ||
3515 | dev_priv-> rps.is_bdw_sw_turbo = false; | ||
3516 | } else { | ||
3517 | I915_WRITE(GEN6_PMINTRMSK, ~GEN8_PMINTR_REDIRECT_TO_NON_DISP); | ||
3518 | I915_WRITE(GEN8_GT_IER(2), I915_READ(GEN8_GT_IER(2)) & | ||
3519 | ~dev_priv->pm_rps_events); | ||
3520 | /* Complete PM interrupt masking here doesn't race with the rps work | ||
3521 | * item again unmasking PM interrupts because that is using a different | ||
3522 | * register (GEN8_GT_IMR(2)) to mask PM interrupts. The only risk is in | ||
3523 | * leaving stale bits in GEN8_GT_IIR(2) and GEN8_GT_IMR(2) which | ||
3524 | * gen8_enable_rps will clean up. */ | ||
3525 | 3516 | ||
3526 | spin_lock_irq(&dev_priv->irq_lock); | 3517 | I915_WRITE(GEN6_PMINTRMSK, ~GEN8_PMINTR_REDIRECT_TO_NON_DISP); |
3527 | dev_priv->rps.pm_iir = 0; | 3518 | I915_WRITE(GEN8_GT_IER(2), I915_READ(GEN8_GT_IER(2)) & |
3528 | spin_unlock_irq(&dev_priv->irq_lock); | 3519 | ~dev_priv->pm_rps_events); |
3520 | /* Complete PM interrupt masking here doesn't race with the rps work | ||
3521 | * item again unmasking PM interrupts because that is using a different | ||
3522 | * register (GEN8_GT_IMR(2)) to mask PM interrupts. The only risk is in | ||
3523 | * leaving stale bits in GEN8_GT_IIR(2) and GEN8_GT_IMR(2) which | ||
3524 | * gen8_enable_rps will clean up. */ | ||
3525 | |||
3526 | spin_lock_irq(&dev_priv->irq_lock); | ||
3527 | dev_priv->rps.pm_iir = 0; | ||
3528 | spin_unlock_irq(&dev_priv->irq_lock); | ||
3529 | 3529 | ||
3530 | I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); | 3530 | I915_WRITE(GEN8_GT_IIR(2), dev_priv->pm_rps_events); |
3531 | } | ||
3532 | } | 3531 | } |
3533 | 3532 | ||
3534 | static void gen6_disable_rps_interrupts(struct drm_device *dev) | 3533 | static void gen6_disable_rps_interrupts(struct drm_device *dev) |
@@ -3686,111 +3685,13 @@ static void parse_rp_state_cap(struct drm_i915_private *dev_priv, u32 rp_state_c | |||
3686 | dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; | 3685 | dev_priv->rps.min_freq_softlimit = dev_priv->rps.min_freq; |
3687 | } | 3686 | } |
3688 | 3687 | ||
3689 | static void bdw_sw_calculate_freq(struct drm_device *dev, | ||
3690 | struct intel_rps_bdw_cal *c, u32 *cur_time, u32 *c0) | ||
3691 | { | ||
3692 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3693 | u64 busy = 0; | ||
3694 | u32 busyness_pct = 0; | ||
3695 | u32 elapsed_time = 0; | ||
3696 | u16 new_freq = 0; | ||
3697 | |||
3698 | if (!c || !cur_time || !c0) | ||
3699 | return; | ||
3700 | |||
3701 | if (0 == c->last_c0) | ||
3702 | goto out; | ||
3703 | |||
3704 | /* Check Evaluation interval */ | ||
3705 | elapsed_time = *cur_time - c->last_ts; | ||
3706 | if (elapsed_time < c->eval_interval) | ||
3707 | return; | ||
3708 | |||
3709 | mutex_lock(&dev_priv->rps.hw_lock); | ||
3710 | |||
3711 | /* | ||
3712 | * c0 unit in 32*1.28 usec, elapsed_time unit in 1 usec. | ||
3713 | * Whole busyness_pct calculation should be | ||
3714 | * busy = ((u64)(*c0 - c->last_c0) << 5 << 7) / 100; | ||
3715 | * busyness_pct = (u32)(busy * 100 / elapsed_time); | ||
3716 | * The final formula is to simplify CPU calculation | ||
3717 | */ | ||
3718 | busy = (u64)(*c0 - c->last_c0) << 12; | ||
3719 | do_div(busy, elapsed_time); | ||
3720 | busyness_pct = (u32)busy; | ||
3721 | |||
3722 | if (c->is_up && busyness_pct >= c->it_threshold_pct) | ||
3723 | new_freq = (u16)dev_priv->rps.cur_freq + 3; | ||
3724 | if (!c->is_up && busyness_pct <= c->it_threshold_pct) | ||
3725 | new_freq = (u16)dev_priv->rps.cur_freq - 1; | ||
3726 | |||
3727 | /* Adjust to new frequency busyness and compare with threshold */ | ||
3728 | if (0 != new_freq) { | ||
3729 | if (new_freq > dev_priv->rps.max_freq_softlimit) | ||
3730 | new_freq = dev_priv->rps.max_freq_softlimit; | ||
3731 | else if (new_freq < dev_priv->rps.min_freq_softlimit) | ||
3732 | new_freq = dev_priv->rps.min_freq_softlimit; | ||
3733 | |||
3734 | gen6_set_rps(dev, new_freq); | ||
3735 | } | ||
3736 | |||
3737 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
3738 | |||
3739 | out: | ||
3740 | c->last_c0 = *c0; | ||
3741 | c->last_ts = *cur_time; | ||
3742 | } | ||
3743 | |||
3744 | static void gen8_set_frequency_RP0(struct work_struct *work) | ||
3745 | { | ||
3746 | struct intel_rps_bdw_turbo *p_bdw_turbo = | ||
3747 | container_of(work, struct intel_rps_bdw_turbo, work_max_freq); | ||
3748 | struct intel_gen6_power_mgmt *p_power_mgmt = | ||
3749 | container_of(p_bdw_turbo, struct intel_gen6_power_mgmt, sw_turbo); | ||
3750 | struct drm_i915_private *dev_priv = | ||
3751 | container_of(p_power_mgmt, struct drm_i915_private, rps); | ||
3752 | |||
3753 | mutex_lock(&dev_priv->rps.hw_lock); | ||
3754 | gen6_set_rps(dev_priv->dev, dev_priv->rps.rp0_freq); | ||
3755 | mutex_unlock(&dev_priv->rps.hw_lock); | ||
3756 | } | ||
3757 | |||
3758 | static void flip_active_timeout_handler(unsigned long var) | ||
3759 | { | ||
3760 | struct drm_i915_private *dev_priv = (struct drm_i915_private *) var; | ||
3761 | |||
3762 | del_timer(&dev_priv->rps.sw_turbo.flip_timer); | ||
3763 | atomic_set(&dev_priv->rps.sw_turbo.flip_received, false); | ||
3764 | |||
3765 | queue_work(dev_priv->wq, &dev_priv->rps.sw_turbo.work_max_freq); | ||
3766 | } | ||
3767 | |||
3768 | void bdw_software_turbo(struct drm_device *dev) | ||
3769 | { | ||
3770 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
3771 | |||
3772 | u32 current_time = I915_READ(TIMESTAMP_CTR); /* unit in usec */ | ||
3773 | u32 current_c0 = I915_READ(MCHBAR_PCU_C0); /* unit in 32*1.28 usec */ | ||
3774 | |||
3775 | bdw_sw_calculate_freq(dev, &dev_priv->rps.sw_turbo.up, | ||
3776 | ¤t_time, ¤t_c0); | ||
3777 | bdw_sw_calculate_freq(dev, &dev_priv->rps.sw_turbo.down, | ||
3778 | ¤t_time, ¤t_c0); | ||
3779 | } | ||
3780 | |||
3781 | static void gen8_enable_rps(struct drm_device *dev) | 3688 | static void gen8_enable_rps(struct drm_device *dev) |
3782 | { | 3689 | { |
3783 | struct drm_i915_private *dev_priv = dev->dev_private; | 3690 | struct drm_i915_private *dev_priv = dev->dev_private; |
3784 | struct intel_engine_cs *ring; | 3691 | struct intel_engine_cs *ring; |
3785 | uint32_t rc6_mask = 0, rp_state_cap; | 3692 | uint32_t rc6_mask = 0, rp_state_cap; |
3786 | uint32_t threshold_up_pct, threshold_down_pct; | ||
3787 | uint32_t ei_up, ei_down; /* up and down evaluation interval */ | ||
3788 | u32 rp_ctl_flag; | ||
3789 | int unused; | 3693 | int unused; |
3790 | 3694 | ||
3791 | /* Use software Turbo for BDW */ | ||
3792 | dev_priv->rps.is_bdw_sw_turbo = IS_BROADWELL(dev); | ||
3793 | |||
3794 | /* 1a: Software RC state - RC0 */ | 3695 | /* 1a: Software RC state - RC0 */ |
3795 | I915_WRITE(GEN6_RC_STATE, 0); | 3696 | I915_WRITE(GEN6_RC_STATE, 0); |
3796 | 3697 | ||
@@ -3834,74 +3735,35 @@ static void gen8_enable_rps(struct drm_device *dev) | |||
3834 | HSW_FREQUENCY(dev_priv->rps.rp1_freq)); | 3735 | HSW_FREQUENCY(dev_priv->rps.rp1_freq)); |
3835 | I915_WRITE(GEN6_RC_VIDEO_FREQ, | 3736 | I915_WRITE(GEN6_RC_VIDEO_FREQ, |
3836 | HSW_FREQUENCY(dev_priv->rps.rp1_freq)); | 3737 | HSW_FREQUENCY(dev_priv->rps.rp1_freq)); |
3837 | ei_up = 84480; /* 84.48ms */ | 3738 | /* NB: Docs say 1s, and 1000000 - which aren't equivalent */ |
3838 | ei_down = 448000; | 3739 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 100000000 / 128); /* 1 second timeout */ |
3839 | threshold_up_pct = 90; /* x percent busy */ | ||
3840 | threshold_down_pct = 70; | ||
3841 | |||
3842 | if (dev_priv->rps.is_bdw_sw_turbo) { | ||
3843 | dev_priv->rps.sw_turbo.up.it_threshold_pct = threshold_up_pct; | ||
3844 | dev_priv->rps.sw_turbo.up.eval_interval = ei_up; | ||
3845 | dev_priv->rps.sw_turbo.up.is_up = true; | ||
3846 | dev_priv->rps.sw_turbo.up.last_ts = 0; | ||
3847 | dev_priv->rps.sw_turbo.up.last_c0 = 0; | ||
3848 | |||
3849 | dev_priv->rps.sw_turbo.down.it_threshold_pct = threshold_down_pct; | ||
3850 | dev_priv->rps.sw_turbo.down.eval_interval = ei_down; | ||
3851 | dev_priv->rps.sw_turbo.down.is_up = false; | ||
3852 | dev_priv->rps.sw_turbo.down.last_ts = 0; | ||
3853 | dev_priv->rps.sw_turbo.down.last_c0 = 0; | ||
3854 | |||
3855 | /* Start the timer to track if flip comes*/ | ||
3856 | dev_priv->rps.sw_turbo.timeout = 200*1000; /* in us */ | ||
3857 | |||
3858 | init_timer(&dev_priv->rps.sw_turbo.flip_timer); | ||
3859 | dev_priv->rps.sw_turbo.flip_timer.function = flip_active_timeout_handler; | ||
3860 | dev_priv->rps.sw_turbo.flip_timer.data = (unsigned long) dev_priv; | ||
3861 | dev_priv->rps.sw_turbo.flip_timer.expires = | ||
3862 | usecs_to_jiffies(dev_priv->rps.sw_turbo.timeout) + jiffies; | ||
3863 | add_timer(&dev_priv->rps.sw_turbo.flip_timer); | ||
3864 | INIT_WORK(&dev_priv->rps.sw_turbo.work_max_freq, gen8_set_frequency_RP0); | ||
3865 | |||
3866 | atomic_set(&dev_priv->rps.sw_turbo.flip_received, true); | ||
3867 | } else { | ||
3868 | /* NB: Docs say 1s, and 1000000 - which aren't equivalent | ||
3869 | * 1 second timeout*/ | ||
3870 | I915_WRITE(GEN6_RP_DOWN_TIMEOUT, FREQ_1_28_US(1000000)); | ||
3871 | 3740 | ||
3872 | /* Docs recommend 900MHz, and 300 MHz respectively */ | 3741 | /* Docs recommend 900MHz, and 300 MHz respectively */ |
3873 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, | 3742 | I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, |
3874 | dev_priv->rps.max_freq_softlimit << 24 | | 3743 | dev_priv->rps.max_freq_softlimit << 24 | |
3875 | dev_priv->rps.min_freq_softlimit << 16); | 3744 | dev_priv->rps.min_freq_softlimit << 16); |
3876 | 3745 | ||
3877 | I915_WRITE(GEN6_RP_UP_THRESHOLD, | 3746 | I915_WRITE(GEN6_RP_UP_THRESHOLD, 7600000 / 128); /* 76ms busyness per EI, 90% */ |
3878 | FREQ_1_28_US(ei_up * threshold_up_pct / 100)); | 3747 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 31300000 / 128); /* 313ms busyness per EI, 70%*/ |
3879 | I915_WRITE(GEN6_RP_DOWN_THRESHOLD, | 3748 | I915_WRITE(GEN6_RP_UP_EI, 66000); /* 84.48ms, XXX: random? */ |
3880 | FREQ_1_28_US(ei_down * threshold_down_pct / 100)); | 3749 | I915_WRITE(GEN6_RP_DOWN_EI, 350000); /* 448ms, XXX: random? */ |
3881 | I915_WRITE(GEN6_RP_UP_EI, | ||
3882 | FREQ_1_28_US(ei_up)); | ||
3883 | I915_WRITE(GEN6_RP_DOWN_EI, | ||
3884 | FREQ_1_28_US(ei_down)); | ||
3885 | 3750 | ||
3886 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); | 3751 | I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); |
3887 | } | ||
3888 | 3752 | ||
3889 | /* 5: Enable RPS */ | 3753 | /* 5: Enable RPS */ |
3890 | rp_ctl_flag = GEN6_RP_MEDIA_TURBO | | 3754 | I915_WRITE(GEN6_RP_CONTROL, |
3891 | GEN6_RP_MEDIA_HW_NORMAL_MODE | | 3755 | GEN6_RP_MEDIA_TURBO | |
3892 | GEN6_RP_MEDIA_IS_GFX | | 3756 | GEN6_RP_MEDIA_HW_NORMAL_MODE | |
3893 | GEN6_RP_UP_BUSY_AVG | | 3757 | GEN6_RP_MEDIA_IS_GFX | |
3894 | GEN6_RP_DOWN_IDLE_AVG; | 3758 | GEN6_RP_ENABLE | |
3895 | if (!dev_priv->rps.is_bdw_sw_turbo) | 3759 | GEN6_RP_UP_BUSY_AVG | |
3896 | rp_ctl_flag |= GEN6_RP_ENABLE; | 3760 | GEN6_RP_DOWN_IDLE_AVG); |
3897 | 3761 | ||
3898 | I915_WRITE(GEN6_RP_CONTROL, rp_ctl_flag); | 3762 | /* 6: Ring frequency + overclocking (our driver does this later */ |
3899 | 3763 | ||
3900 | /* 6: Ring frequency + overclocking | ||
3901 | * (our driver does this later */ | ||
3902 | gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); | 3764 | gen6_set_rps(dev, (I915_READ(GEN6_GT_PERF_STATUS) & 0xff00) >> 8); |
3903 | if (!dev_priv->rps.is_bdw_sw_turbo) | 3765 | |
3904 | gen8_enable_rps_interrupts(dev); | 3766 | gen8_enable_rps_interrupts(dev); |
3905 | 3767 | ||
3906 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); | 3768 | gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); |
3907 | } | 3769 | } |
@@ -5375,8 +5237,6 @@ static void intel_gen6_powersave_work(struct work_struct *work) | |||
5375 | rps.delayed_resume_work.work); | 5237 | rps.delayed_resume_work.work); |
5376 | struct drm_device *dev = dev_priv->dev; | 5238 | struct drm_device *dev = dev_priv->dev; |
5377 | 5239 | ||
5378 | dev_priv->rps.is_bdw_sw_turbo = false; | ||
5379 | |||
5380 | mutex_lock(&dev_priv->rps.hw_lock); | 5240 | mutex_lock(&dev_priv->rps.hw_lock); |
5381 | 5241 | ||
5382 | if (IS_CHERRYVIEW(dev)) { | 5242 | if (IS_CHERRYVIEW(dev)) { |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 109de2eeb9a8..0a80e419b589 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -707,7 +707,7 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) | |||
707 | * update the number of dwords required based on the | 707 | * update the number of dwords required based on the |
708 | * actual number of workarounds applied | 708 | * actual number of workarounds applied |
709 | */ | 709 | */ |
710 | ret = intel_ring_begin(ring, 24); | 710 | ret = intel_ring_begin(ring, 18); |
711 | if (ret) | 711 | if (ret) |
712 | return ret; | 712 | return ret; |
713 | 713 | ||
@@ -722,19 +722,8 @@ static int bdw_init_workarounds(struct intel_engine_cs *ring) | |||
722 | intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2, | 722 | intel_ring_emit_wa(ring, GEN7_ROW_CHICKEN2, |
723 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); | 723 | _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); |
724 | 724 | ||
725 | /* | ||
726 | * This GEN8_CENTROID_PIXEL_OPT_DIS W/A is only needed for | ||
727 | * pre-production hardware | ||
728 | */ | ||
729 | intel_ring_emit_wa(ring, HALF_SLICE_CHICKEN3, | 725 | intel_ring_emit_wa(ring, HALF_SLICE_CHICKEN3, |
730 | _MASKED_BIT_ENABLE(GEN8_CENTROID_PIXEL_OPT_DIS | 726 | _MASKED_BIT_ENABLE(GEN8_SAMPLER_POWER_BYPASS_DIS)); |
731 | | GEN8_SAMPLER_POWER_BYPASS_DIS)); | ||
732 | |||
733 | intel_ring_emit_wa(ring, GEN7_HALF_SLICE_CHICKEN1, | ||
734 | _MASKED_BIT_ENABLE(GEN7_SINGLE_SUBSCAN_DISPATCH_ENABLE)); | ||
735 | |||
736 | intel_ring_emit_wa(ring, COMMON_SLICE_CHICKEN2, | ||
737 | _MASKED_BIT_ENABLE(GEN8_CSC2_SBE_VUE_CACHE_CONSERVATIVE)); | ||
738 | 727 | ||
739 | /* Use Force Non-Coherent whenever executing a 3D context. This is a | 728 | /* Use Force Non-Coherent whenever executing a 3D context. This is a |
740 | * workaround for for a possible hang in the unlikely event a TLB | 729 | * workaround for for a possible hang in the unlikely event a TLB |
@@ -1579,7 +1568,7 @@ i830_dispatch_execbuffer(struct intel_engine_cs *ring, | |||
1579 | */ | 1568 | */ |
1580 | intel_ring_emit(ring, SRC_COPY_BLT_CMD | BLT_WRITE_RGBA); | 1569 | intel_ring_emit(ring, SRC_COPY_BLT_CMD | BLT_WRITE_RGBA); |
1581 | intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096); | 1570 | intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096); |
1582 | intel_ring_emit(ring, DIV_ROUND_UP(len, 4096) << 16 | 1024); | 1571 | intel_ring_emit(ring, DIV_ROUND_UP(len, 4096) << 16 | 4096); |
1583 | intel_ring_emit(ring, cs_offset); | 1572 | intel_ring_emit(ring, cs_offset); |
1584 | intel_ring_emit(ring, 4096); | 1573 | intel_ring_emit(ring, 4096); |
1585 | intel_ring_emit(ring, offset); | 1574 | intel_ring_emit(ring, offset); |
@@ -2203,8 +2192,9 @@ hsw_ring_dispatch_execbuffer(struct intel_engine_cs *ring, | |||
2203 | return ret; | 2192 | return ret; |
2204 | 2193 | ||
2205 | intel_ring_emit(ring, | 2194 | intel_ring_emit(ring, |
2206 | MI_BATCH_BUFFER_START | MI_BATCH_PPGTT_HSW | | 2195 | MI_BATCH_BUFFER_START | |
2207 | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_HSW)); | 2196 | (flags & I915_DISPATCH_SECURE ? |
2197 | 0 : MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW)); | ||
2208 | /* bit0-7 is the length on GEN6+ */ | 2198 | /* bit0-7 is the length on GEN6+ */ |
2209 | intel_ring_emit(ring, offset); | 2199 | intel_ring_emit(ring, offset); |
2210 | intel_ring_advance(ring); | 2200 | intel_ring_advance(ring); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index a7efbff4dc8f..2df3a937037d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -1846,9 +1846,10 @@ nv50_disp_intr_unk40_0_tmds(struct nv50_disp_priv *priv, struct dcb_output *outp | |||
1846 | const int or = ffs(outp->or) - 1; | 1846 | const int or = ffs(outp->or) - 1; |
1847 | const u32 loff = (or * 0x800) + (link * 0x80); | 1847 | const u32 loff = (or * 0x800) + (link * 0x80); |
1848 | const u16 mask = (outp->sorconf.link << 6) | outp->or; | 1848 | const u16 mask = (outp->sorconf.link << 6) | outp->or; |
1849 | struct dcb_output match; | ||
1849 | u8 ver, hdr; | 1850 | u8 ver, hdr; |
1850 | 1851 | ||
1851 | if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, outp)) | 1852 | if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, &match)) |
1852 | nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000); | 1853 | nv_mask(priv, 0x61c10c + loff, 0x00000001, 0x00000000); |
1853 | } | 1854 | } |
1854 | 1855 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c index 0a44459844e3..05a278bab247 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c | |||
@@ -200,7 +200,6 @@ nvc0_bar_init(struct nouveau_object *object) | |||
200 | 200 | ||
201 | nv_mask(priv, 0x000200, 0x00000100, 0x00000000); | 201 | nv_mask(priv, 0x000200, 0x00000100, 0x00000000); |
202 | nv_mask(priv, 0x000200, 0x00000100, 0x00000100); | 202 | nv_mask(priv, 0x000200, 0x00000100, 0x00000100); |
203 | nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); | ||
204 | 203 | ||
205 | nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12); | 204 | nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12); |
206 | if (priv->bar[0].mem) | 205 | if (priv->bar[0].mem) |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c index b19a2b3c1081..32f28dc73ef2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c | |||
@@ -60,6 +60,7 @@ nvc0_fb_init(struct nouveau_object *object) | |||
60 | 60 | ||
61 | if (priv->r100c10_page) | 61 | if (priv->r100c10_page) |
62 | nv_wr32(priv, 0x100c10, priv->r100c10 >> 8); | 62 | nv_wr32(priv, 0x100c10, priv->r100c10 >> 8); |
63 | nv_mask(priv, 0x100c80, 0x00000001, 0x00000000); /* 128KiB lpg */ | ||
63 | return 0; | 64 | return 0; |
64 | } | 65 | } |
65 | 66 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c index e7b7872481ef..2db0977284f8 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gf100.c | |||
@@ -115,6 +115,7 @@ static int | |||
115 | gf100_ltc_init(struct nouveau_object *object) | 115 | gf100_ltc_init(struct nouveau_object *object) |
116 | { | 116 | { |
117 | struct nvkm_ltc_priv *priv = (void *)object; | 117 | struct nvkm_ltc_priv *priv = (void *)object; |
118 | u32 lpg128 = !(nv_rd32(priv, 0x100c80) & 0x00000001); | ||
118 | int ret; | 119 | int ret; |
119 | 120 | ||
120 | ret = nvkm_ltc_init(priv); | 121 | ret = nvkm_ltc_init(priv); |
@@ -124,6 +125,7 @@ gf100_ltc_init(struct nouveau_object *object) | |||
124 | nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ | 125 | nv_mask(priv, 0x17e820, 0x00100000, 0x00000000); /* INTR_EN &= ~0x10 */ |
125 | nv_wr32(priv, 0x17e8d8, priv->ltc_nr); | 126 | nv_wr32(priv, 0x17e8d8, priv->ltc_nr); |
126 | nv_wr32(priv, 0x17e8d4, priv->tag_base); | 127 | nv_wr32(priv, 0x17e8d4, priv->tag_base); |
128 | nv_mask(priv, 0x17e8c0, 0x00000002, lpg128 ? 0x00000002 : 0x00000000); | ||
127 | return 0; | 129 | return 0; |
128 | } | 130 | } |
129 | 131 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c index ea716569745d..b39b5d0eb8f9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gk104.c | |||
@@ -28,6 +28,7 @@ static int | |||
28 | gk104_ltc_init(struct nouveau_object *object) | 28 | gk104_ltc_init(struct nouveau_object *object) |
29 | { | 29 | { |
30 | struct nvkm_ltc_priv *priv = (void *)object; | 30 | struct nvkm_ltc_priv *priv = (void *)object; |
31 | u32 lpg128 = !(nv_rd32(priv, 0x100c80) & 0x00000001); | ||
31 | int ret; | 32 | int ret; |
32 | 33 | ||
33 | ret = nvkm_ltc_init(priv); | 34 | ret = nvkm_ltc_init(priv); |
@@ -37,6 +38,7 @@ gk104_ltc_init(struct nouveau_object *object) | |||
37 | nv_wr32(priv, 0x17e8d8, priv->ltc_nr); | 38 | nv_wr32(priv, 0x17e8d8, priv->ltc_nr); |
38 | nv_wr32(priv, 0x17e000, priv->ltc_nr); | 39 | nv_wr32(priv, 0x17e000, priv->ltc_nr); |
39 | nv_wr32(priv, 0x17e8d4, priv->tag_base); | 40 | nv_wr32(priv, 0x17e8d4, priv->tag_base); |
41 | nv_mask(priv, 0x17e8c0, 0x00000002, lpg128 ? 0x00000002 : 0x00000000); | ||
40 | return 0; | 42 | return 0; |
41 | } | 43 | } |
42 | 44 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c index a26bed86f384..89fc4238f50c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c +++ b/drivers/gpu/drm/nouveau/core/subdev/ltc/gm107.c | |||
@@ -93,6 +93,7 @@ static int | |||
93 | gm107_ltc_init(struct nouveau_object *object) | 93 | gm107_ltc_init(struct nouveau_object *object) |
94 | { | 94 | { |
95 | struct nvkm_ltc_priv *priv = (void *)object; | 95 | struct nvkm_ltc_priv *priv = (void *)object; |
96 | u32 lpg128 = !(nv_rd32(priv, 0x100c80) & 0x00000001); | ||
96 | int ret; | 97 | int ret; |
97 | 98 | ||
98 | ret = nvkm_ltc_init(priv); | 99 | ret = nvkm_ltc_init(priv); |
@@ -101,6 +102,7 @@ gm107_ltc_init(struct nouveau_object *object) | |||
101 | 102 | ||
102 | nv_wr32(priv, 0x17e27c, priv->ltc_nr); | 103 | nv_wr32(priv, 0x17e27c, priv->ltc_nr); |
103 | nv_wr32(priv, 0x17e278, priv->tag_base); | 104 | nv_wr32(priv, 0x17e278, priv->tag_base); |
105 | nv_mask(priv, 0x17e264, 0x00000002, lpg128 ? 0x00000002 : 0x00000000); | ||
104 | return 0; | 106 | return 0; |
105 | } | 107 | } |
106 | 108 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 279206997e5c..622424692b3b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -46,7 +46,6 @@ static struct nouveau_dsm_priv { | |||
46 | bool dsm_detected; | 46 | bool dsm_detected; |
47 | bool optimus_detected; | 47 | bool optimus_detected; |
48 | acpi_handle dhandle; | 48 | acpi_handle dhandle; |
49 | acpi_handle other_handle; | ||
50 | acpi_handle rom_handle; | 49 | acpi_handle rom_handle; |
51 | } nouveau_dsm_priv; | 50 | } nouveau_dsm_priv; |
52 | 51 | ||
@@ -222,10 +221,9 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) | |||
222 | if (!dhandle) | 221 | if (!dhandle) |
223 | return false; | 222 | return false; |
224 | 223 | ||
225 | if (!acpi_has_method(dhandle, "_DSM")) { | 224 | if (!acpi_has_method(dhandle, "_DSM")) |
226 | nouveau_dsm_priv.other_handle = dhandle; | ||
227 | return false; | 225 | return false; |
228 | } | 226 | |
229 | if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102, | 227 | if (acpi_check_dsm(dhandle, nouveau_dsm_muid, 0x00000102, |
230 | 1 << NOUVEAU_DSM_POWER)) | 228 | 1 << NOUVEAU_DSM_POWER)) |
231 | retval |= NOUVEAU_DSM_HAS_MUX; | 229 | retval |= NOUVEAU_DSM_HAS_MUX; |
@@ -301,16 +299,6 @@ static bool nouveau_dsm_detect(void) | |||
301 | printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", | 299 | printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", |
302 | acpi_method_name); | 300 | acpi_method_name); |
303 | nouveau_dsm_priv.dsm_detected = true; | 301 | nouveau_dsm_priv.dsm_detected = true; |
304 | /* | ||
305 | * On some systems hotplug events are generated for the device | ||
306 | * being switched off when _DSM is executed. They cause ACPI | ||
307 | * hotplug to trigger and attempt to remove the device from | ||
308 | * the system, which causes it to break down. Prevent that from | ||
309 | * happening by setting the no_hotplug flag for the involved | ||
310 | * ACPI device objects. | ||
311 | */ | ||
312 | acpi_bus_no_hotplug(nouveau_dsm_priv.dhandle); | ||
313 | acpi_bus_no_hotplug(nouveau_dsm_priv.other_handle); | ||
314 | ret = true; | 302 | ret = true; |
315 | } | 303 | } |
316 | 304 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 77c81d6b45ee..fd3dbd59d73e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c | |||
@@ -285,6 +285,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) | |||
285 | struct nouveau_software_chan *swch; | 285 | struct nouveau_software_chan *swch; |
286 | struct nv_dma_v0 args = {}; | 286 | struct nv_dma_v0 args = {}; |
287 | int ret, i; | 287 | int ret, i; |
288 | bool save; | ||
288 | 289 | ||
289 | nvif_object_map(chan->object); | 290 | nvif_object_map(chan->object); |
290 | 291 | ||
@@ -386,7 +387,11 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) | |||
386 | } | 387 | } |
387 | 388 | ||
388 | /* initialise synchronisation */ | 389 | /* initialise synchronisation */ |
389 | return nouveau_fence(chan->drm)->context_new(chan); | 390 | save = cli->base.super; |
391 | cli->base.super = true; /* hack until fencenv50 fixed */ | ||
392 | ret = nouveau_fence(chan->drm)->context_new(chan); | ||
393 | cli->base.super = save; | ||
394 | return ret; | ||
390 | } | 395 | } |
391 | 396 | ||
392 | int | 397 | int |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 334db3c6e40c..a88e6927f571 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -550,14 +550,12 @@ nouveau_display_destroy(struct drm_device *dev) | |||
550 | } | 550 | } |
551 | 551 | ||
552 | int | 552 | int |
553 | nouveau_display_suspend(struct drm_device *dev) | 553 | nouveau_display_suspend(struct drm_device *dev, bool runtime) |
554 | { | 554 | { |
555 | struct nouveau_drm *drm = nouveau_drm(dev); | ||
556 | struct drm_crtc *crtc; | 555 | struct drm_crtc *crtc; |
557 | 556 | ||
558 | nouveau_display_fini(dev); | 557 | nouveau_display_fini(dev); |
559 | 558 | ||
560 | NV_INFO(drm, "unpinning framebuffer(s)...\n"); | ||
561 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 559 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
562 | struct nouveau_framebuffer *nouveau_fb; | 560 | struct nouveau_framebuffer *nouveau_fb; |
563 | 561 | ||
@@ -579,12 +577,13 @@ nouveau_display_suspend(struct drm_device *dev) | |||
579 | } | 577 | } |
580 | 578 | ||
581 | void | 579 | void |
582 | nouveau_display_repin(struct drm_device *dev) | 580 | nouveau_display_resume(struct drm_device *dev, bool runtime) |
583 | { | 581 | { |
584 | struct nouveau_drm *drm = nouveau_drm(dev); | 582 | struct nouveau_drm *drm = nouveau_drm(dev); |
585 | struct drm_crtc *crtc; | 583 | struct drm_crtc *crtc; |
586 | int ret; | 584 | int ret, head; |
587 | 585 | ||
586 | /* re-pin fb/cursors */ | ||
588 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 587 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
589 | struct nouveau_framebuffer *nouveau_fb; | 588 | struct nouveau_framebuffer *nouveau_fb; |
590 | 589 | ||
@@ -606,13 +605,6 @@ nouveau_display_repin(struct drm_device *dev) | |||
606 | if (ret) | 605 | if (ret) |
607 | NV_ERROR(drm, "Could not pin/map cursor.\n"); | 606 | NV_ERROR(drm, "Could not pin/map cursor.\n"); |
608 | } | 607 | } |
609 | } | ||
610 | |||
611 | void | ||
612 | nouveau_display_resume(struct drm_device *dev) | ||
613 | { | ||
614 | struct drm_crtc *crtc; | ||
615 | int head; | ||
616 | 608 | ||
617 | nouveau_display_init(dev); | 609 | nouveau_display_init(dev); |
618 | 610 | ||
@@ -627,6 +619,13 @@ nouveau_display_resume(struct drm_device *dev) | |||
627 | for (head = 0; head < dev->mode_config.num_crtc; head++) | 619 | for (head = 0; head < dev->mode_config.num_crtc; head++) |
628 | drm_vblank_on(dev, head); | 620 | drm_vblank_on(dev, head); |
629 | 621 | ||
622 | /* This should ensure we don't hit a locking problem when someone | ||
623 | * wakes us up via a connector. We should never go into suspend | ||
624 | * while the display is on anyways. | ||
625 | */ | ||
626 | if (runtime) | ||
627 | return; | ||
628 | |||
630 | drm_helper_resume_force_mode(dev); | 629 | drm_helper_resume_force_mode(dev); |
631 | 630 | ||
632 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 631 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 88ca177cb1c7..be3d5947c6be 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h | |||
@@ -63,9 +63,8 @@ int nouveau_display_create(struct drm_device *dev); | |||
63 | void nouveau_display_destroy(struct drm_device *dev); | 63 | void nouveau_display_destroy(struct drm_device *dev); |
64 | int nouveau_display_init(struct drm_device *dev); | 64 | int nouveau_display_init(struct drm_device *dev); |
65 | void nouveau_display_fini(struct drm_device *dev); | 65 | void nouveau_display_fini(struct drm_device *dev); |
66 | int nouveau_display_suspend(struct drm_device *dev); | 66 | int nouveau_display_suspend(struct drm_device *dev, bool runtime); |
67 | void nouveau_display_repin(struct drm_device *dev); | 67 | void nouveau_display_resume(struct drm_device *dev, bool runtime); |
68 | void nouveau_display_resume(struct drm_device *dev); | ||
69 | int nouveau_display_vblank_enable(struct drm_device *, int); | 68 | int nouveau_display_vblank_enable(struct drm_device *, int); |
70 | void nouveau_display_vblank_disable(struct drm_device *, int); | 69 | void nouveau_display_vblank_disable(struct drm_device *, int); |
71 | int nouveau_display_scanoutpos(struct drm_device *, int, unsigned int, | 70 | int nouveau_display_scanoutpos(struct drm_device *, int, unsigned int, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 244d78fc0cb5..57238076049f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c | |||
@@ -550,9 +550,11 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) | |||
550 | struct nouveau_cli *cli; | 550 | struct nouveau_cli *cli; |
551 | int ret; | 551 | int ret; |
552 | 552 | ||
553 | if (dev->mode_config.num_crtc && !runtime) { | 553 | if (dev->mode_config.num_crtc) { |
554 | NV_INFO(drm, "suspending console...\n"); | ||
555 | nouveau_fbcon_set_suspend(dev, 1); | ||
554 | NV_INFO(drm, "suspending display...\n"); | 556 | NV_INFO(drm, "suspending display...\n"); |
555 | ret = nouveau_display_suspend(dev); | 557 | ret = nouveau_display_suspend(dev, runtime); |
556 | if (ret) | 558 | if (ret) |
557 | return ret; | 559 | return ret; |
558 | } | 560 | } |
@@ -606,7 +608,7 @@ fail_client: | |||
606 | fail_display: | 608 | fail_display: |
607 | if (dev->mode_config.num_crtc) { | 609 | if (dev->mode_config.num_crtc) { |
608 | NV_INFO(drm, "resuming display...\n"); | 610 | NV_INFO(drm, "resuming display...\n"); |
609 | nouveau_display_resume(dev); | 611 | nouveau_display_resume(dev, runtime); |
610 | } | 612 | } |
611 | return ret; | 613 | return ret; |
612 | } | 614 | } |
@@ -621,21 +623,19 @@ int nouveau_pmops_suspend(struct device *dev) | |||
621 | drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF) | 623 | drm_dev->switch_power_state == DRM_SWITCH_POWER_DYNAMIC_OFF) |
622 | return 0; | 624 | return 0; |
623 | 625 | ||
624 | if (drm_dev->mode_config.num_crtc) | ||
625 | nouveau_fbcon_set_suspend(drm_dev, 1); | ||
626 | |||
627 | ret = nouveau_do_suspend(drm_dev, false); | 626 | ret = nouveau_do_suspend(drm_dev, false); |
628 | if (ret) | 627 | if (ret) |
629 | return ret; | 628 | return ret; |
630 | 629 | ||
631 | pci_save_state(pdev); | 630 | pci_save_state(pdev); |
632 | pci_disable_device(pdev); | 631 | pci_disable_device(pdev); |
632 | pci_ignore_hotplug(pdev); | ||
633 | pci_set_power_state(pdev, PCI_D3hot); | 633 | pci_set_power_state(pdev, PCI_D3hot); |
634 | return 0; | 634 | return 0; |
635 | } | 635 | } |
636 | 636 | ||
637 | static int | 637 | static int |
638 | nouveau_do_resume(struct drm_device *dev) | 638 | nouveau_do_resume(struct drm_device *dev, bool runtime) |
639 | { | 639 | { |
640 | struct nouveau_drm *drm = nouveau_drm(dev); | 640 | struct nouveau_drm *drm = nouveau_drm(dev); |
641 | struct nouveau_cli *cli; | 641 | struct nouveau_cli *cli; |
@@ -660,7 +660,9 @@ nouveau_do_resume(struct drm_device *dev) | |||
660 | 660 | ||
661 | if (dev->mode_config.num_crtc) { | 661 | if (dev->mode_config.num_crtc) { |
662 | NV_INFO(drm, "resuming display...\n"); | 662 | NV_INFO(drm, "resuming display...\n"); |
663 | nouveau_display_repin(dev); | 663 | nouveau_display_resume(dev, runtime); |
664 | NV_INFO(drm, "resuming console...\n"); | ||
665 | nouveau_fbcon_set_suspend(dev, 0); | ||
664 | } | 666 | } |
665 | 667 | ||
666 | return 0; | 668 | return 0; |
@@ -683,47 +685,21 @@ int nouveau_pmops_resume(struct device *dev) | |||
683 | return ret; | 685 | return ret; |
684 | pci_set_master(pdev); | 686 | pci_set_master(pdev); |
685 | 687 | ||
686 | ret = nouveau_do_resume(drm_dev); | 688 | return nouveau_do_resume(drm_dev, false); |
687 | if (ret) | ||
688 | return ret; | ||
689 | |||
690 | if (drm_dev->mode_config.num_crtc) { | ||
691 | nouveau_display_resume(drm_dev); | ||
692 | nouveau_fbcon_set_suspend(drm_dev, 0); | ||
693 | } | ||
694 | |||
695 | return 0; | ||
696 | } | 689 | } |
697 | 690 | ||
698 | static int nouveau_pmops_freeze(struct device *dev) | 691 | static int nouveau_pmops_freeze(struct device *dev) |
699 | { | 692 | { |
700 | struct pci_dev *pdev = to_pci_dev(dev); | 693 | struct pci_dev *pdev = to_pci_dev(dev); |
701 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 694 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
702 | int ret; | 695 | return nouveau_do_suspend(drm_dev, false); |
703 | |||
704 | if (drm_dev->mode_config.num_crtc) | ||
705 | nouveau_fbcon_set_suspend(drm_dev, 1); | ||
706 | |||
707 | ret = nouveau_do_suspend(drm_dev, false); | ||
708 | return ret; | ||
709 | } | 696 | } |
710 | 697 | ||
711 | static int nouveau_pmops_thaw(struct device *dev) | 698 | static int nouveau_pmops_thaw(struct device *dev) |
712 | { | 699 | { |
713 | struct pci_dev *pdev = to_pci_dev(dev); | 700 | struct pci_dev *pdev = to_pci_dev(dev); |
714 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | 701 | struct drm_device *drm_dev = pci_get_drvdata(pdev); |
715 | int ret; | 702 | return nouveau_do_resume(drm_dev, false); |
716 | |||
717 | ret = nouveau_do_resume(drm_dev); | ||
718 | if (ret) | ||
719 | return ret; | ||
720 | |||
721 | if (drm_dev->mode_config.num_crtc) { | ||
722 | nouveau_display_resume(drm_dev); | ||
723 | nouveau_fbcon_set_suspend(drm_dev, 0); | ||
724 | } | ||
725 | |||
726 | return 0; | ||
727 | } | 703 | } |
728 | 704 | ||
729 | 705 | ||
@@ -979,7 +955,7 @@ static int nouveau_pmops_runtime_resume(struct device *dev) | |||
979 | return ret; | 955 | return ret; |
980 | pci_set_master(pdev); | 956 | pci_set_master(pdev); |
981 | 957 | ||
982 | ret = nouveau_do_resume(drm_dev); | 958 | ret = nouveau_do_resume(drm_dev, true); |
983 | drm_kms_helper_poll_enable(drm_dev); | 959 | drm_kms_helper_poll_enable(drm_dev); |
984 | /* do magic */ | 960 | /* do magic */ |
985 | nvif_mask(device, 0x88488, (1 << 25), (1 << 25)); | 961 | nvif_mask(device, 0x88488, (1 << 25), (1 << 25)); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index dc1753c368e3..593ef8a2a069 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -487,6 +487,16 @@ static const struct drm_fb_helper_funcs nouveau_fbcon_helper_funcs = { | |||
487 | .fb_probe = nouveau_fbcon_create, | 487 | .fb_probe = nouveau_fbcon_create, |
488 | }; | 488 | }; |
489 | 489 | ||
490 | static void | ||
491 | nouveau_fbcon_set_suspend_work(struct work_struct *work) | ||
492 | { | ||
493 | struct nouveau_fbdev *fbcon = container_of(work, typeof(*fbcon), work); | ||
494 | console_lock(); | ||
495 | nouveau_fbcon_accel_restore(fbcon->dev); | ||
496 | nouveau_fbcon_zfill(fbcon->dev, fbcon); | ||
497 | fb_set_suspend(fbcon->helper.fbdev, FBINFO_STATE_RUNNING); | ||
498 | console_unlock(); | ||
499 | } | ||
490 | 500 | ||
491 | int | 501 | int |
492 | nouveau_fbcon_init(struct drm_device *dev) | 502 | nouveau_fbcon_init(struct drm_device *dev) |
@@ -504,6 +514,7 @@ nouveau_fbcon_init(struct drm_device *dev) | |||
504 | if (!fbcon) | 514 | if (!fbcon) |
505 | return -ENOMEM; | 515 | return -ENOMEM; |
506 | 516 | ||
517 | INIT_WORK(&fbcon->work, nouveau_fbcon_set_suspend_work); | ||
507 | fbcon->dev = dev; | 518 | fbcon->dev = dev; |
508 | drm->fbcon = fbcon; | 519 | drm->fbcon = fbcon; |
509 | 520 | ||
@@ -552,14 +563,14 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state) | |||
552 | { | 563 | { |
553 | struct nouveau_drm *drm = nouveau_drm(dev); | 564 | struct nouveau_drm *drm = nouveau_drm(dev); |
554 | if (drm->fbcon) { | 565 | if (drm->fbcon) { |
555 | console_lock(); | 566 | if (state == FBINFO_STATE_RUNNING) { |
556 | if (state == 0) { | 567 | schedule_work(&drm->fbcon->work); |
557 | nouveau_fbcon_accel_restore(dev); | 568 | return; |
558 | nouveau_fbcon_zfill(dev, drm->fbcon); | ||
559 | } | 569 | } |
570 | flush_work(&drm->fbcon->work); | ||
571 | console_lock(); | ||
560 | fb_set_suspend(drm->fbcon->helper.fbdev, state); | 572 | fb_set_suspend(drm->fbcon->helper.fbdev, state); |
561 | if (state == 1) | 573 | nouveau_fbcon_accel_save_disable(dev); |
562 | nouveau_fbcon_accel_save_disable(dev); | ||
563 | console_unlock(); | 574 | console_unlock(); |
564 | } | 575 | } |
565 | } | 576 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 1e2e9e27a03b..6208e70e4a1c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h | |||
@@ -36,6 +36,7 @@ struct nouveau_fbdev { | |||
36 | struct nouveau_framebuffer nouveau_fb; | 36 | struct nouveau_framebuffer nouveau_fb; |
37 | struct list_head fbdev_list; | 37 | struct list_head fbdev_list; |
38 | struct drm_device *dev; | 38 | struct drm_device *dev; |
39 | struct work_struct work; | ||
39 | unsigned int saved_flags; | 40 | unsigned int saved_flags; |
40 | struct nvif_object surf2d; | 41 | struct nvif_object surf2d; |
41 | struct nvif_object clip; | 42 | struct nvif_object clip; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_nvif.c b/drivers/gpu/drm/nouveau/nouveau_nvif.c index 47ca88623753..6544b84f0303 100644 --- a/drivers/gpu/drm/nouveau/nouveau_nvif.c +++ b/drivers/gpu/drm/nouveau/nouveau_nvif.c | |||
@@ -40,12 +40,12 @@ | |||
40 | #include "nouveau_usif.h" | 40 | #include "nouveau_usif.h" |
41 | 41 | ||
42 | static void | 42 | static void |
43 | nvkm_client_unmap(void *priv, void *ptr, u32 size) | 43 | nvkm_client_unmap(void *priv, void __iomem *ptr, u32 size) |
44 | { | 44 | { |
45 | iounmap(ptr); | 45 | iounmap(ptr); |
46 | } | 46 | } |
47 | 47 | ||
48 | static void * | 48 | static void __iomem * |
49 | nvkm_client_map(void *priv, u64 handle, u32 size) | 49 | nvkm_client_map(void *priv, u64 handle, u32 size) |
50 | { | 50 | { |
51 | return ioremap(handle, size); | 51 | return ioremap(handle, size); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index 18d55d447248..c7592ec8ecb8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c | |||
@@ -108,7 +108,16 @@ void | |||
108 | nouveau_vga_fini(struct nouveau_drm *drm) | 108 | nouveau_vga_fini(struct nouveau_drm *drm) |
109 | { | 109 | { |
110 | struct drm_device *dev = drm->dev; | 110 | struct drm_device *dev = drm->dev; |
111 | bool runtime = false; | ||
112 | |||
113 | if (nouveau_runtime_pm == 1) | ||
114 | runtime = true; | ||
115 | if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm())) | ||
116 | runtime = true; | ||
117 | |||
111 | vga_switcheroo_unregister_client(dev->pdev); | 118 | vga_switcheroo_unregister_client(dev->pdev); |
119 | if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus()) | ||
120 | vga_switcheroo_fini_domain_pm_ops(drm->dev->dev); | ||
112 | vga_client_register(dev->pdev, NULL, NULL, NULL); | 121 | vga_client_register(dev->pdev, NULL, NULL, NULL); |
113 | } | 122 | } |
114 | 123 | ||
diff --git a/drivers/gpu/drm/nouveau/nvif/driver.h b/drivers/gpu/drm/nouveau/nvif/driver.h index b72a8f0c2758..ac4bdb3ea506 100644 --- a/drivers/gpu/drm/nouveau/nvif/driver.h +++ b/drivers/gpu/drm/nouveau/nvif/driver.h | |||
@@ -9,8 +9,8 @@ struct nvif_driver { | |||
9 | int (*suspend)(void *priv); | 9 | int (*suspend)(void *priv); |
10 | int (*resume)(void *priv); | 10 | int (*resume)(void *priv); |
11 | int (*ioctl)(void *priv, bool super, void *data, u32 size, void **hack); | 11 | int (*ioctl)(void *priv, bool super, void *data, u32 size, void **hack); |
12 | void *(*map)(void *priv, u64 handle, u32 size); | 12 | void __iomem *(*map)(void *priv, u64 handle, u32 size); |
13 | void (*unmap)(void *priv, void *ptr, u32 size); | 13 | void (*unmap)(void *priv, void __iomem *ptr, u32 size); |
14 | bool keep; | 14 | bool keep; |
15 | }; | 15 | }; |
16 | 16 | ||
diff --git a/drivers/gpu/drm/nouveau/nvif/object.h b/drivers/gpu/drm/nouveau/nvif/object.h index fac3a3bbec44..fe519179b76c 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.h +++ b/drivers/gpu/drm/nouveau/nvif/object.h | |||
@@ -14,7 +14,7 @@ struct nvif_object { | |||
14 | void *priv; /*XXX: hack */ | 14 | void *priv; /*XXX: hack */ |
15 | void (*dtor)(struct nvif_object *); | 15 | void (*dtor)(struct nvif_object *); |
16 | struct { | 16 | struct { |
17 | void *ptr; | 17 | void __iomem *ptr; |
18 | u32 size; | 18 | u32 size; |
19 | } map; | 19 | } map; |
20 | }; | 20 | }; |
@@ -42,7 +42,7 @@ void nvif_object_unmap(struct nvif_object *); | |||
42 | struct nvif_object *_object = nvif_object(a); \ | 42 | struct nvif_object *_object = nvif_object(a); \ |
43 | u32 _data; \ | 43 | u32 _data; \ |
44 | if (likely(_object->map.ptr)) \ | 44 | if (likely(_object->map.ptr)) \ |
45 | _data = ioread##b##_native((u8 *)_object->map.ptr + (c)); \ | 45 | _data = ioread##b##_native((u8 __iomem *)_object->map.ptr + (c)); \ |
46 | else \ | 46 | else \ |
47 | _data = nvif_object_rd(_object, (b) / 8, (c)); \ | 47 | _data = nvif_object_rd(_object, (b) / 8, (c)); \ |
48 | _data; \ | 48 | _data; \ |
@@ -50,7 +50,7 @@ void nvif_object_unmap(struct nvif_object *); | |||
50 | #define nvif_wr(a,b,c,d) ({ \ | 50 | #define nvif_wr(a,b,c,d) ({ \ |
51 | struct nvif_object *_object = nvif_object(a); \ | 51 | struct nvif_object *_object = nvif_object(a); \ |
52 | if (likely(_object->map.ptr)) \ | 52 | if (likely(_object->map.ptr)) \ |
53 | iowrite##b##_native((d), (u8 *)_object->map.ptr + (c)); \ | 53 | iowrite##b##_native((d), (u8 __iomem *)_object->map.ptr + (c)); \ |
54 | else \ | 54 | else \ |
55 | nvif_object_wr(_object, (b) / 8, (c), (d)); \ | 55 | nvif_object_wr(_object, (b) / 8, (c), (d)); \ |
56 | }) | 56 | }) |
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 7d7aed5357f0..d01b87991422 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -72,7 +72,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
72 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ | 72 | radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ |
73 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ | 73 | rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ |
74 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit_shaders.o \ | 74 | r200.o radeon_legacy_tv.o r600_cs.o r600_blit_shaders.o \ |
75 | radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o dce3_1_afmt.o \ | 75 | radeon_pm.o atombios_dp.o r600_hdmi.o dce3_1_afmt.o \ |
76 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o \ | 76 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o \ |
77 | evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ | 77 | evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \ |
78 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ | 78 | atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \ |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index a7f2ddf09a9d..b8cd7975f797 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
@@ -291,29 +291,6 @@ static void radeon_atom_backlight_exit(struct radeon_encoder *encoder) | |||
291 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, | 291 | bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index, |
292 | struct drm_display_mode *mode); | 292 | struct drm_display_mode *mode); |
293 | 293 | ||
294 | |||
295 | static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | ||
296 | { | ||
297 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
298 | switch (radeon_encoder->encoder_id) { | ||
299 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
300 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
301 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
302 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
303 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
304 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
305 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
306 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
307 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
308 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
309 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
310 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: | ||
311 | return true; | ||
312 | default: | ||
313 | return false; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 294 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
318 | const struct drm_display_mode *mode, | 295 | const struct drm_display_mode *mode, |
319 | struct drm_display_mode *adjusted_mode) | 296 | struct drm_display_mode *adjusted_mode) |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index f81d7ca134db..0b2929de9f41 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | ||
27 | #include "btcd.h" | 28 | #include "btcd.h" |
28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
29 | #include "cypress_dpm.h" | 30 | #include "cypress_dpm.h" |
@@ -2099,7 +2100,6 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2099 | bool disable_mclk_switching; | 2100 | bool disable_mclk_switching; |
2100 | u32 mclk, sclk; | 2101 | u32 mclk, sclk; |
2101 | u16 vddc, vddci; | 2102 | u16 vddc, vddci; |
2102 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; | ||
2103 | 2103 | ||
2104 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 2104 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
2105 | btc_dpm_vblank_too_short(rdev)) | 2105 | btc_dpm_vblank_too_short(rdev)) |
@@ -2141,39 +2141,6 @@ static void btc_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2141 | ps->low.vddci = max_limits->vddci; | 2141 | ps->low.vddci = max_limits->vddci; |
2142 | } | 2142 | } |
2143 | 2143 | ||
2144 | /* limit clocks to max supported clocks based on voltage dependency tables */ | ||
2145 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, | ||
2146 | &max_sclk_vddc); | ||
2147 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, | ||
2148 | &max_mclk_vddci); | ||
2149 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, | ||
2150 | &max_mclk_vddc); | ||
2151 | |||
2152 | if (max_sclk_vddc) { | ||
2153 | if (ps->low.sclk > max_sclk_vddc) | ||
2154 | ps->low.sclk = max_sclk_vddc; | ||
2155 | if (ps->medium.sclk > max_sclk_vddc) | ||
2156 | ps->medium.sclk = max_sclk_vddc; | ||
2157 | if (ps->high.sclk > max_sclk_vddc) | ||
2158 | ps->high.sclk = max_sclk_vddc; | ||
2159 | } | ||
2160 | if (max_mclk_vddci) { | ||
2161 | if (ps->low.mclk > max_mclk_vddci) | ||
2162 | ps->low.mclk = max_mclk_vddci; | ||
2163 | if (ps->medium.mclk > max_mclk_vddci) | ||
2164 | ps->medium.mclk = max_mclk_vddci; | ||
2165 | if (ps->high.mclk > max_mclk_vddci) | ||
2166 | ps->high.mclk = max_mclk_vddci; | ||
2167 | } | ||
2168 | if (max_mclk_vddc) { | ||
2169 | if (ps->low.mclk > max_mclk_vddc) | ||
2170 | ps->low.mclk = max_mclk_vddc; | ||
2171 | if (ps->medium.mclk > max_mclk_vddc) | ||
2172 | ps->medium.mclk = max_mclk_vddc; | ||
2173 | if (ps->high.mclk > max_mclk_vddc) | ||
2174 | ps->high.mclk = max_mclk_vddc; | ||
2175 | } | ||
2176 | |||
2177 | /* XXX validate the min clocks required for display */ | 2144 | /* XXX validate the min clocks required for display */ |
2178 | 2145 | ||
2179 | if (disable_mclk_switching) { | 2146 | if (disable_mclk_switching) { |
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index d416bb2ff48d..11a55e9dad7f 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | ||
27 | #include "radeon_ucode.h" | 28 | #include "radeon_ucode.h" |
28 | #include "cikd.h" | 29 | #include "cikd.h" |
29 | #include "r600_dpm.h" | 30 | #include "r600_dpm.h" |
@@ -162,8 +163,6 @@ static const struct ci_pt_config_reg didt_config_ci[] = | |||
162 | }; | 163 | }; |
163 | 164 | ||
164 | extern u8 rv770_get_memory_module_index(struct radeon_device *rdev); | 165 | extern u8 rv770_get_memory_module_index(struct radeon_device *rdev); |
165 | extern void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table, | ||
166 | u32 *max_clock); | ||
167 | extern int ni_copy_and_switch_arb_sets(struct radeon_device *rdev, | 166 | extern int ni_copy_and_switch_arb_sets(struct radeon_device *rdev, |
168 | u32 arb_freq_src, u32 arb_freq_dest); | 167 | u32 arb_freq_src, u32 arb_freq_dest); |
169 | extern u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock); | 168 | extern u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock); |
@@ -748,7 +747,6 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev, | |||
748 | struct radeon_clock_and_voltage_limits *max_limits; | 747 | struct radeon_clock_and_voltage_limits *max_limits; |
749 | bool disable_mclk_switching; | 748 | bool disable_mclk_switching; |
750 | u32 sclk, mclk; | 749 | u32 sclk, mclk; |
751 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; | ||
752 | int i; | 750 | int i; |
753 | 751 | ||
754 | if (rps->vce_active) { | 752 | if (rps->vce_active) { |
@@ -784,29 +782,6 @@ static void ci_apply_state_adjust_rules(struct radeon_device *rdev, | |||
784 | } | 782 | } |
785 | } | 783 | } |
786 | 784 | ||
787 | /* limit clocks to max supported clocks based on voltage dependency tables */ | ||
788 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, | ||
789 | &max_sclk_vddc); | ||
790 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, | ||
791 | &max_mclk_vddci); | ||
792 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, | ||
793 | &max_mclk_vddc); | ||
794 | |||
795 | for (i = 0; i < ps->performance_level_count; i++) { | ||
796 | if (max_sclk_vddc) { | ||
797 | if (ps->performance_levels[i].sclk > max_sclk_vddc) | ||
798 | ps->performance_levels[i].sclk = max_sclk_vddc; | ||
799 | } | ||
800 | if (max_mclk_vddci) { | ||
801 | if (ps->performance_levels[i].mclk > max_mclk_vddci) | ||
802 | ps->performance_levels[i].mclk = max_mclk_vddci; | ||
803 | } | ||
804 | if (max_mclk_vddc) { | ||
805 | if (ps->performance_levels[i].mclk > max_mclk_vddc) | ||
806 | ps->performance_levels[i].mclk = max_mclk_vddc; | ||
807 | } | ||
808 | } | ||
809 | |||
810 | /* XXX validate the min clocks required for display */ | 785 | /* XXX validate the min clocks required for display */ |
811 | 786 | ||
812 | if (disable_mclk_switching) { | 787 | if (disable_mclk_switching) { |
@@ -5293,9 +5268,13 @@ int ci_dpm_init(struct radeon_device *rdev) | |||
5293 | void ci_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 5268 | void ci_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
5294 | struct seq_file *m) | 5269 | struct seq_file *m) |
5295 | { | 5270 | { |
5271 | struct ci_power_info *pi = ci_get_pi(rdev); | ||
5272 | struct radeon_ps *rps = &pi->current_rps; | ||
5296 | u32 sclk = ci_get_average_sclk_freq(rdev); | 5273 | u32 sclk = ci_get_average_sclk_freq(rdev); |
5297 | u32 mclk = ci_get_average_mclk_freq(rdev); | 5274 | u32 mclk = ci_get_average_mclk_freq(rdev); |
5298 | 5275 | ||
5276 | seq_printf(m, "uvd %sabled\n", pi->uvd_enabled ? "en" : "dis"); | ||
5277 | seq_printf(m, "vce %sabled\n", rps->vce_active ? "en" : "dis"); | ||
5299 | seq_printf(m, "power level avg sclk: %u mclk: %u\n", | 5278 | seq_printf(m, "power level avg sclk: %u mclk: %u\n", |
5300 | sclk, mclk); | 5279 | sclk, mclk); |
5301 | } | 5280 | } |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 0d761f73a7fa..377afa504d2b 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -3993,7 +3993,7 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, | |||
3993 | return ERR_PTR(r); | 3993 | return ERR_PTR(r); |
3994 | } | 3994 | } |
3995 | 3995 | ||
3996 | radeon_semaphore_sync_resv(sem, resv, false); | 3996 | radeon_semaphore_sync_resv(rdev, sem, resv, false); |
3997 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 3997 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
3998 | 3998 | ||
3999 | for (i = 0; i < num_loops; i++) { | 3999 | for (i = 0; i < num_loops; i++) { |
@@ -4235,7 +4235,7 @@ static int cik_cp_gfx_load_microcode(struct radeon_device *rdev) | |||
4235 | WREG32(CP_PFP_UCODE_ADDR, 0); | 4235 | WREG32(CP_PFP_UCODE_ADDR, 0); |
4236 | for (i = 0; i < fw_size; i++) | 4236 | for (i = 0; i < fw_size; i++) |
4237 | WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++)); | 4237 | WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++)); |
4238 | WREG32(CP_PFP_UCODE_ADDR, 0); | 4238 | WREG32(CP_PFP_UCODE_ADDR, le32_to_cpu(pfp_hdr->header.ucode_version)); |
4239 | 4239 | ||
4240 | /* CE */ | 4240 | /* CE */ |
4241 | fw_data = (const __le32 *) | 4241 | fw_data = (const __le32 *) |
@@ -4244,7 +4244,7 @@ static int cik_cp_gfx_load_microcode(struct radeon_device *rdev) | |||
4244 | WREG32(CP_CE_UCODE_ADDR, 0); | 4244 | WREG32(CP_CE_UCODE_ADDR, 0); |
4245 | for (i = 0; i < fw_size; i++) | 4245 | for (i = 0; i < fw_size; i++) |
4246 | WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++)); | 4246 | WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++)); |
4247 | WREG32(CP_CE_UCODE_ADDR, 0); | 4247 | WREG32(CP_CE_UCODE_ADDR, le32_to_cpu(ce_hdr->header.ucode_version)); |
4248 | 4248 | ||
4249 | /* ME */ | 4249 | /* ME */ |
4250 | fw_data = (const __be32 *) | 4250 | fw_data = (const __be32 *) |
@@ -4253,7 +4253,8 @@ static int cik_cp_gfx_load_microcode(struct radeon_device *rdev) | |||
4253 | WREG32(CP_ME_RAM_WADDR, 0); | 4253 | WREG32(CP_ME_RAM_WADDR, 0); |
4254 | for (i = 0; i < fw_size; i++) | 4254 | for (i = 0; i < fw_size; i++) |
4255 | WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++)); | 4255 | WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++)); |
4256 | WREG32(CP_ME_RAM_WADDR, 0); | 4256 | WREG32(CP_ME_RAM_WADDR, le32_to_cpu(me_hdr->header.ucode_version)); |
4257 | WREG32(CP_ME_RAM_RADDR, le32_to_cpu(me_hdr->header.ucode_version)); | ||
4257 | } else { | 4258 | } else { |
4258 | const __be32 *fw_data; | 4259 | const __be32 *fw_data; |
4259 | 4260 | ||
@@ -4279,10 +4280,6 @@ static int cik_cp_gfx_load_microcode(struct radeon_device *rdev) | |||
4279 | WREG32(CP_ME_RAM_WADDR, 0); | 4280 | WREG32(CP_ME_RAM_WADDR, 0); |
4280 | } | 4281 | } |
4281 | 4282 | ||
4282 | WREG32(CP_PFP_UCODE_ADDR, 0); | ||
4283 | WREG32(CP_CE_UCODE_ADDR, 0); | ||
4284 | WREG32(CP_ME_RAM_WADDR, 0); | ||
4285 | WREG32(CP_ME_RAM_RADDR, 0); | ||
4286 | return 0; | 4283 | return 0; |
4287 | } | 4284 | } |
4288 | 4285 | ||
@@ -4564,7 +4561,7 @@ static int cik_cp_compute_load_microcode(struct radeon_device *rdev) | |||
4564 | WREG32(CP_MEC_ME1_UCODE_ADDR, 0); | 4561 | WREG32(CP_MEC_ME1_UCODE_ADDR, 0); |
4565 | for (i = 0; i < fw_size; i++) | 4562 | for (i = 0; i < fw_size; i++) |
4566 | WREG32(CP_MEC_ME1_UCODE_DATA, le32_to_cpup(fw_data++)); | 4563 | WREG32(CP_MEC_ME1_UCODE_DATA, le32_to_cpup(fw_data++)); |
4567 | WREG32(CP_MEC_ME1_UCODE_ADDR, 0); | 4564 | WREG32(CP_MEC_ME1_UCODE_ADDR, le32_to_cpu(mec_hdr->header.ucode_version)); |
4568 | 4565 | ||
4569 | /* MEC2 */ | 4566 | /* MEC2 */ |
4570 | if (rdev->family == CHIP_KAVERI) { | 4567 | if (rdev->family == CHIP_KAVERI) { |
@@ -4578,7 +4575,7 @@ static int cik_cp_compute_load_microcode(struct radeon_device *rdev) | |||
4578 | WREG32(CP_MEC_ME2_UCODE_ADDR, 0); | 4575 | WREG32(CP_MEC_ME2_UCODE_ADDR, 0); |
4579 | for (i = 0; i < fw_size; i++) | 4576 | for (i = 0; i < fw_size; i++) |
4580 | WREG32(CP_MEC_ME2_UCODE_DATA, le32_to_cpup(fw_data++)); | 4577 | WREG32(CP_MEC_ME2_UCODE_DATA, le32_to_cpup(fw_data++)); |
4581 | WREG32(CP_MEC_ME2_UCODE_ADDR, 0); | 4578 | WREG32(CP_MEC_ME2_UCODE_ADDR, le32_to_cpu(mec2_hdr->header.ucode_version)); |
4582 | } | 4579 | } |
4583 | } else { | 4580 | } else { |
4584 | const __be32 *fw_data; | 4581 | const __be32 *fw_data; |
@@ -4690,7 +4687,7 @@ static int cik_mec_init(struct radeon_device *rdev) | |||
4690 | r = radeon_bo_create(rdev, | 4687 | r = radeon_bo_create(rdev, |
4691 | rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2, | 4688 | rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2, |
4692 | PAGE_SIZE, true, | 4689 | PAGE_SIZE, true, |
4693 | RADEON_GEM_DOMAIN_GTT, 0, NULL, | 4690 | RADEON_GEM_DOMAIN_GTT, 0, NULL, NULL, |
4694 | &rdev->mec.hpd_eop_obj); | 4691 | &rdev->mec.hpd_eop_obj); |
4695 | if (r) { | 4692 | if (r) { |
4696 | dev_warn(rdev->dev, "(%d) create HDP EOP bo failed\n", r); | 4693 | dev_warn(rdev->dev, "(%d) create HDP EOP bo failed\n", r); |
@@ -4804,7 +4801,7 @@ struct bonaire_mqd | |||
4804 | */ | 4801 | */ |
4805 | static int cik_cp_compute_resume(struct radeon_device *rdev) | 4802 | static int cik_cp_compute_resume(struct radeon_device *rdev) |
4806 | { | 4803 | { |
4807 | int r, i, idx; | 4804 | int r, i, j, idx; |
4808 | u32 tmp; | 4805 | u32 tmp; |
4809 | bool use_doorbell = true; | 4806 | bool use_doorbell = true; |
4810 | u64 hqd_gpu_addr; | 4807 | u64 hqd_gpu_addr; |
@@ -4861,7 +4858,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
4861 | sizeof(struct bonaire_mqd), | 4858 | sizeof(struct bonaire_mqd), |
4862 | PAGE_SIZE, true, | 4859 | PAGE_SIZE, true, |
4863 | RADEON_GEM_DOMAIN_GTT, 0, NULL, | 4860 | RADEON_GEM_DOMAIN_GTT, 0, NULL, |
4864 | &rdev->ring[idx].mqd_obj); | 4861 | NULL, &rdev->ring[idx].mqd_obj); |
4865 | if (r) { | 4862 | if (r) { |
4866 | dev_warn(rdev->dev, "(%d) create MQD bo failed\n", r); | 4863 | dev_warn(rdev->dev, "(%d) create MQD bo failed\n", r); |
4867 | return r; | 4864 | return r; |
@@ -4923,7 +4920,7 @@ static int cik_cp_compute_resume(struct radeon_device *rdev) | |||
4923 | mqd->queue_state.cp_hqd_pq_wptr= 0; | 4920 | mqd->queue_state.cp_hqd_pq_wptr= 0; |
4924 | if (RREG32(CP_HQD_ACTIVE) & 1) { | 4921 | if (RREG32(CP_HQD_ACTIVE) & 1) { |
4925 | WREG32(CP_HQD_DEQUEUE_REQUEST, 1); | 4922 | WREG32(CP_HQD_DEQUEUE_REQUEST, 1); |
4926 | for (i = 0; i < rdev->usec_timeout; i++) { | 4923 | for (j = 0; j < rdev->usec_timeout; j++) { |
4927 | if (!(RREG32(CP_HQD_ACTIVE) & 1)) | 4924 | if (!(RREG32(CP_HQD_ACTIVE) & 1)) |
4928 | break; | 4925 | break; |
4929 | udelay(1); | 4926 | udelay(1); |
@@ -6227,7 +6224,7 @@ static int cik_rlc_resume(struct radeon_device *rdev) | |||
6227 | WREG32(RLC_GPM_UCODE_ADDR, 0); | 6224 | WREG32(RLC_GPM_UCODE_ADDR, 0); |
6228 | for (i = 0; i < size; i++) | 6225 | for (i = 0; i < size; i++) |
6229 | WREG32(RLC_GPM_UCODE_DATA, le32_to_cpup(fw_data++)); | 6226 | WREG32(RLC_GPM_UCODE_DATA, le32_to_cpup(fw_data++)); |
6230 | WREG32(RLC_GPM_UCODE_ADDR, 0); | 6227 | WREG32(RLC_GPM_UCODE_ADDR, le32_to_cpu(hdr->header.ucode_version)); |
6231 | } else { | 6228 | } else { |
6232 | const __be32 *fw_data; | 6229 | const __be32 *fw_data; |
6233 | 6230 | ||
@@ -7752,17 +7749,17 @@ static inline u32 cik_get_ih_wptr(struct radeon_device *rdev) | |||
7752 | wptr = RREG32(IH_RB_WPTR); | 7749 | wptr = RREG32(IH_RB_WPTR); |
7753 | 7750 | ||
7754 | if (wptr & RB_OVERFLOW) { | 7751 | if (wptr & RB_OVERFLOW) { |
7752 | wptr &= ~RB_OVERFLOW; | ||
7755 | /* When a ring buffer overflow happen start parsing interrupt | 7753 | /* When a ring buffer overflow happen start parsing interrupt |
7756 | * from the last not overwritten vector (wptr + 16). Hopefully | 7754 | * from the last not overwritten vector (wptr + 16). Hopefully |
7757 | * this should allow us to catchup. | 7755 | * this should allow us to catchup. |
7758 | */ | 7756 | */ |
7759 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 7757 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
7760 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 7758 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
7761 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 7759 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
7762 | tmp = RREG32(IH_RB_CNTL); | 7760 | tmp = RREG32(IH_RB_CNTL); |
7763 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 7761 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
7764 | WREG32(IH_RB_CNTL, tmp); | 7762 | WREG32(IH_RB_CNTL, tmp); |
7765 | wptr &= ~RB_OVERFLOW; | ||
7766 | } | 7763 | } |
7767 | return (wptr & rdev->ih.ptr_mask); | 7764 | return (wptr & rdev->ih.ptr_mask); |
7768 | } | 7765 | } |
@@ -8252,6 +8249,7 @@ restart_ih: | |||
8252 | /* wptr/rptr are in bytes! */ | 8249 | /* wptr/rptr are in bytes! */ |
8253 | rptr += 16; | 8250 | rptr += 16; |
8254 | rptr &= rdev->ih.ptr_mask; | 8251 | rptr &= rdev->ih.ptr_mask; |
8252 | WREG32(IH_RB_RPTR, rptr); | ||
8255 | } | 8253 | } |
8256 | if (queue_hotplug) | 8254 | if (queue_hotplug) |
8257 | schedule_work(&rdev->hotplug_work); | 8255 | schedule_work(&rdev->hotplug_work); |
@@ -8262,7 +8260,6 @@ restart_ih: | |||
8262 | if (queue_thermal) | 8260 | if (queue_thermal) |
8263 | schedule_work(&rdev->pm.dpm.thermal.work); | 8261 | schedule_work(&rdev->pm.dpm.thermal.work); |
8264 | rdev->ih.rptr = rptr; | 8262 | rdev->ih.rptr = rptr; |
8265 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
8266 | atomic_set(&rdev->ih.lock, 0); | 8263 | atomic_set(&rdev->ih.lock, 0); |
8267 | 8264 | ||
8268 | /* make sure wptr hasn't changed while processing */ | 8265 | /* make sure wptr hasn't changed while processing */ |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index c01a6100c318..4e8432d07f15 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
@@ -489,13 +489,6 @@ int cik_sdma_resume(struct radeon_device *rdev) | |||
489 | { | 489 | { |
490 | int r; | 490 | int r; |
491 | 491 | ||
492 | /* Reset dma */ | ||
493 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_SDMA | SOFT_RESET_SDMA1); | ||
494 | RREG32(SRBM_SOFT_RESET); | ||
495 | udelay(50); | ||
496 | WREG32(SRBM_SOFT_RESET, 0); | ||
497 | RREG32(SRBM_SOFT_RESET); | ||
498 | |||
499 | r = cik_sdma_load_microcode(rdev); | 492 | r = cik_sdma_load_microcode(rdev); |
500 | if (r) | 493 | if (r) |
501 | return r; | 494 | return r; |
@@ -571,7 +564,7 @@ struct radeon_fence *cik_copy_dma(struct radeon_device *rdev, | |||
571 | return ERR_PTR(r); | 564 | return ERR_PTR(r); |
572 | } | 565 | } |
573 | 566 | ||
574 | radeon_semaphore_sync_resv(sem, resv, false); | 567 | radeon_semaphore_sync_resv(rdev, sem, resv, false); |
575 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 568 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
576 | 569 | ||
577 | for (i = 0; i < num_loops; i++) { | 570 | for (i = 0; i < num_loops; i++) { |
@@ -618,16 +611,19 @@ int cik_sdma_ring_test(struct radeon_device *rdev, | |||
618 | { | 611 | { |
619 | unsigned i; | 612 | unsigned i; |
620 | int r; | 613 | int r; |
621 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 614 | unsigned index; |
622 | u32 tmp; | 615 | u32 tmp; |
616 | u64 gpu_addr; | ||
623 | 617 | ||
624 | if (!ptr) { | 618 | if (ring->idx == R600_RING_TYPE_DMA_INDEX) |
625 | DRM_ERROR("invalid vram scratch pointer\n"); | 619 | index = R600_WB_DMA_RING_TEST_OFFSET; |
626 | return -EINVAL; | 620 | else |
627 | } | 621 | index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; |
622 | |||
623 | gpu_addr = rdev->wb.gpu_addr + index; | ||
628 | 624 | ||
629 | tmp = 0xCAFEDEAD; | 625 | tmp = 0xCAFEDEAD; |
630 | writel(tmp, ptr); | 626 | rdev->wb.wb[index/4] = cpu_to_le32(tmp); |
631 | 627 | ||
632 | r = radeon_ring_lock(rdev, ring, 5); | 628 | r = radeon_ring_lock(rdev, ring, 5); |
633 | if (r) { | 629 | if (r) { |
@@ -635,14 +631,14 @@ int cik_sdma_ring_test(struct radeon_device *rdev, | |||
635 | return r; | 631 | return r; |
636 | } | 632 | } |
637 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); | 633 | radeon_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_WRITE, SDMA_WRITE_SUB_OPCODE_LINEAR, 0)); |
638 | radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc); | 634 | radeon_ring_write(ring, lower_32_bits(gpu_addr)); |
639 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr)); | 635 | radeon_ring_write(ring, upper_32_bits(gpu_addr)); |
640 | radeon_ring_write(ring, 1); /* number of DWs to follow */ | 636 | radeon_ring_write(ring, 1); /* number of DWs to follow */ |
641 | radeon_ring_write(ring, 0xDEADBEEF); | 637 | radeon_ring_write(ring, 0xDEADBEEF); |
642 | radeon_ring_unlock_commit(rdev, ring, false); | 638 | radeon_ring_unlock_commit(rdev, ring, false); |
643 | 639 | ||
644 | for (i = 0; i < rdev->usec_timeout; i++) { | 640 | for (i = 0; i < rdev->usec_timeout; i++) { |
645 | tmp = readl(ptr); | 641 | tmp = le32_to_cpu(rdev->wb.wb[index/4]); |
646 | if (tmp == 0xDEADBEEF) | 642 | if (tmp == 0xDEADBEEF) |
647 | break; | 643 | break; |
648 | DRM_UDELAY(1); | 644 | DRM_UDELAY(1); |
diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 47d31e915758..9aad0327e4d1 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | ||
27 | #include "evergreend.h" | 28 | #include "evergreend.h" |
28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
29 | #include "cypress_dpm.h" | 30 | #include "cypress_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 51800e340a57..2fe8cfc966d9 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c | |||
@@ -32,7 +32,7 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
32 | struct drm_connector *connector; | 32 | struct drm_connector *connector; |
33 | struct radeon_connector *radeon_connector = NULL; | 33 | struct radeon_connector *radeon_connector = NULL; |
34 | u32 tmp; | 34 | u32 tmp; |
35 | u8 *sadb; | 35 | u8 *sadb = NULL; |
36 | int sad_count; | 36 | int sad_count; |
37 | 37 | ||
38 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 38 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
@@ -49,8 +49,8 @@ static void dce3_2_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
49 | 49 | ||
50 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); | 50 | sad_count = drm_edid_to_speaker_allocation(radeon_connector->edid, &sadb); |
51 | if (sad_count < 0) { | 51 | if (sad_count < 0) { |
52 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 52 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
53 | return; | 53 | sad_count = 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* program the speaker allocation */ | 56 | /* program the speaker allocation */ |
@@ -165,7 +165,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m | |||
165 | 165 | ||
166 | /* disable audio prior to setting up hw */ | 166 | /* disable audio prior to setting up hw */ |
167 | dig->afmt->pin = r600_audio_get_pin(rdev); | 167 | dig->afmt->pin = r600_audio_get_pin(rdev); |
168 | r600_audio_enable(rdev, dig->afmt->pin, false); | 168 | r600_audio_enable(rdev, dig->afmt->pin, 0); |
169 | 169 | ||
170 | r600_audio_set_dto(encoder, mode->clock); | 170 | r600_audio_set_dto(encoder, mode->clock); |
171 | 171 | ||
@@ -240,5 +240,5 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m | |||
240 | r600_hdmi_audio_workaround(encoder); | 240 | r600_hdmi_audio_workaround(encoder); |
241 | 241 | ||
242 | /* enable audio after to setting up hw */ | 242 | /* enable audio after to setting up hw */ |
243 | r600_audio_enable(rdev, dig->afmt->pin, true); | 243 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); |
244 | } | 244 | } |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index ab29f953a767..f312edf4d50e 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -155,7 +155,7 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
155 | struct drm_connector *connector; | 155 | struct drm_connector *connector; |
156 | struct radeon_connector *radeon_connector = NULL; | 156 | struct radeon_connector *radeon_connector = NULL; |
157 | u32 offset, tmp; | 157 | u32 offset, tmp; |
158 | u8 *sadb; | 158 | u8 *sadb = NULL; |
159 | int sad_count; | 159 | int sad_count; |
160 | 160 | ||
161 | if (!dig || !dig->afmt || !dig->afmt->pin) | 161 | if (!dig || !dig->afmt || !dig->afmt->pin) |
@@ -176,9 +176,9 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
176 | } | 176 | } |
177 | 177 | ||
178 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); | 178 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); |
179 | if (sad_count <= 0) { | 179 | if (sad_count < 0) { |
180 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 180 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
181 | return; | 181 | sad_count = 0; |
182 | } | 182 | } |
183 | 183 | ||
184 | /* program the speaker allocation */ | 184 | /* program the speaker allocation */ |
@@ -284,13 +284,13 @@ static int dce6_audio_chipset_supported(struct radeon_device *rdev) | |||
284 | 284 | ||
285 | void dce6_audio_enable(struct radeon_device *rdev, | 285 | void dce6_audio_enable(struct radeon_device *rdev, |
286 | struct r600_audio_pin *pin, | 286 | struct r600_audio_pin *pin, |
287 | bool enable) | 287 | u8 enable_mask) |
288 | { | 288 | { |
289 | if (!pin) | 289 | if (!pin) |
290 | return; | 290 | return; |
291 | 291 | ||
292 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL, | 292 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, |
293 | enable ? AUDIO_ENABLED : 0); | 293 | enable_mask ? AUDIO_ENABLED : 0); |
294 | } | 294 | } |
295 | 295 | ||
296 | static const u32 pin_offsets[7] = | 296 | static const u32 pin_offsets[7] = |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index dbca60c7d097..a31f1ca40c6a 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -22,7 +22,6 @@ | |||
22 | * Authors: Alex Deucher | 22 | * Authors: Alex Deucher |
23 | */ | 23 | */ |
24 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
27 | #include <drm/drmP.h> | 26 | #include <drm/drmP.h> |
28 | #include "radeon.h" | 27 | #include "radeon.h" |
@@ -4023,7 +4022,7 @@ int sumo_rlc_init(struct radeon_device *rdev) | |||
4023 | if (rdev->rlc.save_restore_obj == NULL) { | 4022 | if (rdev->rlc.save_restore_obj == NULL) { |
4024 | r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true, | 4023 | r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true, |
4025 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, | 4024 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, |
4026 | &rdev->rlc.save_restore_obj); | 4025 | NULL, &rdev->rlc.save_restore_obj); |
4027 | if (r) { | 4026 | if (r) { |
4028 | dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r); | 4027 | dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r); |
4029 | return r; | 4028 | return r; |
@@ -4102,7 +4101,7 @@ int sumo_rlc_init(struct radeon_device *rdev) | |||
4102 | if (rdev->rlc.clear_state_obj == NULL) { | 4101 | if (rdev->rlc.clear_state_obj == NULL) { |
4103 | r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true, | 4102 | r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true, |
4104 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, | 4103 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, |
4105 | &rdev->rlc.clear_state_obj); | 4104 | NULL, &rdev->rlc.clear_state_obj); |
4106 | if (r) { | 4105 | if (r) { |
4107 | dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r); | 4106 | dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r); |
4108 | sumo_rlc_fini(rdev); | 4107 | sumo_rlc_fini(rdev); |
@@ -4179,7 +4178,7 @@ int sumo_rlc_init(struct radeon_device *rdev) | |||
4179 | r = radeon_bo_create(rdev, rdev->rlc.cp_table_size, | 4178 | r = radeon_bo_create(rdev, rdev->rlc.cp_table_size, |
4180 | PAGE_SIZE, true, | 4179 | PAGE_SIZE, true, |
4181 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, | 4180 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, |
4182 | &rdev->rlc.cp_table_obj); | 4181 | NULL, &rdev->rlc.cp_table_obj); |
4183 | if (r) { | 4182 | if (r) { |
4184 | dev_warn(rdev->dev, "(%d) create RLC cp table bo failed\n", r); | 4183 | dev_warn(rdev->dev, "(%d) create RLC cp table bo failed\n", r); |
4185 | sumo_rlc_fini(rdev); | 4184 | sumo_rlc_fini(rdev); |
@@ -4749,17 +4748,17 @@ static u32 evergreen_get_ih_wptr(struct radeon_device *rdev) | |||
4749 | wptr = RREG32(IH_RB_WPTR); | 4748 | wptr = RREG32(IH_RB_WPTR); |
4750 | 4749 | ||
4751 | if (wptr & RB_OVERFLOW) { | 4750 | if (wptr & RB_OVERFLOW) { |
4751 | wptr &= ~RB_OVERFLOW; | ||
4752 | /* When a ring buffer overflow happen start parsing interrupt | 4752 | /* When a ring buffer overflow happen start parsing interrupt |
4753 | * from the last not overwritten vector (wptr + 16). Hopefully | 4753 | * from the last not overwritten vector (wptr + 16). Hopefully |
4754 | * this should allow us to catchup. | 4754 | * this should allow us to catchup. |
4755 | */ | 4755 | */ |
4756 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 4756 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
4757 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 4757 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
4758 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 4758 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
4759 | tmp = RREG32(IH_RB_CNTL); | 4759 | tmp = RREG32(IH_RB_CNTL); |
4760 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 4760 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
4761 | WREG32(IH_RB_CNTL, tmp); | 4761 | WREG32(IH_RB_CNTL, tmp); |
4762 | wptr &= ~RB_OVERFLOW; | ||
4763 | } | 4762 | } |
4764 | return (wptr & rdev->ih.ptr_mask); | 4763 | return (wptr & rdev->ih.ptr_mask); |
4765 | } | 4764 | } |
@@ -5137,6 +5136,7 @@ restart_ih: | |||
5137 | /* wptr/rptr are in bytes! */ | 5136 | /* wptr/rptr are in bytes! */ |
5138 | rptr += 16; | 5137 | rptr += 16; |
5139 | rptr &= rdev->ih.ptr_mask; | 5138 | rptr &= rdev->ih.ptr_mask; |
5139 | WREG32(IH_RB_RPTR, rptr); | ||
5140 | } | 5140 | } |
5141 | if (queue_hotplug) | 5141 | if (queue_hotplug) |
5142 | schedule_work(&rdev->hotplug_work); | 5142 | schedule_work(&rdev->hotplug_work); |
@@ -5145,7 +5145,6 @@ restart_ih: | |||
5145 | if (queue_thermal && rdev->pm.dpm_enabled) | 5145 | if (queue_thermal && rdev->pm.dpm_enabled) |
5146 | schedule_work(&rdev->pm.dpm.thermal.work); | 5146 | schedule_work(&rdev->pm.dpm.thermal.work); |
5147 | rdev->ih.rptr = rptr; | 5147 | rdev->ih.rptr = rptr; |
5148 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
5149 | atomic_set(&rdev->ih.lock, 0); | 5148 | atomic_set(&rdev->ih.lock, 0); |
5150 | 5149 | ||
5151 | /* make sure wptr hasn't changed while processing */ | 5150 | /* make sure wptr hasn't changed while processing */ |
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c index 946f37d0b469..66bcfadeedd1 100644 --- a/drivers/gpu/drm/radeon/evergreen_dma.c +++ b/drivers/gpu/drm/radeon/evergreen_dma.c | |||
@@ -133,7 +133,7 @@ struct radeon_fence *evergreen_copy_dma(struct radeon_device *rdev, | |||
133 | return ERR_PTR(r); | 133 | return ERR_PTR(r); |
134 | } | 134 | } |
135 | 135 | ||
136 | radeon_semaphore_sync_resv(sem, resv, false); | 136 | radeon_semaphore_sync_resv(rdev, sem, resv, false); |
137 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 137 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
138 | 138 | ||
139 | for (i = 0; i < num_loops; i++) { | 139 | for (i = 0; i < num_loops; i++) { |
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 278c7a139d74..53abd9b17a50 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -38,6 +38,37 @@ extern void dce6_afmt_select_pin(struct drm_encoder *encoder); | |||
38 | extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | 38 | extern void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, |
39 | struct drm_display_mode *mode); | 39 | struct drm_display_mode *mode); |
40 | 40 | ||
41 | /* enable the audio stream */ | ||
42 | static void dce4_audio_enable(struct radeon_device *rdev, | ||
43 | struct r600_audio_pin *pin, | ||
44 | u8 enable_mask) | ||
45 | { | ||
46 | u32 tmp = RREG32(AZ_HOT_PLUG_CONTROL); | ||
47 | |||
48 | if (!pin) | ||
49 | return; | ||
50 | |||
51 | if (enable_mask) { | ||
52 | tmp |= AUDIO_ENABLED; | ||
53 | if (enable_mask & 1) | ||
54 | tmp |= PIN0_AUDIO_ENABLED; | ||
55 | if (enable_mask & 2) | ||
56 | tmp |= PIN1_AUDIO_ENABLED; | ||
57 | if (enable_mask & 4) | ||
58 | tmp |= PIN2_AUDIO_ENABLED; | ||
59 | if (enable_mask & 8) | ||
60 | tmp |= PIN3_AUDIO_ENABLED; | ||
61 | } else { | ||
62 | tmp &= ~(AUDIO_ENABLED | | ||
63 | PIN0_AUDIO_ENABLED | | ||
64 | PIN1_AUDIO_ENABLED | | ||
65 | PIN2_AUDIO_ENABLED | | ||
66 | PIN3_AUDIO_ENABLED); | ||
67 | } | ||
68 | |||
69 | WREG32(AZ_HOT_PLUG_CONTROL, tmp); | ||
70 | } | ||
71 | |||
41 | /* | 72 | /* |
42 | * update the N and CTS parameters for a given pixel clock rate | 73 | * update the N and CTS parameters for a given pixel clock rate |
43 | */ | 74 | */ |
@@ -102,7 +133,7 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
102 | struct drm_connector *connector; | 133 | struct drm_connector *connector; |
103 | struct radeon_connector *radeon_connector = NULL; | 134 | struct radeon_connector *radeon_connector = NULL; |
104 | u32 tmp; | 135 | u32 tmp; |
105 | u8 *sadb; | 136 | u8 *sadb = NULL; |
106 | int sad_count; | 137 | int sad_count; |
107 | 138 | ||
108 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | 139 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { |
@@ -118,9 +149,9 @@ static void dce4_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
118 | } | 149 | } |
119 | 150 | ||
120 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); | 151 | sad_count = drm_edid_to_speaker_allocation(radeon_connector_edid(connector), &sadb); |
121 | if (sad_count <= 0) { | 152 | if (sad_count < 0) { |
122 | DRM_ERROR("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); | 153 | DRM_DEBUG("Couldn't read Speaker Allocation Data Block: %d\n", sad_count); |
123 | return; | 154 | sad_count = 0; |
124 | } | 155 | } |
125 | 156 | ||
126 | /* program the speaker allocation */ | 157 | /* program the speaker allocation */ |
@@ -318,10 +349,10 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
318 | /* disable audio prior to setting up hw */ | 349 | /* disable audio prior to setting up hw */ |
319 | if (ASIC_IS_DCE6(rdev)) { | 350 | if (ASIC_IS_DCE6(rdev)) { |
320 | dig->afmt->pin = dce6_audio_get_pin(rdev); | 351 | dig->afmt->pin = dce6_audio_get_pin(rdev); |
321 | dce6_audio_enable(rdev, dig->afmt->pin, false); | 352 | dce6_audio_enable(rdev, dig->afmt->pin, 0); |
322 | } else { | 353 | } else { |
323 | dig->afmt->pin = r600_audio_get_pin(rdev); | 354 | dig->afmt->pin = r600_audio_get_pin(rdev); |
324 | r600_audio_enable(rdev, dig->afmt->pin, false); | 355 | dce4_audio_enable(rdev, dig->afmt->pin, 0); |
325 | } | 356 | } |
326 | 357 | ||
327 | evergreen_audio_set_dto(encoder, mode->clock); | 358 | evergreen_audio_set_dto(encoder, mode->clock); |
@@ -463,13 +494,15 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
463 | 494 | ||
464 | /* enable audio after to setting up hw */ | 495 | /* enable audio after to setting up hw */ |
465 | if (ASIC_IS_DCE6(rdev)) | 496 | if (ASIC_IS_DCE6(rdev)) |
466 | dce6_audio_enable(rdev, dig->afmt->pin, true); | 497 | dce6_audio_enable(rdev, dig->afmt->pin, 1); |
467 | else | 498 | else |
468 | r600_audio_enable(rdev, dig->afmt->pin, true); | 499 | dce4_audio_enable(rdev, dig->afmt->pin, 0xf); |
469 | } | 500 | } |
470 | 501 | ||
471 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | 502 | void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) |
472 | { | 503 | { |
504 | struct drm_device *dev = encoder->dev; | ||
505 | struct radeon_device *rdev = dev->dev_private; | ||
473 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 506 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
474 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 507 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
475 | 508 | ||
@@ -482,6 +515,14 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
482 | if (!enable && !dig->afmt->enabled) | 515 | if (!enable && !dig->afmt->enabled) |
483 | return; | 516 | return; |
484 | 517 | ||
518 | if (!enable && dig->afmt->pin) { | ||
519 | if (ASIC_IS_DCE6(rdev)) | ||
520 | dce6_audio_enable(rdev, dig->afmt->pin, 0); | ||
521 | else | ||
522 | dce4_audio_enable(rdev, dig->afmt->pin, 0); | ||
523 | dig->afmt->pin = NULL; | ||
524 | } | ||
525 | |||
485 | dig->afmt->enabled = enable; | 526 | dig->afmt->enabled = enable; |
486 | 527 | ||
487 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", | 528 | DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 8b58e11b64fa..1dd976f447fa 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #define KV_MINIMUM_ENGINE_CLOCK 800 | 33 | #define KV_MINIMUM_ENGINE_CLOCK 800 |
34 | #define SMC_RAM_END 0x40000 | 34 | #define SMC_RAM_END 0x40000 |
35 | 35 | ||
36 | static int kv_enable_nb_dpm(struct radeon_device *rdev, | ||
37 | bool enable); | ||
36 | static void kv_init_graphics_levels(struct radeon_device *rdev); | 38 | static void kv_init_graphics_levels(struct radeon_device *rdev); |
37 | static int kv_calculate_ds_divider(struct radeon_device *rdev); | 39 | static int kv_calculate_ds_divider(struct radeon_device *rdev); |
38 | static int kv_calculate_nbps_level_settings(struct radeon_device *rdev); | 40 | static int kv_calculate_nbps_level_settings(struct radeon_device *rdev); |
@@ -1295,6 +1297,9 @@ void kv_dpm_disable(struct radeon_device *rdev) | |||
1295 | { | 1297 | { |
1296 | kv_smc_bapm_enable(rdev, false); | 1298 | kv_smc_bapm_enable(rdev, false); |
1297 | 1299 | ||
1300 | if (rdev->family == CHIP_MULLINS) | ||
1301 | kv_enable_nb_dpm(rdev, false); | ||
1302 | |||
1298 | /* powerup blocks */ | 1303 | /* powerup blocks */ |
1299 | kv_dpm_powergate_acp(rdev, false); | 1304 | kv_dpm_powergate_acp(rdev, false); |
1300 | kv_dpm_powergate_samu(rdev, false); | 1305 | kv_dpm_powergate_samu(rdev, false); |
@@ -1769,15 +1774,24 @@ static int kv_update_dfs_bypass_settings(struct radeon_device *rdev, | |||
1769 | return ret; | 1774 | return ret; |
1770 | } | 1775 | } |
1771 | 1776 | ||
1772 | static int kv_enable_nb_dpm(struct radeon_device *rdev) | 1777 | static int kv_enable_nb_dpm(struct radeon_device *rdev, |
1778 | bool enable) | ||
1773 | { | 1779 | { |
1774 | struct kv_power_info *pi = kv_get_pi(rdev); | 1780 | struct kv_power_info *pi = kv_get_pi(rdev); |
1775 | int ret = 0; | 1781 | int ret = 0; |
1776 | 1782 | ||
1777 | if (pi->enable_nb_dpm && !pi->nb_dpm_enabled) { | 1783 | if (enable) { |
1778 | ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_NBDPM_Enable); | 1784 | if (pi->enable_nb_dpm && !pi->nb_dpm_enabled) { |
1779 | if (ret == 0) | 1785 | ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_NBDPM_Enable); |
1780 | pi->nb_dpm_enabled = true; | 1786 | if (ret == 0) |
1787 | pi->nb_dpm_enabled = true; | ||
1788 | } | ||
1789 | } else { | ||
1790 | if (pi->enable_nb_dpm && pi->nb_dpm_enabled) { | ||
1791 | ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_NBDPM_Disable); | ||
1792 | if (ret == 0) | ||
1793 | pi->nb_dpm_enabled = false; | ||
1794 | } | ||
1781 | } | 1795 | } |
1782 | 1796 | ||
1783 | return ret; | 1797 | return ret; |
@@ -1864,7 +1878,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1864 | } | 1878 | } |
1865 | kv_update_sclk_t(rdev); | 1879 | kv_update_sclk_t(rdev); |
1866 | if (rdev->family == CHIP_MULLINS) | 1880 | if (rdev->family == CHIP_MULLINS) |
1867 | kv_enable_nb_dpm(rdev); | 1881 | kv_enable_nb_dpm(rdev, true); |
1868 | } | 1882 | } |
1869 | } else { | 1883 | } else { |
1870 | if (pi->enable_dpm) { | 1884 | if (pi->enable_dpm) { |
@@ -1889,7 +1903,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1889 | } | 1903 | } |
1890 | kv_update_acp_boot_level(rdev); | 1904 | kv_update_acp_boot_level(rdev); |
1891 | kv_update_sclk_t(rdev); | 1905 | kv_update_sclk_t(rdev); |
1892 | kv_enable_nb_dpm(rdev); | 1906 | kv_enable_nb_dpm(rdev, true); |
1893 | } | 1907 | } |
1894 | } | 1908 | } |
1895 | 1909 | ||
@@ -2773,6 +2787,8 @@ void kv_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | |||
2773 | tmp = (RREG32_SMC(SMU_VOLTAGE_STATUS) & SMU_VOLTAGE_CURRENT_LEVEL_MASK) >> | 2787 | tmp = (RREG32_SMC(SMU_VOLTAGE_STATUS) & SMU_VOLTAGE_CURRENT_LEVEL_MASK) >> |
2774 | SMU_VOLTAGE_CURRENT_LEVEL_SHIFT; | 2788 | SMU_VOLTAGE_CURRENT_LEVEL_SHIFT; |
2775 | vddc = kv_convert_8bit_index_to_voltage(rdev, (u16)tmp); | 2789 | vddc = kv_convert_8bit_index_to_voltage(rdev, (u16)tmp); |
2790 | seq_printf(m, "uvd %sabled\n", pi->uvd_power_gated ? "dis" : "en"); | ||
2791 | seq_printf(m, "vce %sabled\n", pi->vce_power_gated ? "dis" : "en"); | ||
2776 | seq_printf(m, "power level %d sclk: %u vddc: %u\n", | 2792 | seq_printf(m, "power level %d sclk: %u vddc: %u\n", |
2777 | current_index, sclk, vddc); | 2793 | current_index, sclk, vddc); |
2778 | } | 2794 | } |
diff --git a/drivers/gpu/drm/radeon/ni_dma.c b/drivers/gpu/drm/radeon/ni_dma.c index 8a3e6221cece..f26f0a9fb522 100644 --- a/drivers/gpu/drm/radeon/ni_dma.c +++ b/drivers/gpu/drm/radeon/ni_dma.c | |||
@@ -191,12 +191,6 @@ int cayman_dma_resume(struct radeon_device *rdev) | |||
191 | u32 reg_offset, wb_offset; | 191 | u32 reg_offset, wb_offset; |
192 | int i, r; | 192 | int i, r; |
193 | 193 | ||
194 | /* Reset dma */ | ||
195 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
196 | RREG32(SRBM_SOFT_RESET); | ||
197 | udelay(50); | ||
198 | WREG32(SRBM_SOFT_RESET, 0); | ||
199 | |||
200 | for (i = 0; i < 2; i++) { | 194 | for (i = 0; i < 2; i++) { |
201 | if (i == 0) { | 195 | if (i == 0) { |
202 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; | 196 | ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 01fc4888e6fe..6d2f16cf2c1c 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "drmP.h" | 24 | #include "drmP.h" |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_asic.h" | ||
26 | #include "nid.h" | 27 | #include "nid.h" |
27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
28 | #include "ni_dpm.h" | 29 | #include "ni_dpm.h" |
@@ -789,7 +790,6 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev, | |||
789 | bool disable_mclk_switching; | 790 | bool disable_mclk_switching; |
790 | u32 mclk; | 791 | u32 mclk; |
791 | u16 vddci; | 792 | u16 vddci; |
792 | u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc; | ||
793 | int i; | 793 | int i; |
794 | 794 | ||
795 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || | 795 | if ((rdev->pm.dpm.new_active_crtc_count > 1) || |
@@ -816,29 +816,6 @@ static void ni_apply_state_adjust_rules(struct radeon_device *rdev, | |||
816 | } | 816 | } |
817 | } | 817 | } |
818 | 818 | ||
819 | /* limit clocks to max supported clocks based on voltage dependency tables */ | ||
820 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk, | ||
821 | &max_sclk_vddc); | ||
822 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk, | ||
823 | &max_mclk_vddci); | ||
824 | btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk, | ||
825 | &max_mclk_vddc); | ||
826 | |||
827 | for (i = 0; i < ps->performance_level_count; i++) { | ||
828 | if (max_sclk_vddc) { | ||
829 | if (ps->performance_levels[i].sclk > max_sclk_vddc) | ||
830 | ps->performance_levels[i].sclk = max_sclk_vddc; | ||
831 | } | ||
832 | if (max_mclk_vddci) { | ||
833 | if (ps->performance_levels[i].mclk > max_mclk_vddci) | ||
834 | ps->performance_levels[i].mclk = max_mclk_vddci; | ||
835 | } | ||
836 | if (max_mclk_vddc) { | ||
837 | if (ps->performance_levels[i].mclk > max_mclk_vddc) | ||
838 | ps->performance_levels[i].mclk = max_mclk_vddc; | ||
839 | } | ||
840 | } | ||
841 | |||
842 | /* XXX validate the min clocks required for display */ | 819 | /* XXX validate the min clocks required for display */ |
843 | 820 | ||
844 | /* adjust low state */ | 821 | /* adjust low state */ |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index c6b486f888d5..10f8be0ee173 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -821,6 +821,20 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) | |||
821 | return RREG32(RADEON_CRTC2_CRNT_FRAME); | 821 | return RREG32(RADEON_CRTC2_CRNT_FRAME); |
822 | } | 822 | } |
823 | 823 | ||
824 | /** | ||
825 | * r100_ring_hdp_flush - flush Host Data Path via the ring buffer | ||
826 | * rdev: radeon device structure | ||
827 | * ring: ring buffer struct for emitting packets | ||
828 | */ | ||
829 | static void r100_ring_hdp_flush(struct radeon_device *rdev, struct radeon_ring *ring) | ||
830 | { | ||
831 | radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
832 | radeon_ring_write(ring, rdev->config.r100.hdp_cntl | | ||
833 | RADEON_HDP_READ_BUFFER_INVALIDATE); | ||
834 | radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
835 | radeon_ring_write(ring, rdev->config.r100.hdp_cntl); | ||
836 | } | ||
837 | |||
824 | /* Who ever call radeon_fence_emit should call ring_lock and ask | 838 | /* Who ever call radeon_fence_emit should call ring_lock and ask |
825 | * for enough space (today caller are ib schedule and buffer move) */ | 839 | * for enough space (today caller are ib schedule and buffer move) */ |
826 | void r100_fence_ring_emit(struct radeon_device *rdev, | 840 | void r100_fence_ring_emit(struct radeon_device *rdev, |
@@ -1059,20 +1073,6 @@ void r100_gfx_set_wptr(struct radeon_device *rdev, | |||
1059 | (void)RREG32(RADEON_CP_RB_WPTR); | 1073 | (void)RREG32(RADEON_CP_RB_WPTR); |
1060 | } | 1074 | } |
1061 | 1075 | ||
1062 | /** | ||
1063 | * r100_ring_hdp_flush - flush Host Data Path via the ring buffer | ||
1064 | * rdev: radeon device structure | ||
1065 | * ring: ring buffer struct for emitting packets | ||
1066 | */ | ||
1067 | void r100_ring_hdp_flush(struct radeon_device *rdev, struct radeon_ring *ring) | ||
1068 | { | ||
1069 | radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
1070 | radeon_ring_write(ring, rdev->config.r100.hdp_cntl | | ||
1071 | RADEON_HDP_READ_BUFFER_INVALIDATE); | ||
1072 | radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); | ||
1073 | radeon_ring_write(ring, rdev->config.r100.hdp_cntl); | ||
1074 | } | ||
1075 | |||
1076 | static void r100_cp_load_microcode(struct radeon_device *rdev) | 1076 | static void r100_cp_load_microcode(struct radeon_device *rdev) |
1077 | { | 1077 | { |
1078 | const __be32 *fw_data; | 1078 | const __be32 *fw_data; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 25f367ac4637..56b02927cd3d 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1430,7 +1430,7 @@ int r600_vram_scratch_init(struct radeon_device *rdev) | |||
1430 | if (rdev->vram_scratch.robj == NULL) { | 1430 | if (rdev->vram_scratch.robj == NULL) { |
1431 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | 1431 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, |
1432 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 1432 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
1433 | 0, NULL, &rdev->vram_scratch.robj); | 1433 | 0, NULL, NULL, &rdev->vram_scratch.robj); |
1434 | if (r) { | 1434 | if (r) { |
1435 | return r; | 1435 | return r; |
1436 | } | 1436 | } |
@@ -2912,7 +2912,7 @@ struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev, | |||
2912 | return ERR_PTR(r); | 2912 | return ERR_PTR(r); |
2913 | } | 2913 | } |
2914 | 2914 | ||
2915 | radeon_semaphore_sync_resv(sem, resv, false); | 2915 | radeon_semaphore_sync_resv(rdev, sem, resv, false); |
2916 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 2916 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
2917 | 2917 | ||
2918 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 2918 | radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
@@ -3368,7 +3368,7 @@ int r600_ih_ring_alloc(struct radeon_device *rdev) | |||
3368 | r = radeon_bo_create(rdev, rdev->ih.ring_size, | 3368 | r = radeon_bo_create(rdev, rdev->ih.ring_size, |
3369 | PAGE_SIZE, true, | 3369 | PAGE_SIZE, true, |
3370 | RADEON_GEM_DOMAIN_GTT, 0, | 3370 | RADEON_GEM_DOMAIN_GTT, 0, |
3371 | NULL, &rdev->ih.ring_obj); | 3371 | NULL, NULL, &rdev->ih.ring_obj); |
3372 | if (r) { | 3372 | if (r) { |
3373 | DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); | 3373 | DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); |
3374 | return r; | 3374 | return r; |
@@ -3925,17 +3925,17 @@ static u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
3925 | wptr = RREG32(IH_RB_WPTR); | 3925 | wptr = RREG32(IH_RB_WPTR); |
3926 | 3926 | ||
3927 | if (wptr & RB_OVERFLOW) { | 3927 | if (wptr & RB_OVERFLOW) { |
3928 | wptr &= ~RB_OVERFLOW; | ||
3928 | /* When a ring buffer overflow happen start parsing interrupt | 3929 | /* When a ring buffer overflow happen start parsing interrupt |
3929 | * from the last not overwritten vector (wptr + 16). Hopefully | 3930 | * from the last not overwritten vector (wptr + 16). Hopefully |
3930 | * this should allow us to catchup. | 3931 | * this should allow us to catchup. |
3931 | */ | 3932 | */ |
3932 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 3933 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
3933 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 3934 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
3934 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 3935 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
3935 | tmp = RREG32(IH_RB_CNTL); | 3936 | tmp = RREG32(IH_RB_CNTL); |
3936 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 3937 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
3937 | WREG32(IH_RB_CNTL, tmp); | 3938 | WREG32(IH_RB_CNTL, tmp); |
3938 | wptr &= ~RB_OVERFLOW; | ||
3939 | } | 3939 | } |
3940 | return (wptr & rdev->ih.ptr_mask); | 3940 | return (wptr & rdev->ih.ptr_mask); |
3941 | } | 3941 | } |
@@ -4181,6 +4181,7 @@ restart_ih: | |||
4181 | /* wptr/rptr are in bytes! */ | 4181 | /* wptr/rptr are in bytes! */ |
4182 | rptr += 16; | 4182 | rptr += 16; |
4183 | rptr &= rdev->ih.ptr_mask; | 4183 | rptr &= rdev->ih.ptr_mask; |
4184 | WREG32(IH_RB_RPTR, rptr); | ||
4184 | } | 4185 | } |
4185 | if (queue_hotplug) | 4186 | if (queue_hotplug) |
4186 | schedule_work(&rdev->hotplug_work); | 4187 | schedule_work(&rdev->hotplug_work); |
@@ -4189,7 +4190,6 @@ restart_ih: | |||
4189 | if (queue_thermal && rdev->pm.dpm_enabled) | 4190 | if (queue_thermal && rdev->pm.dpm_enabled) |
4190 | schedule_work(&rdev->pm.dpm.thermal.work); | 4191 | schedule_work(&rdev->pm.dpm.thermal.work); |
4191 | rdev->ih.rptr = rptr; | 4192 | rdev->ih.rptr = rptr; |
4192 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
4193 | atomic_set(&rdev->ih.lock, 0); | 4193 | atomic_set(&rdev->ih.lock, 0); |
4194 | 4194 | ||
4195 | /* make sure wptr hasn't changed while processing */ | 4195 | /* make sure wptr hasn't changed while processing */ |
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c deleted file mode 100644 index bffac10c4296..000000000000 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ /dev/null | |||
@@ -1,207 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2008 Red Hat Inc. | ||
4 | * Copyright 2009 Christian König. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice shall be included in | ||
14 | * all copies or substantial portions of the Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: Christian König | ||
25 | */ | ||
26 | #include <drm/drmP.h> | ||
27 | #include "radeon.h" | ||
28 | #include "radeon_reg.h" | ||
29 | #include "radeon_asic.h" | ||
30 | #include "atom.h" | ||
31 | |||
32 | /* | ||
33 | * check if enc_priv stores radeon_encoder_atom_dig | ||
34 | */ | ||
35 | static bool radeon_dig_encoder(struct drm_encoder *encoder) | ||
36 | { | ||
37 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
38 | switch (radeon_encoder->encoder_id) { | ||
39 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
40 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
41 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
42 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
43 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
44 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
45 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
46 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
47 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
48 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
49 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
50 | return true; | ||
51 | } | ||
52 | return false; | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * check if the chipset is supported | ||
57 | */ | ||
58 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | ||
59 | { | ||
60 | return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); | ||
61 | } | ||
62 | |||
63 | struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) | ||
64 | { | ||
65 | struct r600_audio_pin status; | ||
66 | uint32_t value; | ||
67 | |||
68 | value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); | ||
69 | |||
70 | /* number of channels */ | ||
71 | status.channels = (value & 0x7) + 1; | ||
72 | |||
73 | /* bits per sample */ | ||
74 | switch ((value & 0xF0) >> 4) { | ||
75 | case 0x0: | ||
76 | status.bits_per_sample = 8; | ||
77 | break; | ||
78 | case 0x1: | ||
79 | status.bits_per_sample = 16; | ||
80 | break; | ||
81 | case 0x2: | ||
82 | status.bits_per_sample = 20; | ||
83 | break; | ||
84 | case 0x3: | ||
85 | status.bits_per_sample = 24; | ||
86 | break; | ||
87 | case 0x4: | ||
88 | status.bits_per_sample = 32; | ||
89 | break; | ||
90 | default: | ||
91 | dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n", | ||
92 | (int)value); | ||
93 | status.bits_per_sample = 16; | ||
94 | } | ||
95 | |||
96 | /* current sampling rate in HZ */ | ||
97 | if (value & 0x4000) | ||
98 | status.rate = 44100; | ||
99 | else | ||
100 | status.rate = 48000; | ||
101 | status.rate *= ((value >> 11) & 0x7) + 1; | ||
102 | status.rate /= ((value >> 8) & 0x7) + 1; | ||
103 | |||
104 | value = RREG32(R600_AUDIO_STATUS_BITS); | ||
105 | |||
106 | /* iec 60958 status bits */ | ||
107 | status.status_bits = value & 0xff; | ||
108 | |||
109 | /* iec 60958 category code */ | ||
110 | status.category_code = (value >> 8) & 0xff; | ||
111 | |||
112 | return status; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * update all hdmi interfaces with current audio parameters | ||
117 | */ | ||
118 | void r600_audio_update_hdmi(struct work_struct *work) | ||
119 | { | ||
120 | struct radeon_device *rdev = container_of(work, struct radeon_device, | ||
121 | audio_work); | ||
122 | struct drm_device *dev = rdev->ddev; | ||
123 | struct r600_audio_pin audio_status = r600_audio_status(rdev); | ||
124 | struct drm_encoder *encoder; | ||
125 | bool changed = false; | ||
126 | |||
127 | if (rdev->audio.pin[0].channels != audio_status.channels || | ||
128 | rdev->audio.pin[0].rate != audio_status.rate || | ||
129 | rdev->audio.pin[0].bits_per_sample != audio_status.bits_per_sample || | ||
130 | rdev->audio.pin[0].status_bits != audio_status.status_bits || | ||
131 | rdev->audio.pin[0].category_code != audio_status.category_code) { | ||
132 | rdev->audio.pin[0] = audio_status; | ||
133 | changed = true; | ||
134 | } | ||
135 | |||
136 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
137 | if (!radeon_dig_encoder(encoder)) | ||
138 | continue; | ||
139 | if (changed || r600_hdmi_buffer_status_changed(encoder)) | ||
140 | r600_hdmi_update_audio_settings(encoder); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | /* enable the audio stream */ | ||
145 | void r600_audio_enable(struct radeon_device *rdev, | ||
146 | struct r600_audio_pin *pin, | ||
147 | bool enable) | ||
148 | { | ||
149 | u32 value = 0; | ||
150 | |||
151 | if (!pin) | ||
152 | return; | ||
153 | |||
154 | if (ASIC_IS_DCE4(rdev)) { | ||
155 | if (enable) { | ||
156 | value |= 0x81000000; /* Required to enable audio */ | ||
157 | value |= 0x0e1000f0; /* fglrx sets that too */ | ||
158 | } | ||
159 | WREG32(EVERGREEN_AUDIO_ENABLE, value); | ||
160 | } else { | ||
161 | WREG32_P(R600_AUDIO_ENABLE, | ||
162 | enable ? 0x81000000 : 0x0, ~0x81000000); | ||
163 | } | ||
164 | } | ||
165 | |||
166 | /* | ||
167 | * initialize the audio vars | ||
168 | */ | ||
169 | int r600_audio_init(struct radeon_device *rdev) | ||
170 | { | ||
171 | if (!radeon_audio || !r600_audio_chipset_supported(rdev)) | ||
172 | return 0; | ||
173 | |||
174 | rdev->audio.enabled = true; | ||
175 | |||
176 | rdev->audio.num_pins = 1; | ||
177 | rdev->audio.pin[0].channels = -1; | ||
178 | rdev->audio.pin[0].rate = -1; | ||
179 | rdev->audio.pin[0].bits_per_sample = -1; | ||
180 | rdev->audio.pin[0].status_bits = 0; | ||
181 | rdev->audio.pin[0].category_code = 0; | ||
182 | rdev->audio.pin[0].id = 0; | ||
183 | /* disable audio. it will be set up later */ | ||
184 | r600_audio_enable(rdev, &rdev->audio.pin[0], false); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | /* | ||
190 | * release the audio timer | ||
191 | * TODO: How to do this correctly on SMP systems? | ||
192 | */ | ||
193 | void r600_audio_fini(struct radeon_device *rdev) | ||
194 | { | ||
195 | if (!rdev->audio.enabled) | ||
196 | return; | ||
197 | |||
198 | r600_audio_enable(rdev, &rdev->audio.pin[0], false); | ||
199 | |||
200 | rdev->audio.enabled = false; | ||
201 | } | ||
202 | |||
203 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) | ||
204 | { | ||
205 | /* only one pin on 6xx-NI */ | ||
206 | return &rdev->audio.pin[0]; | ||
207 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c index fc54224ce87b..aabc343b9a8f 100644 --- a/drivers/gpu/drm/radeon/r600_dma.c +++ b/drivers/gpu/drm/radeon/r600_dma.c | |||
@@ -124,15 +124,6 @@ int r600_dma_resume(struct radeon_device *rdev) | |||
124 | u32 rb_bufsz; | 124 | u32 rb_bufsz; |
125 | int r; | 125 | int r; |
126 | 126 | ||
127 | /* Reset dma */ | ||
128 | if (rdev->family >= CHIP_RV770) | ||
129 | WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA); | ||
130 | else | ||
131 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA); | ||
132 | RREG32(SRBM_SOFT_RESET); | ||
133 | udelay(50); | ||
134 | WREG32(SRBM_SOFT_RESET, 0); | ||
135 | |||
136 | WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL, 0); | 127 | WREG32(DMA_SEM_INCOMPLETE_TIMER_CNTL, 0); |
137 | WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL, 0); | 128 | WREG32(DMA_SEM_WAIT_FAIL_TIMER_CNTL, 0); |
138 | 129 | ||
@@ -241,16 +232,19 @@ int r600_dma_ring_test(struct radeon_device *rdev, | |||
241 | { | 232 | { |
242 | unsigned i; | 233 | unsigned i; |
243 | int r; | 234 | int r; |
244 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 235 | unsigned index; |
245 | u32 tmp; | 236 | u32 tmp; |
237 | u64 gpu_addr; | ||
246 | 238 | ||
247 | if (!ptr) { | 239 | if (ring->idx == R600_RING_TYPE_DMA_INDEX) |
248 | DRM_ERROR("invalid vram scratch pointer\n"); | 240 | index = R600_WB_DMA_RING_TEST_OFFSET; |
249 | return -EINVAL; | 241 | else |
250 | } | 242 | index = CAYMAN_WB_DMA1_RING_TEST_OFFSET; |
243 | |||
244 | gpu_addr = rdev->wb.gpu_addr + index; | ||
251 | 245 | ||
252 | tmp = 0xCAFEDEAD; | 246 | tmp = 0xCAFEDEAD; |
253 | writel(tmp, ptr); | 247 | rdev->wb.wb[index/4] = cpu_to_le32(tmp); |
254 | 248 | ||
255 | r = radeon_ring_lock(rdev, ring, 4); | 249 | r = radeon_ring_lock(rdev, ring, 4); |
256 | if (r) { | 250 | if (r) { |
@@ -258,13 +252,13 @@ int r600_dma_ring_test(struct radeon_device *rdev, | |||
258 | return r; | 252 | return r; |
259 | } | 253 | } |
260 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1)); | 254 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 1)); |
261 | radeon_ring_write(ring, rdev->vram_scratch.gpu_addr & 0xfffffffc); | 255 | radeon_ring_write(ring, lower_32_bits(gpu_addr)); |
262 | radeon_ring_write(ring, upper_32_bits(rdev->vram_scratch.gpu_addr) & 0xff); | 256 | radeon_ring_write(ring, upper_32_bits(gpu_addr) & 0xff); |
263 | radeon_ring_write(ring, 0xDEADBEEF); | 257 | radeon_ring_write(ring, 0xDEADBEEF); |
264 | radeon_ring_unlock_commit(rdev, ring, false); | 258 | radeon_ring_unlock_commit(rdev, ring, false); |
265 | 259 | ||
266 | for (i = 0; i < rdev->usec_timeout; i++) { | 260 | for (i = 0; i < rdev->usec_timeout; i++) { |
267 | tmp = readl(ptr); | 261 | tmp = le32_to_cpu(rdev->wb.wb[index/4]); |
268 | if (tmp == 0xDEADBEEF) | 262 | if (tmp == 0xDEADBEEF) |
269 | break; | 263 | break; |
270 | DRM_UDELAY(1); | 264 | DRM_UDELAY(1); |
@@ -470,7 +464,7 @@ struct radeon_fence *r600_copy_dma(struct radeon_device *rdev, | |||
470 | return ERR_PTR(r); | 464 | return ERR_PTR(r); |
471 | } | 465 | } |
472 | 466 | ||
473 | radeon_semaphore_sync_resv(sem, resv, false); | 467 | radeon_semaphore_sync_resv(rdev, sem, resv, false); |
474 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 468 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
475 | 469 | ||
476 | for (i = 0; i < num_loops; i++) { | 470 | for (i = 0; i < num_loops; i++) { |
diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index 9c61b74ef441..f6309bd23e01 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | ||
27 | #include "r600d.h" | 28 | #include "r600d.h" |
28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
29 | #include "atom.h" | 30 | #include "atom.h" |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 26ef8ced6f89..b90dc0eb08e6 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -72,6 +72,169 @@ static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = { | |||
72 | 72 | ||
73 | 73 | ||
74 | /* | 74 | /* |
75 | * check if the chipset is supported | ||
76 | */ | ||
77 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | ||
78 | { | ||
79 | return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); | ||
80 | } | ||
81 | |||
82 | static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) | ||
83 | { | ||
84 | struct r600_audio_pin status; | ||
85 | uint32_t value; | ||
86 | |||
87 | value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); | ||
88 | |||
89 | /* number of channels */ | ||
90 | status.channels = (value & 0x7) + 1; | ||
91 | |||
92 | /* bits per sample */ | ||
93 | switch ((value & 0xF0) >> 4) { | ||
94 | case 0x0: | ||
95 | status.bits_per_sample = 8; | ||
96 | break; | ||
97 | case 0x1: | ||
98 | status.bits_per_sample = 16; | ||
99 | break; | ||
100 | case 0x2: | ||
101 | status.bits_per_sample = 20; | ||
102 | break; | ||
103 | case 0x3: | ||
104 | status.bits_per_sample = 24; | ||
105 | break; | ||
106 | case 0x4: | ||
107 | status.bits_per_sample = 32; | ||
108 | break; | ||
109 | default: | ||
110 | dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n", | ||
111 | (int)value); | ||
112 | status.bits_per_sample = 16; | ||
113 | } | ||
114 | |||
115 | /* current sampling rate in HZ */ | ||
116 | if (value & 0x4000) | ||
117 | status.rate = 44100; | ||
118 | else | ||
119 | status.rate = 48000; | ||
120 | status.rate *= ((value >> 11) & 0x7) + 1; | ||
121 | status.rate /= ((value >> 8) & 0x7) + 1; | ||
122 | |||
123 | value = RREG32(R600_AUDIO_STATUS_BITS); | ||
124 | |||
125 | /* iec 60958 status bits */ | ||
126 | status.status_bits = value & 0xff; | ||
127 | |||
128 | /* iec 60958 category code */ | ||
129 | status.category_code = (value >> 8) & 0xff; | ||
130 | |||
131 | return status; | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * update all hdmi interfaces with current audio parameters | ||
136 | */ | ||
137 | void r600_audio_update_hdmi(struct work_struct *work) | ||
138 | { | ||
139 | struct radeon_device *rdev = container_of(work, struct radeon_device, | ||
140 | audio_work); | ||
141 | struct drm_device *dev = rdev->ddev; | ||
142 | struct r600_audio_pin audio_status = r600_audio_status(rdev); | ||
143 | struct drm_encoder *encoder; | ||
144 | bool changed = false; | ||
145 | |||
146 | if (rdev->audio.pin[0].channels != audio_status.channels || | ||
147 | rdev->audio.pin[0].rate != audio_status.rate || | ||
148 | rdev->audio.pin[0].bits_per_sample != audio_status.bits_per_sample || | ||
149 | rdev->audio.pin[0].status_bits != audio_status.status_bits || | ||
150 | rdev->audio.pin[0].category_code != audio_status.category_code) { | ||
151 | rdev->audio.pin[0] = audio_status; | ||
152 | changed = true; | ||
153 | } | ||
154 | |||
155 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
156 | if (!radeon_encoder_is_digital(encoder)) | ||
157 | continue; | ||
158 | if (changed || r600_hdmi_buffer_status_changed(encoder)) | ||
159 | r600_hdmi_update_audio_settings(encoder); | ||
160 | } | ||
161 | } | ||
162 | |||
163 | /* enable the audio stream */ | ||
164 | void r600_audio_enable(struct radeon_device *rdev, | ||
165 | struct r600_audio_pin *pin, | ||
166 | u8 enable_mask) | ||
167 | { | ||
168 | u32 tmp = RREG32(AZ_HOT_PLUG_CONTROL); | ||
169 | |||
170 | if (!pin) | ||
171 | return; | ||
172 | |||
173 | if (enable_mask) { | ||
174 | tmp |= AUDIO_ENABLED; | ||
175 | if (enable_mask & 1) | ||
176 | tmp |= PIN0_AUDIO_ENABLED; | ||
177 | if (enable_mask & 2) | ||
178 | tmp |= PIN1_AUDIO_ENABLED; | ||
179 | if (enable_mask & 4) | ||
180 | tmp |= PIN2_AUDIO_ENABLED; | ||
181 | if (enable_mask & 8) | ||
182 | tmp |= PIN3_AUDIO_ENABLED; | ||
183 | } else { | ||
184 | tmp &= ~(AUDIO_ENABLED | | ||
185 | PIN0_AUDIO_ENABLED | | ||
186 | PIN1_AUDIO_ENABLED | | ||
187 | PIN2_AUDIO_ENABLED | | ||
188 | PIN3_AUDIO_ENABLED); | ||
189 | } | ||
190 | |||
191 | WREG32(AZ_HOT_PLUG_CONTROL, tmp); | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * initialize the audio vars | ||
196 | */ | ||
197 | int r600_audio_init(struct radeon_device *rdev) | ||
198 | { | ||
199 | if (!radeon_audio || !r600_audio_chipset_supported(rdev)) | ||
200 | return 0; | ||
201 | |||
202 | rdev->audio.enabled = true; | ||
203 | |||
204 | rdev->audio.num_pins = 1; | ||
205 | rdev->audio.pin[0].channels = -1; | ||
206 | rdev->audio.pin[0].rate = -1; | ||
207 | rdev->audio.pin[0].bits_per_sample = -1; | ||
208 | rdev->audio.pin[0].status_bits = 0; | ||
209 | rdev->audio.pin[0].category_code = 0; | ||
210 | rdev->audio.pin[0].id = 0; | ||
211 | /* disable audio. it will be set up later */ | ||
212 | r600_audio_enable(rdev, &rdev->audio.pin[0], 0); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * release the audio timer | ||
219 | * TODO: How to do this correctly on SMP systems? | ||
220 | */ | ||
221 | void r600_audio_fini(struct radeon_device *rdev) | ||
222 | { | ||
223 | if (!rdev->audio.enabled) | ||
224 | return; | ||
225 | |||
226 | r600_audio_enable(rdev, &rdev->audio.pin[0], 0); | ||
227 | |||
228 | rdev->audio.enabled = false; | ||
229 | } | ||
230 | |||
231 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) | ||
232 | { | ||
233 | /* only one pin on 6xx-NI */ | ||
234 | return &rdev->audio.pin[0]; | ||
235 | } | ||
236 | |||
237 | /* | ||
75 | * calculate CTS and N values if they are not found in the table | 238 | * calculate CTS and N values if they are not found in the table |
76 | */ | 239 | */ |
77 | static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) | 240 | static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq) |
@@ -357,7 +520,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
357 | 520 | ||
358 | /* disable audio prior to setting up hw */ | 521 | /* disable audio prior to setting up hw */ |
359 | dig->afmt->pin = r600_audio_get_pin(rdev); | 522 | dig->afmt->pin = r600_audio_get_pin(rdev); |
360 | r600_audio_enable(rdev, dig->afmt->pin, false); | 523 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); |
361 | 524 | ||
362 | r600_audio_set_dto(encoder, mode->clock); | 525 | r600_audio_set_dto(encoder, mode->clock); |
363 | 526 | ||
@@ -443,7 +606,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
443 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); | 606 | WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); |
444 | 607 | ||
445 | /* enable audio after to setting up hw */ | 608 | /* enable audio after to setting up hw */ |
446 | r600_audio_enable(rdev, dig->afmt->pin, true); | 609 | r600_audio_enable(rdev, dig->afmt->pin, 0xf); |
447 | } | 610 | } |
448 | 611 | ||
449 | /** | 612 | /** |
@@ -528,6 +691,11 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) | |||
528 | if (!enable && !dig->afmt->enabled) | 691 | if (!enable && !dig->afmt->enabled) |
529 | return; | 692 | return; |
530 | 693 | ||
694 | if (!enable && dig->afmt->pin) { | ||
695 | r600_audio_enable(rdev, dig->afmt->pin, 0); | ||
696 | dig->afmt->pin = NULL; | ||
697 | } | ||
698 | |||
531 | /* Older chipsets require setting HDMI and routing manually */ | 699 | /* Older chipsets require setting HDMI and routing manually */ |
532 | if (!ASIC_IS_DCE3(rdev)) { | 700 | if (!ASIC_IS_DCE3(rdev)) { |
533 | if (enable) | 701 | if (enable) |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 671b48032a3d..1e8495cca41e 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -44,13 +44,6 @@ | |||
44 | #define R6XX_MAX_PIPES 8 | 44 | #define R6XX_MAX_PIPES 8 |
45 | #define R6XX_MAX_PIPES_MASK 0xff | 45 | #define R6XX_MAX_PIPES_MASK 0xff |
46 | 46 | ||
47 | /* PTE flags */ | ||
48 | #define PTE_VALID (1 << 0) | ||
49 | #define PTE_SYSTEM (1 << 1) | ||
50 | #define PTE_SNOOPED (1 << 2) | ||
51 | #define PTE_READABLE (1 << 5) | ||
52 | #define PTE_WRITEABLE (1 << 6) | ||
53 | |||
54 | /* tiling bits */ | 47 | /* tiling bits */ |
55 | #define ARRAY_LINEAR_GENERAL 0x00000000 | 48 | #define ARRAY_LINEAR_GENERAL 0x00000000 |
56 | #define ARRAY_LINEAR_ALIGNED 0x00000001 | 49 | #define ARRAY_LINEAR_ALIGNED 0x00000001 |
@@ -934,6 +927,23 @@ | |||
934 | # define TARGET_LINK_SPEED_MASK (0xf << 0) | 927 | # define TARGET_LINK_SPEED_MASK (0xf << 0) |
935 | # define SELECTABLE_DEEMPHASIS (1 << 6) | 928 | # define SELECTABLE_DEEMPHASIS (1 << 6) |
936 | 929 | ||
930 | /* Audio */ | ||
931 | #define AZ_HOT_PLUG_CONTROL 0x7300 | ||
932 | # define AZ_FORCE_CODEC_WAKE (1 << 0) | ||
933 | # define JACK_DETECTION_ENABLE (1 << 4) | ||
934 | # define UNSOLICITED_RESPONSE_ENABLE (1 << 8) | ||
935 | # define CODEC_HOT_PLUG_ENABLE (1 << 12) | ||
936 | # define AUDIO_ENABLED (1 << 31) | ||
937 | /* DCE3 adds */ | ||
938 | # define PIN0_JACK_DETECTION_ENABLE (1 << 4) | ||
939 | # define PIN1_JACK_DETECTION_ENABLE (1 << 5) | ||
940 | # define PIN2_JACK_DETECTION_ENABLE (1 << 6) | ||
941 | # define PIN3_JACK_DETECTION_ENABLE (1 << 7) | ||
942 | # define PIN0_AUDIO_ENABLED (1 << 24) | ||
943 | # define PIN1_AUDIO_ENABLED (1 << 25) | ||
944 | # define PIN2_AUDIO_ENABLED (1 << 26) | ||
945 | # define PIN3_AUDIO_ENABLED (1 << 27) | ||
946 | |||
937 | /* Audio clocks DCE 2.0/3.0 */ | 947 | /* Audio clocks DCE 2.0/3.0 */ |
938 | #define AUDIO_DTO 0x7340 | 948 | #define AUDIO_DTO 0x7340 |
939 | # define AUDIO_DTO_PHASE(x) (((x) & 0xffff) << 0) | 949 | # define AUDIO_DTO_PHASE(x) (((x) & 0xffff) << 0) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index ef91ebb7c671..a9717b3fbf1b 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -110,6 +110,7 @@ extern int radeon_vm_block_size; | |||
110 | extern int radeon_deep_color; | 110 | extern int radeon_deep_color; |
111 | extern int radeon_use_pflipirq; | 111 | extern int radeon_use_pflipirq; |
112 | extern int radeon_bapm; | 112 | extern int radeon_bapm; |
113 | extern int radeon_backlight; | ||
113 | 114 | ||
114 | /* | 115 | /* |
115 | * Copy from radeon_drv.h so we don't have to include both and have conflicting | 116 | * Copy from radeon_drv.h so we don't have to include both and have conflicting |
@@ -589,9 +590,10 @@ bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, | |||
589 | struct radeon_semaphore *semaphore); | 590 | struct radeon_semaphore *semaphore); |
590 | void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, | 591 | void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, |
591 | struct radeon_fence *fence); | 592 | struct radeon_fence *fence); |
592 | void radeon_semaphore_sync_resv(struct radeon_semaphore *semaphore, | 593 | int radeon_semaphore_sync_resv(struct radeon_device *rdev, |
593 | struct reservation_object *resv, | 594 | struct radeon_semaphore *semaphore, |
594 | bool shared); | 595 | struct reservation_object *resv, |
596 | bool shared); | ||
595 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, | 597 | int radeon_semaphore_sync_rings(struct radeon_device *rdev, |
596 | struct radeon_semaphore *semaphore, | 598 | struct radeon_semaphore *semaphore, |
597 | int waiting_ring); | 599 | int waiting_ring); |
@@ -712,7 +714,7 @@ struct radeon_flip_work { | |||
712 | uint64_t base; | 714 | uint64_t base; |
713 | struct drm_pending_vblank_event *event; | 715 | struct drm_pending_vblank_event *event; |
714 | struct radeon_bo *old_rbo; | 716 | struct radeon_bo *old_rbo; |
715 | struct radeon_fence *fence; | 717 | struct fence *fence; |
716 | }; | 718 | }; |
717 | 719 | ||
718 | struct r500_irq_stat_regs { | 720 | struct r500_irq_stat_regs { |
@@ -1131,6 +1133,8 @@ struct radeon_wb { | |||
1131 | #define R600_WB_EVENT_OFFSET 3072 | 1133 | #define R600_WB_EVENT_OFFSET 3072 |
1132 | #define CIK_WB_CP1_WPTR_OFFSET 3328 | 1134 | #define CIK_WB_CP1_WPTR_OFFSET 3328 |
1133 | #define CIK_WB_CP2_WPTR_OFFSET 3584 | 1135 | #define CIK_WB_CP2_WPTR_OFFSET 3584 |
1136 | #define R600_WB_DMA_RING_TEST_OFFSET 3588 | ||
1137 | #define CAYMAN_WB_DMA1_RING_TEST_OFFSET 3592 | ||
1134 | 1138 | ||
1135 | /** | 1139 | /** |
1136 | * struct radeon_pm - power management datas | 1140 | * struct radeon_pm - power management datas |
@@ -2977,10 +2981,10 @@ struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); | |||
2977 | struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); | 2981 | struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); |
2978 | void r600_audio_enable(struct radeon_device *rdev, | 2982 | void r600_audio_enable(struct radeon_device *rdev, |
2979 | struct r600_audio_pin *pin, | 2983 | struct r600_audio_pin *pin, |
2980 | bool enable); | 2984 | u8 enable_mask); |
2981 | void dce6_audio_enable(struct radeon_device *rdev, | 2985 | void dce6_audio_enable(struct radeon_device *rdev, |
2982 | struct r600_audio_pin *pin, | 2986 | struct r600_audio_pin *pin, |
2983 | bool enable); | 2987 | u8 enable_mask); |
2984 | 2988 | ||
2985 | /* | 2989 | /* |
2986 | * R600 vram scratch functions | 2990 | * R600 vram scratch functions |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index d91f965e8219..850de57069be 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -185,7 +185,6 @@ static struct radeon_asic_ring r100_gfx_ring = { | |||
185 | .get_rptr = &r100_gfx_get_rptr, | 185 | .get_rptr = &r100_gfx_get_rptr, |
186 | .get_wptr = &r100_gfx_get_wptr, | 186 | .get_wptr = &r100_gfx_get_wptr, |
187 | .set_wptr = &r100_gfx_set_wptr, | 187 | .set_wptr = &r100_gfx_set_wptr, |
188 | .hdp_flush = &r100_ring_hdp_flush, | ||
189 | }; | 188 | }; |
190 | 189 | ||
191 | static struct radeon_asic r100_asic = { | 190 | static struct radeon_asic r100_asic = { |
@@ -332,7 +331,6 @@ static struct radeon_asic_ring r300_gfx_ring = { | |||
332 | .get_rptr = &r100_gfx_get_rptr, | 331 | .get_rptr = &r100_gfx_get_rptr, |
333 | .get_wptr = &r100_gfx_get_wptr, | 332 | .get_wptr = &r100_gfx_get_wptr, |
334 | .set_wptr = &r100_gfx_set_wptr, | 333 | .set_wptr = &r100_gfx_set_wptr, |
335 | .hdp_flush = &r100_ring_hdp_flush, | ||
336 | }; | 334 | }; |
337 | 335 | ||
338 | static struct radeon_asic r300_asic = { | 336 | static struct radeon_asic r300_asic = { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index ca01bb8ea217..d8ace5b28a5b 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -148,8 +148,7 @@ u32 r100_gfx_get_wptr(struct radeon_device *rdev, | |||
148 | struct radeon_ring *ring); | 148 | struct radeon_ring *ring); |
149 | void r100_gfx_set_wptr(struct radeon_device *rdev, | 149 | void r100_gfx_set_wptr(struct radeon_device *rdev, |
150 | struct radeon_ring *ring); | 150 | struct radeon_ring *ring); |
151 | void r100_ring_hdp_flush(struct radeon_device *rdev, | 151 | |
152 | struct radeon_ring *ring); | ||
153 | /* | 152 | /* |
154 | * r200,rv250,rs300,rv280 | 153 | * r200,rv250,rs300,rv280 |
155 | */ | 154 | */ |
@@ -392,7 +391,6 @@ void r600_disable_interrupts(struct radeon_device *rdev); | |||
392 | void r600_rlc_stop(struct radeon_device *rdev); | 391 | void r600_rlc_stop(struct radeon_device *rdev); |
393 | /* r600 audio */ | 392 | /* r600 audio */ |
394 | int r600_audio_init(struct radeon_device *rdev); | 393 | int r600_audio_init(struct radeon_device *rdev); |
395 | struct r600_audio_pin r600_audio_status(struct radeon_device *rdev); | ||
396 | void r600_audio_fini(struct radeon_device *rdev); | 394 | void r600_audio_fini(struct radeon_device *rdev); |
397 | void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock); | 395 | void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock); |
398 | void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, | 396 | void r600_hdmi_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index e74c7e387dde..df69b92ba164 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -458,7 +458,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
458 | return true; | 458 | return true; |
459 | } | 459 | } |
460 | 460 | ||
461 | const int supported_devices_connector_convert[] = { | 461 | static const int supported_devices_connector_convert[] = { |
462 | DRM_MODE_CONNECTOR_Unknown, | 462 | DRM_MODE_CONNECTOR_Unknown, |
463 | DRM_MODE_CONNECTOR_VGA, | 463 | DRM_MODE_CONNECTOR_VGA, |
464 | DRM_MODE_CONNECTOR_DVII, | 464 | DRM_MODE_CONNECTOR_DVII, |
@@ -477,7 +477,7 @@ const int supported_devices_connector_convert[] = { | |||
477 | DRM_MODE_CONNECTOR_DisplayPort | 477 | DRM_MODE_CONNECTOR_DisplayPort |
478 | }; | 478 | }; |
479 | 479 | ||
480 | const uint16_t supported_devices_connector_object_id_convert[] = { | 480 | static const uint16_t supported_devices_connector_object_id_convert[] = { |
481 | CONNECTOR_OBJECT_ID_NONE, | 481 | CONNECTOR_OBJECT_ID_NONE, |
482 | CONNECTOR_OBJECT_ID_VGA, | 482 | CONNECTOR_OBJECT_ID_VGA, |
483 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */ | 483 | CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I, /* not all boards support DL */ |
@@ -494,7 +494,7 @@ const uint16_t supported_devices_connector_object_id_convert[] = { | |||
494 | CONNECTOR_OBJECT_ID_SVIDEO | 494 | CONNECTOR_OBJECT_ID_SVIDEO |
495 | }; | 495 | }; |
496 | 496 | ||
497 | const int object_connector_convert[] = { | 497 | static const int object_connector_convert[] = { |
498 | DRM_MODE_CONNECTOR_Unknown, | 498 | DRM_MODE_CONNECTOR_Unknown, |
499 | DRM_MODE_CONNECTOR_DVII, | 499 | DRM_MODE_CONNECTOR_DVII, |
500 | DRM_MODE_CONNECTOR_DVII, | 500 | DRM_MODE_CONNECTOR_DVII, |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index a9fb0d016d38..8bc7d0bbd3c8 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -33,7 +33,6 @@ static struct radeon_atpx_priv { | |||
33 | bool atpx_detected; | 33 | bool atpx_detected; |
34 | /* handle for device - and atpx */ | 34 | /* handle for device - and atpx */ |
35 | acpi_handle dhandle; | 35 | acpi_handle dhandle; |
36 | acpi_handle other_handle; | ||
37 | struct radeon_atpx atpx; | 36 | struct radeon_atpx atpx; |
38 | } radeon_atpx_priv; | 37 | } radeon_atpx_priv; |
39 | 38 | ||
@@ -453,10 +452,9 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev) | |||
453 | return false; | 452 | return false; |
454 | 453 | ||
455 | status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); | 454 | status = acpi_get_handle(dhandle, "ATPX", &atpx_handle); |
456 | if (ACPI_FAILURE(status)) { | 455 | if (ACPI_FAILURE(status)) |
457 | radeon_atpx_priv.other_handle = dhandle; | ||
458 | return false; | 456 | return false; |
459 | } | 457 | |
460 | radeon_atpx_priv.dhandle = dhandle; | 458 | radeon_atpx_priv.dhandle = dhandle; |
461 | radeon_atpx_priv.atpx.handle = atpx_handle; | 459 | radeon_atpx_priv.atpx.handle = atpx_handle; |
462 | return true; | 460 | return true; |
@@ -540,16 +538,6 @@ static bool radeon_atpx_detect(void) | |||
540 | printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", | 538 | printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", |
541 | acpi_method_name); | 539 | acpi_method_name); |
542 | radeon_atpx_priv.atpx_detected = true; | 540 | radeon_atpx_priv.atpx_detected = true; |
543 | /* | ||
544 | * On some systems hotplug events are generated for the device | ||
545 | * being switched off when ATPX is executed. They cause ACPI | ||
546 | * hotplug to trigger and attempt to remove the device from | ||
547 | * the system, which causes it to break down. Prevent that from | ||
548 | * happening by setting the no_hotplug flag for the involved | ||
549 | * ACPI device objects. | ||
550 | */ | ||
551 | acpi_bus_no_hotplug(radeon_atpx_priv.dhandle); | ||
552 | acpi_bus_no_hotplug(radeon_atpx_priv.other_handle); | ||
553 | return true; | 541 | return true; |
554 | } | 542 | } |
555 | return false; | 543 | return false; |
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 1e8855060fc7..9e7f23dd14bd 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -93,7 +93,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, | |||
93 | int time; | 93 | int time; |
94 | 94 | ||
95 | n = RADEON_BENCHMARK_ITERATIONS; | 95 | n = RADEON_BENCHMARK_ITERATIONS; |
96 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, 0, NULL, &sobj); | 96 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, 0, NULL, NULL, &sobj); |
97 | if (r) { | 97 | if (r) { |
98 | goto out_cleanup; | 98 | goto out_cleanup; |
99 | } | 99 | } |
@@ -105,7 +105,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, | |||
105 | if (r) { | 105 | if (r) { |
106 | goto out_cleanup; | 106 | goto out_cleanup; |
107 | } | 107 | } |
108 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, 0, NULL, &dobj); | 108 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, 0, NULL, NULL, &dobj); |
109 | if (r) { | 109 | if (r) { |
110 | goto out_cleanup; | 110 | goto out_cleanup; |
111 | } | 111 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 6651177110f0..3e5f6b71f3ad 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -116,7 +116,7 @@ enum radeon_combios_connector { | |||
116 | CONNECTOR_UNSUPPORTED_LEGACY | 116 | CONNECTOR_UNSUPPORTED_LEGACY |
117 | }; | 117 | }; |
118 | 118 | ||
119 | const int legacy_connector_convert[] = { | 119 | static const int legacy_connector_convert[] = { |
120 | DRM_MODE_CONNECTOR_Unknown, | 120 | DRM_MODE_CONNECTOR_Unknown, |
121 | DRM_MODE_CONNECTOR_DVID, | 121 | DRM_MODE_CONNECTOR_DVID, |
122 | DRM_MODE_CONNECTOR_VGA, | 122 | DRM_MODE_CONNECTOR_VGA, |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index f662de41ba49..1c893447d7cd 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -249,9 +249,9 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority | |||
249 | return 0; | 249 | return 0; |
250 | } | 250 | } |
251 | 251 | ||
252 | static void radeon_cs_sync_rings(struct radeon_cs_parser *p) | 252 | static int radeon_cs_sync_rings(struct radeon_cs_parser *p) |
253 | { | 253 | { |
254 | int i; | 254 | int i, r = 0; |
255 | 255 | ||
256 | for (i = 0; i < p->nrelocs; i++) { | 256 | for (i = 0; i < p->nrelocs; i++) { |
257 | struct reservation_object *resv; | 257 | struct reservation_object *resv; |
@@ -260,9 +260,13 @@ static void radeon_cs_sync_rings(struct radeon_cs_parser *p) | |||
260 | continue; | 260 | continue; |
261 | 261 | ||
262 | resv = p->relocs[i].robj->tbo.resv; | 262 | resv = p->relocs[i].robj->tbo.resv; |
263 | radeon_semaphore_sync_resv(p->ib.semaphore, resv, | 263 | r = radeon_semaphore_sync_resv(p->rdev, p->ib.semaphore, resv, |
264 | p->relocs[i].tv.shared); | 264 | p->relocs[i].tv.shared); |
265 | |||
266 | if (r) | ||
267 | break; | ||
265 | } | 268 | } |
269 | return r; | ||
266 | } | 270 | } |
267 | 271 | ||
268 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ | 272 | /* XXX: note that this is called from the legacy UMS CS ioctl as well */ |
@@ -472,13 +476,19 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, | |||
472 | return r; | 476 | return r; |
473 | } | 477 | } |
474 | 478 | ||
479 | r = radeon_cs_sync_rings(parser); | ||
480 | if (r) { | ||
481 | if (r != -ERESTARTSYS) | ||
482 | DRM_ERROR("Failed to sync rings: %i\n", r); | ||
483 | return r; | ||
484 | } | ||
485 | |||
475 | if (parser->ring == R600_RING_TYPE_UVD_INDEX) | 486 | if (parser->ring == R600_RING_TYPE_UVD_INDEX) |
476 | radeon_uvd_note_usage(rdev); | 487 | radeon_uvd_note_usage(rdev); |
477 | else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) || | 488 | else if ((parser->ring == TN_RING_TYPE_VCE1_INDEX) || |
478 | (parser->ring == TN_RING_TYPE_VCE2_INDEX)) | 489 | (parser->ring == TN_RING_TYPE_VCE2_INDEX)) |
479 | radeon_vce_note_usage(rdev); | 490 | radeon_vce_note_usage(rdev); |
480 | 491 | ||
481 | radeon_cs_sync_rings(parser); | ||
482 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); | 492 | r = radeon_ib_schedule(rdev, &parser->ib, NULL, true); |
483 | if (r) { | 493 | if (r) { |
484 | DRM_ERROR("Failed to schedule IB !\n"); | 494 | DRM_ERROR("Failed to schedule IB !\n"); |
@@ -565,7 +575,13 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
565 | if (r) { | 575 | if (r) { |
566 | goto out; | 576 | goto out; |
567 | } | 577 | } |
568 | radeon_cs_sync_rings(parser); | 578 | |
579 | r = radeon_cs_sync_rings(parser); | ||
580 | if (r) { | ||
581 | if (r != -ERESTARTSYS) | ||
582 | DRM_ERROR("Failed to sync rings: %i\n", r); | ||
583 | goto out; | ||
584 | } | ||
569 | radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); | 585 | radeon_semaphore_sync_fence(parser->ib.semaphore, vm->fence); |
570 | 586 | ||
571 | if ((rdev->family >= CHIP_TAHITI) && | 587 | if ((rdev->family >= CHIP_TAHITI) && |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e84a76e6656a..ea2676954dde 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -123,6 +123,10 @@ static struct radeon_px_quirk radeon_px_quirk_list[] = { | |||
123 | * https://bugzilla.kernel.org/show_bug.cgi?id=51381 | 123 | * https://bugzilla.kernel.org/show_bug.cgi?id=51381 |
124 | */ | 124 | */ |
125 | { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX }, | 125 | { PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX }, |
126 | /* Asus K53TK laptop with AMD A6-3420M APU and Radeon 7670m GPU | ||
127 | * https://bugzilla.kernel.org/show_bug.cgi?id=51381 | ||
128 | */ | ||
129 | { PCI_VENDOR_ID_ATI, 0x6840, 0x1043, 0x2122, RADEON_PX_QUIRK_DISABLE_PX }, | ||
126 | /* macbook pro 8.2 */ | 130 | /* macbook pro 8.2 */ |
127 | { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP }, | 131 | { PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP }, |
128 | { 0, 0, 0, 0, 0 }, | 132 | { 0, 0, 0, 0, 0 }, |
@@ -430,7 +434,7 @@ int radeon_wb_init(struct radeon_device *rdev) | |||
430 | 434 | ||
431 | if (rdev->wb.wb_obj == NULL) { | 435 | if (rdev->wb.wb_obj == NULL) { |
432 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, | 436 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, |
433 | RADEON_GEM_DOMAIN_GTT, 0, NULL, | 437 | RADEON_GEM_DOMAIN_GTT, 0, NULL, NULL, |
434 | &rdev->wb.wb_obj); | 438 | &rdev->wb.wb_obj); |
435 | if (r) { | 439 | if (r) { |
436 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); | 440 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
@@ -1126,7 +1130,7 @@ static void radeon_check_arguments(struct radeon_device *rdev) | |||
1126 | if (radeon_vm_block_size == -1) { | 1130 | if (radeon_vm_block_size == -1) { |
1127 | 1131 | ||
1128 | /* Total bits covered by PD + PTs */ | 1132 | /* Total bits covered by PD + PTs */ |
1129 | unsigned bits = ilog2(radeon_vm_size) + 17; | 1133 | unsigned bits = ilog2(radeon_vm_size) + 18; |
1130 | 1134 | ||
1131 | /* Make sure the PD is 4K in size up to 8GB address space. | 1135 | /* Make sure the PD is 4K in size up to 8GB address space. |
1132 | Above that split equal between PD and PTs */ | 1136 | Above that split equal between PD and PTs */ |
@@ -1396,7 +1400,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1396 | 1400 | ||
1397 | r = radeon_init(rdev); | 1401 | r = radeon_init(rdev); |
1398 | if (r) | 1402 | if (r) |
1399 | return r; | 1403 | goto failed; |
1400 | 1404 | ||
1401 | r = radeon_gem_debugfs_init(rdev); | 1405 | r = radeon_gem_debugfs_init(rdev); |
1402 | if (r) { | 1406 | if (r) { |
@@ -1412,7 +1416,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1412 | radeon_agp_disable(rdev); | 1416 | radeon_agp_disable(rdev); |
1413 | r = radeon_init(rdev); | 1417 | r = radeon_init(rdev); |
1414 | if (r) | 1418 | if (r) |
1415 | return r; | 1419 | goto failed; |
1416 | } | 1420 | } |
1417 | 1421 | ||
1418 | r = radeon_ib_ring_tests(rdev); | 1422 | r = radeon_ib_ring_tests(rdev); |
@@ -1438,6 +1442,11 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1438 | DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n"); | 1442 | DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n"); |
1439 | } | 1443 | } |
1440 | return 0; | 1444 | return 0; |
1445 | |||
1446 | failed: | ||
1447 | if (runtime) | ||
1448 | vga_switcheroo_fini_domain_pm_ops(rdev->dev); | ||
1449 | return r; | ||
1441 | } | 1450 | } |
1442 | 1451 | ||
1443 | static void radeon_debugfs_remove_files(struct radeon_device *rdev); | 1452 | static void radeon_debugfs_remove_files(struct radeon_device *rdev); |
@@ -1458,6 +1467,8 @@ void radeon_device_fini(struct radeon_device *rdev) | |||
1458 | radeon_bo_evict_vram(rdev); | 1467 | radeon_bo_evict_vram(rdev); |
1459 | radeon_fini(rdev); | 1468 | radeon_fini(rdev); |
1460 | vga_switcheroo_unregister_client(rdev->pdev); | 1469 | vga_switcheroo_unregister_client(rdev->pdev); |
1470 | if (rdev->flags & RADEON_IS_PX) | ||
1471 | vga_switcheroo_fini_domain_pm_ops(rdev->dev); | ||
1461 | vga_client_register(rdev->pdev, NULL, NULL, NULL); | 1472 | vga_client_register(rdev->pdev, NULL, NULL, NULL); |
1462 | if (rdev->rio_mem) | 1473 | if (rdev->rio_mem) |
1463 | pci_iounmap(rdev->pdev, rdev->rio_mem); | 1474 | pci_iounmap(rdev->pdev, rdev->rio_mem); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 4eb37976f879..00ead8c2758a 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -402,14 +402,21 @@ static void radeon_flip_work_func(struct work_struct *__work) | |||
402 | 402 | ||
403 | down_read(&rdev->exclusive_lock); | 403 | down_read(&rdev->exclusive_lock); |
404 | if (work->fence) { | 404 | if (work->fence) { |
405 | r = radeon_fence_wait(work->fence, false); | 405 | struct radeon_fence *fence; |
406 | if (r == -EDEADLK) { | 406 | |
407 | up_read(&rdev->exclusive_lock); | 407 | fence = to_radeon_fence(work->fence); |
408 | do { | 408 | if (fence && fence->rdev == rdev) { |
409 | r = radeon_gpu_reset(rdev); | 409 | r = radeon_fence_wait(fence, false); |
410 | } while (r == -EAGAIN); | 410 | if (r == -EDEADLK) { |
411 | down_read(&rdev->exclusive_lock); | 411 | up_read(&rdev->exclusive_lock); |
412 | } | 412 | do { |
413 | r = radeon_gpu_reset(rdev); | ||
414 | } while (r == -EAGAIN); | ||
415 | down_read(&rdev->exclusive_lock); | ||
416 | } | ||
417 | } else | ||
418 | r = fence_wait(work->fence, false); | ||
419 | |||
413 | if (r) | 420 | if (r) |
414 | DRM_ERROR("failed to wait on page flip fence (%d)!\n", r); | 421 | DRM_ERROR("failed to wait on page flip fence (%d)!\n", r); |
415 | 422 | ||
@@ -418,7 +425,8 @@ static void radeon_flip_work_func(struct work_struct *__work) | |||
418 | * confused about which BO the CRTC is scanning out | 425 | * confused about which BO the CRTC is scanning out |
419 | */ | 426 | */ |
420 | 427 | ||
421 | radeon_fence_unref(&work->fence); | 428 | fence_put(work->fence); |
429 | work->fence = NULL; | ||
422 | } | 430 | } |
423 | 431 | ||
424 | /* We borrow the event spin lock for protecting flip_status */ | 432 | /* We borrow the event spin lock for protecting flip_status */ |
@@ -494,7 +502,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc, | |||
494 | DRM_ERROR("failed to pin new rbo buffer before flip\n"); | 502 | DRM_ERROR("failed to pin new rbo buffer before flip\n"); |
495 | goto cleanup; | 503 | goto cleanup; |
496 | } | 504 | } |
497 | work->fence = (struct radeon_fence *)fence_get(reservation_object_get_excl(new_rbo->tbo.resv)); | 505 | work->fence = fence_get(reservation_object_get_excl(new_rbo->tbo.resv)); |
498 | radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL); | 506 | radeon_bo_get_tiling_flags(new_rbo, &tiling_flags, NULL); |
499 | radeon_bo_unreserve(new_rbo); | 507 | radeon_bo_unreserve(new_rbo); |
500 | 508 | ||
@@ -576,7 +584,7 @@ pflip_cleanup: | |||
576 | 584 | ||
577 | cleanup: | 585 | cleanup: |
578 | drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); | 586 | drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); |
579 | radeon_fence_unref(&work->fence); | 587 | fence_put(work->fence); |
580 | kfree(work); | 588 | kfree(work); |
581 | return r; | 589 | return r; |
582 | } | 590 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 69c6a835bcd5..dcffa30ee2db 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -85,7 +85,7 @@ | |||
85 | * CIK: 1D and linear tiling modes contain valid PIPE_CONFIG | 85 | * CIK: 1D and linear tiling modes contain valid PIPE_CONFIG |
86 | * 2.39.0 - Add INFO query for number of active CUs | 86 | * 2.39.0 - Add INFO query for number of active CUs |
87 | * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting | 87 | * 2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting |
88 | * CS to GPU | 88 | * CS to GPU on >= r600 |
89 | */ | 89 | */ |
90 | #define KMS_DRIVER_MAJOR 2 | 90 | #define KMS_DRIVER_MAJOR 2 |
91 | #define KMS_DRIVER_MINOR 40 | 91 | #define KMS_DRIVER_MINOR 40 |
@@ -186,6 +186,7 @@ int radeon_vm_block_size = -1; | |||
186 | int radeon_deep_color = 0; | 186 | int radeon_deep_color = 0; |
187 | int radeon_use_pflipirq = 2; | 187 | int radeon_use_pflipirq = 2; |
188 | int radeon_bapm = -1; | 188 | int radeon_bapm = -1; |
189 | int radeon_backlight = -1; | ||
189 | 190 | ||
190 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); | 191 | MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); |
191 | module_param_named(no_wb, radeon_no_wb, int, 0444); | 192 | module_param_named(no_wb, radeon_no_wb, int, 0444); |
@@ -268,6 +269,9 @@ module_param_named(use_pflipirq, radeon_use_pflipirq, int, 0444); | |||
268 | MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); | 269 | MODULE_PARM_DESC(bapm, "BAPM support (1 = enable, 0 = disable, -1 = auto)"); |
269 | module_param_named(bapm, radeon_bapm, int, 0444); | 270 | module_param_named(bapm, radeon_bapm, int, 0444); |
270 | 271 | ||
272 | MODULE_PARM_DESC(backlight, "backlight support (1 = enable, 0 = disable, -1 = auto)"); | ||
273 | module_param_named(backlight, radeon_backlight, int, 0444); | ||
274 | |||
271 | static struct pci_device_id pciidlist[] = { | 275 | static struct pci_device_id pciidlist[] = { |
272 | radeon_PCI_IDS | 276 | radeon_PCI_IDS |
273 | }; | 277 | }; |
@@ -446,6 +450,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev) | |||
446 | ret = radeon_suspend_kms(drm_dev, false, false); | 450 | ret = radeon_suspend_kms(drm_dev, false, false); |
447 | pci_save_state(pdev); | 451 | pci_save_state(pdev); |
448 | pci_disable_device(pdev); | 452 | pci_disable_device(pdev); |
453 | pci_ignore_hotplug(pdev); | ||
449 | pci_set_power_state(pdev, PCI_D3cold); | 454 | pci_set_power_state(pdev, PCI_D3cold); |
450 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; | 455 | drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; |
451 | 456 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 3c2094c25b53..9a19e52cc655 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -158,10 +158,43 @@ radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8 | |||
158 | return ret; | 158 | return ret; |
159 | } | 159 | } |
160 | 160 | ||
161 | static void radeon_encoder_add_backlight(struct radeon_encoder *radeon_encoder, | ||
162 | struct drm_connector *connector) | ||
163 | { | ||
164 | struct drm_device *dev = radeon_encoder->base.dev; | ||
165 | struct radeon_device *rdev = dev->dev_private; | ||
166 | bool use_bl = false; | ||
167 | |||
168 | if (!(radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))) | ||
169 | return; | ||
170 | |||
171 | if (radeon_backlight == 0) { | ||
172 | return; | ||
173 | } else if (radeon_backlight == 1) { | ||
174 | use_bl = true; | ||
175 | } else if (radeon_backlight == -1) { | ||
176 | /* Quirks */ | ||
177 | /* Amilo Xi 2550 only works with acpi bl */ | ||
178 | if ((rdev->pdev->device == 0x9583) && | ||
179 | (rdev->pdev->subsystem_vendor == 0x1734) && | ||
180 | (rdev->pdev->subsystem_device == 0x1107)) | ||
181 | use_bl = false; | ||
182 | else | ||
183 | use_bl = true; | ||
184 | } | ||
185 | |||
186 | if (use_bl) { | ||
187 | if (rdev->is_atom_bios) | ||
188 | radeon_atom_backlight_init(radeon_encoder, connector); | ||
189 | else | ||
190 | radeon_legacy_backlight_init(radeon_encoder, connector); | ||
191 | rdev->mode_info.bl_encoder = radeon_encoder; | ||
192 | } | ||
193 | } | ||
194 | |||
161 | void | 195 | void |
162 | radeon_link_encoder_connector(struct drm_device *dev) | 196 | radeon_link_encoder_connector(struct drm_device *dev) |
163 | { | 197 | { |
164 | struct radeon_device *rdev = dev->dev_private; | ||
165 | struct drm_connector *connector; | 198 | struct drm_connector *connector; |
166 | struct radeon_connector *radeon_connector; | 199 | struct radeon_connector *radeon_connector; |
167 | struct drm_encoder *encoder; | 200 | struct drm_encoder *encoder; |
@@ -174,13 +207,8 @@ radeon_link_encoder_connector(struct drm_device *dev) | |||
174 | radeon_encoder = to_radeon_encoder(encoder); | 207 | radeon_encoder = to_radeon_encoder(encoder); |
175 | if (radeon_encoder->devices & radeon_connector->devices) { | 208 | if (radeon_encoder->devices & radeon_connector->devices) { |
176 | drm_mode_connector_attach_encoder(connector, encoder); | 209 | drm_mode_connector_attach_encoder(connector, encoder); |
177 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 210 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) |
178 | if (rdev->is_atom_bios) | 211 | radeon_encoder_add_backlight(radeon_encoder, connector); |
179 | radeon_atom_backlight_init(radeon_encoder, connector); | ||
180 | else | ||
181 | radeon_legacy_backlight_init(radeon_encoder, connector); | ||
182 | rdev->mode_info.bl_encoder = radeon_encoder; | ||
183 | } | ||
184 | } | 212 | } |
185 | } | 213 | } |
186 | } | 214 | } |
@@ -382,3 +410,24 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | |||
382 | } | 410 | } |
383 | } | 411 | } |
384 | 412 | ||
413 | bool radeon_encoder_is_digital(struct drm_encoder *encoder) | ||
414 | { | ||
415 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
416 | switch (radeon_encoder->encoder_id) { | ||
417 | case ENCODER_OBJECT_ID_INTERNAL_LVDS: | ||
418 | case ENCODER_OBJECT_ID_INTERNAL_TMDS1: | ||
419 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: | ||
420 | case ENCODER_OBJECT_ID_INTERNAL_LVTM1: | ||
421 | case ENCODER_OBJECT_ID_INTERNAL_DVO1: | ||
422 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1: | ||
423 | case ENCODER_OBJECT_ID_INTERNAL_DDI: | ||
424 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
425 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
426 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
427 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
428 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3: | ||
429 | return true; | ||
430 | default: | ||
431 | return false; | ||
432 | } | ||
433 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index af9f2d6bd7d0..995167025282 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -541,6 +541,15 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) | |||
541 | uint64_t seq[RADEON_NUM_RINGS] = {}; | 541 | uint64_t seq[RADEON_NUM_RINGS] = {}; |
542 | long r; | 542 | long r; |
543 | 543 | ||
544 | /* | ||
545 | * This function should not be called on !radeon fences. | ||
546 | * If this is the case, it would mean this function can | ||
547 | * also be called on radeon fences belonging to another card. | ||
548 | * exclusive_lock is not held in that case. | ||
549 | */ | ||
550 | if (WARN_ON_ONCE(!to_radeon_fence(&fence->base))) | ||
551 | return fence_wait(&fence->base, intr); | ||
552 | |||
544 | seq[fence->ring] = fence->seq; | 553 | seq[fence->ring] = fence->seq; |
545 | r = radeon_fence_wait_seq_timeout(fence->rdev, seq, intr, MAX_SCHEDULE_TIMEOUT); | 554 | r = radeon_fence_wait_seq_timeout(fence->rdev, seq, intr, MAX_SCHEDULE_TIMEOUT); |
546 | if (r < 0) { | 555 | if (r < 0) { |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index a053a0779aac..84146d5901aa 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -128,7 +128,7 @@ int radeon_gart_table_vram_alloc(struct radeon_device *rdev) | |||
128 | if (rdev->gart.robj == NULL) { | 128 | if (rdev->gart.robj == NULL) { |
129 | r = radeon_bo_create(rdev, rdev->gart.table_size, | 129 | r = radeon_bo_create(rdev, rdev->gart.table_size, |
130 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 130 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
131 | 0, NULL, &rdev->gart.robj); | 131 | 0, NULL, NULL, &rdev->gart.robj); |
132 | if (r) { | 132 | if (r) { |
133 | return r; | 133 | return r; |
134 | } | 134 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 4b7c8ec36c2f..c194497aa586 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -67,7 +67,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, unsigned long size, | |||
67 | 67 | ||
68 | retry: | 68 | retry: |
69 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, | 69 | r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, |
70 | flags, NULL, &robj); | 70 | flags, NULL, NULL, &robj); |
71 | if (r) { | 71 | if (r) { |
72 | if (r != -ERESTARTSYS) { | 72 | if (r != -ERESTARTSYS) { |
73 | if (initial_domain == RADEON_GEM_DOMAIN_VRAM) { | 73 | if (initial_domain == RADEON_GEM_DOMAIN_VRAM) { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index e27608c29c11..04db2fdd8692 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -777,6 +777,7 @@ extern void atombios_digital_setup(struct drm_encoder *encoder, int action); | |||
777 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); | 777 | extern int atombios_get_encoder_mode(struct drm_encoder *encoder); |
778 | extern bool atombios_set_edp_panel_power(struct drm_connector *connector, int action); | 778 | extern bool atombios_set_edp_panel_power(struct drm_connector *connector, int action); |
779 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); | 779 | extern void radeon_encoder_set_active_device(struct drm_encoder *encoder); |
780 | extern bool radeon_encoder_is_digital(struct drm_encoder *encoder); | ||
780 | 781 | ||
781 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); | 782 | extern void radeon_crtc_load_lut(struct drm_crtc *crtc); |
782 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, | 783 | extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 0e82f0223fd4..99a960a4f302 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -167,8 +167,10 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
167 | } | 167 | } |
168 | 168 | ||
169 | int radeon_bo_create(struct radeon_device *rdev, | 169 | int radeon_bo_create(struct radeon_device *rdev, |
170 | unsigned long size, int byte_align, bool kernel, u32 domain, | 170 | unsigned long size, int byte_align, bool kernel, |
171 | u32 flags, struct sg_table *sg, struct radeon_bo **bo_ptr) | 171 | u32 domain, u32 flags, struct sg_table *sg, |
172 | struct reservation_object *resv, | ||
173 | struct radeon_bo **bo_ptr) | ||
172 | { | 174 | { |
173 | struct radeon_bo *bo; | 175 | struct radeon_bo *bo; |
174 | enum ttm_bo_type type; | 176 | enum ttm_bo_type type; |
@@ -216,7 +218,7 @@ int radeon_bo_create(struct radeon_device *rdev, | |||
216 | down_read(&rdev->pm.mclk_lock); | 218 | down_read(&rdev->pm.mclk_lock); |
217 | r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, | 219 | r = ttm_bo_init(&rdev->mman.bdev, &bo->tbo, size, type, |
218 | &bo->placement, page_align, !kernel, NULL, | 220 | &bo->placement, page_align, !kernel, NULL, |
219 | acc_size, sg, NULL, &radeon_ttm_bo_destroy); | 221 | acc_size, sg, resv, &radeon_ttm_bo_destroy); |
220 | up_read(&rdev->pm.mclk_lock); | 222 | up_read(&rdev->pm.mclk_lock); |
221 | if (unlikely(r != 0)) { | 223 | if (unlikely(r != 0)) { |
222 | return r; | 224 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index 98a47fdf3625..1b8ec7917154 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h | |||
@@ -126,6 +126,7 @@ extern int radeon_bo_create(struct radeon_device *rdev, | |||
126 | unsigned long size, int byte_align, | 126 | unsigned long size, int byte_align, |
127 | bool kernel, u32 domain, u32 flags, | 127 | bool kernel, u32 domain, u32 flags, |
128 | struct sg_table *sg, | 128 | struct sg_table *sg, |
129 | struct reservation_object *resv, | ||
129 | struct radeon_bo **bo_ptr); | 130 | struct radeon_bo **bo_ptr); |
130 | extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); | 131 | extern int radeon_bo_kmap(struct radeon_bo *bo, void **ptr); |
131 | extern void radeon_bo_kunmap(struct radeon_bo *bo); | 132 | extern void radeon_bo_kunmap(struct radeon_bo *bo); |
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index 171daf7fc483..f3609c97496b 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c | |||
@@ -61,12 +61,15 @@ struct drm_gem_object *radeon_gem_prime_import_sg_table(struct drm_device *dev, | |||
61 | struct dma_buf_attachment *attach, | 61 | struct dma_buf_attachment *attach, |
62 | struct sg_table *sg) | 62 | struct sg_table *sg) |
63 | { | 63 | { |
64 | struct reservation_object *resv = attach->dmabuf->resv; | ||
64 | struct radeon_device *rdev = dev->dev_private; | 65 | struct radeon_device *rdev = dev->dev_private; |
65 | struct radeon_bo *bo; | 66 | struct radeon_bo *bo; |
66 | int ret; | 67 | int ret; |
67 | 68 | ||
69 | ww_mutex_lock(&resv->lock, NULL); | ||
68 | ret = radeon_bo_create(rdev, attach->dmabuf->size, PAGE_SIZE, false, | 70 | ret = radeon_bo_create(rdev, attach->dmabuf->size, PAGE_SIZE, false, |
69 | RADEON_GEM_DOMAIN_GTT, 0, sg, &bo); | 71 | RADEON_GEM_DOMAIN_GTT, 0, sg, resv, &bo); |
72 | ww_mutex_unlock(&resv->lock); | ||
70 | if (ret) | 73 | if (ret) |
71 | return ERR_PTR(ret); | 74 | return ERR_PTR(ret); |
72 | 75 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 6f2a9bd6bb54..3d17af34afa7 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -383,7 +383,7 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig | |||
383 | /* Allocate ring buffer */ | 383 | /* Allocate ring buffer */ |
384 | if (ring->ring_obj == NULL) { | 384 | if (ring->ring_obj == NULL) { |
385 | r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, | 385 | r = radeon_bo_create(rdev, ring->ring_size, PAGE_SIZE, true, |
386 | RADEON_GEM_DOMAIN_GTT, 0, | 386 | RADEON_GEM_DOMAIN_GTT, 0, NULL, |
387 | NULL, &ring->ring_obj); | 387 | NULL, &ring->ring_obj); |
388 | if (r) { | 388 | if (r) { |
389 | dev_err(rdev->dev, "(%d) ring create failed\n", r); | 389 | dev_err(rdev->dev, "(%d) ring create failed\n", r); |
diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c index b84f97c8718c..c507896aca45 100644 --- a/drivers/gpu/drm/radeon/radeon_sa.c +++ b/drivers/gpu/drm/radeon/radeon_sa.c | |||
@@ -65,7 +65,7 @@ int radeon_sa_bo_manager_init(struct radeon_device *rdev, | |||
65 | } | 65 | } |
66 | 66 | ||
67 | r = radeon_bo_create(rdev, size, align, true, | 67 | r = radeon_bo_create(rdev, size, align, true, |
68 | domain, flags, NULL, &sa_manager->bo); | 68 | domain, flags, NULL, NULL, &sa_manager->bo); |
69 | if (r) { | 69 | if (r) { |
70 | dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r); | 70 | dev_err(rdev->dev, "(%d) failed to allocate bo for manager\n", r); |
71 | return r; | 71 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 4d4b0773638a..6deb08f045b7 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
@@ -124,27 +124,42 @@ void radeon_semaphore_sync_fence(struct radeon_semaphore *semaphore, | |||
124 | * | 124 | * |
125 | * Sync to the fence using this semaphore object | 125 | * Sync to the fence using this semaphore object |
126 | */ | 126 | */ |
127 | void radeon_semaphore_sync_resv(struct radeon_semaphore *sema, | 127 | int radeon_semaphore_sync_resv(struct radeon_device *rdev, |
128 | struct reservation_object *resv, | 128 | struct radeon_semaphore *sema, |
129 | bool shared) | 129 | struct reservation_object *resv, |
130 | bool shared) | ||
130 | { | 131 | { |
131 | struct reservation_object_list *flist; | 132 | struct reservation_object_list *flist; |
132 | struct fence *f; | 133 | struct fence *f; |
134 | struct radeon_fence *fence; | ||
133 | unsigned i; | 135 | unsigned i; |
136 | int r = 0; | ||
134 | 137 | ||
135 | /* always sync to the exclusive fence */ | 138 | /* always sync to the exclusive fence */ |
136 | f = reservation_object_get_excl(resv); | 139 | f = reservation_object_get_excl(resv); |
137 | radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); | 140 | fence = f ? to_radeon_fence(f) : NULL; |
141 | if (fence && fence->rdev == rdev) | ||
142 | radeon_semaphore_sync_fence(sema, fence); | ||
143 | else if (f) | ||
144 | r = fence_wait(f, true); | ||
138 | 145 | ||
139 | flist = reservation_object_get_list(resv); | 146 | flist = reservation_object_get_list(resv); |
140 | if (shared || !flist) | 147 | if (shared || !flist || r) |
141 | return; | 148 | return r; |
142 | 149 | ||
143 | for (i = 0; i < flist->shared_count; ++i) { | 150 | for (i = 0; i < flist->shared_count; ++i) { |
144 | f = rcu_dereference_protected(flist->shared[i], | 151 | f = rcu_dereference_protected(flist->shared[i], |
145 | reservation_object_held(resv)); | 152 | reservation_object_held(resv)); |
146 | radeon_semaphore_sync_fence(sema, (struct radeon_fence*)f); | 153 | fence = to_radeon_fence(f); |
154 | if (fence && fence->rdev == rdev) | ||
155 | radeon_semaphore_sync_fence(sema, fence); | ||
156 | else | ||
157 | r = fence_wait(f, true); | ||
158 | |||
159 | if (r) | ||
160 | break; | ||
147 | } | 161 | } |
162 | return r; | ||
148 | } | 163 | } |
149 | 164 | ||
150 | /** | 165 | /** |
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index ce943e1a5e51..07b506b41008 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -67,7 +67,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | 69 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
70 | 0, NULL, &vram_obj); | 70 | 0, NULL, NULL, &vram_obj); |
71 | if (r) { | 71 | if (r) { |
72 | DRM_ERROR("Failed to create VRAM object\n"); | 72 | DRM_ERROR("Failed to create VRAM object\n"); |
73 | goto out_cleanup; | 73 | goto out_cleanup; |
@@ -87,7 +87,8 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) | |||
87 | struct radeon_fence *fence = NULL; | 87 | struct radeon_fence *fence = NULL; |
88 | 88 | ||
89 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, | 89 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, |
90 | RADEON_GEM_DOMAIN_GTT, 0, NULL, gtt_obj + i); | 90 | RADEON_GEM_DOMAIN_GTT, 0, NULL, NULL, |
91 | gtt_obj + i); | ||
91 | if (r) { | 92 | if (r) { |
92 | DRM_ERROR("Failed to create GTT object %d\n", i); | 93 | DRM_ERROR("Failed to create GTT object %d\n", i); |
93 | goto out_lclean; | 94 | goto out_lclean; |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 738a2f248b36..8624979afb65 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
@@ -865,7 +865,7 @@ int radeon_ttm_init(struct radeon_device *rdev) | |||
865 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | 865 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
866 | 866 | ||
867 | r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, | 867 | r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true, |
868 | RADEON_GEM_DOMAIN_VRAM, 0, | 868 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, |
869 | NULL, &rdev->stollen_vga_memory); | 869 | NULL, &rdev->stollen_vga_memory); |
870 | if (r) { | 870 | if (r) { |
871 | return r; | 871 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index ba4f38916026..11b662469253 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -141,7 +141,8 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
141 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE + | 141 | RADEON_UVD_STACK_SIZE + RADEON_UVD_HEAP_SIZE + |
142 | RADEON_GPU_PAGE_SIZE; | 142 | RADEON_GPU_PAGE_SIZE; |
143 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, | 143 | r = radeon_bo_create(rdev, bo_size, PAGE_SIZE, true, |
144 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, &rdev->uvd.vcpu_bo); | 144 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, |
145 | NULL, &rdev->uvd.vcpu_bo); | ||
145 | if (r) { | 146 | if (r) { |
146 | dev_err(rdev->dev, "(%d) failed to allocate UVD bo\n", r); | 147 | dev_err(rdev->dev, "(%d) failed to allocate UVD bo\n", r); |
147 | return r; | 148 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index c7190aadbd89..9e85757d5599 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c | |||
@@ -126,7 +126,8 @@ int radeon_vce_init(struct radeon_device *rdev) | |||
126 | size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) + | 126 | size = RADEON_GPU_PAGE_ALIGN(rdev->vce_fw->size) + |
127 | RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE; | 127 | RADEON_VCE_STACK_SIZE + RADEON_VCE_HEAP_SIZE; |
128 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, | 128 | r = radeon_bo_create(rdev, size, PAGE_SIZE, true, |
129 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, &rdev->vce.vcpu_bo); | 129 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, |
130 | &rdev->vce.vcpu_bo); | ||
130 | if (r) { | 131 | if (r) { |
131 | dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r); | 132 | dev_err(rdev->dev, "(%d) failed to allocate VCE bo\n", r); |
132 | return r; | 133 | return r; |
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index ce870959dff8..4532cc76a0a6 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -548,7 +548,8 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
548 | 548 | ||
549 | r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8, | 549 | r = radeon_bo_create(rdev, RADEON_VM_PTE_COUNT * 8, |
550 | RADEON_GPU_PAGE_SIZE, true, | 550 | RADEON_GPU_PAGE_SIZE, true, |
551 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, &pt); | 551 | RADEON_GEM_DOMAIN_VRAM, 0, |
552 | NULL, NULL, &pt); | ||
552 | if (r) | 553 | if (r) |
553 | return r; | 554 | return r; |
554 | 555 | ||
@@ -698,7 +699,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, | |||
698 | if (ib.length_dw != 0) { | 699 | if (ib.length_dw != 0) { |
699 | radeon_asic_vm_pad_ib(rdev, &ib); | 700 | radeon_asic_vm_pad_ib(rdev, &ib); |
700 | 701 | ||
701 | radeon_semaphore_sync_resv(ib.semaphore, pd->tbo.resv, false); | 702 | radeon_semaphore_sync_resv(rdev, ib.semaphore, pd->tbo.resv, false); |
702 | radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use); | 703 | radeon_semaphore_sync_fence(ib.semaphore, vm->last_id_use); |
703 | WARN_ON(ib.length_dw > ndw); | 704 | WARN_ON(ib.length_dw > ndw); |
704 | r = radeon_ib_schedule(rdev, &ib, NULL, false); | 705 | r = radeon_ib_schedule(rdev, &ib, NULL, false); |
@@ -825,7 +826,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, | |||
825 | unsigned nptes; | 826 | unsigned nptes; |
826 | uint64_t pte; | 827 | uint64_t pte; |
827 | 828 | ||
828 | radeon_semaphore_sync_resv(ib->semaphore, pt->tbo.resv, false); | 829 | radeon_semaphore_sync_resv(rdev, ib->semaphore, pt->tbo.resv, false); |
829 | 830 | ||
830 | if ((addr & ~mask) == (end & ~mask)) | 831 | if ((addr & ~mask) == (end & ~mask)) |
831 | nptes = end - addr; | 832 | nptes = end - addr; |
@@ -1127,7 +1128,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
1127 | 1128 | ||
1128 | r = radeon_bo_create(rdev, pd_size, align, true, | 1129 | r = radeon_bo_create(rdev, pd_size, align, true, |
1129 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, | 1130 | RADEON_GEM_DOMAIN_VRAM, 0, NULL, |
1130 | &vm->page_directory); | 1131 | NULL, &vm->page_directory); |
1131 | if (r) | 1132 | if (r) |
1132 | return r; | 1133 | return r; |
1133 | 1134 | ||
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 6c1fc339d228..c5799f16aa4b 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c | |||
@@ -221,9 +221,9 @@ void rs400_gart_set_page(struct radeon_device *rdev, unsigned i, | |||
221 | entry = (lower_32_bits(addr) & PAGE_MASK) | | 221 | entry = (lower_32_bits(addr) & PAGE_MASK) | |
222 | ((upper_32_bits(addr) & 0xff) << 4); | 222 | ((upper_32_bits(addr) & 0xff) << 4); |
223 | if (flags & RADEON_GART_PAGE_READ) | 223 | if (flags & RADEON_GART_PAGE_READ) |
224 | addr |= RS400_PTE_READABLE; | 224 | entry |= RS400_PTE_READABLE; |
225 | if (flags & RADEON_GART_PAGE_WRITE) | 225 | if (flags & RADEON_GART_PAGE_WRITE) |
226 | addr |= RS400_PTE_WRITEABLE; | 226 | entry |= RS400_PTE_WRITEABLE; |
227 | if (!(flags & RADEON_GART_PAGE_SNOOP)) | 227 | if (!(flags & RADEON_GART_PAGE_SNOOP)) |
228 | entry |= RS400_PTE_UNSNOOPED; | 228 | entry |= RS400_PTE_UNSNOOPED; |
229 | entry = cpu_to_le32(entry); | 229 | entry = cpu_to_le32(entry); |
diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c index 02f7710de470..9031f4b69824 100644 --- a/drivers/gpu/drm/radeon/rs780_dpm.c +++ b/drivers/gpu/drm/radeon/rs780_dpm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | ||
27 | #include "rs780d.h" | 28 | #include "rs780d.h" |
28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
29 | #include "rs780_dpm.h" | 30 | #include "rs780_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index e7045b085715..6a5c233361e9 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | ||
27 | #include "rv6xxd.h" | 28 | #include "rv6xxd.h" |
28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
29 | #include "rv6xx_dpm.h" | 30 | #include "rv6xx_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index d9f5ce715c9b..372016e266d0 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -26,7 +26,6 @@ | |||
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #include <linux/firmware.h> | 28 | #include <linux/firmware.h> |
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
31 | #include <drm/drmP.h> | 30 | #include <drm/drmP.h> |
32 | #include "radeon.h" | 31 | #include "radeon.h" |
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c index c112764adfdf..7f34bad2e724 100644 --- a/drivers/gpu/drm/radeon/rv770_dma.c +++ b/drivers/gpu/drm/radeon/rv770_dma.c | |||
@@ -67,7 +67,7 @@ struct radeon_fence *rv770_copy_dma(struct radeon_device *rdev, | |||
67 | return ERR_PTR(r); | 67 | return ERR_PTR(r); |
68 | } | 68 | } |
69 | 69 | ||
70 | radeon_semaphore_sync_resv(sem, resv, false); | 70 | radeon_semaphore_sync_resv(rdev, sem, resv, false); |
71 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 71 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
72 | 72 | ||
73 | for (i = 0; i < num_loops; i++) { | 73 | for (i = 0; i < num_loops; i++) { |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 3c76e1dcdf04..755a8f96fe46 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "drmP.h" | 25 | #include "drmP.h" |
26 | #include "radeon.h" | 26 | #include "radeon.h" |
27 | #include "radeon_asic.h" | ||
27 | #include "rv770d.h" | 28 | #include "rv770d.h" |
28 | #include "r600_dpm.h" | 29 | #include "r600_dpm.h" |
29 | #include "rv770_dpm.h" | 30 | #include "rv770_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 6bce40847753..eeea5b6a1775 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -4684,7 +4684,7 @@ static int si_vm_packet3_compute_check(struct radeon_device *rdev, | |||
4684 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | 4684 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) |
4685 | { | 4685 | { |
4686 | int ret = 0; | 4686 | int ret = 0; |
4687 | u32 idx = 0; | 4687 | u32 idx = 0, i; |
4688 | struct radeon_cs_packet pkt; | 4688 | struct radeon_cs_packet pkt; |
4689 | 4689 | ||
4690 | do { | 4690 | do { |
@@ -4695,6 +4695,12 @@ int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | |||
4695 | switch (pkt.type) { | 4695 | switch (pkt.type) { |
4696 | case RADEON_PACKET_TYPE0: | 4696 | case RADEON_PACKET_TYPE0: |
4697 | dev_err(rdev->dev, "Packet0 not allowed!\n"); | 4697 | dev_err(rdev->dev, "Packet0 not allowed!\n"); |
4698 | for (i = 0; i < ib->length_dw; i++) { | ||
4699 | if (i == idx) | ||
4700 | printk("\t0x%08x <---\n", ib->ptr[i]); | ||
4701 | else | ||
4702 | printk("\t0x%08x\n", ib->ptr[i]); | ||
4703 | } | ||
4698 | ret = -EINVAL; | 4704 | ret = -EINVAL; |
4699 | break; | 4705 | break; |
4700 | case RADEON_PACKET_TYPE2: | 4706 | case RADEON_PACKET_TYPE2: |
@@ -6316,17 +6322,17 @@ static inline u32 si_get_ih_wptr(struct radeon_device *rdev) | |||
6316 | wptr = RREG32(IH_RB_WPTR); | 6322 | wptr = RREG32(IH_RB_WPTR); |
6317 | 6323 | ||
6318 | if (wptr & RB_OVERFLOW) { | 6324 | if (wptr & RB_OVERFLOW) { |
6325 | wptr &= ~RB_OVERFLOW; | ||
6319 | /* When a ring buffer overflow happen start parsing interrupt | 6326 | /* When a ring buffer overflow happen start parsing interrupt |
6320 | * from the last not overwritten vector (wptr + 16). Hopefully | 6327 | * from the last not overwritten vector (wptr + 16). Hopefully |
6321 | * this should allow us to catchup. | 6328 | * this should allow us to catchup. |
6322 | */ | 6329 | */ |
6323 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | 6330 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", |
6324 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | 6331 | wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); |
6325 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | 6332 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; |
6326 | tmp = RREG32(IH_RB_CNTL); | 6333 | tmp = RREG32(IH_RB_CNTL); |
6327 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | 6334 | tmp |= IH_WPTR_OVERFLOW_CLEAR; |
6328 | WREG32(IH_RB_CNTL, tmp); | 6335 | WREG32(IH_RB_CNTL, tmp); |
6329 | wptr &= ~RB_OVERFLOW; | ||
6330 | } | 6336 | } |
6331 | return (wptr & rdev->ih.ptr_mask); | 6337 | return (wptr & rdev->ih.ptr_mask); |
6332 | } | 6338 | } |
@@ -6664,13 +6670,13 @@ restart_ih: | |||
6664 | /* wptr/rptr are in bytes! */ | 6670 | /* wptr/rptr are in bytes! */ |
6665 | rptr += 16; | 6671 | rptr += 16; |
6666 | rptr &= rdev->ih.ptr_mask; | 6672 | rptr &= rdev->ih.ptr_mask; |
6673 | WREG32(IH_RB_RPTR, rptr); | ||
6667 | } | 6674 | } |
6668 | if (queue_hotplug) | 6675 | if (queue_hotplug) |
6669 | schedule_work(&rdev->hotplug_work); | 6676 | schedule_work(&rdev->hotplug_work); |
6670 | if (queue_thermal && rdev->pm.dpm_enabled) | 6677 | if (queue_thermal && rdev->pm.dpm_enabled) |
6671 | schedule_work(&rdev->pm.dpm.thermal.work); | 6678 | schedule_work(&rdev->pm.dpm.thermal.work); |
6672 | rdev->ih.rptr = rptr; | 6679 | rdev->ih.rptr = rptr; |
6673 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
6674 | atomic_set(&rdev->ih.lock, 0); | 6680 | atomic_set(&rdev->ih.lock, 0); |
6675 | 6681 | ||
6676 | /* make sure wptr hasn't changed while processing */ | 6682 | /* make sure wptr hasn't changed while processing */ |
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index 9b0dfbc913f3..b58f12b762d7 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
@@ -252,7 +252,7 @@ struct radeon_fence *si_copy_dma(struct radeon_device *rdev, | |||
252 | return ERR_PTR(r); | 252 | return ERR_PTR(r); |
253 | } | 253 | } |
254 | 254 | ||
255 | radeon_semaphore_sync_resv(sem, resv, false); | 255 | radeon_semaphore_sync_resv(rdev, sem, resv, false); |
256 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); | 256 | radeon_semaphore_sync_rings(rdev, sem, ring->idx); |
257 | 257 | ||
258 | for (i = 0; i < num_loops; i++) { | 258 | for (i = 0; i < num_loops; i++) { |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 70e61ffeace2..a53c2e79d9cb 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "drmP.h" | 24 | #include "drmP.h" |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_asic.h" | ||
26 | #include "sid.h" | 27 | #include "sid.h" |
27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
28 | #include "si_dpm.h" | 29 | #include "si_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index fd414d34d885..6635da9ec986 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -736,7 +736,7 @@ | |||
736 | # define DESCRIPTION16(x) (((x) & 0xff) << 0) | 736 | # define DESCRIPTION16(x) (((x) & 0xff) << 0) |
737 | # define DESCRIPTION17(x) (((x) & 0xff) << 8) | 737 | # define DESCRIPTION17(x) (((x) & 0xff) << 8) |
738 | 738 | ||
739 | #define AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL 0x54 | 739 | #define AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL 0x54 |
740 | # define AUDIO_ENABLED (1 << 31) | 740 | # define AUDIO_ENABLED (1 << 31) |
741 | 741 | ||
742 | #define AZ_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x56 | 742 | #define AZ_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT 0x56 |
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index 3f0e8d7b8dbe..1f8a8833e1be 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "drmP.h" | 24 | #include "drmP.h" |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_asic.h" | ||
26 | #include "sumod.h" | 27 | #include "sumod.h" |
27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
28 | #include "cypress_dpm.h" | 29 | #include "cypress_dpm.h" |
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 57f780053b3e..b4ec5c4e7969 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include "drmP.h" | 24 | #include "drmP.h" |
25 | #include "radeon.h" | 25 | #include "radeon.h" |
26 | #include "radeon_asic.h" | ||
26 | #include "trinityd.h" | 27 | #include "trinityd.h" |
27 | #include "r600_dpm.h" | 28 | #include "r600_dpm.h" |
28 | #include "trinity_dpm.h" | 29 | #include "trinity_dpm.h" |
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index ef93156a69c6..b22968c08d1f 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c | |||
@@ -298,7 +298,6 @@ static int hdmi_avi_infoframe_config(struct sti_hdmi *hdmi) | |||
298 | hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD2(HDMI_IFRAME_SLOT_AVI)); | 298 | hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD2(HDMI_IFRAME_SLOT_AVI)); |
299 | 299 | ||
300 | val = frame[0xC]; | 300 | val = frame[0xC]; |
301 | val |= frame[0xD] << 8; | ||
302 | hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD3(HDMI_IFRAME_SLOT_AVI)); | 301 | hdmi_write(hdmi, val, HDMI_SW_DI_N_PKT_WORD3(HDMI_IFRAME_SLOT_AVI)); |
303 | 302 | ||
304 | /* Enable transmission slot for AVI infoframe | 303 | /* Enable transmission slot for AVI infoframe |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 8f5cec67c47d..d395b0bef73b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
@@ -709,6 +709,7 @@ out: | |||
709 | 709 | ||
710 | static int ttm_mem_evict_first(struct ttm_bo_device *bdev, | 710 | static int ttm_mem_evict_first(struct ttm_bo_device *bdev, |
711 | uint32_t mem_type, | 711 | uint32_t mem_type, |
712 | const struct ttm_place *place, | ||
712 | bool interruptible, | 713 | bool interruptible, |
713 | bool no_wait_gpu) | 714 | bool no_wait_gpu) |
714 | { | 715 | { |
@@ -720,8 +721,21 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, | |||
720 | spin_lock(&glob->lru_lock); | 721 | spin_lock(&glob->lru_lock); |
721 | list_for_each_entry(bo, &man->lru, lru) { | 722 | list_for_each_entry(bo, &man->lru, lru) { |
722 | ret = __ttm_bo_reserve(bo, false, true, false, NULL); | 723 | ret = __ttm_bo_reserve(bo, false, true, false, NULL); |
723 | if (!ret) | 724 | if (!ret) { |
725 | if (place && (place->fpfn || place->lpfn)) { | ||
726 | /* Don't evict this BO if it's outside of the | ||
727 | * requested placement range | ||
728 | */ | ||
729 | if (place->fpfn >= (bo->mem.start + bo->mem.size) || | ||
730 | (place->lpfn && place->lpfn <= bo->mem.start)) { | ||
731 | __ttm_bo_unreserve(bo); | ||
732 | ret = -EBUSY; | ||
733 | continue; | ||
734 | } | ||
735 | } | ||
736 | |||
724 | break; | 737 | break; |
738 | } | ||
725 | } | 739 | } |
726 | 740 | ||
727 | if (ret) { | 741 | if (ret) { |
@@ -782,7 +796,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, | |||
782 | return ret; | 796 | return ret; |
783 | if (mem->mm_node) | 797 | if (mem->mm_node) |
784 | break; | 798 | break; |
785 | ret = ttm_mem_evict_first(bdev, mem_type, | 799 | ret = ttm_mem_evict_first(bdev, mem_type, place, |
786 | interruptible, no_wait_gpu); | 800 | interruptible, no_wait_gpu); |
787 | if (unlikely(ret != 0)) | 801 | if (unlikely(ret != 0)) |
788 | return ret; | 802 | return ret; |
@@ -994,9 +1008,9 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement, | |||
994 | 1008 | ||
995 | for (i = 0; i < placement->num_placement; i++) { | 1009 | for (i = 0; i < placement->num_placement; i++) { |
996 | const struct ttm_place *heap = &placement->placement[i]; | 1010 | const struct ttm_place *heap = &placement->placement[i]; |
997 | if (mem->mm_node && heap->lpfn != 0 && | 1011 | if (mem->mm_node && |
998 | (mem->start < heap->fpfn || | 1012 | (mem->start < heap->fpfn || |
999 | mem->start + mem->num_pages > heap->lpfn)) | 1013 | (heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn))) |
1000 | continue; | 1014 | continue; |
1001 | 1015 | ||
1002 | *new_flags = heap->flags; | 1016 | *new_flags = heap->flags; |
@@ -1007,9 +1021,9 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement, | |||
1007 | 1021 | ||
1008 | for (i = 0; i < placement->num_busy_placement; i++) { | 1022 | for (i = 0; i < placement->num_busy_placement; i++) { |
1009 | const struct ttm_place *heap = &placement->busy_placement[i]; | 1023 | const struct ttm_place *heap = &placement->busy_placement[i]; |
1010 | if (mem->mm_node && heap->lpfn != 0 && | 1024 | if (mem->mm_node && |
1011 | (mem->start < heap->fpfn || | 1025 | (mem->start < heap->fpfn || |
1012 | mem->start + mem->num_pages > heap->lpfn)) | 1026 | (heap->lpfn != 0 && (mem->start + mem->num_pages) > heap->lpfn))) |
1013 | continue; | 1027 | continue; |
1014 | 1028 | ||
1015 | *new_flags = heap->flags; | 1029 | *new_flags = heap->flags; |
@@ -1233,7 +1247,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev, | |||
1233 | spin_lock(&glob->lru_lock); | 1247 | spin_lock(&glob->lru_lock); |
1234 | while (!list_empty(&man->lru)) { | 1248 | while (!list_empty(&man->lru)) { |
1235 | spin_unlock(&glob->lru_lock); | 1249 | spin_unlock(&glob->lru_lock); |
1236 | ret = ttm_mem_evict_first(bdev, mem_type, false, false); | 1250 | ret = ttm_mem_evict_first(bdev, mem_type, NULL, false, false); |
1237 | if (ret) { | 1251 | if (ret) { |
1238 | if (allow_errors) { | 1252 | if (allow_errors) { |
1239 | return ret; | 1253 | return ret; |
diff --git a/drivers/gpu/drm/vmwgfx/svga_reg.h b/drivers/gpu/drm/vmwgfx/svga_reg.h index 11323dd5196f..e4259c2c1acc 100644 --- a/drivers/gpu/drm/vmwgfx/svga_reg.h +++ b/drivers/gpu/drm/vmwgfx/svga_reg.h | |||
@@ -35,7 +35,6 @@ | |||
35 | /* | 35 | /* |
36 | * PCI device IDs. | 36 | * PCI device IDs. |
37 | */ | 37 | */ |
38 | #define PCI_VENDOR_ID_VMWARE 0x15AD | ||
39 | #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 | 38 | #define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405 |
40 | 39 | ||
41 | /* | 40 | /* |
diff --git a/drivers/gpu/ipu-v3/Kconfig b/drivers/gpu/ipu-v3/Kconfig index 2f228a2f2a48..aefdff95356d 100644 --- a/drivers/gpu/ipu-v3/Kconfig +++ b/drivers/gpu/ipu-v3/Kconfig | |||
@@ -1,7 +1,8 @@ | |||
1 | config IMX_IPUV3_CORE | 1 | config IMX_IPUV3_CORE |
2 | tristate "IPUv3 core support" | 2 | tristate "IPUv3 core support" |
3 | depends on SOC_IMX5 || SOC_IMX6Q || SOC_IMX6SL || ARCH_MULTIPLATFORM | 3 | depends on SOC_IMX5 || SOC_IMX6Q || ARCH_MULTIPLATFORM |
4 | depends on RESET_CONTROLLER | 4 | depends on RESET_CONTROLLER |
5 | select GENERIC_IRQ_CHIP | ||
5 | help | 6 | help |
6 | Choose this if you have a i.MX5/6 system and want to use the Image | 7 | Choose this if you have a i.MX5/6 system and want to use the Image |
7 | Processing Unit. This option only enables IPU base support. | 8 | Processing Unit. This option only enables IPU base support. |
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index df65d2bca522..f707d25ae78f 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c | |||
@@ -1060,8 +1060,10 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base) | |||
1060 | id++, ®->pdata, sizeof(reg->pdata)); | 1060 | id++, ®->pdata, sizeof(reg->pdata)); |
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | if (IS_ERR(pdev)) | 1063 | if (IS_ERR(pdev)) { |
1064 | ret = PTR_ERR(pdev); | ||
1064 | goto err_register; | 1065 | goto err_register; |
1066 | } | ||
1065 | } | 1067 | } |
1066 | 1068 | ||
1067 | return 0; | 1069 | return 0; |
diff --git a/drivers/gpu/ipu-v3/ipu-smfc.c b/drivers/gpu/ipu-v3/ipu-smfc.c index 6ca9b43ce25a..4ef910991413 100644 --- a/drivers/gpu/ipu-v3/ipu-smfc.c +++ b/drivers/gpu/ipu-v3/ipu-smfc.c | |||
@@ -8,7 +8,6 @@ | |||
8 | * http://www.opensource.org/licenses/gpl-license.html | 8 | * http://www.opensource.org/licenses/gpl-license.html |
9 | * http://www.gnu.org/copyleft/gpl.html | 9 | * http://www.gnu.org/copyleft/gpl.html |
10 | */ | 10 | */ |
11 | #define DEBUG | ||
12 | #include <linux/export.h> | 11 | #include <linux/export.h> |
13 | #include <linux/types.h> | 12 | #include <linux/types.h> |
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 6866448083b2..37ac7b5dbd06 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
@@ -660,6 +660,12 @@ int vga_switcheroo_init_domain_pm_ops(struct device *dev, struct dev_pm_domain * | |||
660 | } | 660 | } |
661 | EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops); | 661 | EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops); |
662 | 662 | ||
663 | void vga_switcheroo_fini_domain_pm_ops(struct device *dev) | ||
664 | { | ||
665 | dev->pm_domain = NULL; | ||
666 | } | ||
667 | EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops); | ||
668 | |||
663 | static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev) | 669 | static int vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev) |
664 | { | 670 | { |
665 | struct pci_dev *pdev = to_pci_dev(dev); | 671 | struct pci_dev *pdev = to_pci_dev(dev); |
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c index d2077f040f3e..7bcbf863656e 100644 --- a/drivers/gpu/vga/vgaarb.c +++ b/drivers/gpu/vga/vgaarb.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/poll.h> | 41 | #include <linux/poll.h> |
42 | #include <linux/miscdevice.h> | 42 | #include <linux/miscdevice.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/screen_info.h> | ||
44 | 45 | ||
45 | #include <linux/uaccess.h> | 46 | #include <linux/uaccess.h> |
46 | 47 | ||
@@ -112,10 +113,8 @@ both: | |||
112 | return 1; | 113 | return 1; |
113 | } | 114 | } |
114 | 115 | ||
115 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
116 | /* this is only used a cookie - it should not be dereferenced */ | 116 | /* this is only used a cookie - it should not be dereferenced */ |
117 | static struct pci_dev *vga_default; | 117 | static struct pci_dev *vga_default; |
118 | #endif | ||
119 | 118 | ||
120 | static void vga_arb_device_card_gone(struct pci_dev *pdev); | 119 | static void vga_arb_device_card_gone(struct pci_dev *pdev); |
121 | 120 | ||
@@ -131,7 +130,6 @@ static struct vga_device *vgadev_find(struct pci_dev *pdev) | |||
131 | } | 130 | } |
132 | 131 | ||
133 | /* Returns the default VGA device (vgacon's babe) */ | 132 | /* Returns the default VGA device (vgacon's babe) */ |
134 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
135 | struct pci_dev *vga_default_device(void) | 133 | struct pci_dev *vga_default_device(void) |
136 | { | 134 | { |
137 | return vga_default; | 135 | return vga_default; |
@@ -147,7 +145,6 @@ void vga_set_default_device(struct pci_dev *pdev) | |||
147 | pci_dev_put(vga_default); | 145 | pci_dev_put(vga_default); |
148 | vga_default = pci_dev_get(pdev); | 146 | vga_default = pci_dev_get(pdev); |
149 | } | 147 | } |
150 | #endif | ||
151 | 148 | ||
152 | static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) | 149 | static inline void vga_irq_set_state(struct vga_device *vgadev, bool state) |
153 | { | 150 | { |
@@ -403,7 +400,6 @@ int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) | |||
403 | } | 400 | } |
404 | schedule(); | 401 | schedule(); |
405 | remove_wait_queue(&vga_wait_queue, &wait); | 402 | remove_wait_queue(&vga_wait_queue, &wait); |
406 | set_current_state(TASK_RUNNING); | ||
407 | } | 403 | } |
408 | return rc; | 404 | return rc; |
409 | } | 405 | } |
@@ -583,11 +579,12 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) | |||
583 | /* Deal with VGA default device. Use first enabled one | 579 | /* Deal with VGA default device. Use first enabled one |
584 | * by default if arch doesn't have it's own hook | 580 | * by default if arch doesn't have it's own hook |
585 | */ | 581 | */ |
586 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
587 | if (vga_default == NULL && | 582 | if (vga_default == NULL && |
588 | ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) | 583 | ((vgadev->owns & VGA_RSRC_LEGACY_MASK) == VGA_RSRC_LEGACY_MASK)) { |
584 | pr_info("vgaarb: setting as boot device: PCI:%s\n", | ||
585 | pci_name(pdev)); | ||
589 | vga_set_default_device(pdev); | 586 | vga_set_default_device(pdev); |
590 | #endif | 587 | } |
591 | 588 | ||
592 | vga_arbiter_check_bridge_sharing(vgadev); | 589 | vga_arbiter_check_bridge_sharing(vgadev); |
593 | 590 | ||
@@ -621,10 +618,8 @@ static bool vga_arbiter_del_pci_device(struct pci_dev *pdev) | |||
621 | goto bail; | 618 | goto bail; |
622 | } | 619 | } |
623 | 620 | ||
624 | #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE | ||
625 | if (vga_default == pdev) | 621 | if (vga_default == pdev) |
626 | vga_set_default_device(NULL); | 622 | vga_set_default_device(NULL); |
627 | #endif | ||
628 | 623 | ||
629 | if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) | 624 | if (vgadev->decodes & (VGA_RSRC_LEGACY_IO | VGA_RSRC_LEGACY_MEM)) |
630 | vga_decode_count--; | 625 | vga_decode_count--; |
@@ -1320,6 +1315,38 @@ static int __init vga_arb_device_init(void) | |||
1320 | pr_info("vgaarb: loaded\n"); | 1315 | pr_info("vgaarb: loaded\n"); |
1321 | 1316 | ||
1322 | list_for_each_entry(vgadev, &vga_list, list) { | 1317 | list_for_each_entry(vgadev, &vga_list, list) { |
1318 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) | ||
1319 | /* Override I/O based detection done by vga_arbiter_add_pci_device() | ||
1320 | * as it may take the wrong device (e.g. on Apple system under EFI). | ||
1321 | * | ||
1322 | * Select the device owning the boot framebuffer if there is one. | ||
1323 | */ | ||
1324 | resource_size_t start, end; | ||
1325 | int i; | ||
1326 | |||
1327 | /* Does firmware framebuffer belong to us? */ | ||
1328 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | ||
1329 | if (!(pci_resource_flags(vgadev->pdev, i) & IORESOURCE_MEM)) | ||
1330 | continue; | ||
1331 | |||
1332 | start = pci_resource_start(vgadev->pdev, i); | ||
1333 | end = pci_resource_end(vgadev->pdev, i); | ||
1334 | |||
1335 | if (!start || !end) | ||
1336 | continue; | ||
1337 | |||
1338 | if (screen_info.lfb_base < start || | ||
1339 | (screen_info.lfb_base + screen_info.lfb_size) >= end) | ||
1340 | continue; | ||
1341 | if (!vga_default_device()) | ||
1342 | pr_info("vgaarb: setting as boot device: PCI:%s\n", | ||
1343 | pci_name(vgadev->pdev)); | ||
1344 | else if (vgadev->pdev != vga_default_device()) | ||
1345 | pr_info("vgaarb: overriding boot device: PCI:%s\n", | ||
1346 | pci_name(vgadev->pdev)); | ||
1347 | vga_set_default_device(vgadev->pdev); | ||
1348 | } | ||
1349 | #endif | ||
1323 | if (vgadev->bridge_has_one_vga) | 1350 | if (vgadev->bridge_has_one_vga) |
1324 | pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev)); | 1351 | pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev)); |
1325 | else | 1352 | else |