diff options
Diffstat (limited to 'drivers/gpu/drm/sti/sti_crtc.c')
-rw-r--r-- | drivers/gpu/drm/sti/sti_crtc.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index e04deedabd4a..c7d734dc3cf4 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c | |||
@@ -23,22 +23,11 @@ | |||
23 | static void sti_crtc_enable(struct drm_crtc *crtc) | 23 | static void sti_crtc_enable(struct drm_crtc *crtc) |
24 | { | 24 | { |
25 | struct sti_mixer *mixer = to_sti_mixer(crtc); | 25 | struct sti_mixer *mixer = to_sti_mixer(crtc); |
26 | struct device *dev = mixer->dev; | ||
27 | struct sti_compositor *compo = dev_get_drvdata(dev); | ||
28 | 26 | ||
29 | DRM_DEBUG_DRIVER("\n"); | 27 | DRM_DEBUG_DRIVER("\n"); |
30 | 28 | ||
31 | mixer->status = STI_MIXER_READY; | 29 | mixer->status = STI_MIXER_READY; |
32 | 30 | ||
33 | /* Prepare and enable the compo IP clock */ | ||
34 | if (mixer->id == STI_MIXER_MAIN) { | ||
35 | if (clk_prepare_enable(compo->clk_compo_main)) | ||
36 | DRM_INFO("Failed to prepare/enable compo_main clk\n"); | ||
37 | } else { | ||
38 | if (clk_prepare_enable(compo->clk_compo_aux)) | ||
39 | DRM_INFO("Failed to prepare/enable compo_aux clk\n"); | ||
40 | } | ||
41 | |||
42 | drm_crtc_vblank_on(crtc); | 31 | drm_crtc_vblank_on(crtc); |
43 | } | 32 | } |
44 | 33 | ||
@@ -57,9 +46,8 @@ sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
57 | struct sti_mixer *mixer = to_sti_mixer(crtc); | 46 | struct sti_mixer *mixer = to_sti_mixer(crtc); |
58 | struct device *dev = mixer->dev; | 47 | struct device *dev = mixer->dev; |
59 | struct sti_compositor *compo = dev_get_drvdata(dev); | 48 | struct sti_compositor *compo = dev_get_drvdata(dev); |
60 | struct clk *clk; | 49 | struct clk *compo_clk, *pix_clk; |
61 | int rate = mode->clock * 1000; | 50 | int rate = mode->clock * 1000; |
62 | int res; | ||
63 | 51 | ||
64 | DRM_DEBUG_KMS("CRTC:%d (%s) mode:%d (%s)\n", | 52 | DRM_DEBUG_KMS("CRTC:%d (%s) mode:%d (%s)\n", |
65 | crtc->base.id, sti_mixer_to_str(mixer), | 53 | crtc->base.id, sti_mixer_to_str(mixer), |
@@ -74,32 +62,46 @@ sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
74 | mode->vsync_start, mode->vsync_end, | 62 | mode->vsync_start, mode->vsync_end, |
75 | mode->vtotal, mode->type, mode->flags); | 63 | mode->vtotal, mode->type, mode->flags); |
76 | 64 | ||
77 | /* Set rate and prepare/enable pixel clock */ | 65 | if (mixer->id == STI_MIXER_MAIN) { |
78 | if (mixer->id == STI_MIXER_MAIN) | 66 | compo_clk = compo->clk_compo_main; |
79 | clk = compo->clk_pix_main; | 67 | pix_clk = compo->clk_pix_main; |
80 | else | 68 | } else { |
81 | clk = compo->clk_pix_aux; | 69 | compo_clk = compo->clk_compo_aux; |
70 | pix_clk = compo->clk_pix_aux; | ||
71 | } | ||
72 | |||
73 | /* Prepare and enable the compo IP clock */ | ||
74 | if (clk_prepare_enable(compo_clk)) { | ||
75 | DRM_INFO("Failed to prepare/enable compositor clk\n"); | ||
76 | goto compo_error; | ||
77 | } | ||
82 | 78 | ||
83 | res = clk_set_rate(clk, rate); | 79 | /* Set rate and prepare/enable pixel clock */ |
84 | if (res < 0) { | 80 | if (clk_set_rate(pix_clk, rate) < 0) { |
85 | DRM_ERROR("Cannot set rate (%dHz) for pix clk\n", rate); | 81 | DRM_ERROR("Cannot set rate (%dHz) for pix clk\n", rate); |
86 | return -EINVAL; | 82 | goto pix_error; |
87 | } | 83 | } |
88 | if (clk_prepare_enable(clk)) { | 84 | if (clk_prepare_enable(pix_clk)) { |
89 | DRM_ERROR("Failed to prepare/enable pix clk\n"); | 85 | DRM_ERROR("Failed to prepare/enable pix clk\n"); |
90 | return -EINVAL; | 86 | goto pix_error; |
91 | } | 87 | } |
92 | 88 | ||
93 | sti_vtg_set_config(mixer->id == STI_MIXER_MAIN ? | 89 | sti_vtg_set_config(mixer->id == STI_MIXER_MAIN ? |
94 | compo->vtg_main : compo->vtg_aux, &crtc->mode); | 90 | compo->vtg_main : compo->vtg_aux, &crtc->mode); |
95 | 91 | ||
96 | res = sti_mixer_active_video_area(mixer, &crtc->mode); | 92 | if (sti_mixer_active_video_area(mixer, &crtc->mode)) { |
97 | if (res) { | ||
98 | DRM_ERROR("Can't set active video area\n"); | 93 | DRM_ERROR("Can't set active video area\n"); |
99 | return -EINVAL; | 94 | goto mixer_error; |
100 | } | 95 | } |
101 | 96 | ||
102 | return res; | 97 | return 0; |
98 | |||
99 | mixer_error: | ||
100 | clk_disable_unprepare(pix_clk); | ||
101 | pix_error: | ||
102 | clk_disable_unprepare(compo_clk); | ||
103 | compo_error: | ||
104 | return -EINVAL; | ||
103 | } | 105 | } |
104 | 106 | ||
105 | static void sti_crtc_disable(struct drm_crtc *crtc) | 107 | static void sti_crtc_disable(struct drm_crtc *crtc) |
@@ -130,7 +132,6 @@ static void sti_crtc_disable(struct drm_crtc *crtc) | |||
130 | static void | 132 | static void |
131 | sti_crtc_mode_set_nofb(struct drm_crtc *crtc) | 133 | sti_crtc_mode_set_nofb(struct drm_crtc *crtc) |
132 | { | 134 | { |
133 | sti_crtc_enable(crtc); | ||
134 | sti_crtc_mode_set(crtc, &crtc->state->adjusted_mode); | 135 | sti_crtc_mode_set(crtc, &crtc->state->adjusted_mode); |
135 | } | 136 | } |
136 | 137 | ||
@@ -221,9 +222,7 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc, | |||
221 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { | 222 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { |
222 | .enable = sti_crtc_enable, | 223 | .enable = sti_crtc_enable, |
223 | .disable = sti_crtc_disabling, | 224 | .disable = sti_crtc_disabling, |
224 | .mode_set = drm_helper_crtc_mode_set, | ||
225 | .mode_set_nofb = sti_crtc_mode_set_nofb, | 225 | .mode_set_nofb = sti_crtc_mode_set_nofb, |
226 | .mode_set_base = drm_helper_crtc_mode_set_base, | ||
227 | .atomic_begin = sti_crtc_atomic_begin, | 226 | .atomic_begin = sti_crtc_atomic_begin, |
228 | .atomic_flush = sti_crtc_atomic_flush, | 227 | .atomic_flush = sti_crtc_atomic_flush, |
229 | }; | 228 | }; |
@@ -331,6 +330,17 @@ void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe) | |||
331 | } | 330 | } |
332 | } | 331 | } |
333 | 332 | ||
333 | static int sti_crtc_late_register(struct drm_crtc *crtc) | ||
334 | { | ||
335 | struct sti_mixer *mixer = to_sti_mixer(crtc); | ||
336 | struct sti_compositor *compo = dev_get_drvdata(mixer->dev); | ||
337 | |||
338 | if (drm_crtc_index(crtc) == 0) | ||
339 | return sti_compositor_debufs_init(compo, crtc->dev->primary); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | |||
334 | static const struct drm_crtc_funcs sti_crtc_funcs = { | 344 | static const struct drm_crtc_funcs sti_crtc_funcs = { |
335 | .set_config = drm_atomic_helper_set_config, | 345 | .set_config = drm_atomic_helper_set_config, |
336 | .page_flip = drm_atomic_helper_page_flip, | 346 | .page_flip = drm_atomic_helper_page_flip, |
@@ -339,6 +349,7 @@ static const struct drm_crtc_funcs sti_crtc_funcs = { | |||
339 | .reset = drm_atomic_helper_crtc_reset, | 349 | .reset = drm_atomic_helper_crtc_reset, |
340 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, | 350 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, |
341 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, | 351 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, |
352 | .late_register = sti_crtc_late_register, | ||
342 | }; | 353 | }; |
343 | 354 | ||
344 | bool sti_crtc_is_main(struct drm_crtc *crtc) | 355 | bool sti_crtc_is_main(struct drm_crtc *crtc) |