diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2016-11-04 03:20:36 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2016-11-06 23:04:58 -0500 |
commit | f20c665ca04a958c007bb047eca42eb1ae2cb7d0 (patch) | |
tree | 5f1b4ea0685686b9af1fc5410cc9a051290a202e | |
parent | 354d3508bca3d4379f1507eeefb64876c22b50e1 (diff) |
drm/nouveau/kms/nv50: clean-up encoder functions
Just a shuffle of blocks into an order consistent with the rest of the
code, renaming hdmi/audio funtions for atomic, and removal of unused
code.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dp.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_encoder.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 256 |
3 files changed, 122 insertions, 140 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 399eb9d5a3b7..ddffb5cde673 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -58,14 +58,14 @@ nouveau_dp_detect(struct nouveau_encoder *nv_encoder) | |||
58 | struct drm_device *dev = nv_encoder->base.base.dev; | 58 | struct drm_device *dev = nv_encoder->base.base.dev; |
59 | struct nouveau_drm *drm = nouveau_drm(dev); | 59 | struct nouveau_drm *drm = nouveau_drm(dev); |
60 | struct nvkm_i2c_aux *aux; | 60 | struct nvkm_i2c_aux *aux; |
61 | u8 *dpcd = nv_encoder->dp.dpcd; | 61 | u8 dpcd[8]; |
62 | int ret; | 62 | int ret; |
63 | 63 | ||
64 | aux = nv_encoder->aux; | 64 | aux = nv_encoder->aux; |
65 | if (!aux) | 65 | if (!aux) |
66 | return -ENODEV; | 66 | return -ENODEV; |
67 | 67 | ||
68 | ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, 8); | 68 | ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, sizeof(dpcd)); |
69 | if (ret) | 69 | if (ret) |
70 | return ret; | 70 | return ret; |
71 | 71 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index dfa1a660e73b..2cd4a2dab835 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h | |||
@@ -59,10 +59,8 @@ struct nouveau_encoder { | |||
59 | union { | 59 | union { |
60 | struct { | 60 | struct { |
61 | struct nv50_mstm *mstm; | 61 | struct nv50_mstm *mstm; |
62 | u8 dpcd[8]; | ||
63 | int link_nr; | 62 | int link_nr; |
64 | int link_bw; | 63 | int link_bw; |
65 | u32 datarate; | ||
66 | } dp; | 64 | } dp; |
67 | }; | 65 | }; |
68 | 66 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 742ac7cbff55..617c57daad21 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -2835,8 +2835,30 @@ nv50_dac_dpms(struct drm_encoder *encoder, int mode) | |||
2835 | } | 2835 | } |
2836 | 2836 | ||
2837 | static void | 2837 | static void |
2838 | nv50_dac_commit(struct drm_encoder *encoder) | 2838 | nv50_dac_disconnect(struct drm_encoder *encoder) |
2839 | { | 2839 | { |
2840 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
2841 | struct nv50_mast *mast = nv50_mast(encoder->dev); | ||
2842 | const int or = nv_encoder->or; | ||
2843 | u32 *push; | ||
2844 | |||
2845 | if (nv_encoder->crtc) { | ||
2846 | nv50_crtc_prepare(nv_encoder->crtc); | ||
2847 | |||
2848 | push = evo_wait(mast, 4); | ||
2849 | if (push) { | ||
2850 | if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { | ||
2851 | evo_mthd(push, 0x0400 + (or * 0x080), 1); | ||
2852 | evo_data(push, 0x00000000); | ||
2853 | } else { | ||
2854 | evo_mthd(push, 0x0180 + (or * 0x020), 1); | ||
2855 | evo_data(push, 0x00000000); | ||
2856 | } | ||
2857 | evo_kick(push, mast); | ||
2858 | } | ||
2859 | } | ||
2860 | |||
2861 | nv_encoder->crtc = NULL; | ||
2840 | } | 2862 | } |
2841 | 2863 | ||
2842 | static void | 2864 | static void |
@@ -2888,33 +2910,6 @@ nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
2888 | nv_encoder->crtc = encoder->crtc; | 2910 | nv_encoder->crtc = encoder->crtc; |
2889 | } | 2911 | } |
2890 | 2912 | ||
2891 | static void | ||
2892 | nv50_dac_disconnect(struct drm_encoder *encoder) | ||
2893 | { | ||
2894 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
2895 | struct nv50_mast *mast = nv50_mast(encoder->dev); | ||
2896 | const int or = nv_encoder->or; | ||
2897 | u32 *push; | ||
2898 | |||
2899 | if (nv_encoder->crtc) { | ||
2900 | nv50_crtc_prepare(nv_encoder->crtc); | ||
2901 | |||
2902 | push = evo_wait(mast, 4); | ||
2903 | if (push) { | ||
2904 | if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { | ||
2905 | evo_mthd(push, 0x0400 + (or * 0x080), 1); | ||
2906 | evo_data(push, 0x00000000); | ||
2907 | } else { | ||
2908 | evo_mthd(push, 0x0180 + (or * 0x020), 1); | ||
2909 | evo_data(push, 0x00000000); | ||
2910 | } | ||
2911 | evo_kick(push, mast); | ||
2912 | } | ||
2913 | } | ||
2914 | |||
2915 | nv_encoder->crtc = NULL; | ||
2916 | } | ||
2917 | |||
2918 | static enum drm_connector_status | 2913 | static enum drm_connector_status |
2919 | nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | 2914 | nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) |
2920 | { | 2915 | { |
@@ -2942,25 +2937,26 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
2942 | return connector_status_connected; | 2937 | return connector_status_connected; |
2943 | } | 2938 | } |
2944 | 2939 | ||
2945 | static void | 2940 | static const struct drm_encoder_helper_funcs |
2946 | nv50_dac_destroy(struct drm_encoder *encoder) | 2941 | nv50_dac_help = { |
2947 | { | ||
2948 | drm_encoder_cleanup(encoder); | ||
2949 | kfree(encoder); | ||
2950 | } | ||
2951 | |||
2952 | static const struct drm_encoder_helper_funcs nv50_dac_hfunc = { | ||
2953 | .dpms = nv50_dac_dpms, | 2942 | .dpms = nv50_dac_dpms, |
2954 | .mode_fixup = nv50_encoder_mode_fixup, | 2943 | .mode_fixup = nv50_encoder_mode_fixup, |
2955 | .prepare = nv50_dac_disconnect, | 2944 | .prepare = nv50_dac_disconnect, |
2956 | .commit = nv50_dac_commit, | ||
2957 | .mode_set = nv50_dac_mode_set, | 2945 | .mode_set = nv50_dac_mode_set, |
2958 | .disable = nv50_dac_disconnect, | 2946 | .disable = nv50_dac_disconnect, |
2959 | .get_crtc = nv50_display_crtc_get, | 2947 | .get_crtc = nv50_display_crtc_get, |
2960 | .detect = nv50_dac_detect | 2948 | .detect = nv50_dac_detect |
2961 | }; | 2949 | }; |
2962 | 2950 | ||
2963 | static const struct drm_encoder_funcs nv50_dac_func = { | 2951 | static void |
2952 | nv50_dac_destroy(struct drm_encoder *encoder) | ||
2953 | { | ||
2954 | drm_encoder_cleanup(encoder); | ||
2955 | kfree(encoder); | ||
2956 | } | ||
2957 | |||
2958 | static const struct drm_encoder_funcs | ||
2959 | nv50_dac_func = { | ||
2964 | .destroy = nv50_dac_destroy, | 2960 | .destroy = nv50_dac_destroy, |
2965 | }; | 2961 | }; |
2966 | 2962 | ||
@@ -2989,7 +2985,7 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe) | |||
2989 | encoder->possible_clones = 0; | 2985 | encoder->possible_clones = 0; |
2990 | drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type, | 2986 | drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type, |
2991 | "dac-%04x-%04x", dcbe->hasht, dcbe->hashm); | 2987 | "dac-%04x-%04x", dcbe->hasht, dcbe->hashm); |
2992 | drm_encoder_helper_add(encoder, &nv50_dac_hfunc); | 2988 | drm_encoder_helper_add(encoder, &nv50_dac_help); |
2993 | 2989 | ||
2994 | drm_mode_connector_attach_encoder(connector, encoder); | 2990 | drm_mode_connector_attach_encoder(connector, encoder); |
2995 | return 0; | 2991 | return 0; |
@@ -2999,7 +2995,26 @@ nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe) | |||
2999 | * Audio | 2995 | * Audio |
3000 | *****************************************************************************/ | 2996 | *****************************************************************************/ |
3001 | static void | 2997 | static void |
3002 | nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | 2998 | nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) |
2999 | { | ||
3000 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
3001 | struct nv50_disp *disp = nv50_disp(encoder->dev); | ||
3002 | struct { | ||
3003 | struct nv50_disp_mthd_v1 base; | ||
3004 | struct nv50_disp_sor_hda_eld_v0 eld; | ||
3005 | } args = { | ||
3006 | .base.version = 1, | ||
3007 | .base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, | ||
3008 | .base.hasht = nv_encoder->dcb->hasht, | ||
3009 | .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | | ||
3010 | (0x0100 << nv_crtc->index), | ||
3011 | }; | ||
3012 | |||
3013 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); | ||
3014 | } | ||
3015 | |||
3016 | static void | ||
3017 | nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) | ||
3003 | { | 3018 | { |
3004 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 3019 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
3005 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 3020 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
@@ -3030,30 +3045,30 @@ nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
3030 | sizeof(args.base) + drm_eld_size(args.data)); | 3045 | sizeof(args.base) + drm_eld_size(args.data)); |
3031 | } | 3046 | } |
3032 | 3047 | ||
3048 | /****************************************************************************** | ||
3049 | * HDMI | ||
3050 | *****************************************************************************/ | ||
3033 | static void | 3051 | static void |
3034 | nv50_audio_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) | 3052 | nv50_hdmi_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) |
3035 | { | 3053 | { |
3036 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 3054 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
3037 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 3055 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
3038 | struct { | 3056 | struct { |
3039 | struct nv50_disp_mthd_v1 base; | 3057 | struct nv50_disp_mthd_v1 base; |
3040 | struct nv50_disp_sor_hda_eld_v0 eld; | 3058 | struct nv50_disp_sor_hdmi_pwr_v0 pwr; |
3041 | } args = { | 3059 | } args = { |
3042 | .base.version = 1, | 3060 | .base.version = 1, |
3043 | .base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, | 3061 | .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR, |
3044 | .base.hasht = nv_encoder->dcb->hasht, | 3062 | .base.hasht = nv_encoder->dcb->hasht, |
3045 | .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | | 3063 | .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | |
3046 | (0x0100 << nv_crtc->index), | 3064 | (0x0100 << nv_crtc->index), |
3047 | }; | 3065 | }; |
3048 | 3066 | ||
3049 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); | 3067 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); |
3050 | } | 3068 | } |
3051 | 3069 | ||
3052 | /****************************************************************************** | ||
3053 | * HDMI | ||
3054 | *****************************************************************************/ | ||
3055 | static void | 3070 | static void |
3056 | nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | 3071 | nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) |
3057 | { | 3072 | { |
3058 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 3073 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
3059 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 3074 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
@@ -3083,26 +3098,7 @@ nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
3083 | args.pwr.max_ac_packet = max_ac_packet / 32; | 3098 | args.pwr.max_ac_packet = max_ac_packet / 32; |
3084 | 3099 | ||
3085 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); | 3100 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); |
3086 | nv50_audio_mode_set(encoder, mode); | 3101 | nv50_audio_enable(encoder, mode); |
3087 | } | ||
3088 | |||
3089 | static void | ||
3090 | nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) | ||
3091 | { | ||
3092 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
3093 | struct nv50_disp *disp = nv50_disp(encoder->dev); | ||
3094 | struct { | ||
3095 | struct nv50_disp_mthd_v1 base; | ||
3096 | struct nv50_disp_sor_hdmi_pwr_v0 pwr; | ||
3097 | } args = { | ||
3098 | .base.version = 1, | ||
3099 | .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR, | ||
3100 | .base.hasht = nv_encoder->dcb->hasht, | ||
3101 | .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | | ||
3102 | (0x0100 << nv_crtc->index), | ||
3103 | }; | ||
3104 | |||
3105 | nvif_mthd(disp->disp, 0, &args, sizeof(args)); | ||
3106 | } | 3102 | } |
3107 | 3103 | ||
3108 | /****************************************************************************** | 3104 | /****************************************************************************** |
@@ -3292,17 +3288,12 @@ nv50_sor_disconnect(struct drm_encoder *encoder) | |||
3292 | if (nv_crtc) { | 3288 | if (nv_crtc) { |
3293 | nv50_crtc_prepare(&nv_crtc->base); | 3289 | nv50_crtc_prepare(&nv_crtc->base); |
3294 | nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0); | 3290 | nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0); |
3295 | nv50_audio_disconnect(encoder, nv_crtc); | 3291 | nv50_audio_disable(encoder, nv_crtc); |
3296 | nv50_hdmi_disconnect(&nv_encoder->base.base, nv_crtc); | 3292 | nv50_hdmi_disable(&nv_encoder->base.base, nv_crtc); |
3297 | } | 3293 | } |
3298 | } | 3294 | } |
3299 | 3295 | ||
3300 | static void | 3296 | static void |
3301 | nv50_sor_commit(struct drm_encoder *encoder) | ||
3302 | { | ||
3303 | } | ||
3304 | |||
3305 | static void | ||
3306 | nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | 3297 | nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, |
3307 | struct drm_display_mode *mode) | 3298 | struct drm_display_mode *mode) |
3308 | { | 3299 | { |
@@ -3349,7 +3340,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
3349 | proto = 0x2; | 3340 | proto = 0x2; |
3350 | } | 3341 | } |
3351 | 3342 | ||
3352 | nv50_hdmi_mode_set(&nv_encoder->base.base, mode); | 3343 | nv50_hdmi_enable(&nv_encoder->base.base, mode); |
3353 | break; | 3344 | break; |
3354 | case DCB_OUTPUT_LVDS: | 3345 | case DCB_OUTPUT_LVDS: |
3355 | proto = 0x0; | 3346 | proto = 0x0; |
@@ -3383,23 +3374,20 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
3383 | nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds)); | 3374 | nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds)); |
3384 | break; | 3375 | break; |
3385 | case DCB_OUTPUT_DP: | 3376 | case DCB_OUTPUT_DP: |
3386 | if (nv_connector->base.display_info.bpc == 6) { | 3377 | if (nv_connector->base.display_info.bpc == 6) |
3387 | nv_encoder->dp.datarate = mode->clock * 18 / 8; | ||
3388 | depth = 0x2; | 3378 | depth = 0x2; |
3389 | } else | 3379 | else |
3390 | if (nv_connector->base.display_info.bpc == 8) { | 3380 | if (nv_connector->base.display_info.bpc == 8) |
3391 | nv_encoder->dp.datarate = mode->clock * 24 / 8; | ||
3392 | depth = 0x5; | 3381 | depth = 0x5; |
3393 | } else { | 3382 | else |
3394 | nv_encoder->dp.datarate = mode->clock * 30 / 8; | ||
3395 | depth = 0x6; | 3383 | depth = 0x6; |
3396 | } | ||
3397 | 3384 | ||
3398 | if (nv_encoder->dcb->sorconf.link & 1) | 3385 | if (nv_encoder->dcb->sorconf.link & 1) |
3399 | proto = 0x8; | 3386 | proto = 0x8; |
3400 | else | 3387 | else |
3401 | proto = 0x9; | 3388 | proto = 0x9; |
3402 | nv50_audio_mode_set(encoder, mode); | 3389 | |
3390 | nv50_audio_enable(encoder, mode); | ||
3403 | break; | 3391 | break; |
3404 | default: | 3392 | default: |
3405 | BUG_ON(1); | 3393 | BUG_ON(1); |
@@ -3442,6 +3430,16 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
3442 | nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner); | 3430 | nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner); |
3443 | } | 3431 | } |
3444 | 3432 | ||
3433 | static const struct drm_encoder_helper_funcs | ||
3434 | nv50_sor_help = { | ||
3435 | .dpms = nv50_sor_dpms, | ||
3436 | .mode_fixup = nv50_encoder_mode_fixup, | ||
3437 | .prepare = nv50_sor_disconnect, | ||
3438 | .mode_set = nv50_sor_mode_set, | ||
3439 | .disable = nv50_sor_disconnect, | ||
3440 | .get_crtc = nv50_display_crtc_get, | ||
3441 | }; | ||
3442 | |||
3445 | static void | 3443 | static void |
3446 | nv50_sor_destroy(struct drm_encoder *encoder) | 3444 | nv50_sor_destroy(struct drm_encoder *encoder) |
3447 | { | 3445 | { |
@@ -3451,17 +3449,8 @@ nv50_sor_destroy(struct drm_encoder *encoder) | |||
3451 | kfree(encoder); | 3449 | kfree(encoder); |
3452 | } | 3450 | } |
3453 | 3451 | ||
3454 | static const struct drm_encoder_helper_funcs nv50_sor_hfunc = { | 3452 | static const struct drm_encoder_funcs |
3455 | .dpms = nv50_sor_dpms, | 3453 | nv50_sor_func = { |
3456 | .mode_fixup = nv50_encoder_mode_fixup, | ||
3457 | .prepare = nv50_sor_disconnect, | ||
3458 | .commit = nv50_sor_commit, | ||
3459 | .mode_set = nv50_sor_mode_set, | ||
3460 | .disable = nv50_sor_disconnect, | ||
3461 | .get_crtc = nv50_display_crtc_get, | ||
3462 | }; | ||
3463 | |||
3464 | static const struct drm_encoder_funcs nv50_sor_func = { | ||
3465 | .destroy = nv50_sor_destroy, | 3454 | .destroy = nv50_sor_destroy, |
3466 | }; | 3455 | }; |
3467 | 3456 | ||
@@ -3496,7 +3485,7 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) | |||
3496 | encoder->possible_clones = 0; | 3485 | encoder->possible_clones = 0; |
3497 | drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type, | 3486 | drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type, |
3498 | "sor-%04x-%04x", dcbe->hasht, dcbe->hashm); | 3487 | "sor-%04x-%04x", dcbe->hasht, dcbe->hashm); |
3499 | drm_encoder_helper_add(encoder, &nv50_sor_hfunc); | 3488 | drm_encoder_helper_add(encoder, &nv50_sor_help); |
3500 | 3489 | ||
3501 | drm_mode_connector_attach_encoder(connector, encoder); | 3490 | drm_mode_connector_attach_encoder(connector, encoder); |
3502 | 3491 | ||
@@ -3529,7 +3518,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) | |||
3529 | /****************************************************************************** | 3518 | /****************************************************************************** |
3530 | * PIOR | 3519 | * PIOR |
3531 | *****************************************************************************/ | 3520 | *****************************************************************************/ |
3532 | |||
3533 | static void | 3521 | static void |
3534 | nv50_pior_dpms(struct drm_encoder *encoder, int mode) | 3522 | nv50_pior_dpms(struct drm_encoder *encoder, int mode) |
3535 | { | 3523 | { |
@@ -3562,8 +3550,27 @@ nv50_pior_mode_fixup(struct drm_encoder *encoder, | |||
3562 | } | 3550 | } |
3563 | 3551 | ||
3564 | static void | 3552 | static void |
3565 | nv50_pior_commit(struct drm_encoder *encoder) | 3553 | nv50_pior_disconnect(struct drm_encoder *encoder) |
3566 | { | 3554 | { |
3555 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
3556 | struct nv50_mast *mast = nv50_mast(encoder->dev); | ||
3557 | const int or = nv_encoder->or; | ||
3558 | u32 *push; | ||
3559 | |||
3560 | if (nv_encoder->crtc) { | ||
3561 | nv50_crtc_prepare(nv_encoder->crtc); | ||
3562 | |||
3563 | push = evo_wait(mast, 4); | ||
3564 | if (push) { | ||
3565 | if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { | ||
3566 | evo_mthd(push, 0x0700 + (or * 0x040), 1); | ||
3567 | evo_data(push, 0x00000000); | ||
3568 | } | ||
3569 | evo_kick(push, mast); | ||
3570 | } | ||
3571 | } | ||
3572 | |||
3573 | nv_encoder->crtc = NULL; | ||
3567 | } | 3574 | } |
3568 | 3575 | ||
3569 | static void | 3576 | static void |
@@ -3616,48 +3623,25 @@ nv50_pior_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
3616 | nv_encoder->crtc = encoder->crtc; | 3623 | nv_encoder->crtc = encoder->crtc; |
3617 | } | 3624 | } |
3618 | 3625 | ||
3619 | static void | 3626 | static const struct drm_encoder_helper_funcs |
3620 | nv50_pior_disconnect(struct drm_encoder *encoder) | 3627 | nv50_pior_help = { |
3621 | { | ||
3622 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
3623 | struct nv50_mast *mast = nv50_mast(encoder->dev); | ||
3624 | const int or = nv_encoder->or; | ||
3625 | u32 *push; | ||
3626 | |||
3627 | if (nv_encoder->crtc) { | ||
3628 | nv50_crtc_prepare(nv_encoder->crtc); | ||
3629 | |||
3630 | push = evo_wait(mast, 4); | ||
3631 | if (push) { | ||
3632 | if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { | ||
3633 | evo_mthd(push, 0x0700 + (or * 0x040), 1); | ||
3634 | evo_data(push, 0x00000000); | ||
3635 | } | ||
3636 | evo_kick(push, mast); | ||
3637 | } | ||
3638 | } | ||
3639 | |||
3640 | nv_encoder->crtc = NULL; | ||
3641 | } | ||
3642 | |||
3643 | static void | ||
3644 | nv50_pior_destroy(struct drm_encoder *encoder) | ||
3645 | { | ||
3646 | drm_encoder_cleanup(encoder); | ||
3647 | kfree(encoder); | ||
3648 | } | ||
3649 | |||
3650 | static const struct drm_encoder_helper_funcs nv50_pior_hfunc = { | ||
3651 | .dpms = nv50_pior_dpms, | 3628 | .dpms = nv50_pior_dpms, |
3652 | .mode_fixup = nv50_pior_mode_fixup, | 3629 | .mode_fixup = nv50_pior_mode_fixup, |
3653 | .prepare = nv50_pior_disconnect, | 3630 | .prepare = nv50_pior_disconnect, |
3654 | .commit = nv50_pior_commit, | ||
3655 | .mode_set = nv50_pior_mode_set, | 3631 | .mode_set = nv50_pior_mode_set, |
3656 | .disable = nv50_pior_disconnect, | 3632 | .disable = nv50_pior_disconnect, |
3657 | .get_crtc = nv50_display_crtc_get, | 3633 | .get_crtc = nv50_display_crtc_get, |
3658 | }; | 3634 | }; |
3659 | 3635 | ||
3660 | static const struct drm_encoder_funcs nv50_pior_func = { | 3636 | static void |
3637 | nv50_pior_destroy(struct drm_encoder *encoder) | ||
3638 | { | ||
3639 | drm_encoder_cleanup(encoder); | ||
3640 | kfree(encoder); | ||
3641 | } | ||
3642 | |||
3643 | static const struct drm_encoder_funcs | ||
3644 | nv50_pior_func = { | ||
3661 | .destroy = nv50_pior_destroy, | 3645 | .destroy = nv50_pior_destroy, |
3662 | }; | 3646 | }; |
3663 | 3647 | ||
@@ -3701,7 +3685,7 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) | |||
3701 | encoder->possible_clones = 0; | 3685 | encoder->possible_clones = 0; |
3702 | drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type, | 3686 | drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type, |
3703 | "pior-%04x-%04x", dcbe->hasht, dcbe->hashm); | 3687 | "pior-%04x-%04x", dcbe->hasht, dcbe->hashm); |
3704 | drm_encoder_helper_add(encoder, &nv50_pior_hfunc); | 3688 | drm_encoder_helper_add(encoder, &nv50_pior_help); |
3705 | 3689 | ||
3706 | drm_mode_connector_attach_encoder(connector, encoder); | 3690 | drm_mode_connector_attach_encoder(connector, encoder); |
3707 | return 0; | 3691 | return 0; |