aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/sti/sti_compositor.c15
-rw-r--r--drivers/gpu/drm/sti/sti_compositor.h2
-rw-r--r--drivers/gpu/drm/sti/sti_drm_crtc.c7
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c23
-rw-r--r--drivers/gpu/drm/sti/sti_mixer.h2
-rw-r--r--drivers/gpu/drm/sti/sti_tvout.c12
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 */
26struct sti_compositor_data stih407_compositor_data = { 26struct 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 */
70struct sti_compositor { 69struct 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
243static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { 243static 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}
402EXPORT_SYMBOL(sti_drm_crtc_is_main);
402 403
403int sti_drm_crtc_init(struct drm_device *drm_dev, struct sti_mixer *mixer, 404int 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 {
90struct sti_gdp { 92struct 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 */
27struct sti_mixer { 28struct 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
35const char *sti_mixer_to_str(struct sti_mixer *mixer); 37const 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 */
102enum sti_tvout_video_out_type { 104enum 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
410static void sti_hda_encoder_disable(struct drm_encoder *encoder) 412static 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
462static void sti_hdmi_encoder_disable(struct drm_encoder *encoder) 464static 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,