aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2016-11-04 03:20:36 -0400
committerBen Skeggs <bskeggs@redhat.com>2016-11-06 23:05:03 -0500
commitd665c7e91458e19f413ea89d99d89f4743be95e3 (patch)
tree40ece02034a182cd9106ac4d9782141a98a383cb /drivers
parent9bfdee9a08bbe550598fc4098c85470c63b46ff6 (diff)
drm/nouveau/kms/nv50: allow encoder update to be called from other modules
MST encoders will make use of this to share code with SOR> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c86
2 files changed, 44 insertions, 44 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index 2cd4a2dab835..848982bd18e9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -66,6 +66,8 @@ struct nouveau_encoder {
66 66
67 void (*enc_save)(struct drm_encoder *encoder); 67 void (*enc_save)(struct drm_encoder *encoder);
68 void (*enc_restore)(struct drm_encoder *encoder); 68 void (*enc_restore)(struct drm_encoder *encoder);
69 void (*update)(struct nouveau_encoder *, u8 head,
70 struct drm_display_mode *, u8 proto, u8 depth);
69}; 71};
70 72
71struct nouveau_encoder * 73struct nouveau_encoder *
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 45379f90acc8..854fa31eddb6 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -2926,19 +2926,50 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
2926} 2926}
2927 2927
2928static void 2928static void
2929nv50_sor_ctrl(struct nouveau_encoder *nv_encoder, u32 mask, u32 data) 2929nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head,
2930 struct drm_display_mode *mode, u8 proto, u8 depth)
2930{ 2931{
2931 struct nv50_mast *mast = nv50_mast(nv_encoder->base.base.dev); 2932 struct nv50_dmac *core = &nv50_mast(nv_encoder->base.base.dev)->base;
2932 u32 temp = (nv_encoder->ctrl & ~mask) | (data & mask), *push; 2933 u32 *push;
2933 if (temp != nv_encoder->ctrl && (push = evo_wait(mast, 2))) { 2934
2934 if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 2935 if (!mode) {
2936 nv_encoder->ctrl &= ~BIT(head);
2937 if (!(nv_encoder->ctrl & 0x0000000f))
2938 nv_encoder->ctrl = 0;
2939 } else {
2940 nv_encoder->ctrl |= proto << 8;
2941 nv_encoder->ctrl |= BIT(head);
2942 }
2943
2944 if ((push = evo_wait(core, 6))) {
2945 if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) {
2946 if (mode) {
2947 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
2948 nv_encoder->ctrl |= 0x00001000;
2949 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
2950 nv_encoder->ctrl |= 0x00002000;
2951 nv_encoder->ctrl |= depth << 16;
2952 }
2935 evo_mthd(push, 0x0600 + (nv_encoder->or * 0x40), 1); 2953 evo_mthd(push, 0x0600 + (nv_encoder->or * 0x40), 1);
2936 evo_data(push, (nv_encoder->ctrl = temp));
2937 } else { 2954 } else {
2955 if (mode) {
2956 u32 magic = 0x31ec6000 | (head << 25);
2957 u32 syncs = 0x00000001;
2958 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
2959 syncs |= 0x00000008;
2960 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
2961 syncs |= 0x00000010;
2962 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
2963 magic |= 0x00000001;
2964
2965 evo_mthd(push, 0x0404 + (head * 0x300), 2);
2966 evo_data(push, syncs | (depth << 6));
2967 evo_data(push, magic);
2968 }
2938 evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1); 2969 evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1);
2939 evo_data(push, (nv_encoder->ctrl = temp));
2940 } 2970 }
2941 evo_kick(push, mast); 2971 evo_data(push, nv_encoder->ctrl);
2972 evo_kick(push, core);
2942 } 2973 }
2943} 2974}
2944 2975
@@ -2963,7 +2994,7 @@ nv50_sor_disable(struct drm_encoder *encoder)
2963 } 2994 }
2964 } 2995 }
2965 2996
2966 nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0); 2997 nv_encoder->update(nv_encoder, nv_crtc->index, NULL, 0, 0);
2967 nv50_audio_disable(encoder, nv_crtc); 2998 nv50_audio_disable(encoder, nv_crtc);
2968 nv50_hdmi_disable(&nv_encoder->base.base, nv_crtc); 2999 nv50_hdmi_disable(&nv_encoder->base.base, nv_crtc);
2969 } 3000 }
@@ -2985,13 +3016,10 @@ nv50_sor_enable(struct drm_encoder *encoder)
2985 .base.hashm = nv_encoder->dcb->hashm, 3016 .base.hashm = nv_encoder->dcb->hashm,
2986 }; 3017 };
2987 struct nv50_disp *disp = nv50_disp(encoder->dev); 3018 struct nv50_disp *disp = nv50_disp(encoder->dev);
2988 struct nv50_mast *mast = nv50_mast(encoder->dev);
2989 struct drm_device *dev = encoder->dev; 3019 struct drm_device *dev = encoder->dev;
2990 struct nouveau_drm *drm = nouveau_drm(dev); 3020 struct nouveau_drm *drm = nouveau_drm(dev);
2991 struct nouveau_connector *nv_connector; 3021 struct nouveau_connector *nv_connector;
2992 struct nvbios *bios = &drm->vbios; 3022 struct nvbios *bios = &drm->vbios;
2993 u32 mask, ctrl;
2994 u8 owner = 1 << nv_crtc->index;
2995 u8 proto = 0xf; 3023 u8 proto = 0xf;
2996 u8 depth = 0x0; 3024 u8 depth = 0x0;
2997 3025
@@ -3070,38 +3098,7 @@ nv50_sor_enable(struct drm_encoder *encoder)
3070 break; 3098 break;
3071 } 3099 }
3072 3100
3073 if (nv50_vers(mast) >= GF110_DISP) { 3101 nv_encoder->update(nv_encoder, nv_crtc->index, mode, proto, depth);
3074 u32 *push = evo_wait(mast, 3);
3075 if (push) {
3076 u32 magic = 0x31ec6000 | (nv_crtc->index << 25);
3077 u32 syncs = 0x00000001;
3078
3079 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
3080 syncs |= 0x00000008;
3081 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
3082 syncs |= 0x00000010;
3083
3084 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
3085 magic |= 0x00000001;
3086
3087 evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2);
3088 evo_data(push, syncs | (depth << 6));
3089 evo_data(push, magic);
3090 evo_kick(push, mast);
3091 }
3092
3093 ctrl = proto << 8;
3094 mask = 0x00000f00;
3095 } else {
3096 ctrl = (depth << 16) | (proto << 8);
3097 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
3098 ctrl |= 0x00001000;
3099 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
3100 ctrl |= 0x00002000;
3101 mask = 0x000f3f00;
3102 }
3103
3104 nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner);
3105} 3102}
3106 3103
3107static const struct drm_encoder_helper_funcs 3104static const struct drm_encoder_helper_funcs
@@ -3150,6 +3147,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
3150 return -ENOMEM; 3147 return -ENOMEM;
3151 nv_encoder->dcb = dcbe; 3148 nv_encoder->dcb = dcbe;
3152 nv_encoder->or = ffs(dcbe->or) - 1; 3149 nv_encoder->or = ffs(dcbe->or) - 1;
3150 nv_encoder->update = nv50_sor_update;
3153 3151
3154 encoder = to_drm_encoder(nv_encoder); 3152 encoder = to_drm_encoder(nv_encoder);
3155 encoder->possible_crtcs = dcbe->heads; 3153 encoder->possible_crtcs = dcbe->heads;