diff options
Diffstat (limited to 'drivers/gpu')
59 files changed, 670 insertions, 484 deletions
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index 3f46772f0cb2..ba23790450e9 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c | |||
| @@ -101,7 +101,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv, | |||
| 101 | * Searches and unlinks the entry in drm_device::magiclist with the magic | 101 | * Searches and unlinks the entry in drm_device::magiclist with the magic |
| 102 | * number hash key, while holding the drm_device::struct_mutex lock. | 102 | * number hash key, while holding the drm_device::struct_mutex lock. |
| 103 | */ | 103 | */ |
| 104 | static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) | 104 | int drm_remove_magic(struct drm_master *master, drm_magic_t magic) |
| 105 | { | 105 | { |
| 106 | struct drm_magic_entry *pt; | 106 | struct drm_magic_entry *pt; |
| 107 | struct drm_hash_item *hash; | 107 | struct drm_hash_item *hash; |
| @@ -136,6 +136,8 @@ static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) | |||
| 136 | * If there is a magic number in drm_file::magic then use it, otherwise | 136 | * If there is a magic number in drm_file::magic then use it, otherwise |
| 137 | * searches an unique non-zero magic number and add it associating it with \p | 137 | * searches an unique non-zero magic number and add it associating it with \p |
| 138 | * file_priv. | 138 | * file_priv. |
| 139 | * This ioctl needs protection by the drm_global_mutex, which protects | ||
| 140 | * struct drm_file::magic and struct drm_magic_entry::priv. | ||
| 139 | */ | 141 | */ |
| 140 | int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) | 142 | int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) |
| 141 | { | 143 | { |
| @@ -173,6 +175,8 @@ int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
| 173 | * \return zero if authentication successed, or a negative number otherwise. | 175 | * \return zero if authentication successed, or a negative number otherwise. |
| 174 | * | 176 | * |
| 175 | * Checks if \p file_priv is associated with the magic number passed in \arg. | 177 | * Checks if \p file_priv is associated with the magic number passed in \arg. |
| 178 | * This ioctl needs protection by the drm_global_mutex, which protects | ||
| 179 | * struct drm_file::magic and struct drm_magic_entry::priv. | ||
| 176 | */ | 180 | */ |
| 177 | int drm_authmagic(struct drm_device *dev, void *data, | 181 | int drm_authmagic(struct drm_device *dev, void *data, |
| 178 | struct drm_file *file_priv) | 182 | struct drm_file *file_priv) |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index c00cf154cc0b..6263b0147598 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
| @@ -487,6 +487,11 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 487 | (long)old_encode_dev(file_priv->minor->device), | 487 | (long)old_encode_dev(file_priv->minor->device), |
| 488 | dev->open_count); | 488 | dev->open_count); |
| 489 | 489 | ||
| 490 | /* Release any auth tokens that might point to this file_priv, | ||
| 491 | (do that under the drm_global_mutex) */ | ||
| 492 | if (file_priv->magic) | ||
| 493 | (void) drm_remove_magic(file_priv->master, file_priv->magic); | ||
| 494 | |||
| 490 | /* if the master has gone away we can't do anything with the lock */ | 495 | /* if the master has gone away we can't do anything with the lock */ |
| 491 | if (file_priv->minor->master) | 496 | if (file_priv->minor->master) |
| 492 | drm_master_release(dev, filp); | 497 | drm_master_release(dev, filp); |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 396e60ce8114..f8625e290728 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
| @@ -140,7 +140,7 @@ int drm_gem_object_init(struct drm_device *dev, | |||
| 140 | obj->dev = dev; | 140 | obj->dev = dev; |
| 141 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); | 141 | obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); |
| 142 | if (IS_ERR(obj->filp)) | 142 | if (IS_ERR(obj->filp)) |
| 143 | return -ENOMEM; | 143 | return PTR_ERR(obj->filp); |
| 144 | 144 | ||
| 145 | kref_init(&obj->refcount); | 145 | kref_init(&obj->refcount); |
| 146 | atomic_set(&obj->handle_count, 0); | 146 | atomic_set(&obj->handle_count, 0); |
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index ddd70db45f76..637fcc3766c7 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c | |||
| @@ -315,7 +315,8 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, | |||
| 315 | if (err) | 315 | if (err) |
| 316 | return err; | 316 | return err; |
| 317 | 317 | ||
| 318 | if (__get_user(c32.auth, &client->auth) | 318 | if (__get_user(c32.idx, &client->idx) |
| 319 | || __get_user(c32.auth, &client->auth) | ||
| 319 | || __get_user(c32.pid, &client->pid) | 320 | || __get_user(c32.pid, &client->pid) |
| 320 | || __get_user(c32.uid, &client->uid) | 321 | || __get_user(c32.uid, &client->uid) |
| 321 | || __get_user(c32.magic, &client->magic) | 322 | || __get_user(c32.magic, &client->magic) |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index f9aaa56eae07..b9e5266c341b 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
| @@ -13,7 +13,7 @@ config DRM_EXYNOS | |||
| 13 | 13 | ||
| 14 | config DRM_EXYNOS_FIMD | 14 | config DRM_EXYNOS_FIMD |
| 15 | tristate "Exynos DRM FIMD" | 15 | tristate "Exynos DRM FIMD" |
| 16 | depends on DRM_EXYNOS | 16 | depends on DRM_EXYNOS && !FB_S3C |
| 17 | default n | 17 | default n |
| 18 | help | 18 | help |
| 19 | Choose this option if you want to use Exynos FIMD for DRM. | 19 | Choose this option if you want to use Exynos FIMD for DRM. |
| @@ -21,7 +21,7 @@ config DRM_EXYNOS_FIMD | |||
| 21 | 21 | ||
| 22 | config DRM_EXYNOS_HDMI | 22 | config DRM_EXYNOS_HDMI |
| 23 | tristate "Exynos DRM HDMI" | 23 | tristate "Exynos DRM HDMI" |
| 24 | depends on DRM_EXYNOS | 24 | depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV |
| 25 | help | 25 | help |
| 26 | Choose this option if you want to use Exynos HDMI for DRM. | 26 | Choose this option if you want to use Exynos HDMI for DRM. |
| 27 | If M is selected, the module will be called exynos_drm_hdmi | 27 | If M is selected, the module will be called exynos_drm_hdmi |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index ca83139cd309..b6a737d196ae 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
| @@ -158,7 +158,8 @@ static void fimd_dpms(struct device *subdrv_dev, int mode) | |||
| 158 | case DRM_MODE_DPMS_STANDBY: | 158 | case DRM_MODE_DPMS_STANDBY: |
| 159 | case DRM_MODE_DPMS_SUSPEND: | 159 | case DRM_MODE_DPMS_SUSPEND: |
| 160 | case DRM_MODE_DPMS_OFF: | 160 | case DRM_MODE_DPMS_OFF: |
| 161 | pm_runtime_put_sync(subdrv_dev); | 161 | if (!ctx->suspended) |
| 162 | pm_runtime_put_sync(subdrv_dev); | ||
| 162 | break; | 163 | break; |
| 163 | default: | 164 | default: |
| 164 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); | 165 | DRM_DEBUG_KMS("unspecified mode %d\n", mode); |
| @@ -734,6 +735,46 @@ static void fimd_clear_win(struct fimd_context *ctx, int win) | |||
| 734 | writel(val, ctx->regs + SHADOWCON); | 735 | writel(val, ctx->regs + SHADOWCON); |
| 735 | } | 736 | } |
| 736 | 737 | ||
| 738 | static int fimd_power_on(struct fimd_context *ctx, bool enable) | ||
| 739 | { | ||
| 740 | struct exynos_drm_subdrv *subdrv = &ctx->subdrv; | ||
| 741 | struct device *dev = subdrv->manager.dev; | ||
| 742 | |||
| 743 | DRM_DEBUG_KMS("%s\n", __FILE__); | ||
| 744 | |||
| 745 | if (enable != false && enable != true) | ||
| 746 | return -EINVAL; | ||
| 747 | |||
| 748 | if (enable) { | ||
| 749 | int ret; | ||
| 750 | |||
| 751 | ret = clk_enable(ctx->bus_clk); | ||
| 752 | if (ret < 0) | ||
| 753 | return ret; | ||
| 754 | |||
| 755 | ret = clk_enable(ctx->lcd_clk); | ||
| 756 | if (ret < 0) { | ||
| 757 | clk_disable(ctx->bus_clk); | ||
| 758 | return ret; | ||
| 759 | } | ||
| 760 | |||
| 761 | ctx->suspended = false; | ||
| 762 | |||
| 763 | /* if vblank was enabled status, enable it again. */ | ||
| 764 | if (test_and_clear_bit(0, &ctx->irq_flags)) | ||
| 765 | fimd_enable_vblank(dev); | ||
| 766 | |||
| 767 | fimd_apply(dev); | ||
| 768 | } else { | ||
| 769 | clk_disable(ctx->lcd_clk); | ||
| 770 | clk_disable(ctx->bus_clk); | ||
| 771 | |||
| 772 | ctx->suspended = true; | ||
| 773 | } | ||
| 774 | |||
| 775 | return 0; | ||
| 776 | } | ||
| 777 | |||
| 737 | static int __devinit fimd_probe(struct platform_device *pdev) | 778 | static int __devinit fimd_probe(struct platform_device *pdev) |
| 738 | { | 779 | { |
| 739 | struct device *dev = &pdev->dev; | 780 | struct device *dev = &pdev->dev; |
| @@ -911,39 +952,30 @@ out: | |||
| 911 | #ifdef CONFIG_PM_SLEEP | 952 | #ifdef CONFIG_PM_SLEEP |
| 912 | static int fimd_suspend(struct device *dev) | 953 | static int fimd_suspend(struct device *dev) |
| 913 | { | 954 | { |
| 914 | int ret; | 955 | struct fimd_context *ctx = get_fimd_context(dev); |
| 915 | 956 | ||
| 916 | if (pm_runtime_suspended(dev)) | 957 | if (pm_runtime_suspended(dev)) |
| 917 | return 0; | 958 | return 0; |
| 918 | 959 | ||
| 919 | ret = pm_runtime_suspend(dev); | 960 | /* |
| 920 | if (ret < 0) | 961 | * do not use pm_runtime_suspend(). if pm_runtime_suspend() is |
| 921 | return ret; | 962 | * called here, an error would be returned by that interface |
| 922 | 963 | * because the usage_count of pm runtime is more than 1. | |
| 923 | return 0; | 964 | */ |
| 965 | return fimd_power_on(ctx, false); | ||
| 924 | } | 966 | } |
| 925 | 967 | ||
| 926 | static int fimd_resume(struct device *dev) | 968 | static int fimd_resume(struct device *dev) |
| 927 | { | 969 | { |
| 928 | int ret; | 970 | struct fimd_context *ctx = get_fimd_context(dev); |
| 929 | |||
| 930 | ret = pm_runtime_resume(dev); | ||
| 931 | if (ret < 0) { | ||
| 932 | DRM_ERROR("failed to resume runtime pm.\n"); | ||
| 933 | return ret; | ||
| 934 | } | ||
| 935 | |||
| 936 | pm_runtime_disable(dev); | ||
| 937 | |||
| 938 | ret = pm_runtime_set_active(dev); | ||
| 939 | if (ret < 0) { | ||
| 940 | DRM_ERROR("failed to active runtime pm.\n"); | ||
| 941 | pm_runtime_enable(dev); | ||
| 942 | pm_runtime_suspend(dev); | ||
| 943 | return ret; | ||
| 944 | } | ||
| 945 | 971 | ||
| 946 | pm_runtime_enable(dev); | 972 | /* |
| 973 | * if entered to sleep when lcd panel was on, the usage_count | ||
| 974 | * of pm runtime would still be 1 so in this case, fimd driver | ||
| 975 | * should be on directly not drawing on pm runtime interface. | ||
| 976 | */ | ||
| 977 | if (!pm_runtime_suspended(dev)) | ||
| 978 | return fimd_power_on(ctx, true); | ||
| 947 | 979 | ||
| 948 | return 0; | 980 | return 0; |
| 949 | } | 981 | } |
| @@ -956,39 +988,16 @@ static int fimd_runtime_suspend(struct device *dev) | |||
| 956 | 988 | ||
| 957 | DRM_DEBUG_KMS("%s\n", __FILE__); | 989 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 958 | 990 | ||
| 959 | clk_disable(ctx->lcd_clk); | 991 | return fimd_power_on(ctx, false); |
| 960 | clk_disable(ctx->bus_clk); | ||
| 961 | |||
| 962 | ctx->suspended = true; | ||
| 963 | return 0; | ||
| 964 | } | 992 | } |
| 965 | 993 | ||
| 966 | static int fimd_runtime_resume(struct device *dev) | 994 | static int fimd_runtime_resume(struct device *dev) |
| 967 | { | 995 | { |
| 968 | struct fimd_context *ctx = get_fimd_context(dev); | 996 | struct fimd_context *ctx = get_fimd_context(dev); |
| 969 | int ret; | ||
| 970 | 997 | ||
| 971 | DRM_DEBUG_KMS("%s\n", __FILE__); | 998 | DRM_DEBUG_KMS("%s\n", __FILE__); |
| 972 | 999 | ||
| 973 | ret = clk_enable(ctx->bus_clk); | 1000 | return fimd_power_on(ctx, true); |
| 974 | if (ret < 0) | ||
| 975 | return ret; | ||
| 976 | |||
| 977 | ret = clk_enable(ctx->lcd_clk); | ||
| 978 | if (ret < 0) { | ||
| 979 | clk_disable(ctx->bus_clk); | ||
| 980 | return ret; | ||
| 981 | } | ||
| 982 | |||
| 983 | ctx->suspended = false; | ||
| 984 | |||
| 985 | /* if vblank was enabled status, enable it again. */ | ||
| 986 | if (test_and_clear_bit(0, &ctx->irq_flags)) | ||
| 987 | fimd_enable_vblank(dev); | ||
| 988 | |||
| 989 | fimd_apply(dev); | ||
| 990 | |||
| 991 | return 0; | ||
| 992 | } | 1001 | } |
| 993 | #endif | 1002 | #endif |
| 994 | 1003 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index f48f7ce92f5f..3429d3fd93f3 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -1116,8 +1116,8 @@ err_ddc: | |||
| 1116 | err_iomap: | 1116 | err_iomap: |
| 1117 | iounmap(hdata->regs); | 1117 | iounmap(hdata->regs); |
| 1118 | err_req_region: | 1118 | err_req_region: |
| 1119 | release_resource(hdata->regs_res); | 1119 | release_mem_region(hdata->regs_res->start, |
| 1120 | kfree(hdata->regs_res); | 1120 | resource_size(hdata->regs_res)); |
| 1121 | err_resource: | 1121 | err_resource: |
| 1122 | hdmi_resources_cleanup(hdata); | 1122 | hdmi_resources_cleanup(hdata); |
| 1123 | err_data: | 1123 | err_data: |
| @@ -1145,8 +1145,8 @@ static int __devexit hdmi_remove(struct platform_device *pdev) | |||
| 1145 | 1145 | ||
| 1146 | iounmap(hdata->regs); | 1146 | iounmap(hdata->regs); |
| 1147 | 1147 | ||
| 1148 | release_resource(hdata->regs_res); | 1148 | release_mem_region(hdata->regs_res->start, |
| 1149 | kfree(hdata->regs_res); | 1149 | resource_size(hdata->regs_res)); |
| 1150 | 1150 | ||
| 1151 | /* hdmiphy i2c driver */ | 1151 | /* hdmiphy i2c driver */ |
| 1152 | i2c_del_driver(&hdmiphy_driver); | 1152 | i2c_del_driver(&hdmiphy_driver); |
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 791c0ef1a65b..830dfdd6bf15 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c | |||
| @@ -113,12 +113,12 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) | |||
| 113 | 113 | ||
| 114 | void psbfb_suspend(struct drm_device *dev) | 114 | void psbfb_suspend(struct drm_device *dev) |
| 115 | { | 115 | { |
| 116 | struct drm_framebuffer *fb = 0; | 116 | struct drm_framebuffer *fb; |
| 117 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
| 118 | 117 | ||
| 119 | console_lock(); | 118 | console_lock(); |
| 120 | mutex_lock(&dev->mode_config.mutex); | 119 | mutex_lock(&dev->mode_config.mutex); |
| 121 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { | 120 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { |
| 121 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
| 122 | struct fb_info *info = psbfb->fbdev; | 122 | struct fb_info *info = psbfb->fbdev; |
| 123 | fb_set_suspend(info, 1); | 123 | fb_set_suspend(info, 1); |
| 124 | drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); | 124 | drm_fb_helper_blank(FB_BLANK_POWERDOWN, info); |
| @@ -129,12 +129,12 @@ void psbfb_suspend(struct drm_device *dev) | |||
| 129 | 129 | ||
| 130 | void psbfb_resume(struct drm_device *dev) | 130 | void psbfb_resume(struct drm_device *dev) |
| 131 | { | 131 | { |
| 132 | struct drm_framebuffer *fb = 0; | 132 | struct drm_framebuffer *fb; |
| 133 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
| 134 | 133 | ||
| 135 | console_lock(); | 134 | console_lock(); |
| 136 | mutex_lock(&dev->mode_config.mutex); | 135 | mutex_lock(&dev->mode_config.mutex); |
| 137 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { | 136 | list_for_each_entry(fb, &dev->mode_config.fb_list, head) { |
| 137 | struct psb_framebuffer *psbfb = to_psb_fb(fb); | ||
| 138 | struct fb_info *info = psbfb->fbdev; | 138 | struct fb_info *info = psbfb->fbdev; |
| 139 | fb_set_suspend(info, 0); | 139 | fb_set_suspend(info, 0); |
| 140 | drm_fb_helper_blank(FB_BLANK_UNBLANK, info); | 140 | drm_fb_helper_blank(FB_BLANK_UNBLANK, info); |
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index e770bd190a5c..5d5330f667f1 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <drm/drmP.h> | 22 | #include <drm/drmP.h> |
| 23 | #include <linux/shmem_fs.h> | ||
| 23 | #include "psb_drv.h" | 24 | #include "psb_drv.h" |
| 24 | 25 | ||
| 25 | 26 | ||
| @@ -203,9 +204,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) | |||
| 203 | gt->npage = pages; | 204 | gt->npage = pages; |
| 204 | 205 | ||
| 205 | for (i = 0; i < pages; i++) { | 206 | for (i = 0; i < pages; i++) { |
| 206 | /* FIXME: needs updating as per mail from Hugh Dickins */ | 207 | p = shmem_read_mapping_page(mapping, i); |
| 207 | p = read_cache_page_gfp(mapping, i, | ||
| 208 | __GFP_COLD | GFP_KERNEL); | ||
| 209 | if (IS_ERR(p)) | 208 | if (IS_ERR(p)) |
| 210 | goto err; | 209 | goto err; |
| 211 | gt->pages[i] = p; | 210 | gt->pages[i] = p; |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index f7c17b239833..7f4b4e10246e 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
| @@ -886,7 +886,7 @@ static int i810_flush_queue(struct drm_device *dev) | |||
| 886 | } | 886 | } |
| 887 | 887 | ||
| 888 | /* Must be called with the lock held */ | 888 | /* Must be called with the lock held */ |
| 889 | void i810_driver_reclaim_buffers(struct drm_device *dev, | 889 | static void i810_reclaim_buffers(struct drm_device *dev, |
| 890 | struct drm_file *file_priv) | 890 | struct drm_file *file_priv) |
| 891 | { | 891 | { |
| 892 | struct drm_device_dma *dma = dev->dma; | 892 | struct drm_device_dma *dma = dev->dma; |
| @@ -1223,17 +1223,12 @@ void i810_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) | |||
| 1223 | if (dev_priv->page_flipping) | 1223 | if (dev_priv->page_flipping) |
| 1224 | i810_do_cleanup_pageflip(dev); | 1224 | i810_do_cleanup_pageflip(dev); |
| 1225 | } | 1225 | } |
| 1226 | } | ||
| 1226 | 1227 | ||
| 1227 | if (file_priv->master && file_priv->master->lock.hw_lock) { | 1228 | void i810_driver_reclaim_buffers_locked(struct drm_device *dev, |
| 1228 | drm_idlelock_take(&file_priv->master->lock); | 1229 | struct drm_file *file_priv) |
| 1229 | i810_driver_reclaim_buffers(dev, file_priv); | 1230 | { |
| 1230 | drm_idlelock_release(&file_priv->master->lock); | 1231 | i810_reclaim_buffers(dev, file_priv); |
| 1231 | } else { | ||
| 1232 | /* master disappeared, clean up stuff anyway and hope nothing | ||
| 1233 | * goes wrong */ | ||
| 1234 | i810_driver_reclaim_buffers(dev, file_priv); | ||
| 1235 | } | ||
| 1236 | |||
| 1237 | } | 1232 | } |
| 1238 | 1233 | ||
| 1239 | int i810_driver_dma_quiescent(struct drm_device *dev) | 1234 | int i810_driver_dma_quiescent(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index 053f1ee58393..ec12f7dc717a 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
| @@ -63,6 +63,7 @@ static struct drm_driver driver = { | |||
| 63 | .lastclose = i810_driver_lastclose, | 63 | .lastclose = i810_driver_lastclose, |
| 64 | .preclose = i810_driver_preclose, | 64 | .preclose = i810_driver_preclose, |
| 65 | .device_is_agp = i810_driver_device_is_agp, | 65 | .device_is_agp = i810_driver_device_is_agp, |
| 66 | .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked, | ||
| 66 | .dma_quiescent = i810_driver_dma_quiescent, | 67 | .dma_quiescent = i810_driver_dma_quiescent, |
| 67 | .ioctls = i810_ioctls, | 68 | .ioctls = i810_ioctls, |
| 68 | .fops = &i810_driver_fops, | 69 | .fops = &i810_driver_fops, |
diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h index 6e0acad9e0f5..c9339f481795 100644 --- a/drivers/gpu/drm/i810/i810_drv.h +++ b/drivers/gpu/drm/i810/i810_drv.h | |||
| @@ -116,12 +116,14 @@ typedef struct drm_i810_private { | |||
| 116 | 116 | ||
| 117 | /* i810_dma.c */ | 117 | /* i810_dma.c */ |
| 118 | extern int i810_driver_dma_quiescent(struct drm_device *dev); | 118 | extern int i810_driver_dma_quiescent(struct drm_device *dev); |
| 119 | void i810_driver_reclaim_buffers(struct drm_device *dev, | 119 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, |
| 120 | struct drm_file *file_priv); | 120 | struct drm_file *file_priv); |
| 121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); | 121 | extern int i810_driver_load(struct drm_device *, unsigned long flags); |
| 122 | extern void i810_driver_lastclose(struct drm_device *dev); | 122 | extern void i810_driver_lastclose(struct drm_device *dev); |
| 123 | extern void i810_driver_preclose(struct drm_device *dev, | 123 | extern void i810_driver_preclose(struct drm_device *dev, |
| 124 | struct drm_file *file_priv); | 124 | struct drm_file *file_priv); |
| 125 | extern void i810_driver_reclaim_buffers_locked(struct drm_device *dev, | ||
| 126 | struct drm_file *file_priv); | ||
| 125 | extern int i810_driver_device_is_agp(struct drm_device *dev); | 127 | extern int i810_driver_device_is_agp(struct drm_device *dev); |
| 126 | 128 | ||
| 127 | extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 129 | extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 11807989f918..deaa657292b4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
| @@ -121,11 +121,11 @@ static const char *cache_level_str(int type) | |||
| 121 | static void | 121 | static void |
| 122 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | 122 | describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) |
| 123 | { | 123 | { |
| 124 | seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s", | 124 | seq_printf(m, "%p: %s%s %8zdKiB %04x %04x %d %d%s%s%s", |
| 125 | &obj->base, | 125 | &obj->base, |
| 126 | get_pin_flag(obj), | 126 | get_pin_flag(obj), |
| 127 | get_tiling_flag(obj), | 127 | get_tiling_flag(obj), |
| 128 | obj->base.size, | 128 | obj->base.size / 1024, |
| 129 | obj->base.read_domains, | 129 | obj->base.read_domains, |
| 130 | obj->base.write_domain, | 130 | obj->base.write_domain, |
| 131 | obj->last_rendering_seqno, | 131 | obj->last_rendering_seqno, |
| @@ -653,7 +653,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
| 653 | seq_printf(m, " Size : %08x\n", ring->size); | 653 | seq_printf(m, " Size : %08x\n", ring->size); |
| 654 | seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); | 654 | seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); |
| 655 | seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); | 655 | seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); |
| 656 | if (IS_GEN6(dev)) { | 656 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
| 657 | seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); | 657 | seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); |
| 658 | seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); | 658 | seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); |
| 659 | } | 659 | } |
| @@ -1075,6 +1075,7 @@ static int gen6_drpc_info(struct seq_file *m) | |||
| 1075 | struct drm_device *dev = node->minor->dev; | 1075 | struct drm_device *dev = node->minor->dev; |
| 1076 | struct drm_i915_private *dev_priv = dev->dev_private; | 1076 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1077 | u32 rpmodectl1, gt_core_status, rcctl1; | 1077 | u32 rpmodectl1, gt_core_status, rcctl1; |
| 1078 | unsigned forcewake_count; | ||
| 1078 | int count=0, ret; | 1079 | int count=0, ret; |
| 1079 | 1080 | ||
| 1080 | 1081 | ||
| @@ -1082,9 +1083,13 @@ static int gen6_drpc_info(struct seq_file *m) | |||
| 1082 | if (ret) | 1083 | if (ret) |
| 1083 | return ret; | 1084 | return ret; |
| 1084 | 1085 | ||
| 1085 | if (atomic_read(&dev_priv->forcewake_count)) { | 1086 | spin_lock_irq(&dev_priv->gt_lock); |
| 1086 | seq_printf(m, "RC information inaccurate because userspace " | 1087 | forcewake_count = dev_priv->forcewake_count; |
| 1087 | "holds a reference \n"); | 1088 | spin_unlock_irq(&dev_priv->gt_lock); |
| 1089 | |||
| 1090 | if (forcewake_count) { | ||
| 1091 | seq_printf(m, "RC information inaccurate because somebody " | ||
| 1092 | "holds a forcewake reference \n"); | ||
| 1088 | } else { | 1093 | } else { |
| 1089 | /* NB: we cannot use forcewake, else we read the wrong values */ | 1094 | /* NB: we cannot use forcewake, else we read the wrong values */ |
| 1090 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) | 1095 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) |
| @@ -1106,7 +1111,7 @@ static int gen6_drpc_info(struct seq_file *m) | |||
| 1106 | seq_printf(m, "SW control enabled: %s\n", | 1111 | seq_printf(m, "SW control enabled: %s\n", |
| 1107 | yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == | 1112 | yesno((rpmodectl1 & GEN6_RP_MEDIA_MODE_MASK) == |
| 1108 | GEN6_RP_MEDIA_SW_MODE)); | 1113 | GEN6_RP_MEDIA_SW_MODE)); |
| 1109 | seq_printf(m, "RC6 Enabled: %s\n", | 1114 | seq_printf(m, "RC1e Enabled: %s\n", |
| 1110 | yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); | 1115 | yesno(rcctl1 & GEN6_RC_CTL_RC1e_ENABLE)); |
| 1111 | seq_printf(m, "RC6 Enabled: %s\n", | 1116 | seq_printf(m, "RC6 Enabled: %s\n", |
| 1112 | yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); | 1117 | yesno(rcctl1 & GEN6_RC_CTL_RC6_ENABLE)); |
| @@ -1398,9 +1403,13 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) | |||
| 1398 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 1403 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
| 1399 | struct drm_device *dev = node->minor->dev; | 1404 | struct drm_device *dev = node->minor->dev; |
| 1400 | struct drm_i915_private *dev_priv = dev->dev_private; | 1405 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1406 | unsigned forcewake_count; | ||
| 1407 | |||
| 1408 | spin_lock_irq(&dev_priv->gt_lock); | ||
| 1409 | forcewake_count = dev_priv->forcewake_count; | ||
| 1410 | spin_unlock_irq(&dev_priv->gt_lock); | ||
| 1401 | 1411 | ||
| 1402 | seq_printf(m, "forcewake count = %d\n", | 1412 | seq_printf(m, "forcewake count = %u\n", forcewake_count); |
| 1403 | atomic_read(&dev_priv->forcewake_count)); | ||
| 1404 | 1413 | ||
| 1405 | return 0; | 1414 | return 0; |
| 1406 | } | 1415 | } |
| @@ -1665,7 +1674,7 @@ static int i915_forcewake_open(struct inode *inode, struct file *file) | |||
| 1665 | struct drm_i915_private *dev_priv = dev->dev_private; | 1674 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1666 | int ret; | 1675 | int ret; |
| 1667 | 1676 | ||
| 1668 | if (!IS_GEN6(dev)) | 1677 | if (INTEL_INFO(dev)->gen < 6) |
| 1669 | return 0; | 1678 | return 0; |
| 1670 | 1679 | ||
| 1671 | ret = mutex_lock_interruptible(&dev->struct_mutex); | 1680 | ret = mutex_lock_interruptible(&dev->struct_mutex); |
| @@ -1682,7 +1691,7 @@ int i915_forcewake_release(struct inode *inode, struct file *file) | |||
| 1682 | struct drm_device *dev = inode->i_private; | 1691 | struct drm_device *dev = inode->i_private; |
| 1683 | struct drm_i915_private *dev_priv = dev->dev_private; | 1692 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1684 | 1693 | ||
| 1685 | if (!IS_GEN6(dev)) | 1694 | if (INTEL_INFO(dev)->gen < 6) |
| 1686 | return 0; | 1695 | return 0; |
| 1687 | 1696 | ||
| 1688 | /* | 1697 | /* |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 5f4d5893e983..ddfe3d902b2a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -2045,6 +2045,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 2045 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 2045 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
| 2046 | pci_enable_msi(dev->pdev); | 2046 | pci_enable_msi(dev->pdev); |
| 2047 | 2047 | ||
| 2048 | spin_lock_init(&dev_priv->gt_lock); | ||
| 2048 | spin_lock_init(&dev_priv->irq_lock); | 2049 | spin_lock_init(&dev_priv->irq_lock); |
| 2049 | spin_lock_init(&dev_priv->error_lock); | 2050 | spin_lock_init(&dev_priv->error_lock); |
| 2050 | spin_lock_init(&dev_priv->rps_lock); | 2051 | spin_lock_init(&dev_priv->rps_lock); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8f7187915b0d..308f81913562 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -368,11 +368,12 @@ void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
| 368 | */ | 368 | */ |
| 369 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | 369 | void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
| 370 | { | 370 | { |
| 371 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | 371 | unsigned long irqflags; |
| 372 | 372 | ||
| 373 | /* Forcewake is atomic in case we get in here without the lock */ | 373 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); |
| 374 | if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) | 374 | if (dev_priv->forcewake_count++ == 0) |
| 375 | dev_priv->display.force_wake_get(dev_priv); | 375 | dev_priv->display.force_wake_get(dev_priv); |
| 376 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
| 376 | } | 377 | } |
| 377 | 378 | ||
| 378 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 379 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
| @@ -392,10 +393,12 @@ void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | |||
| 392 | */ | 393 | */ |
| 393 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 394 | void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
| 394 | { | 395 | { |
| 395 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | 396 | unsigned long irqflags; |
| 396 | 397 | ||
| 397 | if (atomic_dec_and_test(&dev_priv->forcewake_count)) | 398 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); |
| 399 | if (--dev_priv->forcewake_count == 0) | ||
| 398 | dev_priv->display.force_wake_put(dev_priv); | 400 | dev_priv->display.force_wake_put(dev_priv); |
| 401 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
| 399 | } | 402 | } |
| 400 | 403 | ||
| 401 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) | 404 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
| @@ -597,9 +600,36 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags) | |||
| 597 | static int gen6_do_reset(struct drm_device *dev, u8 flags) | 600 | static int gen6_do_reset(struct drm_device *dev, u8 flags) |
| 598 | { | 601 | { |
| 599 | struct drm_i915_private *dev_priv = dev->dev_private; | 602 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 603 | int ret; | ||
| 604 | unsigned long irqflags; | ||
| 600 | 605 | ||
| 601 | I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); | 606 | /* Hold gt_lock across reset to prevent any register access |
| 602 | return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); | 607 | * with forcewake not set correctly |
| 608 | */ | ||
| 609 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); | ||
| 610 | |||
| 611 | /* Reset the chip */ | ||
| 612 | |||
| 613 | /* GEN6_GDRST is not in the gt power well, no need to check | ||
| 614 | * for fifo space for the write or forcewake the chip for | ||
| 615 | * the read | ||
| 616 | */ | ||
| 617 | I915_WRITE_NOTRACE(GEN6_GDRST, GEN6_GRDOM_FULL); | ||
| 618 | |||
| 619 | /* Spin waiting for the device to ack the reset request */ | ||
| 620 | ret = wait_for((I915_READ_NOTRACE(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); | ||
| 621 | |||
| 622 | /* If reset with a user forcewake, try to restore, otherwise turn it off */ | ||
| 623 | if (dev_priv->forcewake_count) | ||
| 624 | dev_priv->display.force_wake_get(dev_priv); | ||
| 625 | else | ||
| 626 | dev_priv->display.force_wake_put(dev_priv); | ||
| 627 | |||
| 628 | /* Restore fifo count */ | ||
| 629 | dev_priv->gt_fifo_count = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); | ||
| 630 | |||
| 631 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); | ||
| 632 | return ret; | ||
| 603 | } | 633 | } |
| 604 | 634 | ||
| 605 | /** | 635 | /** |
| @@ -643,9 +673,6 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
| 643 | case 7: | 673 | case 7: |
| 644 | case 6: | 674 | case 6: |
| 645 | ret = gen6_do_reset(dev, flags); | 675 | ret = gen6_do_reset(dev, flags); |
| 646 | /* If reset with a user forcewake, try to restore */ | ||
| 647 | if (atomic_read(&dev_priv->forcewake_count)) | ||
| 648 | __gen6_gt_force_wake_get(dev_priv); | ||
| 649 | break; | 676 | break; |
| 650 | case 5: | 677 | case 5: |
| 651 | ret = ironlake_do_reset(dev, flags); | 678 | ret = ironlake_do_reset(dev, flags); |
| @@ -927,9 +954,14 @@ MODULE_LICENSE("GPL and additional rights"); | |||
| 927 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 954 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
| 928 | u##x val = 0; \ | 955 | u##x val = 0; \ |
| 929 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 956 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
| 930 | gen6_gt_force_wake_get(dev_priv); \ | 957 | unsigned long irqflags; \ |
| 958 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ | ||
| 959 | if (dev_priv->forcewake_count == 0) \ | ||
| 960 | dev_priv->display.force_wake_get(dev_priv); \ | ||
| 931 | val = read##y(dev_priv->regs + reg); \ | 961 | val = read##y(dev_priv->regs + reg); \ |
| 932 | gen6_gt_force_wake_put(dev_priv); \ | 962 | if (dev_priv->forcewake_count == 0) \ |
| 963 | dev_priv->display.force_wake_put(dev_priv); \ | ||
| 964 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ | ||
| 933 | } else { \ | 965 | } else { \ |
| 934 | val = read##y(dev_priv->regs + reg); \ | 966 | val = read##y(dev_priv->regs + reg); \ |
| 935 | } \ | 967 | } \ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 602bc80baabb..9689ca38b2b3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -288,7 +288,13 @@ typedef struct drm_i915_private { | |||
| 288 | int relative_constants_mode; | 288 | int relative_constants_mode; |
| 289 | 289 | ||
| 290 | void __iomem *regs; | 290 | void __iomem *regs; |
| 291 | u32 gt_fifo_count; | 291 | /** gt_fifo_count and the subsequent register write are synchronized |
| 292 | * with dev->struct_mutex. */ | ||
| 293 | unsigned gt_fifo_count; | ||
| 294 | /** forcewake_count is protected by gt_lock */ | ||
| 295 | unsigned forcewake_count; | ||
| 296 | /** gt_lock is also taken in irq contexts. */ | ||
| 297 | struct spinlock gt_lock; | ||
| 292 | 298 | ||
| 293 | struct intel_gmbus { | 299 | struct intel_gmbus { |
| 294 | struct i2c_adapter adapter; | 300 | struct i2c_adapter adapter; |
| @@ -741,8 +747,6 @@ typedef struct drm_i915_private { | |||
| 741 | 747 | ||
| 742 | struct drm_property *broadcast_rgb_property; | 748 | struct drm_property *broadcast_rgb_property; |
| 743 | struct drm_property *force_audio_property; | 749 | struct drm_property *force_audio_property; |
| 744 | |||
| 745 | atomic_t forcewake_count; | ||
| 746 | } drm_i915_private_t; | 750 | } drm_i915_private_t; |
| 747 | 751 | ||
| 748 | enum i915_cache_level { | 752 | enum i915_cache_level { |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d433fc11ace..5bd4361ea84d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -1751,7 +1751,8 @@ static void ironlake_irq_preinstall(struct drm_device *dev) | |||
| 1751 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); | 1751 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); |
| 1752 | 1752 | ||
| 1753 | I915_WRITE(HWSTAM, 0xeffe); | 1753 | I915_WRITE(HWSTAM, 0xeffe); |
| 1754 | if (IS_GEN6(dev) || IS_GEN7(dev)) { | 1754 | |
| 1755 | if (IS_GEN6(dev)) { | ||
| 1755 | /* Workaround stalls observed on Sandy Bridge GPUs by | 1756 | /* Workaround stalls observed on Sandy Bridge GPUs by |
| 1756 | * making the blitter command streamer generate a | 1757 | * making the blitter command streamer generate a |
| 1757 | * write to the Hardware Status Page for | 1758 | * write to the Hardware Status Page for |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 7886e4fb60e3..2b5eb229ff2c 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
| @@ -28,14 +28,19 @@ | |||
| 28 | #include "drm.h" | 28 | #include "drm.h" |
| 29 | #include "i915_drm.h" | 29 | #include "i915_drm.h" |
| 30 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
| 31 | #include "i915_reg.h" | ||
| 31 | 32 | ||
| 32 | static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | 33 | static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) |
| 33 | { | 34 | { |
| 34 | struct drm_i915_private *dev_priv = dev->dev_private; | 35 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 35 | u32 dpll_reg; | 36 | u32 dpll_reg; |
| 36 | 37 | ||
| 38 | /* On IVB, 3rd pipe shares PLL with another one */ | ||
| 39 | if (pipe > 1) | ||
| 40 | return false; | ||
| 41 | |||
| 37 | if (HAS_PCH_SPLIT(dev)) | 42 | if (HAS_PCH_SPLIT(dev)) |
| 38 | dpll_reg = (pipe == PIPE_A) ? _PCH_DPLL_A : _PCH_DPLL_B; | 43 | dpll_reg = PCH_DPLL(pipe); |
| 39 | else | 44 | else |
| 40 | dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; | 45 | dpll_reg = (pipe == PIPE_A) ? _DPLL_A : _DPLL_B; |
| 41 | 46 | ||
| @@ -822,7 +827,7 @@ int i915_save_state(struct drm_device *dev) | |||
| 822 | 827 | ||
| 823 | if (IS_IRONLAKE_M(dev)) | 828 | if (IS_IRONLAKE_M(dev)) |
| 824 | ironlake_disable_drps(dev); | 829 | ironlake_disable_drps(dev); |
| 825 | if (IS_GEN6(dev)) | 830 | if (INTEL_INFO(dev)->gen >= 6) |
| 826 | gen6_disable_rps(dev); | 831 | gen6_disable_rps(dev); |
| 827 | 832 | ||
| 828 | /* Cache mode state */ | 833 | /* Cache mode state */ |
| @@ -881,7 +886,7 @@ int i915_restore_state(struct drm_device *dev) | |||
| 881 | intel_init_emon(dev); | 886 | intel_init_emon(dev); |
| 882 | } | 887 | } |
| 883 | 888 | ||
| 884 | if (IS_GEN6(dev)) { | 889 | if (INTEL_INFO(dev)->gen >= 6) { |
| 885 | gen6_enable_rps(dev_priv); | 890 | gen6_enable_rps(dev_priv); |
| 886 | gen6_update_ring_freq(dev_priv); | 891 | gen6_update_ring_freq(dev_priv); |
| 887 | } | 892 | } |
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 8af3735e27c6..dbda6e3bdf07 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h | |||
| @@ -467,8 +467,12 @@ struct edp_link_params { | |||
| 467 | struct bdb_edp { | 467 | struct bdb_edp { |
| 468 | struct edp_power_seq power_seqs[16]; | 468 | struct edp_power_seq power_seqs[16]; |
| 469 | u32 color_depth; | 469 | u32 color_depth; |
| 470 | u32 sdrrs_msa_timing_delay; | ||
| 471 | struct edp_link_params link_params[16]; | 470 | struct edp_link_params link_params[16]; |
| 471 | u32 sdrrs_msa_timing_delay; | ||
| 472 | |||
| 473 | /* ith bit indicates enabled/disabled for (i+1)th panel */ | ||
| 474 | u16 edp_s3d_feature; | ||
| 475 | u16 edp_t3_optimization; | ||
| 472 | } __attribute__ ((packed)); | 476 | } __attribute__ ((packed)); |
| 473 | 477 | ||
| 474 | void intel_setup_bios(struct drm_device *dev); | 478 | void intel_setup_bios(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index fee0ad02c6d0..dd729d46a61f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | * Eric Anholt <eric@anholt.net> | 24 | * Eric Anholt <eric@anholt.net> |
| 25 | */ | 25 | */ |
| 26 | 26 | ||
| 27 | #include <linux/dmi.h> | ||
| 27 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
| 28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 29 | #include "drmP.h" | 30 | #include "drmP.h" |
| @@ -540,6 +541,24 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { | |||
| 540 | .destroy = intel_encoder_destroy, | 541 | .destroy = intel_encoder_destroy, |
| 541 | }; | 542 | }; |
| 542 | 543 | ||
| 544 | static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) | ||
| 545 | { | ||
| 546 | DRM_DEBUG_KMS("Skipping CRT initialization for %s\n", id->ident); | ||
| 547 | return 1; | ||
| 548 | } | ||
| 549 | |||
| 550 | static const struct dmi_system_id intel_no_crt[] = { | ||
| 551 | { | ||
| 552 | .callback = intel_no_crt_dmi_callback, | ||
| 553 | .ident = "ACER ZGB", | ||
| 554 | .matches = { | ||
| 555 | DMI_MATCH(DMI_SYS_VENDOR, "ACER"), | ||
| 556 | DMI_MATCH(DMI_PRODUCT_NAME, "ZGB"), | ||
| 557 | }, | ||
| 558 | }, | ||
| 559 | { } | ||
| 560 | }; | ||
| 561 | |||
| 543 | void intel_crt_init(struct drm_device *dev) | 562 | void intel_crt_init(struct drm_device *dev) |
| 544 | { | 563 | { |
| 545 | struct drm_connector *connector; | 564 | struct drm_connector *connector; |
| @@ -547,6 +566,10 @@ void intel_crt_init(struct drm_device *dev) | |||
| 547 | struct intel_connector *intel_connector; | 566 | struct intel_connector *intel_connector; |
| 548 | struct drm_i915_private *dev_priv = dev->dev_private; | 567 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 549 | 568 | ||
| 569 | /* Skip machines without VGA that falsely report hotplug events */ | ||
| 570 | if (dmi_check_system(intel_no_crt)) | ||
| 571 | return; | ||
| 572 | |||
| 550 | crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); | 573 | crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); |
| 551 | if (!crt) | 574 | if (!crt) |
| 552 | return; | 575 | return; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2a3f707caab8..00fbff5ddd81 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -1872,7 +1872,7 @@ static void intel_update_fbc(struct drm_device *dev) | |||
| 1872 | if (enable_fbc < 0) { | 1872 | if (enable_fbc < 0) { |
| 1873 | DRM_DEBUG_KMS("fbc set to per-chip default\n"); | 1873 | DRM_DEBUG_KMS("fbc set to per-chip default\n"); |
| 1874 | enable_fbc = 1; | 1874 | enable_fbc = 1; |
| 1875 | if (INTEL_INFO(dev)->gen <= 5) | 1875 | if (INTEL_INFO(dev)->gen <= 6) |
| 1876 | enable_fbc = 0; | 1876 | enable_fbc = 0; |
| 1877 | } | 1877 | } |
| 1878 | if (!enable_fbc) { | 1878 | if (!enable_fbc) { |
| @@ -5307,6 +5307,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
| 5307 | } | 5307 | } |
| 5308 | } | 5308 | } |
| 5309 | 5309 | ||
| 5310 | pipeconf &= ~PIPECONF_INTERLACE_MASK; | ||
| 5310 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { | 5311 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
| 5311 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; | 5312 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; |
| 5312 | /* the chip adds 2 halflines automatically */ | 5313 | /* the chip adds 2 halflines automatically */ |
| @@ -5317,7 +5318,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
| 5317 | adjusted_mode->crtc_vsync_end -= 1; | 5318 | adjusted_mode->crtc_vsync_end -= 1; |
| 5318 | adjusted_mode->crtc_vsync_start -= 1; | 5319 | adjusted_mode->crtc_vsync_start -= 1; |
| 5319 | } else | 5320 | } else |
| 5320 | pipeconf &= ~PIPECONF_INTERLACE_MASK; /* progressive */ | 5321 | pipeconf |= PIPECONF_PROGRESSIVE; |
| 5321 | 5322 | ||
| 5322 | I915_WRITE(HTOTAL(pipe), | 5323 | I915_WRITE(HTOTAL(pipe), |
| 5323 | (adjusted_mode->crtc_hdisplay - 1) | | 5324 | (adjusted_mode->crtc_hdisplay - 1) | |
| @@ -5808,12 +5809,15 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 5808 | if (is_lvds) { | 5809 | if (is_lvds) { |
| 5809 | temp = I915_READ(PCH_LVDS); | 5810 | temp = I915_READ(PCH_LVDS); |
| 5810 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; | 5811 | temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP; |
| 5811 | if (HAS_PCH_CPT(dev)) | 5812 | if (HAS_PCH_CPT(dev)) { |
| 5813 | temp &= ~PORT_TRANS_SEL_MASK; | ||
| 5812 | temp |= PORT_TRANS_SEL_CPT(pipe); | 5814 | temp |= PORT_TRANS_SEL_CPT(pipe); |
| 5813 | else if (pipe == 1) | 5815 | } else { |
| 5814 | temp |= LVDS_PIPEB_SELECT; | 5816 | if (pipe == 1) |
| 5815 | else | 5817 | temp |= LVDS_PIPEB_SELECT; |
| 5816 | temp &= ~LVDS_PIPEB_SELECT; | 5818 | else |
| 5819 | temp &= ~LVDS_PIPEB_SELECT; | ||
| 5820 | } | ||
| 5817 | 5821 | ||
| 5818 | /* set the corresponsding LVDS_BORDER bit */ | 5822 | /* set the corresponsding LVDS_BORDER bit */ |
| 5819 | temp |= dev_priv->lvds_border_bits; | 5823 | temp |= dev_priv->lvds_border_bits; |
| @@ -5899,6 +5903,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 5899 | } | 5903 | } |
| 5900 | } | 5904 | } |
| 5901 | 5905 | ||
| 5906 | pipeconf &= ~PIPECONF_INTERLACE_MASK; | ||
| 5902 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { | 5907 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) { |
| 5903 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; | 5908 | pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION; |
| 5904 | /* the chip adds 2 halflines automatically */ | 5909 | /* the chip adds 2 halflines automatically */ |
| @@ -5909,7 +5914,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 5909 | adjusted_mode->crtc_vsync_end -= 1; | 5914 | adjusted_mode->crtc_vsync_end -= 1; |
| 5910 | adjusted_mode->crtc_vsync_start -= 1; | 5915 | adjusted_mode->crtc_vsync_start -= 1; |
| 5911 | } else | 5916 | } else |
| 5912 | pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */ | 5917 | pipeconf |= PIPECONF_PROGRESSIVE; |
| 5913 | 5918 | ||
| 5914 | I915_WRITE(HTOTAL(pipe), | 5919 | I915_WRITE(HTOTAL(pipe), |
| 5915 | (adjusted_mode->crtc_hdisplay - 1) | | 5920 | (adjusted_mode->crtc_hdisplay - 1) | |
| @@ -9025,12 +9030,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 9025 | 9030 | ||
| 9026 | for (i = 0; i < dev_priv->num_pipe; i++) { | 9031 | for (i = 0; i < dev_priv->num_pipe; i++) { |
| 9027 | intel_crtc_init(dev, i); | 9032 | intel_crtc_init(dev, i); |
| 9028 | if (HAS_PCH_SPLIT(dev)) { | 9033 | ret = intel_plane_init(dev, i); |
| 9029 | ret = intel_plane_init(dev, i); | 9034 | if (ret) |
| 9030 | if (ret) | 9035 | DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); |
| 9031 | DRM_ERROR("plane %d init failed: %d\n", | ||
| 9032 | i, ret); | ||
| 9033 | } | ||
| 9034 | } | 9036 | } |
| 9035 | 9037 | ||
| 9036 | /* Just disable it once at startup */ | 9038 | /* Just disable it once at startup */ |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index db3b461ad412..94f860cce3f7 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -208,17 +208,8 @@ intel_dp_link_clock(uint8_t link_bw) | |||
| 208 | */ | 208 | */ |
| 209 | 209 | ||
| 210 | static int | 210 | static int |
| 211 | intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp) | 211 | intel_dp_link_required(int pixel_clock, int bpp) |
| 212 | { | 212 | { |
| 213 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | ||
| 214 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 215 | int bpp = 24; | ||
| 216 | |||
| 217 | if (check_bpp) | ||
| 218 | bpp = check_bpp; | ||
| 219 | else if (intel_crtc) | ||
| 220 | bpp = intel_crtc->bpp; | ||
| 221 | |||
| 222 | return (pixel_clock * bpp + 9) / 10; | 213 | return (pixel_clock * bpp + 9) / 10; |
| 223 | } | 214 | } |
| 224 | 215 | ||
| @@ -245,12 +236,11 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
| 245 | return MODE_PANEL; | 236 | return MODE_PANEL; |
| 246 | } | 237 | } |
| 247 | 238 | ||
| 248 | mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0); | 239 | mode_rate = intel_dp_link_required(mode->clock, 24); |
| 249 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); | 240 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); |
| 250 | 241 | ||
| 251 | if (mode_rate > max_rate) { | 242 | if (mode_rate > max_rate) { |
| 252 | mode_rate = intel_dp_link_required(intel_dp, | 243 | mode_rate = intel_dp_link_required(mode->clock, 18); |
| 253 | mode->clock, 18); | ||
| 254 | if (mode_rate > max_rate) | 244 | if (mode_rate > max_rate) |
| 255 | return MODE_CLOCK_HIGH; | 245 | return MODE_CLOCK_HIGH; |
| 256 | else | 246 | else |
| @@ -683,7 +673,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 683 | int lane_count, clock; | 673 | int lane_count, clock; |
| 684 | int max_lane_count = intel_dp_max_lane_count(intel_dp); | 674 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
| 685 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; | 675 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
| 686 | int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0; | 676 | int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; |
| 687 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 677 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
| 688 | 678 | ||
| 689 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 679 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
| @@ -701,7 +691,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
| 701 | for (clock = 0; clock <= max_clock; clock++) { | 691 | for (clock = 0; clock <= max_clock; clock++) { |
| 702 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 692 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
| 703 | 693 | ||
| 704 | if (intel_dp_link_required(intel_dp, mode->clock, bpp) | 694 | if (intel_dp_link_required(mode->clock, bpp) |
| 705 | <= link_avail) { | 695 | <= link_avail) { |
| 706 | intel_dp->link_bw = bws[clock]; | 696 | intel_dp->link_bw = bws[clock]; |
| 707 | intel_dp->lane_count = lane_count; | 697 | intel_dp->lane_count = lane_count; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index e44191132ac4..aa84832b0e1a 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -694,6 +694,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 694 | }, | 694 | }, |
| 695 | { | 695 | { |
| 696 | .callback = intel_no_lvds_dmi_callback, | 696 | .callback = intel_no_lvds_dmi_callback, |
| 697 | .ident = "AOpen i45GMx-I", | ||
| 698 | .matches = { | ||
| 699 | DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), | ||
| 700 | DMI_MATCH(DMI_BOARD_NAME, "i45GMx-I"), | ||
| 701 | }, | ||
| 702 | }, | ||
| 703 | { | ||
| 704 | .callback = intel_no_lvds_dmi_callback, | ||
| 697 | .ident = "Aopen i945GTt-VFA", | 705 | .ident = "Aopen i945GTt-VFA", |
| 698 | .matches = { | 706 | .matches = { |
| 699 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), | 707 | DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"), |
| @@ -708,6 +716,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
| 708 | }, | 716 | }, |
| 709 | }, | 717 | }, |
| 710 | { | 718 | { |
| 719 | .callback = intel_no_lvds_dmi_callback, | ||
| 720 | .ident = "Clientron E830", | ||
| 721 | .matches = { | ||
| 722 | DMI_MATCH(DMI_SYS_VENDOR, "Clientron"), | ||
| 723 | DMI_MATCH(DMI_PRODUCT_NAME, "E830"), | ||
| 724 | }, | ||
| 725 | }, | ||
| 726 | { | ||
| 711 | .callback = intel_no_lvds_dmi_callback, | 727 | .callback = intel_no_lvds_dmi_callback, |
| 712 | .ident = "Asus EeeBox PC EB1007", | 728 | .ident = "Asus EeeBox PC EB1007", |
| 713 | .matches = { | 729 | .matches = { |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 77e729d4e4f0..1ab842c6032e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
| @@ -636,6 +636,19 @@ render_ring_add_request(struct intel_ring_buffer *ring, | |||
| 636 | } | 636 | } |
| 637 | 637 | ||
| 638 | static u32 | 638 | static u32 |
| 639 | gen6_ring_get_seqno(struct intel_ring_buffer *ring) | ||
| 640 | { | ||
| 641 | struct drm_device *dev = ring->dev; | ||
| 642 | |||
| 643 | /* Workaround to force correct ordering between irq and seqno writes on | ||
| 644 | * ivb (and maybe also on snb) by reading from a CS register (like | ||
| 645 | * ACTHD) before reading the status page. */ | ||
| 646 | if (IS_GEN7(dev)) | ||
| 647 | intel_ring_get_active_head(ring); | ||
| 648 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | ||
| 649 | } | ||
| 650 | |||
| 651 | static u32 | ||
| 639 | ring_get_seqno(struct intel_ring_buffer *ring) | 652 | ring_get_seqno(struct intel_ring_buffer *ring) |
| 640 | { | 653 | { |
| 641 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); | 654 | return intel_read_status_page(ring, I915_GEM_HWS_INDEX); |
| @@ -792,17 +805,6 @@ ring_add_request(struct intel_ring_buffer *ring, | |||
| 792 | } | 805 | } |
| 793 | 806 | ||
| 794 | static bool | 807 | static bool |
| 795 | gen7_blt_ring_get_irq(struct intel_ring_buffer *ring) | ||
| 796 | { | ||
| 797 | /* The BLT ring on IVB appears to have broken synchronization | ||
| 798 | * between the seqno write and the interrupt, so that the | ||
| 799 | * interrupt appears first. Returning false here makes | ||
| 800 | * i915_wait_request() do a polling loop, instead. | ||
| 801 | */ | ||
| 802 | return false; | ||
| 803 | } | ||
| 804 | |||
| 805 | static bool | ||
| 806 | gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) | 808 | gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) |
| 807 | { | 809 | { |
| 808 | struct drm_device *dev = ring->dev; | 810 | struct drm_device *dev = ring->dev; |
| @@ -811,6 +813,12 @@ gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) | |||
| 811 | if (!dev->irq_enabled) | 813 | if (!dev->irq_enabled) |
| 812 | return false; | 814 | return false; |
| 813 | 815 | ||
| 816 | /* It looks like we need to prevent the gt from suspending while waiting | ||
| 817 | * for an notifiy irq, otherwise irqs seem to get lost on at least the | ||
| 818 | * blt/bsd rings on ivb. */ | ||
| 819 | if (IS_GEN7(dev)) | ||
| 820 | gen6_gt_force_wake_get(dev_priv); | ||
| 821 | |||
| 814 | spin_lock(&ring->irq_lock); | 822 | spin_lock(&ring->irq_lock); |
| 815 | if (ring->irq_refcount++ == 0) { | 823 | if (ring->irq_refcount++ == 0) { |
| 816 | ring->irq_mask &= ~rflag; | 824 | ring->irq_mask &= ~rflag; |
| @@ -835,6 +843,9 @@ gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag) | |||
| 835 | ironlake_disable_irq(dev_priv, gflag); | 843 | ironlake_disable_irq(dev_priv, gflag); |
| 836 | } | 844 | } |
| 837 | spin_unlock(&ring->irq_lock); | 845 | spin_unlock(&ring->irq_lock); |
| 846 | |||
| 847 | if (IS_GEN7(dev)) | ||
| 848 | gen6_gt_force_wake_put(dev_priv); | ||
| 838 | } | 849 | } |
| 839 | 850 | ||
| 840 | static bool | 851 | static bool |
| @@ -1341,7 +1352,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { | |||
| 1341 | .write_tail = gen6_bsd_ring_write_tail, | 1352 | .write_tail = gen6_bsd_ring_write_tail, |
| 1342 | .flush = gen6_ring_flush, | 1353 | .flush = gen6_ring_flush, |
| 1343 | .add_request = gen6_add_request, | 1354 | .add_request = gen6_add_request, |
| 1344 | .get_seqno = ring_get_seqno, | 1355 | .get_seqno = gen6_ring_get_seqno, |
| 1345 | .irq_get = gen6_bsd_ring_get_irq, | 1356 | .irq_get = gen6_bsd_ring_get_irq, |
| 1346 | .irq_put = gen6_bsd_ring_put_irq, | 1357 | .irq_put = gen6_bsd_ring_put_irq, |
| 1347 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | 1358 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
| @@ -1476,7 +1487,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { | |||
| 1476 | .write_tail = ring_write_tail, | 1487 | .write_tail = ring_write_tail, |
| 1477 | .flush = blt_ring_flush, | 1488 | .flush = blt_ring_flush, |
| 1478 | .add_request = gen6_add_request, | 1489 | .add_request = gen6_add_request, |
| 1479 | .get_seqno = ring_get_seqno, | 1490 | .get_seqno = gen6_ring_get_seqno, |
| 1480 | .irq_get = blt_ring_get_irq, | 1491 | .irq_get = blt_ring_get_irq, |
| 1481 | .irq_put = blt_ring_put_irq, | 1492 | .irq_put = blt_ring_put_irq, |
| 1482 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, | 1493 | .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, |
| @@ -1499,6 +1510,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) | |||
| 1499 | ring->flush = gen6_render_ring_flush; | 1510 | ring->flush = gen6_render_ring_flush; |
| 1500 | ring->irq_get = gen6_render_ring_get_irq; | 1511 | ring->irq_get = gen6_render_ring_get_irq; |
| 1501 | ring->irq_put = gen6_render_ring_put_irq; | 1512 | ring->irq_put = gen6_render_ring_put_irq; |
| 1513 | ring->get_seqno = gen6_ring_get_seqno; | ||
| 1502 | } else if (IS_GEN5(dev)) { | 1514 | } else if (IS_GEN5(dev)) { |
| 1503 | ring->add_request = pc_render_add_request; | 1515 | ring->add_request = pc_render_add_request; |
| 1504 | ring->get_seqno = pc_render_get_seqno; | 1516 | ring->get_seqno = pc_render_get_seqno; |
| @@ -1577,8 +1589,5 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) | |||
| 1577 | 1589 | ||
| 1578 | *ring = gen6_blt_ring; | 1590 | *ring = gen6_blt_ring; |
| 1579 | 1591 | ||
| 1580 | if (IS_GEN7(dev)) | ||
| 1581 | ring->irq_get = gen7_blt_ring_get_irq; | ||
| 1582 | |||
| 1583 | return intel_init_ring_buffer(dev, ring); | 1592 | return intel_init_ring_buffer(dev, ring); |
| 1584 | } | 1593 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index f7b9268df266..e334ec33a47d 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -1066,15 +1066,13 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1066 | 1066 | ||
| 1067 | /* Set the SDVO control regs. */ | 1067 | /* Set the SDVO control regs. */ |
| 1068 | if (INTEL_INFO(dev)->gen >= 4) { | 1068 | if (INTEL_INFO(dev)->gen >= 4) { |
| 1069 | sdvox = 0; | 1069 | /* The real mode polarity is set by the SDVO commands, using |
| 1070 | * struct intel_sdvo_dtd. */ | ||
| 1071 | sdvox = SDVO_VSYNC_ACTIVE_HIGH | SDVO_HSYNC_ACTIVE_HIGH; | ||
| 1070 | if (intel_sdvo->is_hdmi) | 1072 | if (intel_sdvo->is_hdmi) |
| 1071 | sdvox |= intel_sdvo->color_range; | 1073 | sdvox |= intel_sdvo->color_range; |
| 1072 | if (INTEL_INFO(dev)->gen < 5) | 1074 | if (INTEL_INFO(dev)->gen < 5) |
| 1073 | sdvox |= SDVO_BORDER_ENABLE; | 1075 | sdvox |= SDVO_BORDER_ENABLE; |
| 1074 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
| 1075 | sdvox |= SDVO_VSYNC_ACTIVE_HIGH; | ||
| 1076 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
| 1077 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | ||
| 1078 | } else { | 1076 | } else { |
| 1079 | sdvox = I915_READ(intel_sdvo->sdvo_reg); | 1077 | sdvox = I915_READ(intel_sdvo->sdvo_reg); |
| 1080 | switch (intel_sdvo->sdvo_reg) { | 1078 | switch (intel_sdvo->sdvo_reg) { |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index d13989fda501..2288abf88cce 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
| @@ -466,10 +466,8 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | |||
| 466 | mutex_lock(&dev->struct_mutex); | 466 | mutex_lock(&dev->struct_mutex); |
| 467 | 467 | ||
| 468 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); | 468 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
| 469 | if (ret) { | 469 | if (ret) |
| 470 | DRM_ERROR("failed to pin object\n"); | ||
| 471 | goto out_unlock; | 470 | goto out_unlock; |
| 472 | } | ||
| 473 | 471 | ||
| 474 | intel_plane->obj = obj; | 472 | intel_plane->obj = obj; |
| 475 | 473 | ||
| @@ -632,10 +630,8 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) | |||
| 632 | unsigned long possible_crtcs; | 630 | unsigned long possible_crtcs; |
| 633 | int ret; | 631 | int ret; |
| 634 | 632 | ||
| 635 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) { | 633 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) |
| 636 | DRM_ERROR("new plane code only for SNB+\n"); | ||
| 637 | return -ENODEV; | 634 | return -ENODEV; |
| 638 | } | ||
| 639 | 635 | ||
| 640 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); | 636 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
| 641 | if (!intel_plane) | 637 | if (!intel_plane) |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index f3c6a9a8b081..1571be37ce3e 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -417,7 +417,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 417 | { | 417 | { |
| 418 | .name = "NTSC-M", | 418 | .name = "NTSC-M", |
| 419 | .clock = 108000, | 419 | .clock = 108000, |
| 420 | .refresh = 29970, | 420 | .refresh = 59940, |
| 421 | .oversample = TV_OVERSAMPLE_8X, | 421 | .oversample = TV_OVERSAMPLE_8X, |
| 422 | .component_only = 0, | 422 | .component_only = 0, |
| 423 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ | 423 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ |
| @@ -460,7 +460,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 460 | { | 460 | { |
| 461 | .name = "NTSC-443", | 461 | .name = "NTSC-443", |
| 462 | .clock = 108000, | 462 | .clock = 108000, |
| 463 | .refresh = 29970, | 463 | .refresh = 59940, |
| 464 | .oversample = TV_OVERSAMPLE_8X, | 464 | .oversample = TV_OVERSAMPLE_8X, |
| 465 | .component_only = 0, | 465 | .component_only = 0, |
| 466 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ | 466 | /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ |
| @@ -502,7 +502,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 502 | { | 502 | { |
| 503 | .name = "NTSC-J", | 503 | .name = "NTSC-J", |
| 504 | .clock = 108000, | 504 | .clock = 108000, |
| 505 | .refresh = 29970, | 505 | .refresh = 59940, |
| 506 | .oversample = TV_OVERSAMPLE_8X, | 506 | .oversample = TV_OVERSAMPLE_8X, |
| 507 | .component_only = 0, | 507 | .component_only = 0, |
| 508 | 508 | ||
| @@ -545,7 +545,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 545 | { | 545 | { |
| 546 | .name = "PAL-M", | 546 | .name = "PAL-M", |
| 547 | .clock = 108000, | 547 | .clock = 108000, |
| 548 | .refresh = 29970, | 548 | .refresh = 59940, |
| 549 | .oversample = TV_OVERSAMPLE_8X, | 549 | .oversample = TV_OVERSAMPLE_8X, |
| 550 | .component_only = 0, | 550 | .component_only = 0, |
| 551 | 551 | ||
| @@ -589,7 +589,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 589 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ | 589 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ |
| 590 | .name = "PAL-N", | 590 | .name = "PAL-N", |
| 591 | .clock = 108000, | 591 | .clock = 108000, |
| 592 | .refresh = 25000, | 592 | .refresh = 50000, |
| 593 | .oversample = TV_OVERSAMPLE_8X, | 593 | .oversample = TV_OVERSAMPLE_8X, |
| 594 | .component_only = 0, | 594 | .component_only = 0, |
| 595 | 595 | ||
| @@ -634,7 +634,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 634 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ | 634 | /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ |
| 635 | .name = "PAL", | 635 | .name = "PAL", |
| 636 | .clock = 108000, | 636 | .clock = 108000, |
| 637 | .refresh = 25000, | 637 | .refresh = 50000, |
| 638 | .oversample = TV_OVERSAMPLE_8X, | 638 | .oversample = TV_OVERSAMPLE_8X, |
| 639 | .component_only = 0, | 639 | .component_only = 0, |
| 640 | 640 | ||
| @@ -674,78 +674,6 @@ static const struct tv_mode tv_modes[] = { | |||
| 674 | .filter_table = filter_table, | 674 | .filter_table = filter_table, |
| 675 | }, | 675 | }, |
| 676 | { | 676 | { |
| 677 | .name = "480p@59.94Hz", | ||
| 678 | .clock = 107520, | ||
| 679 | .refresh = 59940, | ||
| 680 | .oversample = TV_OVERSAMPLE_4X, | ||
| 681 | .component_only = 1, | ||
| 682 | |||
| 683 | .hsync_end = 64, .hblank_end = 122, | ||
| 684 | .hblank_start = 842, .htotal = 857, | ||
| 685 | |||
| 686 | .progressive = true, .trilevel_sync = false, | ||
| 687 | |||
| 688 | .vsync_start_f1 = 12, .vsync_start_f2 = 12, | ||
| 689 | .vsync_len = 12, | ||
| 690 | |||
| 691 | .veq_ena = false, | ||
| 692 | |||
| 693 | .vi_end_f1 = 44, .vi_end_f2 = 44, | ||
| 694 | .nbr_end = 479, | ||
| 695 | |||
| 696 | .burst_ena = false, | ||
| 697 | |||
| 698 | .filter_table = filter_table, | ||
| 699 | }, | ||
| 700 | { | ||
| 701 | .name = "480p@60Hz", | ||
| 702 | .clock = 107520, | ||
| 703 | .refresh = 60000, | ||
| 704 | .oversample = TV_OVERSAMPLE_4X, | ||
| 705 | .component_only = 1, | ||
| 706 | |||
| 707 | .hsync_end = 64, .hblank_end = 122, | ||
| 708 | .hblank_start = 842, .htotal = 856, | ||
| 709 | |||
| 710 | .progressive = true, .trilevel_sync = false, | ||
| 711 | |||
| 712 | .vsync_start_f1 = 12, .vsync_start_f2 = 12, | ||
| 713 | .vsync_len = 12, | ||
| 714 | |||
| 715 | .veq_ena = false, | ||
| 716 | |||
| 717 | .vi_end_f1 = 44, .vi_end_f2 = 44, | ||
| 718 | .nbr_end = 479, | ||
| 719 | |||
| 720 | .burst_ena = false, | ||
| 721 | |||
| 722 | .filter_table = filter_table, | ||
| 723 | }, | ||
| 724 | { | ||
| 725 | .name = "576p", | ||
| 726 | .clock = 107520, | ||
| 727 | .refresh = 50000, | ||
| 728 | .oversample = TV_OVERSAMPLE_4X, | ||
| 729 | .component_only = 1, | ||
| 730 | |||
| 731 | .hsync_end = 64, .hblank_end = 139, | ||
| 732 | .hblank_start = 859, .htotal = 863, | ||
| 733 | |||
| 734 | .progressive = true, .trilevel_sync = false, | ||
| 735 | |||
| 736 | .vsync_start_f1 = 10, .vsync_start_f2 = 10, | ||
| 737 | .vsync_len = 10, | ||
| 738 | |||
| 739 | .veq_ena = false, | ||
| 740 | |||
| 741 | .vi_end_f1 = 48, .vi_end_f2 = 48, | ||
| 742 | .nbr_end = 575, | ||
| 743 | |||
| 744 | .burst_ena = false, | ||
| 745 | |||
| 746 | .filter_table = filter_table, | ||
| 747 | }, | ||
| 748 | { | ||
| 749 | .name = "720p@60Hz", | 677 | .name = "720p@60Hz", |
| 750 | .clock = 148800, | 678 | .clock = 148800, |
| 751 | .refresh = 60000, | 679 | .refresh = 60000, |
| @@ -770,30 +698,6 @@ static const struct tv_mode tv_modes[] = { | |||
| 770 | .filter_table = filter_table, | 698 | .filter_table = filter_table, |
| 771 | }, | 699 | }, |
| 772 | { | 700 | { |
| 773 | .name = "720p@59.94Hz", | ||
| 774 | .clock = 148800, | ||
| 775 | .refresh = 59940, | ||
| 776 | .oversample = TV_OVERSAMPLE_2X, | ||
| 777 | .component_only = 1, | ||
| 778 | |||
| 779 | .hsync_end = 80, .hblank_end = 300, | ||
| 780 | .hblank_start = 1580, .htotal = 1651, | ||
| 781 | |||
| 782 | .progressive = true, .trilevel_sync = true, | ||
| 783 | |||
| 784 | .vsync_start_f1 = 10, .vsync_start_f2 = 10, | ||
| 785 | .vsync_len = 10, | ||
| 786 | |||
| 787 | .veq_ena = false, | ||
| 788 | |||
| 789 | .vi_end_f1 = 29, .vi_end_f2 = 29, | ||
| 790 | .nbr_end = 719, | ||
| 791 | |||
| 792 | .burst_ena = false, | ||
| 793 | |||
| 794 | .filter_table = filter_table, | ||
| 795 | }, | ||
| 796 | { | ||
| 797 | .name = "720p@50Hz", | 701 | .name = "720p@50Hz", |
| 798 | .clock = 148800, | 702 | .clock = 148800, |
| 799 | .refresh = 50000, | 703 | .refresh = 50000, |
| @@ -821,7 +725,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 821 | { | 725 | { |
| 822 | .name = "1080i@50Hz", | 726 | .name = "1080i@50Hz", |
| 823 | .clock = 148800, | 727 | .clock = 148800, |
| 824 | .refresh = 25000, | 728 | .refresh = 50000, |
| 825 | .oversample = TV_OVERSAMPLE_2X, | 729 | .oversample = TV_OVERSAMPLE_2X, |
| 826 | .component_only = 1, | 730 | .component_only = 1, |
| 827 | 731 | ||
| @@ -847,7 +751,7 @@ static const struct tv_mode tv_modes[] = { | |||
| 847 | { | 751 | { |
| 848 | .name = "1080i@60Hz", | 752 | .name = "1080i@60Hz", |
| 849 | .clock = 148800, | 753 | .clock = 148800, |
| 850 | .refresh = 30000, | 754 | .refresh = 60000, |
| 851 | .oversample = TV_OVERSAMPLE_2X, | 755 | .oversample = TV_OVERSAMPLE_2X, |
| 852 | .component_only = 1, | 756 | .component_only = 1, |
| 853 | 757 | ||
| @@ -870,32 +774,6 @@ static const struct tv_mode tv_modes[] = { | |||
| 870 | 774 | ||
| 871 | .filter_table = filter_table, | 775 | .filter_table = filter_table, |
| 872 | }, | 776 | }, |
| 873 | { | ||
| 874 | .name = "1080i@59.94Hz", | ||
| 875 | .clock = 148800, | ||
| 876 | .refresh = 29970, | ||
| 877 | .oversample = TV_OVERSAMPLE_2X, | ||
| 878 | .component_only = 1, | ||
| 879 | |||
| 880 | .hsync_end = 88, .hblank_end = 235, | ||
| 881 | .hblank_start = 2155, .htotal = 2201, | ||
| 882 | |||
| 883 | .progressive = false, .trilevel_sync = true, | ||
| 884 | |||
| 885 | .vsync_start_f1 = 4, .vsync_start_f2 = 5, | ||
| 886 | .vsync_len = 10, | ||
| 887 | |||
| 888 | .veq_ena = true, .veq_start_f1 = 4, | ||
| 889 | .veq_start_f2 = 4, .veq_len = 10, | ||
| 890 | |||
| 891 | |||
| 892 | .vi_end_f1 = 21, .vi_end_f2 = 22, | ||
| 893 | .nbr_end = 539, | ||
| 894 | |||
| 895 | .burst_ena = false, | ||
| 896 | |||
| 897 | .filter_table = filter_table, | ||
| 898 | }, | ||
| 899 | }; | 777 | }; |
| 900 | 778 | ||
| 901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | 779 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index 1e382ad5a2b8..a37c31e358aa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
| @@ -54,9 +54,10 @@ struct bit_entry { | |||
| 54 | int bit_table(struct drm_device *, u8 id, struct bit_entry *); | 54 | int bit_table(struct drm_device *, u8 id, struct bit_entry *); |
| 55 | 55 | ||
| 56 | enum dcb_gpio_tag { | 56 | enum dcb_gpio_tag { |
| 57 | DCB_GPIO_TVDAC0 = 0xc, | 57 | DCB_GPIO_PANEL_POWER = 0x01, |
| 58 | DCB_GPIO_TVDAC0 = 0x0c, | ||
| 58 | DCB_GPIO_TVDAC1 = 0x2d, | 59 | DCB_GPIO_TVDAC1 = 0x2d, |
| 59 | DCB_GPIO_PWM_FAN = 0x9, | 60 | DCB_GPIO_PWM_FAN = 0x09, |
| 60 | DCB_GPIO_FAN_SENSE = 0x3d, | 61 | DCB_GPIO_FAN_SENSE = 0x3d, |
| 61 | DCB_GPIO_UNUSED = 0xff | 62 | DCB_GPIO_UNUSED = 0xff |
| 62 | }; | 63 | }; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 724b41a2b9e9..ec54364ac828 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -812,6 +812,10 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem) | |||
| 812 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 812 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
| 813 | struct nouveau_vma *vma; | 813 | struct nouveau_vma *vma; |
| 814 | 814 | ||
| 815 | /* ttm can now (stupidly) pass the driver bos it didn't create... */ | ||
| 816 | if (bo->destroy != nouveau_bo_del_ttm) | ||
| 817 | return; | ||
| 818 | |||
| 815 | list_for_each_entry(vma, &nvbo->vma_list, head) { | 819 | list_for_each_entry(vma, &nvbo->vma_list, head) { |
| 816 | if (new_mem && new_mem->mem_type == TTM_PL_VRAM) { | 820 | if (new_mem && new_mem->mem_type == TTM_PL_VRAM) { |
| 817 | nouveau_vm_map(vma, new_mem->mm_node); | 821 | nouveau_vm_map(vma, new_mem->mm_node); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 3cb52bc52b21..795a9e3c990a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
| @@ -219,6 +219,16 @@ nouveau_display_init(struct drm_device *dev) | |||
| 219 | if (ret) | 219 | if (ret) |
| 220 | return ret; | 220 | return ret; |
| 221 | 221 | ||
| 222 | /* power on internal panel if it's not already. the init tables of | ||
| 223 | * some vbios default this to off for some reason, causing the | ||
| 224 | * panel to not work after resume | ||
| 225 | */ | ||
| 226 | if (nouveau_gpio_func_get(dev, DCB_GPIO_PANEL_POWER) == 0) { | ||
| 227 | nouveau_gpio_func_set(dev, DCB_GPIO_PANEL_POWER, true); | ||
| 228 | msleep(300); | ||
| 229 | } | ||
| 230 | |||
| 231 | /* enable polling for external displays */ | ||
| 222 | drm_kms_helper_poll_enable(dev); | 232 | drm_kms_helper_poll_enable(dev); |
| 223 | 233 | ||
| 224 | /* enable hotplug interrupts */ | 234 | /* enable hotplug interrupts */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index e4a7cfe7898d..81d7962e7252 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
| @@ -124,7 +124,7 @@ MODULE_PARM_DESC(ctxfw, "Use external HUB/GPC ucode (fermi)\n"); | |||
| 124 | int nouveau_ctxfw; | 124 | int nouveau_ctxfw; |
| 125 | module_param_named(ctxfw, nouveau_ctxfw, int, 0400); | 125 | module_param_named(ctxfw, nouveau_ctxfw, int, 0400); |
| 126 | 126 | ||
| 127 | MODULE_PARM_DESC(ctxfw, "Santise DCB table according to MXM-SIS\n"); | 127 | MODULE_PARM_DESC(mxmdcb, "Santise DCB table according to MXM-SIS\n"); |
| 128 | int nouveau_mxmdcb = 1; | 128 | int nouveau_mxmdcb = 1; |
| 129 | module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400); | 129 | module_param_named(mxmdcb, nouveau_mxmdcb, int, 0400); |
| 130 | 130 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 5f0bc57fdaab..7ce3fde40743 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
| @@ -380,6 +380,25 @@ retry: | |||
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | static int | 382 | static int |
| 383 | validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) | ||
| 384 | { | ||
| 385 | struct nouveau_fence *fence = NULL; | ||
| 386 | int ret = 0; | ||
| 387 | |||
| 388 | spin_lock(&nvbo->bo.bdev->fence_lock); | ||
| 389 | if (nvbo->bo.sync_obj) | ||
| 390 | fence = nouveau_fence_ref(nvbo->bo.sync_obj); | ||
| 391 | spin_unlock(&nvbo->bo.bdev->fence_lock); | ||
| 392 | |||
| 393 | if (fence) { | ||
| 394 | ret = nouveau_fence_sync(fence, chan); | ||
| 395 | nouveau_fence_unref(&fence); | ||
| 396 | } | ||
| 397 | |||
| 398 | return ret; | ||
| 399 | } | ||
| 400 | |||
| 401 | static int | ||
| 383 | validate_list(struct nouveau_channel *chan, struct list_head *list, | 402 | validate_list(struct nouveau_channel *chan, struct list_head *list, |
| 384 | struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) | 403 | struct drm_nouveau_gem_pushbuf_bo *pbbo, uint64_t user_pbbo_ptr) |
| 385 | { | 404 | { |
| @@ -393,7 +412,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
| 393 | list_for_each_entry(nvbo, list, entry) { | 412 | list_for_each_entry(nvbo, list, entry) { |
| 394 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 413 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
| 395 | 414 | ||
| 396 | ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); | 415 | ret = validate_sync(chan, nvbo); |
| 397 | if (unlikely(ret)) { | 416 | if (unlikely(ret)) { |
| 398 | NV_ERROR(dev, "fail pre-validate sync\n"); | 417 | NV_ERROR(dev, "fail pre-validate sync\n"); |
| 399 | return ret; | 418 | return ret; |
| @@ -416,7 +435,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
| 416 | return ret; | 435 | return ret; |
| 417 | } | 436 | } |
| 418 | 437 | ||
| 419 | ret = nouveau_fence_sync(nvbo->bo.sync_obj, chan); | 438 | ret = validate_sync(chan, nvbo); |
| 420 | if (unlikely(ret)) { | 439 | if (unlikely(ret)) { |
| 421 | NV_ERROR(dev, "fail post-validate sync\n"); | 440 | NV_ERROR(dev, "fail post-validate sync\n"); |
| 422 | return ret; | 441 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mxm.c b/drivers/gpu/drm/nouveau/nouveau_mxm.c index 8bccddf4eff0..e5a64f0f4cb7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mxm.c +++ b/drivers/gpu/drm/nouveau/nouveau_mxm.c | |||
| @@ -656,7 +656,16 @@ nouveau_mxm_init(struct drm_device *dev) | |||
| 656 | 656 | ||
| 657 | if (mxm_shadow(dev, mxm[0])) { | 657 | if (mxm_shadow(dev, mxm[0])) { |
| 658 | MXM_MSG(dev, "failed to locate valid SIS\n"); | 658 | MXM_MSG(dev, "failed to locate valid SIS\n"); |
| 659 | #if 0 | ||
| 660 | /* we should, perhaps, fall back to some kind of limited | ||
| 661 | * mode here if the x86 vbios hasn't already done the | ||
| 662 | * work for us (so we prevent loading with completely | ||
| 663 | * whacked vbios tables). | ||
| 664 | */ | ||
| 659 | return -EINVAL; | 665 | return -EINVAL; |
| 666 | #else | ||
| 667 | return 0; | ||
| 668 | #endif | ||
| 660 | } | 669 | } |
| 661 | 670 | ||
| 662 | MXM_MSG(dev, "MXMS Version %d.%d\n", | 671 | MXM_MSG(dev, "MXMS Version %d.%d\n", |
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c index 03937212e9d8..ec5481dfcd82 100644 --- a/drivers/gpu/drm/nouveau/nv50_pm.c +++ b/drivers/gpu/drm/nouveau/nv50_pm.c | |||
| @@ -495,9 +495,9 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) | |||
| 495 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 495 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 496 | struct nv50_pm_state *info; | 496 | struct nv50_pm_state *info; |
| 497 | struct pll_lims pll; | 497 | struct pll_lims pll; |
| 498 | int ret = -EINVAL; | 498 | int clk, ret = -EINVAL; |
| 499 | int N, M, P1, P2; | 499 | int N, M, P1, P2; |
| 500 | u32 clk, out; | 500 | u32 out; |
| 501 | 501 | ||
| 502 | if (dev_priv->chipset == 0xaa || | 502 | if (dev_priv->chipset == 0xaa || |
| 503 | dev_priv->chipset == 0xac) | 503 | dev_priv->chipset == 0xac) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 0fda830ef806..742f17f009a9 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -355,15 +355,12 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, | |||
| 355 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | 355 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | static void atombios_disable_ss(struct drm_crtc *crtc) | 358 | static void atombios_disable_ss(struct radeon_device *rdev, int pll_id) |
| 359 | { | 359 | { |
| 360 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
| 361 | struct drm_device *dev = crtc->dev; | ||
| 362 | struct radeon_device *rdev = dev->dev_private; | ||
| 363 | u32 ss_cntl; | 360 | u32 ss_cntl; |
| 364 | 361 | ||
| 365 | if (ASIC_IS_DCE4(rdev)) { | 362 | if (ASIC_IS_DCE4(rdev)) { |
| 366 | switch (radeon_crtc->pll_id) { | 363 | switch (pll_id) { |
| 367 | case ATOM_PPLL1: | 364 | case ATOM_PPLL1: |
| 368 | ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); | 365 | ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL); |
| 369 | ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; | 366 | ss_cntl &= ~EVERGREEN_PxPLL_SS_EN; |
| @@ -379,7 +376,7 @@ static void atombios_disable_ss(struct drm_crtc *crtc) | |||
| 379 | return; | 376 | return; |
| 380 | } | 377 | } |
| 381 | } else if (ASIC_IS_AVIVO(rdev)) { | 378 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 382 | switch (radeon_crtc->pll_id) { | 379 | switch (pll_id) { |
| 383 | case ATOM_PPLL1: | 380 | case ATOM_PPLL1: |
| 384 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); | 381 | ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL); |
| 385 | ss_cntl &= ~1; | 382 | ss_cntl &= ~1; |
| @@ -406,13 +403,11 @@ union atom_enable_ss { | |||
| 406 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; | 403 | ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 v3; |
| 407 | }; | 404 | }; |
| 408 | 405 | ||
| 409 | static void atombios_crtc_program_ss(struct drm_crtc *crtc, | 406 | static void atombios_crtc_program_ss(struct radeon_device *rdev, |
| 410 | int enable, | 407 | int enable, |
| 411 | int pll_id, | 408 | int pll_id, |
| 412 | struct radeon_atom_ss *ss) | 409 | struct radeon_atom_ss *ss) |
| 413 | { | 410 | { |
| 414 | struct drm_device *dev = crtc->dev; | ||
| 415 | struct radeon_device *rdev = dev->dev_private; | ||
| 416 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); | 411 | int index = GetIndexIntoMasterTable(COMMAND, EnableSpreadSpectrumOnPPLL); |
| 417 | union atom_enable_ss args; | 412 | union atom_enable_ss args; |
| 418 | 413 | ||
| @@ -479,7 +474,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, | |||
| 479 | } else if (ASIC_IS_AVIVO(rdev)) { | 474 | } else if (ASIC_IS_AVIVO(rdev)) { |
| 480 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || | 475 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
| 481 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { | 476 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
| 482 | atombios_disable_ss(crtc); | 477 | atombios_disable_ss(rdev, pll_id); |
| 483 | return; | 478 | return; |
| 484 | } | 479 | } |
| 485 | args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); | 480 | args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
| @@ -491,7 +486,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc, | |||
| 491 | } else { | 486 | } else { |
| 492 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || | 487 | if ((enable == ATOM_DISABLE) || (ss->percentage == 0) || |
| 493 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { | 488 | (ss->type & ATOM_EXTERNAL_SS_MASK)) { |
| 494 | atombios_disable_ss(crtc); | 489 | atombios_disable_ss(rdev, pll_id); |
| 495 | return; | 490 | return; |
| 496 | } | 491 | } |
| 497 | args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); | 492 | args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage); |
| @@ -523,6 +518,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 523 | int encoder_mode = 0; | 518 | int encoder_mode = 0; |
| 524 | u32 dp_clock = mode->clock; | 519 | u32 dp_clock = mode->clock; |
| 525 | int bpc = 8; | 520 | int bpc = 8; |
| 521 | bool is_duallink = false; | ||
| 526 | 522 | ||
| 527 | /* reset the pll flags */ | 523 | /* reset the pll flags */ |
| 528 | pll->flags = 0; | 524 | pll->flags = 0; |
| @@ -557,6 +553,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 557 | if (connector && connector->display_info.bpc) | 553 | if (connector && connector->display_info.bpc) |
| 558 | bpc = connector->display_info.bpc; | 554 | bpc = connector->display_info.bpc; |
| 559 | encoder_mode = atombios_get_encoder_mode(encoder); | 555 | encoder_mode = atombios_get_encoder_mode(encoder); |
| 556 | is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); | ||
| 560 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || | 557 | if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || |
| 561 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { | 558 | (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { |
| 562 | if (connector) { | 559 | if (connector) { |
| @@ -652,7 +649,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
| 652 | if (dig->coherent_mode) | 649 | if (dig->coherent_mode) |
| 653 | args.v3.sInput.ucDispPllConfig |= | 650 | args.v3.sInput.ucDispPllConfig |= |
| 654 | DISPPLL_CONFIG_COHERENT_MODE; | 651 | DISPPLL_CONFIG_COHERENT_MODE; |
| 655 | if (mode->clock > 165000) | 652 | if (is_duallink) |
| 656 | args.v3.sInput.ucDispPllConfig |= | 653 | args.v3.sInput.ucDispPllConfig |= |
| 657 | DISPPLL_CONFIG_DUAL_LINK; | 654 | DISPPLL_CONFIG_DUAL_LINK; |
| 658 | } | 655 | } |
| @@ -702,11 +699,9 @@ union set_pixel_clock { | |||
| 702 | /* on DCE5, make sure the voltage is high enough to support the | 699 | /* on DCE5, make sure the voltage is high enough to support the |
| 703 | * required disp clk. | 700 | * required disp clk. |
| 704 | */ | 701 | */ |
| 705 | static void atombios_crtc_set_dcpll(struct drm_crtc *crtc, | 702 | static void atombios_crtc_set_dcpll(struct radeon_device *rdev, |
| 706 | u32 dispclk) | 703 | u32 dispclk) |
| 707 | { | 704 | { |
| 708 | struct drm_device *dev = crtc->dev; | ||
| 709 | struct radeon_device *rdev = dev->dev_private; | ||
| 710 | u8 frev, crev; | 705 | u8 frev, crev; |
| 711 | int index; | 706 | int index; |
| 712 | union set_pixel_clock args; | 707 | union set_pixel_clock args; |
| @@ -996,7 +991,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 996 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, | 991 | radeon_compute_pll_legacy(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div, |
| 997 | &ref_div, &post_div); | 992 | &ref_div, &post_div); |
| 998 | 993 | ||
| 999 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, radeon_crtc->pll_id, &ss); | 994 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, radeon_crtc->pll_id, &ss); |
| 1000 | 995 | ||
| 1001 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 996 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
| 1002 | encoder_mode, radeon_encoder->encoder_id, mode->clock, | 997 | encoder_mode, radeon_encoder->encoder_id, mode->clock, |
| @@ -1019,7 +1014,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode | |||
| 1019 | ss.step = step_size; | 1014 | ss.step = step_size; |
| 1020 | } | 1015 | } |
| 1021 | 1016 | ||
| 1022 | atombios_crtc_program_ss(crtc, ATOM_ENABLE, radeon_crtc->pll_id, &ss); | 1017 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, radeon_crtc->pll_id, &ss); |
| 1023 | } | 1018 | } |
| 1024 | } | 1019 | } |
| 1025 | 1020 | ||
| @@ -1189,7 +1184,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1189 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 1184 | WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
| 1190 | 1185 | ||
| 1191 | WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, | 1186 | WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
| 1192 | crtc->mode.vdisplay); | 1187 | target_fb->height); |
| 1193 | x &= ~3; | 1188 | x &= ~3; |
| 1194 | y &= ~1; | 1189 | y &= ~1; |
| 1195 | WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, | 1190 | WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset, |
| @@ -1358,7 +1353,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1358 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); | 1353 | WREG32(AVIVO_D1GRPH_ENABLE + radeon_crtc->crtc_offset, 1); |
| 1359 | 1354 | ||
| 1360 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, | 1355 | WREG32(AVIVO_D1MODE_DESKTOP_HEIGHT + radeon_crtc->crtc_offset, |
| 1361 | crtc->mode.vdisplay); | 1356 | target_fb->height); |
| 1362 | x &= ~3; | 1357 | x &= ~3; |
| 1363 | y &= ~1; | 1358 | y &= ~1; |
| 1364 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, | 1359 | WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset, |
| @@ -1494,6 +1489,24 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
| 1494 | 1489 | ||
| 1495 | } | 1490 | } |
| 1496 | 1491 | ||
| 1492 | void radeon_atom_dcpll_init(struct radeon_device *rdev) | ||
| 1493 | { | ||
| 1494 | /* always set DCPLL */ | ||
| 1495 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1496 | struct radeon_atom_ss ss; | ||
| 1497 | bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
| 1498 | ASIC_INTERNAL_SS_ON_DCPLL, | ||
| 1499 | rdev->clock.default_dispclk); | ||
| 1500 | if (ss_enabled) | ||
| 1501 | atombios_crtc_program_ss(rdev, ATOM_DISABLE, ATOM_DCPLL, &ss); | ||
| 1502 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ | ||
| 1503 | atombios_crtc_set_dcpll(rdev, rdev->clock.default_dispclk); | ||
| 1504 | if (ss_enabled) | ||
| 1505 | atombios_crtc_program_ss(rdev, ATOM_ENABLE, ATOM_DCPLL, &ss); | ||
| 1506 | } | ||
| 1507 | |||
| 1508 | } | ||
| 1509 | |||
| 1497 | int atombios_crtc_mode_set(struct drm_crtc *crtc, | 1510 | int atombios_crtc_mode_set(struct drm_crtc *crtc, |
| 1498 | struct drm_display_mode *mode, | 1511 | struct drm_display_mode *mode, |
| 1499 | struct drm_display_mode *adjusted_mode, | 1512 | struct drm_display_mode *adjusted_mode, |
| @@ -1515,19 +1528,6 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
| 1515 | } | 1528 | } |
| 1516 | } | 1529 | } |
| 1517 | 1530 | ||
| 1518 | /* always set DCPLL */ | ||
| 1519 | if (ASIC_IS_DCE4(rdev)) { | ||
| 1520 | struct radeon_atom_ss ss; | ||
| 1521 | bool ss_enabled = radeon_atombios_get_asic_ss_info(rdev, &ss, | ||
| 1522 | ASIC_INTERNAL_SS_ON_DCPLL, | ||
| 1523 | rdev->clock.default_dispclk); | ||
| 1524 | if (ss_enabled) | ||
| 1525 | atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss); | ||
| 1526 | /* XXX: DCE5, make sure voltage, dispclk is high enough */ | ||
| 1527 | atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk); | ||
| 1528 | if (ss_enabled) | ||
| 1529 | atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss); | ||
| 1530 | } | ||
| 1531 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1531 | atombios_crtc_set_pll(crtc, adjusted_mode); |
| 1532 | 1532 | ||
| 1533 | if (ASIC_IS_DCE4(rdev)) | 1533 | if (ASIC_IS_DCE4(rdev)) |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 6fb335a4fdda..552b436451fd 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
| @@ -549,8 +549,8 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) | |||
| 549 | return false; | 549 | return false; |
| 550 | } | 550 | } |
| 551 | 551 | ||
| 552 | static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, | 552 | int radeon_dp_get_panel_mode(struct drm_encoder *encoder, |
| 553 | struct drm_connector *connector) | 553 | struct drm_connector *connector) |
| 554 | { | 554 | { |
| 555 | struct drm_device *dev = encoder->dev; | 555 | struct drm_device *dev = encoder->dev; |
| 556 | struct radeon_device *rdev = dev->dev_private; | 556 | struct radeon_device *rdev = dev->dev_private; |
| @@ -558,28 +558,33 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, | |||
| 558 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 558 | int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
| 559 | 559 | ||
| 560 | if (!ASIC_IS_DCE4(rdev)) | 560 | if (!ASIC_IS_DCE4(rdev)) |
| 561 | return; | 561 | return panel_mode; |
| 562 | 562 | ||
| 563 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 563 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
| 564 | ENCODER_OBJECT_ID_NUTMEG) | 564 | ENCODER_OBJECT_ID_NUTMEG) |
| 565 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 565 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
| 566 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == | 566 | else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == |
| 567 | ENCODER_OBJECT_ID_TRAVIS) | 567 | ENCODER_OBJECT_ID_TRAVIS) { |
| 568 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 568 | u8 id[6]; |
| 569 | else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 569 | int i; |
| 570 | for (i = 0; i < 6; i++) | ||
| 571 | id[i] = radeon_read_dpcd_reg(radeon_connector, 0x503 + i); | ||
| 572 | if (id[0] == 0x73 && | ||
| 573 | id[1] == 0x69 && | ||
| 574 | id[2] == 0x76 && | ||
| 575 | id[3] == 0x61 && | ||
| 576 | id[4] == 0x72 && | ||
| 577 | id[5] == 0x54) | ||
| 578 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | ||
| 579 | else | ||
| 580 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | ||
| 581 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | ||
| 570 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); | 582 | u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); |
| 571 | if (tmp & 1) | 583 | if (tmp & 1) |
| 572 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 584 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
| 573 | } | 585 | } |
| 574 | 586 | ||
| 575 | atombios_dig_encoder_setup(encoder, | 587 | return panel_mode; |
| 576 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
| 577 | panel_mode); | ||
| 578 | |||
| 579 | if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) && | ||
| 580 | (panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { | ||
| 581 | radeon_write_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_SET, 1); | ||
| 582 | } | ||
| 583 | } | 588 | } |
| 584 | 589 | ||
| 585 | void radeon_dp_set_link_config(struct drm_connector *connector, | 590 | void radeon_dp_set_link_config(struct drm_connector *connector, |
| @@ -717,6 +722,8 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp) | |||
| 717 | 722 | ||
| 718 | static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) | 723 | static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) |
| 719 | { | 724 | { |
| 725 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(dp_info->encoder); | ||
| 726 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 720 | u8 tmp; | 727 | u8 tmp; |
| 721 | 728 | ||
| 722 | /* power up the sink */ | 729 | /* power up the sink */ |
| @@ -732,7 +739,10 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info) | |||
| 732 | radeon_write_dpcd_reg(dp_info->radeon_connector, | 739 | radeon_write_dpcd_reg(dp_info->radeon_connector, |
| 733 | DP_DOWNSPREAD_CTRL, 0); | 740 | DP_DOWNSPREAD_CTRL, 0); |
| 734 | 741 | ||
| 735 | radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector); | 742 | if ((dp_info->connector->connector_type == DRM_MODE_CONNECTOR_eDP) && |
| 743 | (dig->panel_mode == DP_PANEL_MODE_INTERNAL_DP2_MODE)) { | ||
| 744 | radeon_write_dpcd_reg(dp_info->radeon_connector, DP_EDP_CONFIGURATION_SET, 1); | ||
| 745 | } | ||
| 736 | 746 | ||
| 737 | /* set the lane count on the sink */ | 747 | /* set the lane count on the sink */ |
| 738 | tmp = dp_info->dp_lane_count; | 748 | tmp = dp_info->dp_lane_count; |
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index f1f06ca9f1f5..b88c4608731b 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c | |||
| @@ -57,22 +57,6 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder) | |||
| 57 | } | 57 | } |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | static struct drm_connector * | ||
| 61 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
| 62 | { | ||
| 63 | struct drm_device *dev = encoder->dev; | ||
| 64 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 65 | struct drm_connector *connector; | ||
| 66 | struct radeon_connector *radeon_connector; | ||
| 67 | |||
| 68 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 69 | radeon_connector = to_radeon_connector(connector); | ||
| 70 | if (radeon_encoder->devices & radeon_connector->devices) | ||
| 71 | return connector; | ||
| 72 | } | ||
| 73 | return NULL; | ||
| 74 | } | ||
| 75 | |||
| 76 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, | 60 | static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, |
| 77 | struct drm_display_mode *mode, | 61 | struct drm_display_mode *mode, |
| 78 | struct drm_display_mode *adjusted_mode) | 62 | struct drm_display_mode *adjusted_mode) |
| @@ -253,7 +237,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
| 253 | /* R4xx, R5xx */ | 237 | /* R4xx, R5xx */ |
| 254 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; | 238 | args.ext_tmds.sXTmdsEncoder.ucEnable = action; |
| 255 | 239 | ||
| 256 | if (radeon_encoder->pixel_clock > 165000) | 240 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 257 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 241 | args.ext_tmds.sXTmdsEncoder.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| 258 | 242 | ||
| 259 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; | 243 | args.ext_tmds.sXTmdsEncoder.ucMisc |= ATOM_PANEL_MISC_888RGB; |
| @@ -265,7 +249,7 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action) | |||
| 265 | /* DFP1, CRT1, TV1 depending on the type of port */ | 249 | /* DFP1, CRT1, TV1 depending on the type of port */ |
| 266 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; | 250 | args.dvo.sDVOEncoder.ucDeviceType = ATOM_DEVICE_DFP1_INDEX; |
| 267 | 251 | ||
| 268 | if (radeon_encoder->pixel_clock > 165000) | 252 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 269 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; | 253 | args.dvo.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute |= PANEL_ENCODER_MISC_DUAL; |
| 270 | break; | 254 | break; |
| 271 | case 3: | 255 | case 3: |
| @@ -349,7 +333,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 349 | } else { | 333 | } else { |
| 350 | if (dig->linkb) | 334 | if (dig->linkb) |
| 351 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 335 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
| 352 | if (radeon_encoder->pixel_clock > 165000) | 336 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 353 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 337 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| 354 | /*if (pScrn->rgbBits == 8) */ | 338 | /*if (pScrn->rgbBits == 8) */ |
| 355 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; | 339 | args.v1.ucMisc |= ATOM_PANEL_MISC_888RGB; |
| @@ -388,7 +372,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
| 388 | } else { | 372 | } else { |
| 389 | if (dig->linkb) | 373 | if (dig->linkb) |
| 390 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 374 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
| 391 | if (radeon_encoder->pixel_clock > 165000) | 375 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 392 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 376 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
| 393 | } | 377 | } |
| 394 | break; | 378 | break; |
| @@ -432,7 +416,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 432 | switch (connector->connector_type) { | 416 | switch (connector->connector_type) { |
| 433 | case DRM_MODE_CONNECTOR_DVII: | 417 | case DRM_MODE_CONNECTOR_DVII: |
| 434 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 418 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
| 435 | if (drm_detect_monitor_audio(radeon_connector->edid) && | 419 | if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
| 436 | radeon_audio) | 420 | radeon_audio) |
| 437 | return ATOM_ENCODER_MODE_HDMI; | 421 | return ATOM_ENCODER_MODE_HDMI; |
| 438 | else if (radeon_connector->use_digital) | 422 | else if (radeon_connector->use_digital) |
| @@ -443,7 +427,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 443 | case DRM_MODE_CONNECTOR_DVID: | 427 | case DRM_MODE_CONNECTOR_DVID: |
| 444 | case DRM_MODE_CONNECTOR_HDMIA: | 428 | case DRM_MODE_CONNECTOR_HDMIA: |
| 445 | default: | 429 | default: |
| 446 | if (drm_detect_monitor_audio(radeon_connector->edid) && | 430 | if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
| 447 | radeon_audio) | 431 | radeon_audio) |
| 448 | return ATOM_ENCODER_MODE_HDMI; | 432 | return ATOM_ENCODER_MODE_HDMI; |
| 449 | else | 433 | else |
| @@ -457,7 +441,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
| 457 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 441 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
| 458 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 442 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
| 459 | return ATOM_ENCODER_MODE_DP; | 443 | return ATOM_ENCODER_MODE_DP; |
| 460 | else if (drm_detect_monitor_audio(radeon_connector->edid) && | 444 | else if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
| 461 | radeon_audio) | 445 | radeon_audio) |
| 462 | return ATOM_ENCODER_MODE_HDMI; | 446 | return ATOM_ENCODER_MODE_HDMI; |
| 463 | else | 447 | else |
| @@ -587,7 +571,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
| 587 | 571 | ||
| 588 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 572 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
| 589 | args.v1.ucLaneNum = dp_lane_count; | 573 | args.v1.ucLaneNum = dp_lane_count; |
| 590 | else if (radeon_encoder->pixel_clock > 165000) | 574 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 591 | args.v1.ucLaneNum = 8; | 575 | args.v1.ucLaneNum = 8; |
| 592 | else | 576 | else |
| 593 | args.v1.ucLaneNum = 4; | 577 | args.v1.ucLaneNum = 4; |
| @@ -622,7 +606,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
| 622 | 606 | ||
| 623 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 607 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
| 624 | args.v3.ucLaneNum = dp_lane_count; | 608 | args.v3.ucLaneNum = dp_lane_count; |
| 625 | else if (radeon_encoder->pixel_clock > 165000) | 609 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 626 | args.v3.ucLaneNum = 8; | 610 | args.v3.ucLaneNum = 8; |
| 627 | else | 611 | else |
| 628 | args.v3.ucLaneNum = 4; | 612 | args.v3.ucLaneNum = 4; |
| @@ -662,7 +646,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo | |||
| 662 | 646 | ||
| 663 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) | 647 | if (ENCODER_MODE_IS_DP(args.v1.ucEncoderMode)) |
| 664 | args.v4.ucLaneNum = dp_lane_count; | 648 | args.v4.ucLaneNum = dp_lane_count; |
| 665 | else if (radeon_encoder->pixel_clock > 165000) | 649 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 666 | args.v4.ucLaneNum = 8; | 650 | args.v4.ucLaneNum = 8; |
| 667 | else | 651 | else |
| 668 | args.v4.ucLaneNum = 4; | 652 | args.v4.ucLaneNum = 4; |
| @@ -806,7 +790,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 806 | if (is_dp) | 790 | if (is_dp) |
| 807 | args.v1.usPixelClock = | 791 | args.v1.usPixelClock = |
| 808 | cpu_to_le16(dp_clock / 10); | 792 | cpu_to_le16(dp_clock / 10); |
| 809 | else if (radeon_encoder->pixel_clock > 165000) | 793 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 810 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 794 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 811 | else | 795 | else |
| 812 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 796 | args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -821,7 +805,8 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 821 | 805 | ||
| 822 | if ((rdev->flags & RADEON_IS_IGP) && | 806 | if ((rdev->flags & RADEON_IS_IGP) && |
| 823 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | 807 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
| 824 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | 808 | if (is_dp || |
| 809 | !radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) { | ||
| 825 | if (igp_lane_info & 0x1) | 810 | if (igp_lane_info & 0x1) |
| 826 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 811 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
| 827 | else if (igp_lane_info & 0x2) | 812 | else if (igp_lane_info & 0x2) |
| @@ -848,7 +833,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 848 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 833 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 849 | if (dig->coherent_mode) | 834 | if (dig->coherent_mode) |
| 850 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; | 835 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_COHERENT; |
| 851 | if (radeon_encoder->pixel_clock > 165000) | 836 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 852 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; | 837 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_8LANE_LINK; |
| 853 | } | 838 | } |
| 854 | break; | 839 | break; |
| @@ -863,7 +848,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 863 | if (is_dp) | 848 | if (is_dp) |
| 864 | args.v2.usPixelClock = | 849 | args.v2.usPixelClock = |
| 865 | cpu_to_le16(dp_clock / 10); | 850 | cpu_to_le16(dp_clock / 10); |
| 866 | else if (radeon_encoder->pixel_clock > 165000) | 851 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 867 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 852 | args.v2.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 868 | else | 853 | else |
| 869 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 854 | args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -891,7 +876,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 891 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 876 | } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 892 | if (dig->coherent_mode) | 877 | if (dig->coherent_mode) |
| 893 | args.v2.acConfig.fCoherentMode = 1; | 878 | args.v2.acConfig.fCoherentMode = 1; |
| 894 | if (radeon_encoder->pixel_clock > 165000) | 879 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 895 | args.v2.acConfig.fDualLinkConnector = 1; | 880 | args.v2.acConfig.fDualLinkConnector = 1; |
| 896 | } | 881 | } |
| 897 | break; | 882 | break; |
| @@ -906,7 +891,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 906 | if (is_dp) | 891 | if (is_dp) |
| 907 | args.v3.usPixelClock = | 892 | args.v3.usPixelClock = |
| 908 | cpu_to_le16(dp_clock / 10); | 893 | cpu_to_le16(dp_clock / 10); |
| 909 | else if (radeon_encoder->pixel_clock > 165000) | 894 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 910 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 895 | args.v3.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 911 | else | 896 | else |
| 912 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 897 | args.v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -914,7 +899,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 914 | 899 | ||
| 915 | if (is_dp) | 900 | if (is_dp) |
| 916 | args.v3.ucLaneNum = dp_lane_count; | 901 | args.v3.ucLaneNum = dp_lane_count; |
| 917 | else if (radeon_encoder->pixel_clock > 165000) | 902 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 918 | args.v3.ucLaneNum = 8; | 903 | args.v3.ucLaneNum = 8; |
| 919 | else | 904 | else |
| 920 | args.v3.ucLaneNum = 4; | 905 | args.v3.ucLaneNum = 4; |
| @@ -951,7 +936,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 951 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 936 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 952 | if (dig->coherent_mode) | 937 | if (dig->coherent_mode) |
| 953 | args.v3.acConfig.fCoherentMode = 1; | 938 | args.v3.acConfig.fCoherentMode = 1; |
| 954 | if (radeon_encoder->pixel_clock > 165000) | 939 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 955 | args.v3.acConfig.fDualLinkConnector = 1; | 940 | args.v3.acConfig.fDualLinkConnector = 1; |
| 956 | } | 941 | } |
| 957 | break; | 942 | break; |
| @@ -966,7 +951,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 966 | if (is_dp) | 951 | if (is_dp) |
| 967 | args.v4.usPixelClock = | 952 | args.v4.usPixelClock = |
| 968 | cpu_to_le16(dp_clock / 10); | 953 | cpu_to_le16(dp_clock / 10); |
| 969 | else if (radeon_encoder->pixel_clock > 165000) | 954 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 970 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 955 | args.v4.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
| 971 | else | 956 | else |
| 972 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); | 957 | args.v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); |
| @@ -974,7 +959,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 974 | 959 | ||
| 975 | if (is_dp) | 960 | if (is_dp) |
| 976 | args.v4.ucLaneNum = dp_lane_count; | 961 | args.v4.ucLaneNum = dp_lane_count; |
| 977 | else if (radeon_encoder->pixel_clock > 165000) | 962 | else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 978 | args.v4.ucLaneNum = 8; | 963 | args.v4.ucLaneNum = 8; |
| 979 | else | 964 | else |
| 980 | args.v4.ucLaneNum = 4; | 965 | args.v4.ucLaneNum = 4; |
| @@ -1014,7 +999,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
| 1014 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 999 | else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
| 1015 | if (dig->coherent_mode) | 1000 | if (dig->coherent_mode) |
| 1016 | args.v4.acConfig.fCoherentMode = 1; | 1001 | args.v4.acConfig.fCoherentMode = 1; |
| 1017 | if (radeon_encoder->pixel_clock > 165000) | 1002 | if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 1018 | args.v4.acConfig.fDualLinkConnector = 1; | 1003 | args.v4.acConfig.fDualLinkConnector = 1; |
| 1019 | } | 1004 | } |
| 1020 | break; | 1005 | break; |
| @@ -1137,7 +1122,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1137 | if (dp_clock == 270000) | 1122 | if (dp_clock == 270000) |
| 1138 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 1123 | args.v1.sDigEncoder.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
| 1139 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; | 1124 | args.v1.sDigEncoder.ucLaneNum = dp_lane_count; |
| 1140 | } else if (radeon_encoder->pixel_clock > 165000) | 1125 | } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 1141 | args.v1.sDigEncoder.ucLaneNum = 8; | 1126 | args.v1.sDigEncoder.ucLaneNum = 8; |
| 1142 | else | 1127 | else |
| 1143 | args.v1.sDigEncoder.ucLaneNum = 4; | 1128 | args.v1.sDigEncoder.ucLaneNum = 4; |
| @@ -1156,7 +1141,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, | |||
| 1156 | else if (dp_clock == 540000) | 1141 | else if (dp_clock == 540000) |
| 1157 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; | 1142 | args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; |
| 1158 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; | 1143 | args.v3.sExtEncoder.ucLaneNum = dp_lane_count; |
| 1159 | } else if (radeon_encoder->pixel_clock > 165000) | 1144 | } else if (radeon_dig_monitor_is_duallink(encoder, radeon_encoder->pixel_clock)) |
| 1160 | args.v3.sExtEncoder.ucLaneNum = 8; | 1145 | args.v3.sExtEncoder.ucLaneNum = 8; |
| 1161 | else | 1146 | else |
| 1162 | args.v3.sExtEncoder.ucLaneNum = 4; | 1147 | args.v3.sExtEncoder.ucLaneNum = 4; |
| @@ -1341,7 +1326,8 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1341 | switch (mode) { | 1326 | switch (mode) { |
| 1342 | case DRM_MODE_DPMS_ON: | 1327 | case DRM_MODE_DPMS_ON: |
| 1343 | /* some early dce3.2 boards have a bug in their transmitter control table */ | 1328 | /* some early dce3.2 boards have a bug in their transmitter control table */ |
| 1344 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730)) | 1329 | if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730) || |
| 1330 | ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) | ||
| 1345 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); | 1331 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0); |
| 1346 | else | 1332 | else |
| 1347 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | 1333 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
| @@ -1351,8 +1337,6 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1351 | ATOM_TRANSMITTER_ACTION_POWER_ON); | 1337 | ATOM_TRANSMITTER_ACTION_POWER_ON); |
| 1352 | radeon_dig_connector->edp_on = true; | 1338 | radeon_dig_connector->edp_on = true; |
| 1353 | } | 1339 | } |
| 1354 | if (ASIC_IS_DCE4(rdev)) | ||
| 1355 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | ||
| 1356 | radeon_dp_link_train(encoder, connector); | 1340 | radeon_dp_link_train(encoder, connector); |
| 1357 | if (ASIC_IS_DCE4(rdev)) | 1341 | if (ASIC_IS_DCE4(rdev)) |
| 1358 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); | 1342 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); |
| @@ -1363,7 +1347,10 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) | |||
| 1363 | case DRM_MODE_DPMS_STANDBY: | 1347 | case DRM_MODE_DPMS_STANDBY: |
| 1364 | case DRM_MODE_DPMS_SUSPEND: | 1348 | case DRM_MODE_DPMS_SUSPEND: |
| 1365 | case DRM_MODE_DPMS_OFF: | 1349 | case DRM_MODE_DPMS_OFF: |
| 1366 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | 1350 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) |
| 1351 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | ||
| 1352 | else | ||
| 1353 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
| 1367 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { | 1354 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) { |
| 1368 | if (ASIC_IS_DCE4(rdev)) | 1355 | if (ASIC_IS_DCE4(rdev)) |
| 1369 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); | 1356 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0); |
| @@ -1810,7 +1797,21 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, | |||
| 1810 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1797 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
| 1811 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1798 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
| 1812 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | 1799 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
| 1813 | if (ASIC_IS_DCE4(rdev)) { | 1800 | if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { |
| 1801 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
| 1802 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
| 1803 | |||
| 1804 | if (!connector) | ||
| 1805 | dig->panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | ||
| 1806 | else | ||
| 1807 | dig->panel_mode = radeon_dp_get_panel_mode(encoder, connector); | ||
| 1808 | |||
| 1809 | /* setup and enable the encoder */ | ||
| 1810 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0); | ||
| 1811 | atombios_dig_encoder_setup(encoder, | ||
| 1812 | ATOM_ENCODER_CMD_SETUP_PANEL_MODE, | ||
| 1813 | dig->panel_mode); | ||
| 1814 | } else if (ASIC_IS_DCE4(rdev)) { | ||
| 1814 | /* disable the transmitter */ | 1815 | /* disable the transmitter */ |
| 1815 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); | 1816 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0); |
| 1816 | /* setup and enable the encoder */ | 1817 | /* setup and enable the encoder */ |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 636660fca8c2..9be353b894cc 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -1455,6 +1455,7 @@ int evergreen_cp_resume(struct radeon_device *rdev) | |||
| 1455 | #endif | 1455 | #endif |
| 1456 | WREG32(CP_RB_CNTL, tmp); | 1456 | WREG32(CP_RB_CNTL, tmp); |
| 1457 | WREG32(CP_SEM_WAIT_TIMER, 0x0); | 1457 | WREG32(CP_SEM_WAIT_TIMER, 0x0); |
| 1458 | WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); | ||
| 1458 | 1459 | ||
| 1459 | /* Set the write pointer delay */ | 1460 | /* Set the write pointer delay */ |
| 1460 | WREG32(CP_RB_WPTR_DELAY, 0); | 1461 | WREG32(CP_RB_WPTR_DELAY, 0); |
| @@ -3190,6 +3191,7 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
| 3190 | if (r) { | 3191 | if (r) { |
| 3191 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); | 3192 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
| 3192 | rdev->accel_working = false; | 3193 | rdev->accel_working = false; |
| 3194 | return r; | ||
| 3193 | } | 3195 | } |
| 3194 | 3196 | ||
| 3195 | r = r600_audio_init(rdev); | 3197 | r = r600_audio_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b502216d42af..74713d42df29 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -108,6 +108,7 @@ | |||
| 108 | #define CP_RB_WPTR_ADDR_HI 0xC11C | 108 | #define CP_RB_WPTR_ADDR_HI 0xC11C |
| 109 | #define CP_RB_WPTR_DELAY 0x8704 | 109 | #define CP_RB_WPTR_DELAY 0x8704 |
| 110 | #define CP_SEM_WAIT_TIMER 0x85BC | 110 | #define CP_SEM_WAIT_TIMER 0x85BC |
| 111 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 | ||
| 111 | #define CP_DEBUG 0xC1FC | 112 | #define CP_DEBUG 0xC1FC |
| 112 | 113 | ||
| 113 | 114 | ||
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 321137295400..db09065e68fd 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
| @@ -1219,6 +1219,7 @@ int cayman_cp_resume(struct radeon_device *rdev) | |||
| 1219 | RREG32(GRBM_SOFT_RESET); | 1219 | RREG32(GRBM_SOFT_RESET); |
| 1220 | 1220 | ||
| 1221 | WREG32(CP_SEM_WAIT_TIMER, 0x0); | 1221 | WREG32(CP_SEM_WAIT_TIMER, 0x0); |
| 1222 | WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); | ||
| 1222 | 1223 | ||
| 1223 | /* Set the write pointer delay */ | 1224 | /* Set the write pointer delay */ |
| 1224 | WREG32(CP_RB_WPTR_DELAY, 0); | 1225 | WREG32(CP_RB_WPTR_DELAY, 0); |
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index f9df2a645e79..9a7f3b6e02de 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
| @@ -222,6 +222,7 @@ | |||
| 222 | #define SCRATCH_UMSK 0x8540 | 222 | #define SCRATCH_UMSK 0x8540 |
| 223 | #define SCRATCH_ADDR 0x8544 | 223 | #define SCRATCH_ADDR 0x8544 |
| 224 | #define CP_SEM_WAIT_TIMER 0x85BC | 224 | #define CP_SEM_WAIT_TIMER 0x85BC |
| 225 | #define CP_SEM_INCOMPLETE_TIMER_CNTL 0x85C8 | ||
| 225 | #define CP_COHER_CNTL2 0x85E8 | 226 | #define CP_COHER_CNTL2 0x85E8 |
| 226 | #define CP_ME_CNTL 0x86D8 | 227 | #define CP_ME_CNTL 0x86D8 |
| 227 | #define CP_ME_HALT (1 << 28) | 228 | #define CP_ME_HALT (1 << 28) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bfd36ab643a6..18cd84fae99c 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -789,9 +789,7 @@ int r100_irq_process(struct radeon_device *rdev) | |||
| 789 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); | 789 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); |
| 790 | break; | 790 | break; |
| 791 | default: | 791 | default: |
| 792 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | 792 | WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); |
| 793 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
| 794 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
| 795 | break; | 793 | break; |
| 796 | } | 794 | } |
| 797 | } | 795 | } |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index d996f4381130..accc032c103f 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
| @@ -468,27 +468,42 @@ set_default_state(struct radeon_device *rdev) | |||
| 468 | radeon_ring_write(ring, sq_stack_resource_mgmt_2); | 468 | radeon_ring_write(ring, sq_stack_resource_mgmt_2); |
| 469 | } | 469 | } |
| 470 | 470 | ||
| 471 | #define I2F_MAX_BITS 15 | ||
| 472 | #define I2F_MAX_INPUT ((1 << I2F_MAX_BITS) - 1) | ||
| 473 | #define I2F_SHIFT (24 - I2F_MAX_BITS) | ||
| 474 | |||
| 475 | /* | ||
| 476 | * Converts unsigned integer into 32-bit IEEE floating point representation. | ||
| 477 | * Conversion is not universal and only works for the range from 0 | ||
| 478 | * to 2^I2F_MAX_BITS-1. Currently we only use it with inputs between | ||
| 479 | * 0 and 16384 (inclusive), so I2F_MAX_BITS=15 is enough. If necessary, | ||
| 480 | * I2F_MAX_BITS can be increased, but that will add to the loop iterations | ||
| 481 | * and slow us down. Conversion is done by shifting the input and counting | ||
| 482 | * down until the first 1 reaches bit position 23. The resulting counter | ||
| 483 | * and the shifted input are, respectively, the exponent and the fraction. | ||
| 484 | * The sign is always zero. | ||
| 485 | */ | ||
| 471 | static uint32_t i2f(uint32_t input) | 486 | static uint32_t i2f(uint32_t input) |
| 472 | { | 487 | { |
| 473 | u32 result, i, exponent, fraction; | 488 | u32 result, i, exponent, fraction; |
| 474 | 489 | ||
| 475 | if ((input & 0x3fff) == 0) | 490 | WARN_ON_ONCE(input > I2F_MAX_INPUT); |
| 476 | result = 0; /* 0 is a special case */ | 491 | |
| 492 | if ((input & I2F_MAX_INPUT) == 0) | ||
| 493 | result = 0; | ||
| 477 | else { | 494 | else { |
| 478 | exponent = 140; /* exponent biased by 127; */ | 495 | exponent = 126 + I2F_MAX_BITS; |
| 479 | fraction = (input & 0x3fff) << 10; /* cheat and only | 496 | fraction = (input & I2F_MAX_INPUT) << I2F_SHIFT; |
| 480 | handle numbers below 2^^15 */ | 497 | |
| 481 | for (i = 0; i < 14; i++) { | 498 | for (i = 0; i < I2F_MAX_BITS; i++) { |
| 482 | if (fraction & 0x800000) | 499 | if (fraction & 0x800000) |
| 483 | break; | 500 | break; |
| 484 | else { | 501 | else { |
| 485 | fraction = fraction << 1; /* keep | 502 | fraction = fraction << 1; |
| 486 | shifting left until top bit = 1 */ | ||
| 487 | exponent = exponent - 1; | 503 | exponent = exponent - 1; |
| 488 | } | 504 | } |
| 489 | } | 505 | } |
| 490 | result = exponent << 23 | (fraction & 0x7fffff); /* mask | 506 | result = exponent << 23 | (fraction & 0x7fffff); |
| 491 | off top bit; assumed 1 */ | ||
| 492 | } | 507 | } |
| 493 | return result; | 508 | return result; |
| 494 | } | 509 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 73e05cb85eca..1668ec1ee770 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -157,6 +157,47 @@ bool radeon_get_bios(struct radeon_device *rdev); | |||
| 157 | 157 | ||
| 158 | 158 | ||
| 159 | /* | 159 | /* |
| 160 | * Mutex which allows recursive locking from the same process. | ||
| 161 | */ | ||
| 162 | struct radeon_mutex { | ||
| 163 | struct mutex mutex; | ||
| 164 | struct task_struct *owner; | ||
| 165 | int level; | ||
| 166 | }; | ||
| 167 | |||
| 168 | static inline void radeon_mutex_init(struct radeon_mutex *mutex) | ||
| 169 | { | ||
| 170 | mutex_init(&mutex->mutex); | ||
| 171 | mutex->owner = NULL; | ||
| 172 | mutex->level = 0; | ||
| 173 | } | ||
| 174 | |||
| 175 | static inline void radeon_mutex_lock(struct radeon_mutex *mutex) | ||
| 176 | { | ||
| 177 | if (mutex_trylock(&mutex->mutex)) { | ||
| 178 | /* The mutex was unlocked before, so it's ours now */ | ||
| 179 | mutex->owner = current; | ||
| 180 | } else if (mutex->owner != current) { | ||
| 181 | /* Another process locked the mutex, take it */ | ||
| 182 | mutex_lock(&mutex->mutex); | ||
| 183 | mutex->owner = current; | ||
| 184 | } | ||
| 185 | /* Otherwise the mutex was already locked by this process */ | ||
| 186 | |||
| 187 | mutex->level++; | ||
| 188 | } | ||
| 189 | |||
| 190 | static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) | ||
| 191 | { | ||
| 192 | if (--mutex->level > 0) | ||
| 193 | return; | ||
| 194 | |||
| 195 | mutex->owner = NULL; | ||
| 196 | mutex_unlock(&mutex->mutex); | ||
| 197 | } | ||
| 198 | |||
| 199 | |||
| 200 | /* | ||
| 160 | * Dummy page | 201 | * Dummy page |
| 161 | */ | 202 | */ |
| 162 | struct radeon_dummy_page { | 203 | struct radeon_dummy_page { |
| @@ -598,7 +639,7 @@ struct radeon_ib { | |||
| 598 | * mutex protects scheduled_ibs, ready, alloc_bm | 639 | * mutex protects scheduled_ibs, ready, alloc_bm |
| 599 | */ | 640 | */ |
| 600 | struct radeon_ib_pool { | 641 | struct radeon_ib_pool { |
| 601 | struct mutex mutex; | 642 | struct radeon_mutex mutex; |
| 602 | struct radeon_sa_manager sa_manager; | 643 | struct radeon_sa_manager sa_manager; |
| 603 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; | 644 | struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; |
| 604 | bool ready; | 645 | bool ready; |
| @@ -1355,47 +1396,6 @@ struct r600_vram_scratch { | |||
| 1355 | 1396 | ||
| 1356 | 1397 | ||
| 1357 | /* | 1398 | /* |
| 1358 | * Mutex which allows recursive locking from the same process. | ||
| 1359 | */ | ||
| 1360 | struct radeon_mutex { | ||
| 1361 | struct mutex mutex; | ||
| 1362 | struct task_struct *owner; | ||
| 1363 | int level; | ||
| 1364 | }; | ||
| 1365 | |||
| 1366 | static inline void radeon_mutex_init(struct radeon_mutex *mutex) | ||
| 1367 | { | ||
| 1368 | mutex_init(&mutex->mutex); | ||
| 1369 | mutex->owner = NULL; | ||
| 1370 | mutex->level = 0; | ||
| 1371 | } | ||
| 1372 | |||
| 1373 | static inline void radeon_mutex_lock(struct radeon_mutex *mutex) | ||
| 1374 | { | ||
| 1375 | if (mutex_trylock(&mutex->mutex)) { | ||
| 1376 | /* The mutex was unlocked before, so it's ours now */ | ||
| 1377 | mutex->owner = current; | ||
| 1378 | } else if (mutex->owner != current) { | ||
| 1379 | /* Another process locked the mutex, take it */ | ||
| 1380 | mutex_lock(&mutex->mutex); | ||
| 1381 | mutex->owner = current; | ||
| 1382 | } | ||
| 1383 | /* Otherwise the mutex was already locked by this process */ | ||
| 1384 | |||
| 1385 | mutex->level++; | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | static inline void radeon_mutex_unlock(struct radeon_mutex *mutex) | ||
| 1389 | { | ||
| 1390 | if (--mutex->level > 0) | ||
| 1391 | return; | ||
| 1392 | |||
| 1393 | mutex->owner = NULL; | ||
| 1394 | mutex_unlock(&mutex->mutex); | ||
| 1395 | } | ||
| 1396 | |||
| 1397 | |||
| 1398 | /* | ||
| 1399 | * Core structure, functions and helpers. | 1399 | * Core structure, functions and helpers. |
| 1400 | */ | 1400 | */ |
| 1401 | typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t); | 1401 | typedef uint32_t (*radeon_rreg_t)(struct radeon_device*, uint32_t); |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5082d17d14dc..9e72daeeddc6 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -2931,6 +2931,20 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, | |||
| 2931 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; | 2931 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; |
| 2932 | } | 2932 | } |
| 2933 | } | 2933 | } |
| 2934 | if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) && | ||
| 2935 | (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) { | ||
| 2936 | if (connected) { | ||
| 2937 | DRM_DEBUG_KMS("DFP6 connected\n"); | ||
| 2938 | bios_0_scratch |= ATOM_S0_DFP6; | ||
| 2939 | bios_3_scratch |= ATOM_S3_DFP6_ACTIVE; | ||
| 2940 | bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6; | ||
| 2941 | } else { | ||
| 2942 | DRM_DEBUG_KMS("DFP6 disconnected\n"); | ||
| 2943 | bios_0_scratch &= ~ATOM_S0_DFP6; | ||
| 2944 | bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE; | ||
| 2945 | bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6; | ||
| 2946 | } | ||
| 2947 | } | ||
| 2934 | 2948 | ||
| 2935 | if (rdev->family >= CHIP_R600) { | 2949 | if (rdev->family >= CHIP_R600) { |
| 2936 | WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch); | 2950 | WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch); |
| @@ -2951,6 +2965,9 @@ radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) | |||
| 2951 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 2965 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 2952 | uint32_t bios_3_scratch; | 2966 | uint32_t bios_3_scratch; |
| 2953 | 2967 | ||
| 2968 | if (ASIC_IS_DCE4(rdev)) | ||
| 2969 | return; | ||
| 2970 | |||
| 2954 | if (rdev->family >= CHIP_R600) | 2971 | if (rdev->family >= CHIP_R600) |
| 2955 | bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); | 2972 | bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); |
| 2956 | else | 2973 | else |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index 9d95792bea3e..98724fcb0088 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
| @@ -58,7 +58,8 @@ static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios, | |||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | obj = (union acpi_object *)buffer.pointer; | 60 | obj = (union acpi_object *)buffer.pointer; |
| 61 | memcpy(bios+offset, obj->buffer.pointer, len); | 61 | memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length); |
| 62 | len = obj->buffer.length; | ||
| 62 | kfree(buffer.pointer); | 63 | kfree(buffer.pointer); |
| 63 | return len; | 64 | return len; |
| 64 | } | 65 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 229a20f10e2b..501f4881e5aa 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
| @@ -120,7 +120,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev) | |||
| 120 | ret = radeon_atrm_get_bios_chunk(rdev->bios, | 120 | ret = radeon_atrm_get_bios_chunk(rdev->bios, |
| 121 | (i * ATRM_BIOS_PAGE), | 121 | (i * ATRM_BIOS_PAGE), |
| 122 | ATRM_BIOS_PAGE); | 122 | ATRM_BIOS_PAGE); |
| 123 | if (ret <= 0) | 123 | if (ret < ATRM_BIOS_PAGE) |
| 124 | break; | 124 | break; |
| 125 | } | 125 | } |
| 126 | 126 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 0afb13bd8dca..49f7cb7e226b 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -720,7 +720,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 720 | /* mutex initialization are all done here so we | 720 | /* mutex initialization are all done here so we |
| 721 | * can recall function without having locking issues */ | 721 | * can recall function without having locking issues */ |
| 722 | radeon_mutex_init(&rdev->cs_mutex); | 722 | radeon_mutex_init(&rdev->cs_mutex); |
| 723 | mutex_init(&rdev->ib_pool.mutex); | 723 | radeon_mutex_init(&rdev->ib_pool.mutex); |
| 724 | for (i = 0; i < RADEON_NUM_RINGS; ++i) | 724 | for (i = 0; i < RADEON_NUM_RINGS; ++i) |
| 725 | mutex_init(&rdev->ring[i].mutex); | 725 | mutex_init(&rdev->ring[i].mutex); |
| 726 | mutex_init(&rdev->dc_hw_i2c_mutex); | 726 | mutex_init(&rdev->dc_hw_i2c_mutex); |
| @@ -883,6 +883,8 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) | |||
| 883 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) | 883 | if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
| 884 | return 0; | 884 | return 0; |
| 885 | 885 | ||
| 886 | drm_kms_helper_poll_disable(dev); | ||
| 887 | |||
| 886 | /* turn off display hw */ | 888 | /* turn off display hw */ |
| 887 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 889 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 888 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); | 890 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); |
| @@ -959,9 +961,11 @@ int radeon_resume_kms(struct drm_device *dev) | |||
| 959 | radeon_fbdev_set_suspend(rdev, 0); | 961 | radeon_fbdev_set_suspend(rdev, 0); |
| 960 | console_unlock(); | 962 | console_unlock(); |
| 961 | 963 | ||
| 962 | /* init dig PHYs */ | 964 | /* init dig PHYs, disp eng pll */ |
| 963 | if (rdev->is_atom_bios) | 965 | if (rdev->is_atom_bios) { |
| 964 | radeon_atom_encoder_init(rdev); | 966 | radeon_atom_encoder_init(rdev); |
| 967 | radeon_atom_dcpll_init(rdev); | ||
| 968 | } | ||
| 965 | /* reset hpd state */ | 969 | /* reset hpd state */ |
| 966 | radeon_hpd_init(rdev); | 970 | radeon_hpd_init(rdev); |
| 967 | /* blat the mode back in */ | 971 | /* blat the mode back in */ |
| @@ -970,6 +974,8 @@ int radeon_resume_kms(struct drm_device *dev) | |||
| 970 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 974 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 971 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | 975 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); |
| 972 | } | 976 | } |
| 977 | |||
| 978 | drm_kms_helper_poll_enable(dev); | ||
| 973 | return 0; | 979 | return 0; |
| 974 | } | 980 | } |
| 975 | 981 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index d3ffc18774a6..8c49fef1ce78 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -1305,9 +1305,11 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
| 1305 | return ret; | 1305 | return ret; |
| 1306 | } | 1306 | } |
| 1307 | 1307 | ||
| 1308 | /* init dig PHYs */ | 1308 | /* init dig PHYs, disp eng pll */ |
| 1309 | if (rdev->is_atom_bios) | 1309 | if (rdev->is_atom_bios) { |
| 1310 | radeon_atom_encoder_init(rdev); | 1310 | radeon_atom_encoder_init(rdev); |
| 1311 | radeon_atom_dcpll_init(rdev); | ||
| 1312 | } | ||
| 1311 | 1313 | ||
| 1312 | /* initialize hpd */ | 1314 | /* initialize hpd */ |
| 1313 | radeon_hpd_init(rdev); | 1315 | radeon_hpd_init(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 4b27efa4405b..9419c51bcf50 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
| @@ -202,6 +202,22 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
| 202 | return NULL; | 202 | return NULL; |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | struct drm_connector * | ||
| 206 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder) | ||
| 207 | { | ||
| 208 | struct drm_device *dev = encoder->dev; | ||
| 209 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
| 210 | struct drm_connector *connector; | ||
| 211 | struct radeon_connector *radeon_connector; | ||
| 212 | |||
| 213 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 214 | radeon_connector = to_radeon_connector(connector); | ||
| 215 | if (radeon_encoder->devices & radeon_connector->devices) | ||
| 216 | return connector; | ||
| 217 | } | ||
| 218 | return NULL; | ||
| 219 | } | ||
| 220 | |||
| 205 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) | 221 | struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder) |
| 206 | { | 222 | { |
| 207 | struct drm_device *dev = encoder->dev; | 223 | struct drm_device *dev = encoder->dev; |
| @@ -288,3 +304,64 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, | |||
| 288 | 304 | ||
| 289 | } | 305 | } |
| 290 | 306 | ||
| 307 | bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | ||
| 308 | u32 pixel_clock) | ||
| 309 | { | ||
| 310 | struct drm_device *dev = encoder->dev; | ||
| 311 | struct radeon_device *rdev = dev->dev_private; | ||
| 312 | struct drm_connector *connector; | ||
| 313 | struct radeon_connector *radeon_connector; | ||
| 314 | struct radeon_connector_atom_dig *dig_connector; | ||
| 315 | |||
| 316 | connector = radeon_get_connector_for_encoder(encoder); | ||
| 317 | /* if we don't have an active device yet, just use one of | ||
| 318 | * the connectors tied to the encoder. | ||
| 319 | */ | ||
| 320 | if (!connector) | ||
| 321 | connector = radeon_get_connector_for_encoder_init(encoder); | ||
| 322 | radeon_connector = to_radeon_connector(connector); | ||
| 323 | |||
| 324 | switch (connector->connector_type) { | ||
| 325 | case DRM_MODE_CONNECTOR_DVII: | ||
| 326 | case DRM_MODE_CONNECTOR_HDMIB: | ||
| 327 | if (radeon_connector->use_digital) { | ||
| 328 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | ||
| 329 | if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
| 330 | if (pixel_clock > 340000) | ||
| 331 | return true; | ||
| 332 | else | ||
| 333 | return false; | ||
| 334 | } else { | ||
| 335 | if (pixel_clock > 165000) | ||
| 336 | return true; | ||
| 337 | else | ||
| 338 | return false; | ||
| 339 | } | ||
| 340 | } else | ||
| 341 | return false; | ||
| 342 | case DRM_MODE_CONNECTOR_DVID: | ||
| 343 | case DRM_MODE_CONNECTOR_HDMIA: | ||
| 344 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
| 345 | dig_connector = radeon_connector->con_priv; | ||
| 346 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | ||
| 347 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | ||
| 348 | return false; | ||
| 349 | else { | ||
| 350 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | ||
| 351 | if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { | ||
| 352 | if (pixel_clock > 340000) | ||
| 353 | return true; | ||
| 354 | else | ||
| 355 | return false; | ||
| 356 | } else { | ||
| 357 | if (pixel_clock > 165000) | ||
| 358 | return true; | ||
| 359 | else | ||
| 360 | return false; | ||
| 361 | } | ||
| 362 | } | ||
| 363 | default: | ||
| 364 | return false; | ||
| 365 | } | ||
| 366 | } | ||
| 367 | |||
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 64ea3dd9e6ff..4bd36a354fbe 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
| @@ -364,8 +364,10 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring) | |||
| 364 | int not_processed = 0; | 364 | int not_processed = 0; |
| 365 | 365 | ||
| 366 | read_lock_irqsave(&rdev->fence_lock, irq_flags); | 366 | read_lock_irqsave(&rdev->fence_lock, irq_flags); |
| 367 | if (!rdev->fence_drv[ring].initialized) | 367 | if (!rdev->fence_drv[ring].initialized) { |
| 368 | read_unlock_irqrestore(&rdev->fence_lock, irq_flags); | ||
| 368 | return 0; | 369 | return 0; |
| 370 | } | ||
| 369 | 371 | ||
| 370 | if (!list_empty(&rdev->fence_drv[ring].emitted)) { | 372 | if (!list_empty(&rdev->fence_drv[ring].emitted)) { |
| 371 | struct list_head *ptr; | 373 | struct list_head *ptr; |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 7bb1b079f480..98a8ad680109 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
| @@ -897,6 +897,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
| 897 | i2c->rec = *rec; | 897 | i2c->rec = *rec; |
| 898 | i2c->adapter.owner = THIS_MODULE; | 898 | i2c->adapter.owner = THIS_MODULE; |
| 899 | i2c->adapter.class = I2C_CLASS_DDC; | 899 | i2c->adapter.class = I2C_CLASS_DDC; |
| 900 | i2c->adapter.dev.parent = &dev->pdev->dev; | ||
| 900 | i2c->dev = dev; | 901 | i2c->dev = dev; |
| 901 | i2c_set_adapdata(&i2c->adapter, i2c); | 902 | i2c_set_adapdata(&i2c->adapter, i2c); |
| 902 | if (rec->mm_i2c || | 903 | if (rec->mm_i2c || |
| @@ -957,6 +958,7 @@ struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, | |||
| 957 | i2c->rec = *rec; | 958 | i2c->rec = *rec; |
| 958 | i2c->adapter.owner = THIS_MODULE; | 959 | i2c->adapter.owner = THIS_MODULE; |
| 959 | i2c->adapter.class = I2C_CLASS_DDC; | 960 | i2c->adapter.class = I2C_CLASS_DDC; |
| 961 | i2c->adapter.dev.parent = &dev->pdev->dev; | ||
| 960 | i2c->dev = dev; | 962 | i2c->dev = dev; |
| 961 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), | 963 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
| 962 | "Radeon aux bus %s", name); | 964 | "Radeon aux bus %s", name); |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index be38921bf761..66d5fe1c8174 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
| @@ -138,6 +138,12 @@ static bool radeon_msi_ok(struct radeon_device *rdev) | |||
| 138 | /* Dell RS690 only seems to work with MSIs. */ | 138 | /* Dell RS690 only seems to work with MSIs. */ |
| 139 | if ((rdev->pdev->device == 0x791f) && | 139 | if ((rdev->pdev->device == 0x791f) && |
| 140 | (rdev->pdev->subsystem_vendor == 0x1028) && | 140 | (rdev->pdev->subsystem_vendor == 0x1028) && |
| 141 | (rdev->pdev->subsystem_device == 0x01fc)) | ||
| 142 | return true; | ||
| 143 | |||
| 144 | /* Dell RS690 only seems to work with MSIs. */ | ||
| 145 | if ((rdev->pdev->device == 0x791f) && | ||
| 146 | (rdev->pdev->subsystem_vendor == 0x1028) && | ||
| 141 | (rdev->pdev->subsystem_device == 0x01fd)) | 147 | (rdev->pdev->subsystem_device == 0x01fd)) |
| 142 | return true; | 148 | return true; |
| 143 | 149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 08ff857c8fd6..4330e3253573 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
| @@ -362,6 +362,7 @@ struct radeon_encoder_atom_dig { | |||
| 362 | struct backlight_device *bl_dev; | 362 | struct backlight_device *bl_dev; |
| 363 | int dpms_mode; | 363 | int dpms_mode; |
| 364 | uint8_t backlight_level; | 364 | uint8_t backlight_level; |
| 365 | int panel_mode; | ||
| 365 | }; | 366 | }; |
| 366 | 367 | ||
| 367 | struct radeon_encoder_atom_dac { | 368 | struct radeon_encoder_atom_dac { |
| @@ -466,6 +467,10 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev); | |||
| 466 | 467 | ||
| 467 | extern struct drm_connector * | 468 | extern struct drm_connector * |
| 468 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); | 469 | radeon_get_connector_for_encoder(struct drm_encoder *encoder); |
| 470 | extern struct drm_connector * | ||
| 471 | radeon_get_connector_for_encoder_init(struct drm_encoder *encoder); | ||
| 472 | extern bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | ||
| 473 | u32 pixel_clock); | ||
| 469 | 474 | ||
| 470 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); | 475 | extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); |
| 471 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); | 476 | extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); |
| @@ -482,8 +487,11 @@ extern void radeon_dp_link_train(struct drm_encoder *encoder, | |||
| 482 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); | 487 | extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector); |
| 483 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); | 488 | extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector); |
| 484 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); | 489 | extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); |
| 490 | extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | ||
| 491 | struct drm_connector *connector); | ||
| 485 | extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); | 492 | extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode); |
| 486 | extern void radeon_atom_encoder_init(struct radeon_device *rdev); | 493 | extern void radeon_atom_encoder_init(struct radeon_device *rdev); |
| 494 | extern void radeon_atom_dcpll_init(struct radeon_device *rdev); | ||
| 487 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, | 495 | extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, |
| 488 | int action, uint8_t lane_num, | 496 | int action, uint8_t lane_num, |
| 489 | uint8_t lane_set); | 497 | uint8_t lane_set); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index e8bc70933d1b..30a4c5014c8b 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
| @@ -109,12 +109,12 @@ int radeon_ib_get(struct radeon_device *rdev, int ring, | |||
| 109 | return r; | 109 | return r; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | mutex_lock(&rdev->ib_pool.mutex); | 112 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
| 113 | idx = rdev->ib_pool.head_id; | 113 | idx = rdev->ib_pool.head_id; |
| 114 | retry: | 114 | retry: |
| 115 | if (cretry > 5) { | 115 | if (cretry > 5) { |
| 116 | dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); | 116 | dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); |
| 117 | mutex_unlock(&rdev->ib_pool.mutex); | 117 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
| 118 | radeon_fence_unref(&fence); | 118 | radeon_fence_unref(&fence); |
| 119 | return -ENOMEM; | 119 | return -ENOMEM; |
| 120 | } | 120 | } |
| @@ -139,7 +139,7 @@ retry: | |||
| 139 | */ | 139 | */ |
| 140 | rdev->ib_pool.head_id = (1 + idx); | 140 | rdev->ib_pool.head_id = (1 + idx); |
| 141 | rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); | 141 | rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); |
| 142 | mutex_unlock(&rdev->ib_pool.mutex); | 142 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
| 143 | return 0; | 143 | return 0; |
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| @@ -158,7 +158,7 @@ retry: | |||
| 158 | } | 158 | } |
| 159 | idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); | 159 | idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); |
| 160 | } | 160 | } |
| 161 | mutex_unlock(&rdev->ib_pool.mutex); | 161 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
| 162 | radeon_fence_unref(&fence); | 162 | radeon_fence_unref(&fence); |
| 163 | return r; | 163 | return r; |
| 164 | } | 164 | } |
| @@ -171,12 +171,12 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) | |||
| 171 | if (tmp == NULL) { | 171 | if (tmp == NULL) { |
| 172 | return; | 172 | return; |
| 173 | } | 173 | } |
| 174 | mutex_lock(&rdev->ib_pool.mutex); | 174 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
| 175 | if (tmp->fence && !tmp->fence->emitted) { | 175 | if (tmp->fence && !tmp->fence->emitted) { |
| 176 | radeon_sa_bo_free(rdev, &tmp->sa_bo); | 176 | radeon_sa_bo_free(rdev, &tmp->sa_bo); |
| 177 | radeon_fence_unref(&tmp->fence); | 177 | radeon_fence_unref(&tmp->fence); |
| 178 | } | 178 | } |
| 179 | mutex_unlock(&rdev->ib_pool.mutex); | 179 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | 182 | int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) |
| @@ -204,22 +204,25 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) | |||
| 204 | 204 | ||
| 205 | int radeon_ib_pool_init(struct radeon_device *rdev) | 205 | int radeon_ib_pool_init(struct radeon_device *rdev) |
| 206 | { | 206 | { |
| 207 | struct radeon_sa_manager tmp; | ||
| 207 | int i, r; | 208 | int i, r; |
| 208 | 209 | ||
| 209 | mutex_lock(&rdev->ib_pool.mutex); | 210 | r = radeon_sa_bo_manager_init(rdev, &tmp, |
| 210 | if (rdev->ib_pool.ready) { | ||
| 211 | mutex_unlock(&rdev->ib_pool.mutex); | ||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | |||
| 215 | r = radeon_sa_bo_manager_init(rdev, &rdev->ib_pool.sa_manager, | ||
| 216 | RADEON_IB_POOL_SIZE*64*1024, | 211 | RADEON_IB_POOL_SIZE*64*1024, |
| 217 | RADEON_GEM_DOMAIN_GTT); | 212 | RADEON_GEM_DOMAIN_GTT); |
| 218 | if (r) { | 213 | if (r) { |
| 219 | mutex_unlock(&rdev->ib_pool.mutex); | ||
| 220 | return r; | 214 | return r; |
| 221 | } | 215 | } |
| 222 | 216 | ||
| 217 | radeon_mutex_lock(&rdev->ib_pool.mutex); | ||
| 218 | if (rdev->ib_pool.ready) { | ||
| 219 | radeon_mutex_unlock(&rdev->ib_pool.mutex); | ||
| 220 | radeon_sa_bo_manager_fini(rdev, &tmp); | ||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | rdev->ib_pool.sa_manager = tmp; | ||
| 225 | INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo); | ||
| 223 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { | 226 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
| 224 | rdev->ib_pool.ibs[i].fence = NULL; | 227 | rdev->ib_pool.ibs[i].fence = NULL; |
| 225 | rdev->ib_pool.ibs[i].idx = i; | 228 | rdev->ib_pool.ibs[i].idx = i; |
| @@ -236,7 +239,7 @@ int radeon_ib_pool_init(struct radeon_device *rdev) | |||
| 236 | if (radeon_debugfs_ring_init(rdev)) { | 239 | if (radeon_debugfs_ring_init(rdev)) { |
| 237 | DRM_ERROR("Failed to register debugfs file for rings !\n"); | 240 | DRM_ERROR("Failed to register debugfs file for rings !\n"); |
| 238 | } | 241 | } |
| 239 | mutex_unlock(&rdev->ib_pool.mutex); | 242 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
| 240 | return 0; | 243 | return 0; |
| 241 | } | 244 | } |
| 242 | 245 | ||
| @@ -244,7 +247,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
| 244 | { | 247 | { |
| 245 | unsigned i; | 248 | unsigned i; |
| 246 | 249 | ||
| 247 | mutex_lock(&rdev->ib_pool.mutex); | 250 | radeon_mutex_lock(&rdev->ib_pool.mutex); |
| 248 | if (rdev->ib_pool.ready) { | 251 | if (rdev->ib_pool.ready) { |
| 249 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { | 252 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
| 250 | radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); | 253 | radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); |
| @@ -253,7 +256,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
| 253 | radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); | 256 | radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); |
| 254 | rdev->ib_pool.ready = false; | 257 | rdev->ib_pool.ready = false; |
| 255 | } | 258 | } |
| 256 | mutex_unlock(&rdev->ib_pool.mutex); | 259 | radeon_mutex_unlock(&rdev->ib_pool.mutex); |
| 257 | } | 260 | } |
| 258 | 261 | ||
| 259 | int radeon_ib_pool_start(struct radeon_device *rdev) | 262 | int radeon_ib_pool_start(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index ec46eb45e34c..c05865e5521f 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -684,9 +684,7 @@ int rs600_irq_process(struct radeon_device *rdev) | |||
| 684 | WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); | 684 | WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); |
| 685 | break; | 685 | break; |
| 686 | default: | 686 | default: |
| 687 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; | 687 | WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); |
| 688 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); | ||
| 689 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); | ||
| 690 | break; | 688 | break; |
| 691 | } | 689 | } |
| 692 | } | 690 | } |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 06da063ece2e..573220cc5269 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
| @@ -40,7 +40,6 @@ static struct pci_device_id pciidlist[] = { | |||
| 40 | static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | 40 | static int sis_driver_load(struct drm_device *dev, unsigned long chipset) |
| 41 | { | 41 | { |
| 42 | drm_sis_private_t *dev_priv; | 42 | drm_sis_private_t *dev_priv; |
| 43 | int ret; | ||
| 44 | 43 | ||
| 45 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); | 44 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); |
| 46 | if (dev_priv == NULL) | 45 | if (dev_priv == NULL) |
| @@ -50,7 +49,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 50 | dev_priv->chipset = chipset; | 49 | dev_priv->chipset = chipset; |
| 51 | idr_init(&dev->object_name_idr); | 50 | idr_init(&dev->object_name_idr); |
| 52 | 51 | ||
| 53 | return ret; | 52 | return 0; |
| 54 | } | 53 | } |
| 55 | 54 | ||
| 56 | static int sis_driver_unload(struct drm_device *dev) | 55 | static int sis_driver_unload(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 2f0eab66ece6..7c3a57de8187 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -404,6 +404,9 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
| 404 | } | 404 | } |
| 405 | } | 405 | } |
| 406 | 406 | ||
| 407 | if (bdev->driver->move_notify) | ||
| 408 | bdev->driver->move_notify(bo, mem); | ||
| 409 | |||
| 407 | if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && | 410 | if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && |
| 408 | !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) | 411 | !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) |
| 409 | ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem); | 412 | ret = ttm_bo_move_ttm(bo, evict, no_wait_reserve, no_wait_gpu, mem); |
| @@ -413,11 +416,17 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
| 413 | else | 416 | else |
| 414 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem); | 417 | ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, mem); |
| 415 | 418 | ||
| 416 | if (ret) | 419 | if (ret) { |
| 417 | goto out_err; | 420 | if (bdev->driver->move_notify) { |
| 421 | struct ttm_mem_reg tmp_mem = *mem; | ||
| 422 | *mem = bo->mem; | ||
| 423 | bo->mem = tmp_mem; | ||
| 424 | bdev->driver->move_notify(bo, mem); | ||
| 425 | bo->mem = *mem; | ||
| 426 | } | ||
| 418 | 427 | ||
| 419 | if (bdev->driver->move_notify) | 428 | goto out_err; |
| 420 | bdev->driver->move_notify(bo, mem); | 429 | } |
| 421 | 430 | ||
| 422 | moved: | 431 | moved: |
| 423 | if (bo->evicted) { | 432 | if (bo->evicted) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 0af6ebdf205d..b66ef0e3cde1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -378,7 +378,7 @@ int vmw_framebuffer_create_handle(struct drm_framebuffer *fb, | |||
| 378 | unsigned int *handle) | 378 | unsigned int *handle) |
| 379 | { | 379 | { |
| 380 | if (handle) | 380 | if (handle) |
| 381 | handle = 0; | 381 | *handle = 0; |
| 382 | 382 | ||
| 383 | return 0; | 383 | return 0; |
| 384 | } | 384 | } |
