Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm: sti: enable auxiliary CRTC

For stih407 SoC enable the second mixer to get two CRTC.
Allow GPD planes and encoders to be connected to this new CRTC.
Cursor plane can only be set on first CRTC.
GPD clocks needed change the parent clock depending on which
CRTC GPD are used.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>

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