diff options
Diffstat (limited to 'drivers/gpu/drm')
31 files changed, 266 insertions, 160 deletions
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index f227f544aa36..6e1a1a20cf6b 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
| @@ -51,7 +51,7 @@ config DRM_EXYNOS_G2D | |||
| 51 | 51 | ||
| 52 | config DRM_EXYNOS_IPP | 52 | config DRM_EXYNOS_IPP |
| 53 | bool "Exynos DRM IPP" | 53 | bool "Exynos DRM IPP" |
| 54 | depends on DRM_EXYNOS && !ARCH_MULTIPLATFORM | 54 | depends on DRM_EXYNOS |
| 55 | help | 55 | help |
| 56 | Choose this option if you want to use IPP feature for DRM. | 56 | Choose this option if you want to use IPP feature for DRM. |
| 57 | 57 | ||
| @@ -69,6 +69,6 @@ config DRM_EXYNOS_ROTATOR | |||
| 69 | 69 | ||
| 70 | config DRM_EXYNOS_GSC | 70 | config DRM_EXYNOS_GSC |
| 71 | bool "Exynos DRM GSC" | 71 | bool "Exynos DRM GSC" |
| 72 | depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 | 72 | depends on DRM_EXYNOS_IPP && ARCH_EXYNOS5 && !ARCH_MULTIPLATFORM |
| 73 | help | 73 | help |
| 74 | Choose this option if you want to use Exynos GSC for DRM. | 74 | Choose this option if you want to use Exynos GSC for DRM. |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 9d096a0c5f8d..215131ab1dd2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
| @@ -171,22 +171,24 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) | |||
| 171 | file->driver_priv = file_priv; | 171 | file->driver_priv = file_priv; |
| 172 | 172 | ||
| 173 | ret = exynos_drm_subdrv_open(dev, file); | 173 | ret = exynos_drm_subdrv_open(dev, file); |
| 174 | if (ret) { | 174 | if (ret) |
| 175 | kfree(file_priv); | 175 | goto out; |
| 176 | file->driver_priv = NULL; | ||
| 177 | } | ||
| 178 | 176 | ||
| 179 | anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops, | 177 | anon_filp = anon_inode_getfile("exynos_gem", &exynos_drm_gem_fops, |
| 180 | NULL, 0); | 178 | NULL, 0); |
| 181 | if (IS_ERR(anon_filp)) { | 179 | if (IS_ERR(anon_filp)) { |
| 182 | kfree(file_priv); | 180 | ret = PTR_ERR(anon_filp); |
| 183 | return PTR_ERR(anon_filp); | 181 | goto out; |
| 184 | } | 182 | } |
| 185 | 183 | ||
| 186 | anon_filp->f_mode = FMODE_READ | FMODE_WRITE; | 184 | anon_filp->f_mode = FMODE_READ | FMODE_WRITE; |
| 187 | file_priv->anon_filp = anon_filp; | 185 | file_priv->anon_filp = anon_filp; |
| 188 | 186 | ||
| 189 | return ret; | 187 | return ret; |
| 188 | out: | ||
| 189 | kfree(file_priv); | ||
| 190 | file->driver_priv = NULL; | ||
| 191 | return ret; | ||
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | static void exynos_drm_preclose(struct drm_device *dev, | 194 | static void exynos_drm_preclose(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 380aec28840b..6c1885eedfdf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
| @@ -607,7 +607,7 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset) | |||
| 607 | reg_type = REG_TYPE_NONE; | 607 | reg_type = REG_TYPE_NONE; |
| 608 | DRM_ERROR("Unknown register offset![%d]\n", reg_offset); | 608 | DRM_ERROR("Unknown register offset![%d]\n", reg_offset); |
| 609 | break; | 609 | break; |
| 610 | }; | 610 | } |
| 611 | 611 | ||
| 612 | return reg_type; | 612 | return reg_type; |
| 613 | } | 613 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index d519a4e5fe40..09312b877470 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
| 18 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
| 19 | #include <plat/map-base.h> | ||
| 20 | 19 | ||
| 21 | #include <drm/drmP.h> | 20 | #include <drm/drmP.h> |
| 22 | #include <drm/exynos_drm.h> | 21 | #include <drm/exynos_drm.h> |
| @@ -826,7 +825,7 @@ static void ipp_put_event(struct drm_exynos_ipp_cmd_node *c_node, | |||
| 826 | DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); | 825 | DRM_DEBUG_KMS("count[%d]e[0x%x]\n", count++, (int)e); |
| 827 | 826 | ||
| 828 | /* | 827 | /* |
| 829 | * quf == NULL condition means all event deletion. | 828 | * qbuf == NULL condition means all event deletion. |
| 830 | * stop operations want to delete all event list. | 829 | * stop operations want to delete all event list. |
| 831 | * another case delete only same buf id. | 830 | * another case delete only same buf id. |
| 832 | */ | 831 | */ |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index a0e10aeb0e67..c021ddc1ffb4 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
| 35 | #include <linux/of.h> | 35 | #include <linux/of.h> |
| 36 | #include <linux/of_gpio.h> | 36 | #include <linux/of_gpio.h> |
| 37 | #include <linux/hdmi.h> | ||
| 37 | 38 | ||
| 38 | #include <drm/exynos_drm.h> | 39 | #include <drm/exynos_drm.h> |
| 39 | 40 | ||
| @@ -59,19 +60,6 @@ | |||
| 59 | #define HDMI_AUI_VERSION 0x01 | 60 | #define HDMI_AUI_VERSION 0x01 |
| 60 | #define HDMI_AUI_LENGTH 0x0A | 61 | #define HDMI_AUI_LENGTH 0x0A |
| 61 | 62 | ||
| 62 | /* HDMI infoframe to configure HDMI out packet header, AUI and AVI */ | ||
| 63 | enum HDMI_PACKET_TYPE { | ||
| 64 | /* refer to Table 5-8 Packet Type in HDMI specification v1.4a */ | ||
| 65 | /* InfoFrame packet type */ | ||
| 66 | HDMI_PACKET_TYPE_INFOFRAME = 0x80, | ||
| 67 | /* Vendor-Specific InfoFrame */ | ||
| 68 | HDMI_PACKET_TYPE_VSI = HDMI_PACKET_TYPE_INFOFRAME + 1, | ||
| 69 | /* Auxiliary Video information InfoFrame */ | ||
| 70 | HDMI_PACKET_TYPE_AVI = HDMI_PACKET_TYPE_INFOFRAME + 2, | ||
| 71 | /* Audio information InfoFrame */ | ||
| 72 | HDMI_PACKET_TYPE_AUI = HDMI_PACKET_TYPE_INFOFRAME + 4 | ||
| 73 | }; | ||
| 74 | |||
| 75 | enum hdmi_type { | 63 | enum hdmi_type { |
| 76 | HDMI_TYPE13, | 64 | HDMI_TYPE13, |
| 77 | HDMI_TYPE14, | 65 | HDMI_TYPE14, |
| @@ -379,12 +367,6 @@ static const struct hdmiphy_config hdmiphy_v14_configs[] = { | |||
| 379 | }, | 367 | }, |
| 380 | }; | 368 | }; |
| 381 | 369 | ||
| 382 | struct hdmi_infoframe { | ||
| 383 | enum HDMI_PACKET_TYPE type; | ||
| 384 | u8 ver; | ||
| 385 | u8 len; | ||
| 386 | }; | ||
| 387 | |||
| 388 | static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) | 370 | static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id) |
| 389 | { | 371 | { |
| 390 | return readl(hdata->regs + reg_id); | 372 | return readl(hdata->regs + reg_id); |
| @@ -682,7 +664,7 @@ static u8 hdmi_chksum(struct hdmi_context *hdata, | |||
| 682 | } | 664 | } |
| 683 | 665 | ||
| 684 | static void hdmi_reg_infoframe(struct hdmi_context *hdata, | 666 | static void hdmi_reg_infoframe(struct hdmi_context *hdata, |
| 685 | struct hdmi_infoframe *infoframe) | 667 | union hdmi_infoframe *infoframe) |
| 686 | { | 668 | { |
| 687 | u32 hdr_sum; | 669 | u32 hdr_sum; |
| 688 | u8 chksum; | 670 | u8 chksum; |
| @@ -700,13 +682,15 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata, | |||
| 700 | return; | 682 | return; |
| 701 | } | 683 | } |
| 702 | 684 | ||
| 703 | switch (infoframe->type) { | 685 | switch (infoframe->any.type) { |
| 704 | case HDMI_PACKET_TYPE_AVI: | 686 | case HDMI_INFOFRAME_TYPE_AVI: |
| 705 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); | 687 | hdmi_reg_writeb(hdata, HDMI_AVI_CON, HDMI_AVI_CON_EVERY_VSYNC); |
| 706 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->type); | 688 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER0, infoframe->any.type); |
| 707 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, infoframe->ver); | 689 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER1, |
| 708 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->len); | 690 | infoframe->any.version); |
| 709 | hdr_sum = infoframe->type + infoframe->ver + infoframe->len; | 691 | hdmi_reg_writeb(hdata, HDMI_AVI_HEADER2, infoframe->any.length); |
| 692 | hdr_sum = infoframe->any.type + infoframe->any.version + | ||
| 693 | infoframe->any.length; | ||
| 710 | 694 | ||
| 711 | /* Output format zero hardcoded ,RGB YBCR selection */ | 695 | /* Output format zero hardcoded ,RGB YBCR selection */ |
| 712 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | | 696 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 0 << 5 | |
| @@ -722,18 +706,20 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata, | |||
| 722 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); | 706 | hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(4), vic); |
| 723 | 707 | ||
| 724 | chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), | 708 | chksum = hdmi_chksum(hdata, HDMI_AVI_BYTE(1), |
| 725 | infoframe->len, hdr_sum); | 709 | infoframe->any.length, hdr_sum); |
| 726 | DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); | 710 | DRM_DEBUG_KMS("AVI checksum = 0x%x\n", chksum); |
| 727 | hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); | 711 | hdmi_reg_writeb(hdata, HDMI_AVI_CHECK_SUM, chksum); |
| 728 | break; | 712 | break; |
| 729 | case HDMI_PACKET_TYPE_AUI: | 713 | case HDMI_INFOFRAME_TYPE_AUDIO: |
| 730 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); | 714 | hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); |
| 731 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->type); | 715 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER0, infoframe->any.type); |
| 732 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, infoframe->ver); | 716 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER1, |
| 733 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->len); | 717 | infoframe->any.version); |
| 734 | hdr_sum = infoframe->type + infoframe->ver + infoframe->len; | 718 | hdmi_reg_writeb(hdata, HDMI_AUI_HEADER2, infoframe->any.length); |
| 719 | hdr_sum = infoframe->any.type + infoframe->any.version + | ||
| 720 | infoframe->any.length; | ||
| 735 | chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), | 721 | chksum = hdmi_chksum(hdata, HDMI_AUI_BYTE(1), |
| 736 | infoframe->len, hdr_sum); | 722 | infoframe->any.length, hdr_sum); |
| 737 | DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); | 723 | DRM_DEBUG_KMS("AUI checksum = 0x%x\n", chksum); |
| 738 | hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); | 724 | hdmi_reg_writeb(hdata, HDMI_AUI_CHECK_SUM, chksum); |
| 739 | break; | 725 | break; |
| @@ -985,7 +971,7 @@ static void hdmi_conf_reset(struct hdmi_context *hdata) | |||
| 985 | 971 | ||
| 986 | static void hdmi_conf_init(struct hdmi_context *hdata) | 972 | static void hdmi_conf_init(struct hdmi_context *hdata) |
| 987 | { | 973 | { |
| 988 | struct hdmi_infoframe infoframe; | 974 | union hdmi_infoframe infoframe; |
| 989 | 975 | ||
| 990 | /* disable HPD interrupts from HDMI IP block, use GPIO instead */ | 976 | /* disable HPD interrupts from HDMI IP block, use GPIO instead */ |
| 991 | hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | | 977 | hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL | |
| @@ -1021,14 +1007,14 @@ static void hdmi_conf_init(struct hdmi_context *hdata) | |||
| 1021 | hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); | 1007 | hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02); |
| 1022 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); | 1008 | hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04); |
| 1023 | } else { | 1009 | } else { |
| 1024 | infoframe.type = HDMI_PACKET_TYPE_AVI; | 1010 | infoframe.any.type = HDMI_INFOFRAME_TYPE_AVI; |
| 1025 | infoframe.ver = HDMI_AVI_VERSION; | 1011 | infoframe.any.version = HDMI_AVI_VERSION; |
| 1026 | infoframe.len = HDMI_AVI_LENGTH; | 1012 | infoframe.any.length = HDMI_AVI_LENGTH; |
| 1027 | hdmi_reg_infoframe(hdata, &infoframe); | 1013 | hdmi_reg_infoframe(hdata, &infoframe); |
| 1028 | 1014 | ||
| 1029 | infoframe.type = HDMI_PACKET_TYPE_AUI; | 1015 | infoframe.any.type = HDMI_INFOFRAME_TYPE_AUDIO; |
| 1030 | infoframe.ver = HDMI_AUI_VERSION; | 1016 | infoframe.any.version = HDMI_AUI_VERSION; |
| 1031 | infoframe.len = HDMI_AUI_LENGTH; | 1017 | infoframe.any.length = HDMI_AUI_LENGTH; |
| 1032 | hdmi_reg_infoframe(hdata, &infoframe); | 1018 | hdmi_reg_infoframe(hdata, &infoframe); |
| 1033 | 1019 | ||
| 1034 | /* enable AVI packet every vsync, fixes purple line problem */ | 1020 | /* enable AVI packet every vsync, fixes purple line problem */ |
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c index 400b0c4a10fb..fa18cf374470 100644 --- a/drivers/gpu/drm/i2c/tda998x_drv.c +++ b/drivers/gpu/drm/i2c/tda998x_drv.c | |||
| @@ -208,7 +208,7 @@ struct tda998x_priv { | |||
| 208 | # define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) | 208 | # define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) |
| 209 | # define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) | 209 | # define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) |
| 210 | #define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ | 210 | #define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ |
| 211 | # define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 3) << 0) | 211 | # define PLL_SERIAL_2_SRL_NOSC(x) ((x) << 0) |
| 212 | # define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) | 212 | # define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) |
| 213 | #define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ | 213 | #define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ |
| 214 | # define PLL_SERIAL_3_SRL_CCIR (1 << 0) | 214 | # define PLL_SERIAL_3_SRL_CCIR (1 << 0) |
| @@ -528,10 +528,10 @@ tda998x_write_aif(struct drm_encoder *encoder, struct tda998x_encoder_params *p) | |||
| 528 | { | 528 | { |
| 529 | uint8_t buf[PB(5) + 1]; | 529 | uint8_t buf[PB(5) + 1]; |
| 530 | 530 | ||
| 531 | memset(buf, 0, sizeof(buf)); | ||
| 531 | buf[HB(0)] = 0x84; | 532 | buf[HB(0)] = 0x84; |
| 532 | buf[HB(1)] = 0x01; | 533 | buf[HB(1)] = 0x01; |
| 533 | buf[HB(2)] = 10; | 534 | buf[HB(2)] = 10; |
| 534 | buf[PB(0)] = 0; | ||
| 535 | buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ | 535 | buf[PB(1)] = p->audio_frame[1] & 0x07; /* CC */ |
| 536 | buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ | 536 | buf[PB(2)] = p->audio_frame[2] & 0x1c; /* SF */ |
| 537 | buf[PB(4)] = p->audio_frame[4]; | 537 | buf[PB(4)] = p->audio_frame[4]; |
| @@ -824,6 +824,11 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, | |||
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | div = 148500 / mode->clock; | 826 | div = 148500 / mode->clock; |
| 827 | if (div != 0) { | ||
| 828 | div--; | ||
| 829 | if (div > 3) | ||
| 830 | div = 3; | ||
| 831 | } | ||
| 827 | 832 | ||
| 828 | /* mute the audio FIFO: */ | 833 | /* mute the audio FIFO: */ |
| 829 | reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); | 834 | reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); |
| @@ -913,7 +918,7 @@ tda998x_encoder_mode_set(struct drm_encoder *encoder, | |||
| 913 | 918 | ||
| 914 | if (priv->rev == TDA19988) { | 919 | if (priv->rev == TDA19988) { |
| 915 | /* let incoming pixels fill the active space (if any) */ | 920 | /* let incoming pixels fill the active space (if any) */ |
| 916 | reg_write(encoder, REG_ENABLE_SPACE, 0x01); | 921 | reg_write(encoder, REG_ENABLE_SPACE, 0x00); |
| 917 | } | 922 | } |
| 918 | 923 | ||
| 919 | /* must be last register set: */ | 924 | /* must be last register set: */ |
| @@ -1094,6 +1099,8 @@ tda998x_encoder_destroy(struct drm_encoder *encoder) | |||
| 1094 | { | 1099 | { |
| 1095 | struct tda998x_priv *priv = to_tda998x_priv(encoder); | 1100 | struct tda998x_priv *priv = to_tda998x_priv(encoder); |
| 1096 | drm_i2c_encoder_destroy(encoder); | 1101 | drm_i2c_encoder_destroy(encoder); |
| 1102 | if (priv->cec) | ||
| 1103 | i2c_unregister_device(priv->cec); | ||
| 1097 | kfree(priv); | 1104 | kfree(priv); |
| 1098 | } | 1105 | } |
| 1099 | 1106 | ||
| @@ -1142,8 +1149,10 @@ tda998x_encoder_init(struct i2c_client *client, | |||
| 1142 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); | 1149 | priv->vip_cntrl_1 = VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1); |
| 1143 | priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); | 1150 | priv->vip_cntrl_2 = VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5); |
| 1144 | 1151 | ||
| 1145 | priv->current_page = 0; | 1152 | priv->current_page = 0xff; |
| 1146 | priv->cec = i2c_new_dummy(client->adapter, 0x34); | 1153 | priv->cec = i2c_new_dummy(client->adapter, 0x34); |
| 1154 | if (!priv->cec) | ||
| 1155 | return -ENODEV; | ||
| 1147 | priv->dpms = DRM_MODE_DPMS_OFF; | 1156 | priv->dpms = DRM_MODE_DPMS_OFF; |
| 1148 | 1157 | ||
| 1149 | encoder_slave->slave_priv = priv; | 1158 | encoder_slave->slave_priv = priv; |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4a2bf8e3f739..df77e20e3c3d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -1831,6 +1831,14 @@ struct drm_i915_file_private { | |||
| 1831 | 1831 | ||
| 1832 | /* Early gen2 have a totally busted CS tlb and require pinned batches. */ | 1832 | /* Early gen2 have a totally busted CS tlb and require pinned batches. */ |
| 1833 | #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) | 1833 | #define HAS_BROKEN_CS_TLB(dev) (IS_I830(dev) || IS_845G(dev)) |
| 1834 | /* | ||
| 1835 | * dp aux and gmbus irq on gen4 seems to be able to generate legacy interrupts | ||
| 1836 | * even when in MSI mode. This results in spurious interrupt warnings if the | ||
| 1837 | * legacy irq no. is shared with another device. The kernel then disables that | ||
| 1838 | * interrupt source and so prevents the other device from working properly. | ||
| 1839 | */ | ||
| 1840 | #define HAS_AUX_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) | ||
| 1841 | #define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) | ||
| 1834 | 1842 | ||
| 1835 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte | 1843 | /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte |
| 1836 | * rows, which changed the alignment requirements and fence programming. | 1844 | * rows, which changed the alignment requirements and fence programming. |
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index d7fd2fd2f0a5..990cf8f43efd 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c | |||
| @@ -146,7 +146,10 @@ static void i915_error_vprintf(struct drm_i915_error_state_buf *e, | |||
| 146 | va_list tmp; | 146 | va_list tmp; |
| 147 | 147 | ||
| 148 | va_copy(tmp, args); | 148 | va_copy(tmp, args); |
| 149 | if (!__i915_error_seek(e, vsnprintf(NULL, 0, f, tmp))) | 149 | len = vsnprintf(NULL, 0, f, tmp); |
| 150 | va_end(tmp); | ||
| 151 | |||
| 152 | if (!__i915_error_seek(e, len)) | ||
| 150 | return; | 153 | return; |
| 151 | } | 154 | } |
| 152 | 155 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 17d8fcb1b6f7..9fec71175571 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -567,8 +567,7 @@ static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
| 567 | 567 | ||
| 568 | vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; | 568 | vbl_start = mode->crtc_vblank_start * mode->crtc_htotal; |
| 569 | } else { | 569 | } else { |
| 570 | enum transcoder cpu_transcoder = | 570 | enum transcoder cpu_transcoder = (enum transcoder) pipe; |
| 571 | intel_pipe_to_cpu_transcoder(dev_priv, pipe); | ||
| 572 | u32 htotal; | 571 | u32 htotal; |
| 573 | 572 | ||
| 574 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; | 573 | htotal = ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff) + 1; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 5ede4e8e290d..2f517b85b3f4 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -404,7 +404,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
| 404 | int i, ret, recv_bytes; | 404 | int i, ret, recv_bytes; |
| 405 | uint32_t status; | 405 | uint32_t status; |
| 406 | int try, precharge, clock = 0; | 406 | int try, precharge, clock = 0; |
| 407 | bool has_aux_irq = true; | 407 | bool has_aux_irq = HAS_AUX_IRQ(dev); |
| 408 | uint32_t timeout; | 408 | uint32_t timeout; |
| 409 | 409 | ||
| 410 | /* dp aux is extremely sensitive to irq latency, hence request the | 410 | /* dp aux is extremely sensitive to irq latency, hence request the |
| @@ -1869,10 +1869,12 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder) | |||
| 1869 | 1869 | ||
| 1870 | mutex_unlock(&dev_priv->dpio_lock); | 1870 | mutex_unlock(&dev_priv->dpio_lock); |
| 1871 | 1871 | ||
| 1872 | /* init power sequencer on this pipe and port */ | 1872 | if (is_edp(intel_dp)) { |
| 1873 | intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); | 1873 | /* init power sequencer on this pipe and port */ |
| 1874 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, | 1874 | intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); |
| 1875 | &power_seq); | 1875 | intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, |
| 1876 | &power_seq); | ||
| 1877 | } | ||
| 1876 | 1878 | ||
| 1877 | intel_enable_dp(encoder); | 1879 | intel_enable_dp(encoder); |
| 1878 | 1880 | ||
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index b1dc33f47899..d33b61d0dd33 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
| @@ -258,13 +258,6 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) | |||
| 258 | algo->data = bus; | 258 | algo->data = bus; |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | /* | ||
| 262 | * gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI | ||
| 263 | * mode. This results in spurious interrupt warnings if the legacy irq no. is | ||
| 264 | * shared with another device. The kernel then disables that interrupt source | ||
| 265 | * and so prevents the other device from working properly. | ||
| 266 | */ | ||
| 267 | #define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) | ||
| 268 | static int | 261 | static int |
| 269 | gmbus_wait_hw_status(struct drm_i915_private *dev_priv, | 262 | gmbus_wait_hw_status(struct drm_i915_private *dev_priv, |
| 270 | u32 gmbus2_status, | 263 | u32 gmbus2_status, |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 4e960ec7419f..acde2945eb8a 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
| @@ -226,6 +226,8 @@ struct opregion_asle { | |||
| 226 | #define ACPI_DIGITAL_OUTPUT (3<<8) | 226 | #define ACPI_DIGITAL_OUTPUT (3<<8) |
| 227 | #define ACPI_LVDS_OUTPUT (4<<8) | 227 | #define ACPI_LVDS_OUTPUT (4<<8) |
| 228 | 228 | ||
| 229 | #define MAX_DSLP 1500 | ||
| 230 | |||
| 229 | #ifdef CONFIG_ACPI | 231 | #ifdef CONFIG_ACPI |
| 230 | static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) | 232 | static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) |
| 231 | { | 233 | { |
| @@ -260,10 +262,11 @@ static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) | |||
| 260 | /* The spec says 2ms should be the default, but it's too small | 262 | /* The spec says 2ms should be the default, but it's too small |
| 261 | * for some machines. */ | 263 | * for some machines. */ |
| 262 | dslp = 50; | 264 | dslp = 50; |
| 263 | } else if (dslp > 500) { | 265 | } else if (dslp > MAX_DSLP) { |
| 264 | /* Hey bios, trust must be earned. */ | 266 | /* Hey bios, trust must be earned. */ |
| 265 | WARN_ONCE(1, "excessive driver sleep timeout (DSPL) %u\n", dslp); | 267 | DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, " |
| 266 | dslp = 500; | 268 | "using %u ms instead\n", dslp, MAX_DSLP); |
| 269 | dslp = MAX_DSLP; | ||
| 267 | } | 270 | } |
| 268 | 271 | ||
| 269 | /* The spec tells us to do this, but we are the only user... */ | 272 | /* The spec tells us to do this, but we are the only user... */ |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 1964f4f0d452..84c5b13b33c9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
| @@ -39,6 +39,7 @@ struct mdp4_crtc { | |||
| 39 | spinlock_t lock; | 39 | spinlock_t lock; |
| 40 | bool stale; | 40 | bool stale; |
| 41 | uint32_t width, height; | 41 | uint32_t width, height; |
| 42 | uint32_t x, y; | ||
| 42 | 43 | ||
| 43 | /* next cursor to scan-out: */ | 44 | /* next cursor to scan-out: */ |
| 44 | uint32_t next_iova; | 45 | uint32_t next_iova; |
| @@ -57,9 +58,16 @@ struct mdp4_crtc { | |||
| 57 | #define PENDING_FLIP 0x2 | 58 | #define PENDING_FLIP 0x2 |
| 58 | atomic_t pending; | 59 | atomic_t pending; |
| 59 | 60 | ||
| 60 | /* the fb that we currently hold a scanout ref to: */ | 61 | /* the fb that we logically (from PoV of KMS API) hold a ref |
| 62 | * to. Which we may not yet be scanning out (we may still | ||
| 63 | * be scanning out previous in case of page_flip while waiting | ||
| 64 | * for gpu rendering to complete: | ||
| 65 | */ | ||
| 61 | struct drm_framebuffer *fb; | 66 | struct drm_framebuffer *fb; |
| 62 | 67 | ||
| 68 | /* the fb that we currently hold a scanout ref to: */ | ||
| 69 | struct drm_framebuffer *scanout_fb; | ||
| 70 | |||
| 63 | /* for unref'ing framebuffers after scanout completes: */ | 71 | /* for unref'ing framebuffers after scanout completes: */ |
| 64 | struct drm_flip_work unref_fb_work; | 72 | struct drm_flip_work unref_fb_work; |
| 65 | 73 | ||
| @@ -77,24 +85,73 @@ static struct mdp4_kms *get_kms(struct drm_crtc *crtc) | |||
| 77 | return to_mdp4_kms(to_mdp_kms(priv->kms)); | 85 | return to_mdp4_kms(to_mdp_kms(priv->kms)); |
| 78 | } | 86 | } |
| 79 | 87 | ||
| 80 | static void update_fb(struct drm_crtc *crtc, bool async, | 88 | static void request_pending(struct drm_crtc *crtc, uint32_t pending) |
| 81 | struct drm_framebuffer *new_fb) | ||
| 82 | { | 89 | { |
| 83 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 90 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 84 | struct drm_framebuffer *old_fb = mdp4_crtc->fb; | ||
| 85 | 91 | ||
| 86 | if (old_fb) | 92 | atomic_or(pending, &mdp4_crtc->pending); |
| 87 | drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb); | 93 | mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank); |
| 94 | } | ||
| 95 | |||
| 96 | static void crtc_flush(struct drm_crtc *crtc) | ||
| 97 | { | ||
| 98 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
| 99 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
| 100 | uint32_t i, flush = 0; | ||
| 101 | |||
| 102 | for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { | ||
| 103 | struct drm_plane *plane = mdp4_crtc->planes[i]; | ||
| 104 | if (plane) { | ||
| 105 | enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); | ||
| 106 | flush |= pipe2flush(pipe_id); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | flush |= ovlp2flush(mdp4_crtc->ovlp); | ||
| 110 | |||
| 111 | DBG("%s: flush=%08x", mdp4_crtc->name, flush); | ||
| 112 | |||
| 113 | mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush); | ||
| 114 | } | ||
| 115 | |||
| 116 | static void update_fb(struct drm_crtc *crtc, struct drm_framebuffer *new_fb) | ||
| 117 | { | ||
| 118 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
| 119 | struct drm_framebuffer *old_fb = mdp4_crtc->fb; | ||
| 88 | 120 | ||
| 89 | /* grab reference to incoming scanout fb: */ | 121 | /* grab reference to incoming scanout fb: */ |
| 90 | drm_framebuffer_reference(new_fb); | 122 | drm_framebuffer_reference(new_fb); |
| 91 | mdp4_crtc->base.fb = new_fb; | 123 | mdp4_crtc->base.fb = new_fb; |
| 92 | mdp4_crtc->fb = new_fb; | 124 | mdp4_crtc->fb = new_fb; |
| 93 | 125 | ||
| 94 | if (!async) { | 126 | if (old_fb) |
| 95 | /* enable vblank to pick up the old_fb */ | 127 | drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb); |
| 96 | mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank); | 128 | } |
| 97 | } | 129 | |
| 130 | /* unlike update_fb(), take a ref to the new scanout fb *before* updating | ||
| 131 | * plane, then call this. Needed to ensure we don't unref the buffer that | ||
| 132 | * is actually still being scanned out. | ||
| 133 | * | ||
| 134 | * Note that this whole thing goes away with atomic.. since we can defer | ||
| 135 | * calling into driver until rendering is done. | ||
| 136 | */ | ||
| 137 | static void update_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb) | ||
| 138 | { | ||
| 139 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
| 140 | |||
| 141 | /* flush updates, to make sure hw is updated to new scanout fb, | ||
| 142 | * so that we can safely queue unref to current fb (ie. next | ||
| 143 | * vblank we know hw is done w/ previous scanout_fb). | ||
| 144 | */ | ||
| 145 | crtc_flush(crtc); | ||
| 146 | |||
| 147 | if (mdp4_crtc->scanout_fb) | ||
| 148 | drm_flip_work_queue(&mdp4_crtc->unref_fb_work, | ||
| 149 | mdp4_crtc->scanout_fb); | ||
| 150 | |||
| 151 | mdp4_crtc->scanout_fb = fb; | ||
| 152 | |||
| 153 | /* enable vblank to complete flip: */ | ||
| 154 | request_pending(crtc, PENDING_FLIP); | ||
| 98 | } | 155 | } |
| 99 | 156 | ||
| 100 | /* if file!=NULL, this is preclose potential cancel-flip path */ | 157 | /* if file!=NULL, this is preclose potential cancel-flip path */ |
| @@ -120,34 +177,6 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) | |||
| 120 | spin_unlock_irqrestore(&dev->event_lock, flags); | 177 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 121 | } | 178 | } |
| 122 | 179 | ||
| 123 | static void crtc_flush(struct drm_crtc *crtc) | ||
| 124 | { | ||
| 125 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
| 126 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
| 127 | uint32_t i, flush = 0; | ||
| 128 | |||
| 129 | for (i = 0; i < ARRAY_SIZE(mdp4_crtc->planes); i++) { | ||
| 130 | struct drm_plane *plane = mdp4_crtc->planes[i]; | ||
| 131 | if (plane) { | ||
| 132 | enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane); | ||
| 133 | flush |= pipe2flush(pipe_id); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | flush |= ovlp2flush(mdp4_crtc->ovlp); | ||
| 137 | |||
| 138 | DBG("%s: flush=%08x", mdp4_crtc->name, flush); | ||
| 139 | |||
| 140 | mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush); | ||
| 141 | } | ||
| 142 | |||
| 143 | static void request_pending(struct drm_crtc *crtc, uint32_t pending) | ||
| 144 | { | ||
| 145 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
| 146 | |||
| 147 | atomic_or(pending, &mdp4_crtc->pending); | ||
| 148 | mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank); | ||
| 149 | } | ||
| 150 | |||
| 151 | static void pageflip_cb(struct msm_fence_cb *cb) | 180 | static void pageflip_cb(struct msm_fence_cb *cb) |
| 152 | { | 181 | { |
| 153 | struct mdp4_crtc *mdp4_crtc = | 182 | struct mdp4_crtc *mdp4_crtc = |
| @@ -158,11 +187,9 @@ static void pageflip_cb(struct msm_fence_cb *cb) | |||
| 158 | if (!fb) | 187 | if (!fb) |
| 159 | return; | 188 | return; |
| 160 | 189 | ||
| 190 | drm_framebuffer_reference(fb); | ||
| 161 | mdp4_plane_set_scanout(mdp4_crtc->plane, fb); | 191 | mdp4_plane_set_scanout(mdp4_crtc->plane, fb); |
| 162 | crtc_flush(crtc); | 192 | update_scanout(crtc, fb); |
| 163 | |||
| 164 | /* enable vblank to complete flip: */ | ||
| 165 | request_pending(crtc, PENDING_FLIP); | ||
| 166 | } | 193 | } |
| 167 | 194 | ||
| 168 | static void unref_fb_worker(struct drm_flip_work *work, void *val) | 195 | static void unref_fb_worker(struct drm_flip_work *work, void *val) |
| @@ -320,6 +347,20 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, | |||
| 320 | mode->vsync_end, mode->vtotal, | 347 | mode->vsync_end, mode->vtotal, |
| 321 | mode->type, mode->flags); | 348 | mode->type, mode->flags); |
| 322 | 349 | ||
| 350 | /* grab extra ref for update_scanout() */ | ||
| 351 | drm_framebuffer_reference(crtc->fb); | ||
| 352 | |||
| 353 | ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb, | ||
| 354 | 0, 0, mode->hdisplay, mode->vdisplay, | ||
| 355 | x << 16, y << 16, | ||
| 356 | mode->hdisplay << 16, mode->vdisplay << 16); | ||
| 357 | if (ret) { | ||
| 358 | drm_framebuffer_unreference(crtc->fb); | ||
| 359 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", | ||
| 360 | mdp4_crtc->name, ret); | ||
| 361 | return ret; | ||
| 362 | } | ||
| 363 | |||
| 323 | mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma), | 364 | mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma), |
| 324 | MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) | | 365 | MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) | |
| 325 | MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay)); | 366 | MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay)); |
| @@ -341,24 +382,15 @@ static int mdp4_crtc_mode_set(struct drm_crtc *crtc, | |||
| 341 | 382 | ||
| 342 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); | 383 | mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1); |
| 343 | 384 | ||
| 344 | update_fb(crtc, false, crtc->fb); | ||
| 345 | |||
| 346 | ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb, | ||
| 347 | 0, 0, mode->hdisplay, mode->vdisplay, | ||
| 348 | x << 16, y << 16, | ||
| 349 | mode->hdisplay << 16, mode->vdisplay << 16); | ||
| 350 | if (ret) { | ||
| 351 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", | ||
| 352 | mdp4_crtc->name, ret); | ||
| 353 | return ret; | ||
| 354 | } | ||
| 355 | |||
| 356 | if (dma == DMA_E) { | 385 | if (dma == DMA_E) { |
| 357 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000); | 386 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000); |
| 358 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000); | 387 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000); |
| 359 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); | 388 | mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000); |
| 360 | } | 389 | } |
| 361 | 390 | ||
| 391 | update_fb(crtc, crtc->fb); | ||
| 392 | update_scanout(crtc, crtc->fb); | ||
| 393 | |||
| 362 | return 0; | 394 | return 0; |
| 363 | } | 395 | } |
| 364 | 396 | ||
| @@ -385,13 +417,24 @@ static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 385 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 417 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 386 | struct drm_plane *plane = mdp4_crtc->plane; | 418 | struct drm_plane *plane = mdp4_crtc->plane; |
| 387 | struct drm_display_mode *mode = &crtc->mode; | 419 | struct drm_display_mode *mode = &crtc->mode; |
| 420 | int ret; | ||
| 388 | 421 | ||
| 389 | update_fb(crtc, false, crtc->fb); | 422 | /* grab extra ref for update_scanout() */ |
| 423 | drm_framebuffer_reference(crtc->fb); | ||
| 390 | 424 | ||
| 391 | return mdp4_plane_mode_set(plane, crtc, crtc->fb, | 425 | ret = mdp4_plane_mode_set(plane, crtc, crtc->fb, |
| 392 | 0, 0, mode->hdisplay, mode->vdisplay, | 426 | 0, 0, mode->hdisplay, mode->vdisplay, |
| 393 | x << 16, y << 16, | 427 | x << 16, y << 16, |
| 394 | mode->hdisplay << 16, mode->vdisplay << 16); | 428 | mode->hdisplay << 16, mode->vdisplay << 16); |
| 429 | if (ret) { | ||
| 430 | drm_framebuffer_unreference(crtc->fb); | ||
| 431 | return ret; | ||
| 432 | } | ||
| 433 | |||
| 434 | update_fb(crtc, crtc->fb); | ||
| 435 | update_scanout(crtc, crtc->fb); | ||
| 436 | |||
| 437 | return 0; | ||
| 395 | } | 438 | } |
| 396 | 439 | ||
| 397 | static void mdp4_crtc_load_lut(struct drm_crtc *crtc) | 440 | static void mdp4_crtc_load_lut(struct drm_crtc *crtc) |
| @@ -419,7 +462,7 @@ static int mdp4_crtc_page_flip(struct drm_crtc *crtc, | |||
| 419 | mdp4_crtc->event = event; | 462 | mdp4_crtc->event = event; |
| 420 | spin_unlock_irqrestore(&dev->event_lock, flags); | 463 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 421 | 464 | ||
| 422 | update_fb(crtc, true, new_fb); | 465 | update_fb(crtc, new_fb); |
| 423 | 466 | ||
| 424 | return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb); | 467 | return msm_gem_queue_inactive_cb(obj, &mdp4_crtc->pageflip_cb); |
| 425 | } | 468 | } |
| @@ -442,12 +485,12 @@ static int mdp4_crtc_set_property(struct drm_crtc *crtc, | |||
| 442 | static void update_cursor(struct drm_crtc *crtc) | 485 | static void update_cursor(struct drm_crtc *crtc) |
| 443 | { | 486 | { |
| 444 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 487 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 488 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
| 445 | enum mdp4_dma dma = mdp4_crtc->dma; | 489 | enum mdp4_dma dma = mdp4_crtc->dma; |
| 446 | unsigned long flags; | 490 | unsigned long flags; |
| 447 | 491 | ||
| 448 | spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); | 492 | spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); |
| 449 | if (mdp4_crtc->cursor.stale) { | 493 | if (mdp4_crtc->cursor.stale) { |
| 450 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
| 451 | struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo; | 494 | struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo; |
| 452 | struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo; | 495 | struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo; |
| 453 | uint32_t iova = mdp4_crtc->cursor.next_iova; | 496 | uint32_t iova = mdp4_crtc->cursor.next_iova; |
| @@ -479,6 +522,11 @@ static void update_cursor(struct drm_crtc *crtc) | |||
| 479 | mdp4_crtc->cursor.scanout_bo = next_bo; | 522 | mdp4_crtc->cursor.scanout_bo = next_bo; |
| 480 | mdp4_crtc->cursor.stale = false; | 523 | mdp4_crtc->cursor.stale = false; |
| 481 | } | 524 | } |
| 525 | |||
| 526 | mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), | ||
| 527 | MDP4_DMA_CURSOR_POS_X(mdp4_crtc->cursor.x) | | ||
| 528 | MDP4_DMA_CURSOR_POS_Y(mdp4_crtc->cursor.y)); | ||
| 529 | |||
| 482 | spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); | 530 | spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); |
| 483 | } | 531 | } |
| 484 | 532 | ||
| @@ -530,6 +578,7 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 530 | drm_gem_object_unreference_unlocked(old_bo); | 578 | drm_gem_object_unreference_unlocked(old_bo); |
| 531 | } | 579 | } |
| 532 | 580 | ||
| 581 | crtc_flush(crtc); | ||
| 533 | request_pending(crtc, PENDING_CURSOR); | 582 | request_pending(crtc, PENDING_CURSOR); |
| 534 | 583 | ||
| 535 | return 0; | 584 | return 0; |
| @@ -542,12 +591,15 @@ fail: | |||
| 542 | static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | 591 | static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) |
| 543 | { | 592 | { |
| 544 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 593 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 545 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | 594 | unsigned long flags; |
| 546 | enum mdp4_dma dma = mdp4_crtc->dma; | ||
| 547 | 595 | ||
| 548 | mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma), | 596 | spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags); |
| 549 | MDP4_DMA_CURSOR_POS_X(x) | | 597 | mdp4_crtc->cursor.x = x; |
| 550 | MDP4_DMA_CURSOR_POS_Y(y)); | 598 | mdp4_crtc->cursor.y = y; |
| 599 | spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags); | ||
| 600 | |||
| 601 | crtc_flush(crtc); | ||
| 602 | request_pending(crtc, PENDING_CURSOR); | ||
| 551 | 603 | ||
| 552 | return 0; | 604 | return 0; |
| 553 | } | 605 | } |
| @@ -713,6 +765,7 @@ struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, | |||
| 713 | crtc = &mdp4_crtc->base; | 765 | crtc = &mdp4_crtc->base; |
| 714 | 766 | ||
| 715 | mdp4_crtc->plane = plane; | 767 | mdp4_crtc->plane = plane; |
| 768 | mdp4_crtc->id = id; | ||
| 716 | 769 | ||
| 717 | mdp4_crtc->ovlp = ovlp_id; | 770 | mdp4_crtc->ovlp = ovlp_id; |
| 718 | mdp4_crtc->dma = dma_id; | 771 | mdp4_crtc->dma = dma_id; |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 2406027200ec..1e893dd13859 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | |||
| @@ -170,8 +170,8 @@ int mdp4_plane_mode_set(struct drm_plane *plane, | |||
| 170 | MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h)); | 170 | MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h)); |
| 171 | 171 | ||
| 172 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe), | 172 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe), |
| 173 | MDP4_PIPE_SRC_XY_X(crtc_x) | | 173 | MDP4_PIPE_DST_XY_X(crtc_x) | |
| 174 | MDP4_PIPE_SRC_XY_Y(crtc_y)); | 174 | MDP4_PIPE_DST_XY_Y(crtc_y)); |
| 175 | 175 | ||
| 176 | mdp4_plane_set_scanout(plane, fb); | 176 | mdp4_plane_set_scanout(plane, fb); |
| 177 | 177 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 71a3b2345eb3..f2794021f086 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | |||
| @@ -296,6 +296,7 @@ static int mdp5_crtc_mode_set(struct drm_crtc *crtc, | |||
| 296 | x << 16, y << 16, | 296 | x << 16, y << 16, |
| 297 | mode->hdisplay << 16, mode->vdisplay << 16); | 297 | mode->hdisplay << 16, mode->vdisplay << 16); |
| 298 | if (ret) { | 298 | if (ret) { |
| 299 | drm_framebuffer_unreference(crtc->fb); | ||
| 299 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", | 300 | dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n", |
| 300 | mdp5_crtc->name, ret); | 301 | mdp5_crtc->name, ret); |
| 301 | return ret; | 302 | return ret; |
| @@ -343,11 +344,15 @@ static int mdp5_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 343 | 0, 0, mode->hdisplay, mode->vdisplay, | 344 | 0, 0, mode->hdisplay, mode->vdisplay, |
| 344 | x << 16, y << 16, | 345 | x << 16, y << 16, |
| 345 | mode->hdisplay << 16, mode->vdisplay << 16); | 346 | mode->hdisplay << 16, mode->vdisplay << 16); |
| 347 | if (ret) { | ||
| 348 | drm_framebuffer_unreference(crtc->fb); | ||
| 349 | return ret; | ||
| 350 | } | ||
| 346 | 351 | ||
| 347 | update_fb(crtc, crtc->fb); | 352 | update_fb(crtc, crtc->fb); |
| 348 | update_scanout(crtc, crtc->fb); | 353 | update_scanout(crtc, crtc->fb); |
| 349 | 354 | ||
| 350 | return ret; | 355 | return 0; |
| 351 | } | 356 | } |
| 352 | 357 | ||
| 353 | static void mdp5_crtc_load_lut(struct drm_crtc *crtc) | 358 | static void mdp5_crtc_load_lut(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index d8d60c969ac7..3da8264d3039 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c | |||
| @@ -644,7 +644,7 @@ struct drm_gem_object *msm_gem_new(struct drm_device *dev, | |||
| 644 | 644 | ||
| 645 | fail: | 645 | fail: |
| 646 | if (obj) | 646 | if (obj) |
| 647 | drm_gem_object_unreference_unlocked(obj); | 647 | drm_gem_object_unreference(obj); |
| 648 | 648 | ||
| 649 | return ERR_PTR(ret); | 649 | return ERR_PTR(ret); |
| 650 | } | 650 | } |
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 5281d4bc37f7..5423e914e491 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c | |||
| @@ -163,7 +163,7 @@ retry: | |||
| 163 | 163 | ||
| 164 | 164 | ||
| 165 | /* if locking succeeded, pin bo: */ | 165 | /* if locking succeeded, pin bo: */ |
| 166 | ret = msm_gem_get_iova(&msm_obj->base, | 166 | ret = msm_gem_get_iova_locked(&msm_obj->base, |
| 167 | submit->gpu->id, &iova); | 167 | submit->gpu->id, &iova); |
| 168 | 168 | ||
| 169 | /* this would break the logic in the fail path.. there is no | 169 | /* this would break the logic in the fail path.. there is no |
| @@ -247,7 +247,7 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob | |||
| 247 | /* For now, just map the entire thing. Eventually we probably | 247 | /* For now, just map the entire thing. Eventually we probably |
| 248 | * to do it page-by-page, w/ kmap() if not vmap()d.. | 248 | * to do it page-by-page, w/ kmap() if not vmap()d.. |
| 249 | */ | 249 | */ |
| 250 | ptr = msm_gem_vaddr(&obj->base); | 250 | ptr = msm_gem_vaddr_locked(&obj->base); |
| 251 | 251 | ||
| 252 | if (IS_ERR(ptr)) { | 252 | if (IS_ERR(ptr)) { |
| 253 | ret = PTR_ERR(ptr); | 253 | ret = PTR_ERR(ptr); |
| @@ -307,14 +307,12 @@ static void submit_cleanup(struct msm_gem_submit *submit, bool fail) | |||
| 307 | { | 307 | { |
| 308 | unsigned i; | 308 | unsigned i; |
| 309 | 309 | ||
| 310 | mutex_lock(&submit->dev->struct_mutex); | ||
| 311 | for (i = 0; i < submit->nr_bos; i++) { | 310 | for (i = 0; i < submit->nr_bos; i++) { |
| 312 | struct msm_gem_object *msm_obj = submit->bos[i].obj; | 311 | struct msm_gem_object *msm_obj = submit->bos[i].obj; |
| 313 | submit_unlock_unpin_bo(submit, i); | 312 | submit_unlock_unpin_bo(submit, i); |
| 314 | list_del_init(&msm_obj->submit_entry); | 313 | list_del_init(&msm_obj->submit_entry); |
| 315 | drm_gem_object_unreference(&msm_obj->base); | 314 | drm_gem_object_unreference(&msm_obj->base); |
| 316 | } | 315 | } |
| 317 | mutex_unlock(&submit->dev->struct_mutex); | ||
| 318 | 316 | ||
| 319 | ww_acquire_fini(&submit->ticket); | 317 | ww_acquire_fini(&submit->ticket); |
| 320 | kfree(submit); | 318 | kfree(submit); |
| @@ -342,6 +340,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
| 342 | if (args->nr_cmds > MAX_CMDS) | 340 | if (args->nr_cmds > MAX_CMDS) |
| 343 | return -EINVAL; | 341 | return -EINVAL; |
| 344 | 342 | ||
| 343 | mutex_lock(&dev->struct_mutex); | ||
| 344 | |||
| 345 | submit = submit_create(dev, gpu, args->nr_bos); | 345 | submit = submit_create(dev, gpu, args->nr_bos); |
| 346 | if (!submit) { | 346 | if (!submit) { |
| 347 | ret = -ENOMEM; | 347 | ret = -ENOMEM; |
| @@ -410,5 +410,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, | |||
| 410 | out: | 410 | out: |
| 411 | if (submit) | 411 | if (submit) |
| 412 | submit_cleanup(submit, !!ret); | 412 | submit_cleanup(submit, !!ret); |
| 413 | mutex_unlock(&dev->struct_mutex); | ||
| 413 | return ret; | 414 | return ret; |
| 414 | } | 415 | } |
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 4ebce8be489d..0cfe3f426ee4 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c | |||
| @@ -298,8 +298,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, | |||
| 298 | struct msm_drm_private *priv = dev->dev_private; | 298 | struct msm_drm_private *priv = dev->dev_private; |
| 299 | int i, ret; | 299 | int i, ret; |
| 300 | 300 | ||
| 301 | mutex_lock(&dev->struct_mutex); | ||
| 302 | |||
| 303 | submit->fence = ++priv->next_fence; | 301 | submit->fence = ++priv->next_fence; |
| 304 | 302 | ||
| 305 | gpu->submitted_fence = submit->fence; | 303 | gpu->submitted_fence = submit->fence; |
| @@ -331,7 +329,6 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, | |||
| 331 | msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence); | 329 | msm_gem_move_to_active(&msm_obj->base, gpu, true, submit->fence); |
| 332 | } | 330 | } |
| 333 | hangcheck_timer_reset(gpu); | 331 | hangcheck_timer_reset(gpu); |
| 334 | mutex_unlock(&dev->struct_mutex); | ||
| 335 | 332 | ||
| 336 | return ret; | 333 | return ret; |
| 337 | } | 334 | } |
diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 0fbd36f3d4e9..ea103ccdf4bd 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include "cypress_dpm.h" | 29 | #include "cypress_dpm.h" |
| 30 | #include "btc_dpm.h" | 30 | #include "btc_dpm.h" |
| 31 | #include "atom.h" | 31 | #include "atom.h" |
| 32 | #include <linux/seq_file.h> | ||
| 32 | 33 | ||
| 33 | #define MC_CG_ARB_FREQ_F0 0x0a | 34 | #define MC_CG_ARB_FREQ_F0 0x0a |
| 34 | #define MC_CG_ARB_FREQ_F1 0x0b | 35 | #define MC_CG_ARB_FREQ_F1 0x0b |
| @@ -2756,6 +2757,37 @@ void btc_dpm_fini(struct radeon_device *rdev) | |||
| 2756 | r600_free_extended_power_table(rdev); | 2757 | r600_free_extended_power_table(rdev); |
| 2757 | } | 2758 | } |
| 2758 | 2759 | ||
| 2760 | void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | ||
| 2761 | struct seq_file *m) | ||
| 2762 | { | ||
| 2763 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | ||
| 2764 | struct radeon_ps *rps = &eg_pi->current_rps; | ||
| 2765 | struct rv7xx_ps *ps = rv770_get_ps(rps); | ||
| 2766 | struct rv7xx_pl *pl; | ||
| 2767 | u32 current_index = | ||
| 2768 | (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >> | ||
| 2769 | CURRENT_PROFILE_INDEX_SHIFT; | ||
| 2770 | |||
| 2771 | if (current_index > 2) { | ||
| 2772 | seq_printf(m, "invalid dpm profile %d\n", current_index); | ||
| 2773 | } else { | ||
| 2774 | if (current_index == 0) | ||
| 2775 | pl = &ps->low; | ||
| 2776 | else if (current_index == 1) | ||
| 2777 | pl = &ps->medium; | ||
| 2778 | else /* current_index == 2 */ | ||
| 2779 | pl = &ps->high; | ||
| 2780 | seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk); | ||
| 2781 | if (rdev->family >= CHIP_CEDAR) { | ||
| 2782 | seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u\n", | ||
| 2783 | current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci); | ||
| 2784 | } else { | ||
| 2785 | seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u\n", | ||
| 2786 | current_index, pl->sclk, pl->mclk, pl->vddc); | ||
| 2787 | } | ||
| 2788 | } | ||
| 2789 | } | ||
| 2790 | |||
| 2759 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low) | 2791 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low) |
| 2760 | { | 2792 | { |
| 2761 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 2793 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
diff --git a/drivers/gpu/drm/radeon/btcd.h b/drivers/gpu/drm/radeon/btcd.h index 29e32de7e025..9c65be2d55a9 100644 --- a/drivers/gpu/drm/radeon/btcd.h +++ b/drivers/gpu/drm/radeon/btcd.h | |||
| @@ -44,6 +44,10 @@ | |||
| 44 | # define DYN_SPREAD_SPECTRUM_EN (1 << 23) | 44 | # define DYN_SPREAD_SPECTRUM_EN (1 << 23) |
| 45 | # define AC_DC_SW (1 << 24) | 45 | # define AC_DC_SW (1 << 24) |
| 46 | 46 | ||
| 47 | #define TARGET_AND_CURRENT_PROFILE_INDEX 0x66c | ||
| 48 | # define CURRENT_PROFILE_INDEX_MASK (0xf << 4) | ||
| 49 | # define CURRENT_PROFILE_INDEX_SHIFT 4 | ||
| 50 | |||
| 47 | #define CG_BIF_REQ_AND_RSP 0x7f4 | 51 | #define CG_BIF_REQ_AND_RSP 0x7f4 |
| 48 | #define CG_CLIENT_REQ(x) ((x) << 0) | 52 | #define CG_CLIENT_REQ(x) ((x) << 0) |
| 49 | #define CG_CLIENT_REQ_MASK (0xff << 0) | 53 | #define CG_CLIENT_REQ_MASK (0xff << 0) |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index b6e01d5d2cce..351db361239d 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
| @@ -1223,7 +1223,7 @@ int kv_dpm_enable(struct radeon_device *rdev) | |||
| 1223 | 1223 | ||
| 1224 | int kv_dpm_late_enable(struct radeon_device *rdev) | 1224 | int kv_dpm_late_enable(struct radeon_device *rdev) |
| 1225 | { | 1225 | { |
| 1226 | int ret; | 1226 | int ret = 0; |
| 1227 | 1227 | ||
| 1228 | if (rdev->irq.installed && | 1228 | if (rdev->irq.installed && |
| 1229 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { | 1229 | r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) { |
diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index c351226ecb31..1217fbcbdcca 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c | |||
| @@ -3945,7 +3945,6 @@ static void ni_parse_pplib_clock_info(struct radeon_device *rdev, | |||
| 3945 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | 3945 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
| 3946 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 3946 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
| 3947 | struct ni_ps *ps = ni_get_ps(rps); | 3947 | struct ni_ps *ps = ni_get_ps(rps); |
| 3948 | u16 vddc; | ||
| 3949 | struct rv7xx_pl *pl = &ps->performance_levels[index]; | 3948 | struct rv7xx_pl *pl = &ps->performance_levels[index]; |
| 3950 | 3949 | ||
| 3951 | ps->performance_level_count = index + 1; | 3950 | ps->performance_level_count = index + 1; |
| @@ -3961,8 +3960,8 @@ static void ni_parse_pplib_clock_info(struct radeon_device *rdev, | |||
| 3961 | 3960 | ||
| 3962 | /* patch up vddc if necessary */ | 3961 | /* patch up vddc if necessary */ |
| 3963 | if (pl->vddc == 0xff01) { | 3962 | if (pl->vddc == 0xff01) { |
| 3964 | if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0) | 3963 | if (pi->max_vddc) |
| 3965 | pl->vddc = vddc; | 3964 | pl->vddc = pi->max_vddc; |
| 3966 | } | 3965 | } |
| 3967 | 3966 | ||
| 3968 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { | 3967 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { |
| @@ -4322,7 +4321,8 @@ void ni_dpm_print_power_state(struct radeon_device *rdev, | |||
| 4322 | void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 4321 | void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
| 4323 | struct seq_file *m) | 4322 | struct seq_file *m) |
| 4324 | { | 4323 | { |
| 4325 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 4324 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
| 4325 | struct radeon_ps *rps = &eg_pi->current_rps; | ||
| 4326 | struct ni_ps *ps = ni_get_ps(rps); | 4326 | struct ni_ps *ps = ni_get_ps(rps); |
| 4327 | struct rv7xx_pl *pl; | 4327 | struct rv7xx_pl *pl; |
| 4328 | u32 current_index = | 4328 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 56140b4e5bb2..cdbc4171fe73 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -3991,6 +3991,10 @@ restart_ih: | |||
| 3991 | break; | 3991 | break; |
| 3992 | } | 3992 | } |
| 3993 | break; | 3993 | break; |
| 3994 | case 124: /* UVD */ | ||
| 3995 | DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); | ||
| 3996 | radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); | ||
| 3997 | break; | ||
| 3994 | case 176: /* CP_INT in ring buffer */ | 3998 | case 176: /* CP_INT in ring buffer */ |
| 3995 | case 177: /* CP_INT in IB1 */ | 3999 | case 177: /* CP_INT in IB1 */ |
| 3996 | case 178: /* CP_INT in IB2 */ | 4000 | case 178: /* CP_INT in IB2 */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index f74db43346fd..dda02bfc10a4 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
| @@ -1555,7 +1555,7 @@ static struct radeon_asic btc_asic = { | |||
| 1555 | .get_sclk = &btc_dpm_get_sclk, | 1555 | .get_sclk = &btc_dpm_get_sclk, |
| 1556 | .get_mclk = &btc_dpm_get_mclk, | 1556 | .get_mclk = &btc_dpm_get_mclk, |
| 1557 | .print_power_state = &rv770_dpm_print_power_state, | 1557 | .print_power_state = &rv770_dpm_print_power_state, |
| 1558 | .debugfs_print_current_performance_level = &rv770_dpm_debugfs_print_current_performance_level, | 1558 | .debugfs_print_current_performance_level = &btc_dpm_debugfs_print_current_performance_level, |
| 1559 | .force_performance_level = &rv770_dpm_force_performance_level, | 1559 | .force_performance_level = &rv770_dpm_force_performance_level, |
| 1560 | .vblank_too_short = &btc_dpm_vblank_too_short, | 1560 | .vblank_too_short = &btc_dpm_vblank_too_short, |
| 1561 | }, | 1561 | }, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index b3bc433eed4c..ae637cfda783 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -551,6 +551,8 @@ void btc_dpm_fini(struct radeon_device *rdev); | |||
| 551 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low); | 551 | u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low); |
| 552 | u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low); | 552 | u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low); |
| 553 | bool btc_dpm_vblank_too_short(struct radeon_device *rdev); | 553 | bool btc_dpm_vblank_too_short(struct radeon_device *rdev); |
| 554 | void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | ||
| 555 | struct seq_file *m); | ||
| 554 | int sumo_dpm_init(struct radeon_device *rdev); | 556 | int sumo_dpm_init(struct radeon_device *rdev); |
| 555 | int sumo_dpm_enable(struct radeon_device *rdev); | 557 | int sumo_dpm_enable(struct radeon_device *rdev); |
| 556 | int sumo_dpm_late_enable(struct radeon_device *rdev); | 558 | int sumo_dpm_late_enable(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index 80c595aba359..5b2ea8ac0731 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c | |||
| @@ -2174,7 +2174,6 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
| 2174 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); | 2174 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
| 2175 | struct rv7xx_ps *ps = rv770_get_ps(rps); | 2175 | struct rv7xx_ps *ps = rv770_get_ps(rps); |
| 2176 | u32 sclk, mclk; | 2176 | u32 sclk, mclk; |
| 2177 | u16 vddc; | ||
| 2178 | struct rv7xx_pl *pl; | 2177 | struct rv7xx_pl *pl; |
| 2179 | 2178 | ||
| 2180 | switch (index) { | 2179 | switch (index) { |
| @@ -2214,8 +2213,8 @@ static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev, | |||
| 2214 | 2213 | ||
| 2215 | /* patch up vddc if necessary */ | 2214 | /* patch up vddc if necessary */ |
| 2216 | if (pl->vddc == 0xff01) { | 2215 | if (pl->vddc == 0xff01) { |
| 2217 | if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0) | 2216 | if (pi->max_vddc) |
| 2218 | pl->vddc = vddc; | 2217 | pl->vddc = pi->max_vddc; |
| 2219 | } | 2218 | } |
| 2220 | 2219 | ||
| 2221 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { | 2220 | if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) { |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 09ec4f6c53bb..83578324e5d1 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
| @@ -6338,6 +6338,10 @@ restart_ih: | |||
| 6338 | break; | 6338 | break; |
| 6339 | } | 6339 | } |
| 6340 | break; | 6340 | break; |
| 6341 | case 124: /* UVD */ | ||
| 6342 | DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); | ||
| 6343 | radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); | ||
| 6344 | break; | ||
| 6341 | case 146: | 6345 | case 146: |
| 6342 | case 147: | 6346 | case 147: |
| 6343 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); | 6347 | addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); |
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 0471501338fb..eafb0e6bc67e 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
| @@ -6472,7 +6472,8 @@ void si_dpm_fini(struct radeon_device *rdev) | |||
| 6472 | void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 6472 | void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
| 6473 | struct seq_file *m) | 6473 | struct seq_file *m) |
| 6474 | { | 6474 | { |
| 6475 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 6475 | struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev); |
| 6476 | struct radeon_ps *rps = &eg_pi->current_rps; | ||
| 6476 | struct ni_ps *ps = ni_get_ps(rps); | 6477 | struct ni_ps *ps = ni_get_ps(rps); |
| 6477 | struct rv7xx_pl *pl; | 6478 | struct rv7xx_pl *pl; |
| 6478 | u32 current_index = | 6479 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index f121efe12dc5..8b47b3cd0357 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c | |||
| @@ -1807,7 +1807,7 @@ void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev | |||
| 1807 | struct seq_file *m) | 1807 | struct seq_file *m) |
| 1808 | { | 1808 | { |
| 1809 | struct sumo_power_info *pi = sumo_get_pi(rdev); | 1809 | struct sumo_power_info *pi = sumo_get_pi(rdev); |
| 1810 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 1810 | struct radeon_ps *rps = &pi->current_rps; |
| 1811 | struct sumo_ps *ps = sumo_get_ps(rps); | 1811 | struct sumo_ps *ps = sumo_get_ps(rps); |
| 1812 | struct sumo_pl *pl; | 1812 | struct sumo_pl *pl; |
| 1813 | u32 current_index = | 1813 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index 2d447192d6f7..2da0e17eb960 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c | |||
| @@ -1926,7 +1926,8 @@ void trinity_dpm_print_power_state(struct radeon_device *rdev, | |||
| 1926 | void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, | 1926 | void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev, |
| 1927 | struct seq_file *m) | 1927 | struct seq_file *m) |
| 1928 | { | 1928 | { |
| 1929 | struct radeon_ps *rps = rdev->pm.dpm.current_ps; | 1929 | struct trinity_power_info *pi = trinity_get_pi(rdev); |
| 1930 | struct radeon_ps *rps = &pi->current_rps; | ||
| 1930 | struct trinity_ps *ps = trinity_get_ps(rps); | 1931 | struct trinity_ps *ps = trinity_get_ps(rps); |
| 1931 | struct trinity_pl *pl; | 1932 | struct trinity_pl *pl; |
| 1932 | u32 current_index = | 1933 | u32 current_index = |
diff --git a/drivers/gpu/drm/radeon/uvd_v2_2.c b/drivers/gpu/drm/radeon/uvd_v2_2.c index 824550db3fed..d1771004cb52 100644 --- a/drivers/gpu/drm/radeon/uvd_v2_2.c +++ b/drivers/gpu/drm/radeon/uvd_v2_2.c | |||
| @@ -57,7 +57,6 @@ void uvd_v2_2_fence_emit(struct radeon_device *rdev, | |||
| 57 | radeon_ring_write(ring, 0); | 57 | radeon_ring_write(ring, 0); |
| 58 | radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); | 58 | radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0)); |
| 59 | radeon_ring_write(ring, 2); | 59 | radeon_ring_write(ring, 2); |
| 60 | return; | ||
| 61 | } | 60 | } |
| 62 | 61 | ||
| 63 | /** | 62 | /** |
