diff options
-rw-r--r-- | drivers/gpu/drm/sti/sti_compositor.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_compositor.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_drm_crtc.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_gdp.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_mixer.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_tvout.c | 12 |
6 files changed, 44 insertions, 17 deletions
diff --git a/drivers/gpu/drm/sti/sti_compositor.c b/drivers/gpu/drm/sti/sti_compositor.c index 390d93e9a06c..bbf8462879ce 100644 --- a/drivers/gpu/drm/sti/sti_compositor.c +++ b/drivers/gpu/drm/sti/sti_compositor.c | |||
@@ -24,14 +24,15 @@ | |||
24 | * stiH407 compositor properties | 24 | * stiH407 compositor properties |
25 | */ | 25 | */ |
26 | struct sti_compositor_data stih407_compositor_data = { | 26 | struct sti_compositor_data stih407_compositor_data = { |
27 | .nb_subdev = 6, | 27 | .nb_subdev = 7, |
28 | .subdev_desc = { | 28 | .subdev_desc = { |
29 | {STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100}, | 29 | {STI_GPD_SUBDEV, (int)STI_GDP_0, 0x100}, |
30 | {STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200}, | 30 | {STI_GPD_SUBDEV, (int)STI_GDP_1, 0x200}, |
31 | {STI_GPD_SUBDEV, (int)STI_GDP_2, 0x300}, | 31 | {STI_GPD_SUBDEV, (int)STI_GDP_2, 0x300}, |
32 | {STI_GPD_SUBDEV, (int)STI_GDP_3, 0x400}, | 32 | {STI_GPD_SUBDEV, (int)STI_GDP_3, 0x400}, |
33 | {STI_VID_SUBDEV, (int)STI_VID_0, 0x700}, | 33 | {STI_VID_SUBDEV, (int)STI_VID_0, 0x700}, |
34 | {STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00} | 34 | {STI_MIXER_MAIN_SUBDEV, STI_MIXER_MAIN, 0xC00}, |
35 | {STI_MIXER_AUX_SUBDEV, STI_MIXER_AUX, 0xD00}, | ||
35 | }, | 36 | }, |
36 | }; | 37 | }; |
37 | 38 | ||
@@ -102,21 +103,21 @@ static int sti_compositor_bind(struct device *dev, struct device *master, | |||
102 | enum sti_layer_type type = desc & STI_LAYER_TYPE_MASK; | 103 | enum sti_layer_type type = desc & STI_LAYER_TYPE_MASK; |
103 | enum drm_plane_type plane_type = DRM_PLANE_TYPE_OVERLAY; | 104 | enum drm_plane_type plane_type = DRM_PLANE_TYPE_OVERLAY; |
104 | 105 | ||
105 | if (compo->mixer[crtc]) | 106 | if (crtc < compo->nb_mixers) |
106 | plane_type = DRM_PLANE_TYPE_PRIMARY; | 107 | plane_type = DRM_PLANE_TYPE_PRIMARY; |
107 | 108 | ||
108 | switch (type) { | 109 | switch (type) { |
109 | case STI_CUR: | 110 | case STI_CUR: |
110 | cursor = sti_drm_plane_init(drm_dev, | 111 | cursor = sti_drm_plane_init(drm_dev, |
111 | compo->layer[i], | 112 | compo->layer[i], |
112 | (1 << crtc) - 1, | 113 | 1, DRM_PLANE_TYPE_CURSOR); |
113 | DRM_PLANE_TYPE_CURSOR); | ||
114 | break; | 114 | break; |
115 | case STI_GDP: | 115 | case STI_GDP: |
116 | case STI_VID: | 116 | case STI_VID: |
117 | primary = sti_drm_plane_init(drm_dev, | 117 | primary = sti_drm_plane_init(drm_dev, |
118 | compo->layer[i], | 118 | compo->layer[i], |
119 | (1 << crtc) - 1, plane_type); | 119 | (1 << compo->nb_mixers) - 1, |
120 | plane_type); | ||
120 | plane++; | 121 | plane++; |
121 | break; | 122 | break; |
122 | case STI_BCK: | 123 | case STI_BCK: |
@@ -124,7 +125,7 @@ static int sti_compositor_bind(struct device *dev, struct device *master, | |||
124 | } | 125 | } |
125 | 126 | ||
126 | /* The first planes are reserved for primary planes*/ | 127 | /* The first planes are reserved for primary planes*/ |
127 | if (compo->mixer[crtc]) { | 128 | if (crtc < compo->nb_mixers) { |
128 | sti_drm_crtc_init(drm_dev, compo->mixer[crtc], | 129 | sti_drm_crtc_init(drm_dev, compo->mixer[crtc], |
129 | primary, cursor); | 130 | primary, cursor); |
130 | crtc++; | 131 | crtc++; |
diff --git a/drivers/gpu/drm/sti/sti_compositor.h b/drivers/gpu/drm/sti/sti_compositor.h index 3ea19db72e0f..019eb44c62cc 100644 --- a/drivers/gpu/drm/sti/sti_compositor.h +++ b/drivers/gpu/drm/sti/sti_compositor.h | |||
@@ -64,7 +64,6 @@ struct sti_compositor_data { | |||
64 | * @layer: array of layers | 64 | * @layer: array of layers |
65 | * @nb_mixers: number of mixers for this compositor | 65 | * @nb_mixers: number of mixers for this compositor |
66 | * @nb_layers: number of layers (GDP,VID,...) for this compositor | 66 | * @nb_layers: number of layers (GDP,VID,...) for this compositor |
67 | * @enable: true if compositor is enable else false | ||
68 | * @vtg_vblank_nb: callback for VTG VSYNC notification | 67 | * @vtg_vblank_nb: callback for VTG VSYNC notification |
69 | */ | 68 | */ |
70 | struct sti_compositor { | 69 | struct sti_compositor { |
@@ -83,7 +82,6 @@ struct sti_compositor { | |||
83 | struct sti_layer *layer[STI_MAX_LAYER]; | 82 | struct sti_layer *layer[STI_MAX_LAYER]; |
84 | int nb_mixers; | 83 | int nb_mixers; |
85 | int nb_layers; | 84 | int nb_layers; |
86 | bool enable; | ||
87 | struct notifier_block vtg_vblank_nb; | 85 | struct notifier_block vtg_vblank_nb; |
88 | }; | 86 | }; |
89 | 87 | ||
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.c b/drivers/gpu/drm/sti/sti_drm_crtc.c index 534cd2c810ec..928b44fd3717 100644 --- a/drivers/gpu/drm/sti/sti_drm_crtc.c +++ b/drivers/gpu/drm/sti/sti_drm_crtc.c | |||
@@ -28,7 +28,7 @@ static void sti_drm_crtc_prepare(struct drm_crtc *crtc) | |||
28 | struct device *dev = mixer->dev; | 28 | struct device *dev = mixer->dev; |
29 | struct sti_compositor *compo = dev_get_drvdata(dev); | 29 | struct sti_compositor *compo = dev_get_drvdata(dev); |
30 | 30 | ||
31 | compo->enable = true; | 31 | mixer->enabled = true; |
32 | 32 | ||
33 | /* Prepare and enable the compo IP clock */ | 33 | /* Prepare and enable the compo IP clock */ |
34 | if (mixer->id == STI_MIXER_MAIN) { | 34 | if (mixer->id == STI_MIXER_MAIN) { |
@@ -200,7 +200,7 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc) | |||
200 | struct sti_compositor *compo = dev_get_drvdata(dev); | 200 | struct sti_compositor *compo = dev_get_drvdata(dev); |
201 | struct sti_layer *layer; | 201 | struct sti_layer *layer; |
202 | 202 | ||
203 | if (!compo->enable) | 203 | if (!mixer->enabled) |
204 | return; | 204 | return; |
205 | 205 | ||
206 | DRM_DEBUG_KMS("CRTC:%d (%s)\n", crtc->base.id, sti_mixer_to_str(mixer)); | 206 | DRM_DEBUG_KMS("CRTC:%d (%s)\n", crtc->base.id, sti_mixer_to_str(mixer)); |
@@ -237,7 +237,7 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc) | |||
237 | clk_disable_unprepare(compo->clk_compo_aux); | 237 | clk_disable_unprepare(compo->clk_compo_aux); |
238 | } | 238 | } |
239 | 239 | ||
240 | compo->enable = false; | 240 | mixer->enabled = false; |
241 | } | 241 | } |
242 | 242 | ||
243 | static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { | 243 | static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { |
@@ -399,6 +399,7 @@ bool sti_drm_crtc_is_main(struct drm_crtc *crtc) | |||
399 | 399 | ||
400 | return false; | 400 | return false; |
401 | } | 401 | } |
402 | EXPORT_SYMBOL(sti_drm_crtc_is_main); | ||
402 | 403 | ||
403 | int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer, | 404 | int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer, |
404 | struct drm_plane *primary, struct drm_plane *cursor) | 405 | struct drm_plane *primary, struct drm_plane *cursor) |
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c index 1b903ffb345b..32448d1d1e8f 100644 --- a/drivers/gpu/drm/sti/sti_gdp.c +++ b/drivers/gpu/drm/sti/sti_gdp.c | |||
@@ -83,6 +83,8 @@ struct sti_gdp_node_list { | |||
83 | * | 83 | * |
84 | * @layer: layer structure | 84 | * @layer: layer structure |
85 | * @clk_pix: pixel clock for the current gdp | 85 | * @clk_pix: pixel clock for the current gdp |
86 | * @clk_main_parent: gdp parent clock if main path used | ||
87 | * @clk_aux_parent: gdp parent clock if aux path used | ||
86 | * @vtg_field_nb: callback for VTG FIELD (top or bottom) notification | 88 | * @vtg_field_nb: callback for VTG FIELD (top or bottom) notification |
87 | * @is_curr_top: true if the current node processed is the top field | 89 | * @is_curr_top: true if the current node processed is the top field |
88 | * @node_list: array of node list | 90 | * @node_list: array of node list |
@@ -90,6 +92,8 @@ struct sti_gdp_node_list { | |||
90 | struct sti_gdp { | 92 | struct sti_gdp { |
91 | struct sti_layer layer; | 93 | struct sti_layer layer; |
92 | struct clk *clk_pix; | 94 | struct clk *clk_pix; |
95 | struct clk *clk_main_parent; | ||
96 | struct clk *clk_aux_parent; | ||
93 | struct notifier_block vtg_field_nb; | 97 | struct notifier_block vtg_field_nb; |
94 | bool is_curr_top; | 98 | bool is_curr_top; |
95 | struct sti_gdp_node_list node_list[GDP_NODE_NB_BANK]; | 99 | struct sti_gdp_node_list node_list[GDP_NODE_NB_BANK]; |
@@ -307,6 +311,17 @@ static int sti_gdp_prepare_layer(struct sti_layer *layer, bool first_prepare) | |||
307 | 311 | ||
308 | /* Set and enable gdp clock */ | 312 | /* Set and enable gdp clock */ |
309 | if (gdp->clk_pix) { | 313 | if (gdp->clk_pix) { |
314 | struct clk *clkp; | ||
315 | /* According to the mixer used, the gdp pixel clock | ||
316 | * should have a different parent clock. */ | ||
317 | if (layer->mixer_id == STI_MIXER_MAIN) | ||
318 | clkp = gdp->clk_main_parent; | ||
319 | else | ||
320 | clkp = gdp->clk_aux_parent; | ||
321 | |||
322 | if (clkp) | ||
323 | clk_set_parent(gdp->clk_pix, clkp); | ||
324 | |||
310 | res = clk_set_rate(gdp->clk_pix, rate); | 325 | res = clk_set_rate(gdp->clk_pix, rate); |
311 | if (res < 0) { | 326 | if (res < 0) { |
312 | DRM_ERROR("Cannot set rate (%dHz) for gdp\n", | 327 | DRM_ERROR("Cannot set rate (%dHz) for gdp\n", |
@@ -521,6 +536,14 @@ static void sti_gdp_init(struct sti_layer *layer) | |||
521 | gdp->clk_pix = devm_clk_get(layer->dev, clk_name); | 536 | gdp->clk_pix = devm_clk_get(layer->dev, clk_name); |
522 | if (IS_ERR(gdp->clk_pix)) | 537 | if (IS_ERR(gdp->clk_pix)) |
523 | DRM_ERROR("Cannot get %s clock\n", clk_name); | 538 | DRM_ERROR("Cannot get %s clock\n", clk_name); |
539 | |||
540 | gdp->clk_main_parent = devm_clk_get(layer->dev, "main_parent"); | ||
541 | if (IS_ERR(gdp->clk_main_parent)) | ||
542 | DRM_ERROR("Cannot get main_parent clock\n"); | ||
543 | |||
544 | gdp->clk_aux_parent = devm_clk_get(layer->dev, "aux_parent"); | ||
545 | if (IS_ERR(gdp->clk_aux_parent)) | ||
546 | DRM_ERROR("Cannot get aux_parent clock\n"); | ||
524 | } | 547 | } |
525 | } | 548 | } |
526 | 549 | ||
diff --git a/drivers/gpu/drm/sti/sti_mixer.h b/drivers/gpu/drm/sti/sti_mixer.h index 750e1fd5a8ce..b97282182908 100644 --- a/drivers/gpu/drm/sti/sti_mixer.h +++ b/drivers/gpu/drm/sti/sti_mixer.h | |||
@@ -23,6 +23,7 @@ | |||
23 | * @id: id of the mixer | 23 | * @id: id of the mixer |
24 | * @drm_crtc: crtc object link to the mixer | 24 | * @drm_crtc: crtc object link to the mixer |
25 | * @pending_event: set if a flip event is pending on crtc | 25 | * @pending_event: set if a flip event is pending on crtc |
26 | * @enabled: to know if the mixer is active or not | ||
26 | */ | 27 | */ |
27 | struct sti_mixer { | 28 | struct sti_mixer { |
28 | struct device *dev; | 29 | struct device *dev; |
@@ -30,6 +31,7 @@ struct sti_mixer { | |||
30 | int id; | 31 | int id; |
31 | struct drm_crtc drm_crtc; | 32 | struct drm_crtc drm_crtc; |
32 | struct drm_pending_vblank_event *pending_event; | 33 | struct drm_pending_vblank_event *pending_event; |
34 | bool enabled; | ||
33 | }; | 35 | }; |
34 | 36 | ||
35 | const char *sti_mixer_to_str(struct sti_mixer *mixer); | 37 | const char *sti_mixer_to_str(struct sti_mixer *mixer); |
diff --git a/drivers/gpu/drm/sti/sti_tvout.c b/drivers/gpu/drm/sti/sti_tvout.c index 604e574d726e..cb924aa2b321 100644 --- a/drivers/gpu/drm/sti/sti_tvout.c +++ b/drivers/gpu/drm/sti/sti_tvout.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <drm/drmP.h> | 16 | #include <drm/drmP.h> |
17 | #include <drm/drm_crtc_helper.h> | 17 | #include <drm/drm_crtc_helper.h> |
18 | 18 | ||
19 | #include "sti_drm_crtc.h" | ||
20 | |||
19 | /* glue registers */ | 21 | /* glue registers */ |
20 | #define TVO_CSC_MAIN_M0 0x000 | 22 | #define TVO_CSC_MAIN_M0 0x000 |
21 | #define TVO_CSC_MAIN_M1 0x004 | 23 | #define TVO_CSC_MAIN_M1 0x004 |
@@ -96,7 +98,7 @@ | |||
96 | 98 | ||
97 | #define TVO_SYNC_HD_DCS_SHIFT 8 | 99 | #define TVO_SYNC_HD_DCS_SHIFT 8 |
98 | 100 | ||
99 | #define ENCODER_MAIN_CRTC_MASK BIT(0) | 101 | #define ENCODER_CRTC_MASK (BIT(0) | BIT(1)) |
100 | 102 | ||
101 | /* enum listing the supported output data format */ | 103 | /* enum listing the supported output data format */ |
102 | enum sti_tvout_video_out_type { | 104 | enum sti_tvout_video_out_type { |
@@ -404,7 +406,7 @@ static void sti_hda_encoder_commit(struct drm_encoder *encoder) | |||
404 | { | 406 | { |
405 | struct sti_tvout *tvout = to_sti_tvout(encoder); | 407 | struct sti_tvout *tvout = to_sti_tvout(encoder); |
406 | 408 | ||
407 | tvout_hda_start(tvout, true); | 409 | tvout_hda_start(tvout, sti_drm_crtc_is_main(encoder->crtc)); |
408 | } | 410 | } |
409 | 411 | ||
410 | static void sti_hda_encoder_disable(struct drm_encoder *encoder) | 412 | static void sti_hda_encoder_disable(struct drm_encoder *encoder) |
@@ -441,7 +443,7 @@ static struct drm_encoder *sti_tvout_create_hda_encoder(struct drm_device *dev, | |||
441 | 443 | ||
442 | drm_encoder = (struct drm_encoder *) encoder; | 444 | drm_encoder = (struct drm_encoder *) encoder; |
443 | 445 | ||
444 | drm_encoder->possible_crtcs = ENCODER_MAIN_CRTC_MASK; | 446 | drm_encoder->possible_crtcs = ENCODER_CRTC_MASK; |
445 | drm_encoder->possible_clones = 1 << 0; | 447 | drm_encoder->possible_clones = 1 << 0; |
446 | 448 | ||
447 | drm_encoder_init(dev, drm_encoder, | 449 | drm_encoder_init(dev, drm_encoder, |
@@ -456,7 +458,7 @@ static void sti_hdmi_encoder_commit(struct drm_encoder *encoder) | |||
456 | { | 458 | { |
457 | struct sti_tvout *tvout = to_sti_tvout(encoder); | 459 | struct sti_tvout *tvout = to_sti_tvout(encoder); |
458 | 460 | ||
459 | tvout_hdmi_start(tvout, true); | 461 | tvout_hdmi_start(tvout, sti_drm_crtc_is_main(encoder->crtc)); |
460 | } | 462 | } |
461 | 463 | ||
462 | static void sti_hdmi_encoder_disable(struct drm_encoder *encoder) | 464 | static void sti_hdmi_encoder_disable(struct drm_encoder *encoder) |
@@ -490,7 +492,7 @@ static struct drm_encoder *sti_tvout_create_hdmi_encoder(struct drm_device *dev, | |||
490 | 492 | ||
491 | drm_encoder = (struct drm_encoder *) encoder; | 493 | drm_encoder = (struct drm_encoder *) encoder; |
492 | 494 | ||
493 | drm_encoder->possible_crtcs = ENCODER_MAIN_CRTC_MASK; | 495 | drm_encoder->possible_crtcs = ENCODER_CRTC_MASK; |
494 | drm_encoder->possible_clones = 1 << 1; | 496 | drm_encoder->possible_clones = 1 << 1; |
495 | 497 | ||
496 | drm_encoder_init(dev, drm_encoder, | 498 | drm_encoder_init(dev, drm_encoder, |