diff options
author | Dave Airlie <airlied@redhat.com> | 2018-05-15 01:23:47 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2018-05-15 01:23:48 -0400 |
commit | 9037d4b98b255979c6636045794775f5a89cc623 (patch) | |
tree | 4eef5575a28ee4aaa3928c87d26fb89077add084 /drivers/gpu | |
parent | 2989b3ced370aa8e23e572c9ecaa7404d96e1c7a (diff) | |
parent | b06078de418d6f77c81aa74516f787663f51a262 (diff) |
Merge branch 'drm/du/next' of git://linuxtv.org/pinchartl/media into drm-next
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/2792436.F0zlxykWp6@avalon
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 26 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_group.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_group.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_kms.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_of.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_regs.h | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 10 |
10 files changed, 104 insertions, 50 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index c4420538ec85..f2a0bd1e5119 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c | |||
@@ -767,7 +767,8 @@ static irqreturn_t rcar_du_crtc_irq(int irq, void *arg) | |||
767 | * Initialization | 767 | * Initialization |
768 | */ | 768 | */ |
769 | 769 | ||
770 | int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | 770 | int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex, |
771 | unsigned int hwindex) | ||
771 | { | 772 | { |
772 | static const unsigned int mmio_offsets[] = { | 773 | static const unsigned int mmio_offsets[] = { |
773 | DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET | 774 | DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET, DU3_REG_OFFSET |
@@ -775,7 +776,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | |||
775 | 776 | ||
776 | struct rcar_du_device *rcdu = rgrp->dev; | 777 | struct rcar_du_device *rcdu = rgrp->dev; |
777 | struct platform_device *pdev = to_platform_device(rcdu->dev); | 778 | struct platform_device *pdev = to_platform_device(rcdu->dev); |
778 | struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index]; | 779 | struct rcar_du_crtc *rcrtc = &rcdu->crtcs[swindex]; |
779 | struct drm_crtc *crtc = &rcrtc->crtc; | 780 | struct drm_crtc *crtc = &rcrtc->crtc; |
780 | struct drm_plane *primary; | 781 | struct drm_plane *primary; |
781 | unsigned int irqflags; | 782 | unsigned int irqflags; |
@@ -787,7 +788,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | |||
787 | 788 | ||
788 | /* Get the CRTC clock and the optional external clock. */ | 789 | /* Get the CRTC clock and the optional external clock. */ |
789 | if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { | 790 | if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { |
790 | sprintf(clk_name, "du.%u", index); | 791 | sprintf(clk_name, "du.%u", hwindex); |
791 | name = clk_name; | 792 | name = clk_name; |
792 | } else { | 793 | } else { |
793 | name = NULL; | 794 | name = NULL; |
@@ -795,16 +796,16 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | |||
795 | 796 | ||
796 | rcrtc->clock = devm_clk_get(rcdu->dev, name); | 797 | rcrtc->clock = devm_clk_get(rcdu->dev, name); |
797 | if (IS_ERR(rcrtc->clock)) { | 798 | if (IS_ERR(rcrtc->clock)) { |
798 | dev_err(rcdu->dev, "no clock for CRTC %u\n", index); | 799 | dev_err(rcdu->dev, "no clock for DU channel %u\n", hwindex); |
799 | return PTR_ERR(rcrtc->clock); | 800 | return PTR_ERR(rcrtc->clock); |
800 | } | 801 | } |
801 | 802 | ||
802 | sprintf(clk_name, "dclkin.%u", index); | 803 | sprintf(clk_name, "dclkin.%u", hwindex); |
803 | clk = devm_clk_get(rcdu->dev, clk_name); | 804 | clk = devm_clk_get(rcdu->dev, clk_name); |
804 | if (!IS_ERR(clk)) { | 805 | if (!IS_ERR(clk)) { |
805 | rcrtc->extclock = clk; | 806 | rcrtc->extclock = clk; |
806 | } else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) { | 807 | } else if (PTR_ERR(rcrtc->clock) == -EPROBE_DEFER) { |
807 | dev_info(rcdu->dev, "can't get external clock %u\n", index); | 808 | dev_info(rcdu->dev, "can't get external clock %u\n", hwindex); |
808 | return -EPROBE_DEFER; | 809 | return -EPROBE_DEFER; |
809 | } | 810 | } |
810 | 811 | ||
@@ -813,13 +814,13 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | |||
813 | spin_lock_init(&rcrtc->vblank_lock); | 814 | spin_lock_init(&rcrtc->vblank_lock); |
814 | 815 | ||
815 | rcrtc->group = rgrp; | 816 | rcrtc->group = rgrp; |
816 | rcrtc->mmio_offset = mmio_offsets[index]; | 817 | rcrtc->mmio_offset = mmio_offsets[hwindex]; |
817 | rcrtc->index = index; | 818 | rcrtc->index = hwindex; |
818 | 819 | ||
819 | if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) | 820 | if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE)) |
820 | primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane; | 821 | primary = &rcrtc->vsp->planes[rcrtc->vsp_pipe].plane; |
821 | else | 822 | else |
822 | primary = &rgrp->planes[index % 2].plane; | 823 | primary = &rgrp->planes[swindex % 2].plane; |
823 | 824 | ||
824 | ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, | 825 | ret = drm_crtc_init_with_planes(rcdu->ddev, crtc, primary, |
825 | NULL, &crtc_funcs, NULL); | 826 | NULL, &crtc_funcs, NULL); |
@@ -833,7 +834,8 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | |||
833 | 834 | ||
834 | /* Register the interrupt handler. */ | 835 | /* Register the interrupt handler. */ |
835 | if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { | 836 | if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { |
836 | irq = platform_get_irq(pdev, index); | 837 | /* The IRQ's are associated with the CRTC (sw)index. */ |
838 | irq = platform_get_irq(pdev, swindex); | ||
837 | irqflags = 0; | 839 | irqflags = 0; |
838 | } else { | 840 | } else { |
839 | irq = platform_get_irq(pdev, 0); | 841 | irq = platform_get_irq(pdev, 0); |
@@ -841,7 +843,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | |||
841 | } | 843 | } |
842 | 844 | ||
843 | if (irq < 0) { | 845 | if (irq < 0) { |
844 | dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index); | 846 | dev_err(rcdu->dev, "no IRQ for CRTC %u\n", swindex); |
845 | return irq; | 847 | return irq; |
846 | } | 848 | } |
847 | 849 | ||
@@ -849,7 +851,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) | |||
849 | dev_name(rcdu->dev), rcrtc); | 851 | dev_name(rcdu->dev), rcrtc); |
850 | if (ret < 0) { | 852 | if (ret < 0) { |
851 | dev_err(rcdu->dev, | 853 | dev_err(rcdu->dev, |
852 | "failed to register IRQ for CRTC %u\n", index); | 854 | "failed to register IRQ for CRTC %u\n", swindex); |
853 | return ret; | 855 | return ret; |
854 | } | 856 | } |
855 | 857 | ||
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h index fdc2bf99bda1..84b5e23a85b1 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h | |||
@@ -80,7 +80,8 @@ enum rcar_du_output { | |||
80 | RCAR_DU_OUTPUT_MAX, | 80 | RCAR_DU_OUTPUT_MAX, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index); | 83 | int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex, |
84 | unsigned int hwindex); | ||
84 | void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); | 85 | void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); |
85 | void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); | 86 | void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); |
86 | 87 | ||
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c index 3917d839c04c..02aee6cb0e53 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c | |||
@@ -40,7 +40,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info = { | |||
40 | .gen = 2, | 40 | .gen = 2, |
41 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 41 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
42 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, | 42 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, |
43 | .num_crtcs = 2, | 43 | .channels_mask = BIT(1) | BIT(0), |
44 | .routes = { | 44 | .routes = { |
45 | /* | 45 | /* |
46 | * R8A7743 has one RGB output and one LVDS output | 46 | * R8A7743 has one RGB output and one LVDS output |
@@ -61,7 +61,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = { | |||
61 | .gen = 2, | 61 | .gen = 2, |
62 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 62 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
63 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, | 63 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, |
64 | .num_crtcs = 2, | 64 | .channels_mask = BIT(1) | BIT(0), |
65 | .routes = { | 65 | .routes = { |
66 | /* | 66 | /* |
67 | * R8A7745 has two RGB outputs | 67 | * R8A7745 has two RGB outputs |
@@ -80,7 +80,7 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info = { | |||
80 | static const struct rcar_du_device_info rcar_du_r8a7779_info = { | 80 | static const struct rcar_du_device_info rcar_du_r8a7779_info = { |
81 | .gen = 2, | 81 | .gen = 2, |
82 | .features = 0, | 82 | .features = 0, |
83 | .num_crtcs = 2, | 83 | .channels_mask = BIT(1) | BIT(0), |
84 | .routes = { | 84 | .routes = { |
85 | /* | 85 | /* |
86 | * R8A7779 has two RGB outputs and one (currently unsupported) | 86 | * R8A7779 has two RGB outputs and one (currently unsupported) |
@@ -102,7 +102,7 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = { | |||
102 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 102 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
103 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, | 103 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, |
104 | .quirks = RCAR_DU_QUIRK_ALIGN_128B, | 104 | .quirks = RCAR_DU_QUIRK_ALIGN_128B, |
105 | .num_crtcs = 3, | 105 | .channels_mask = BIT(2) | BIT(1) | BIT(0), |
106 | .routes = { | 106 | .routes = { |
107 | /* | 107 | /* |
108 | * R8A7790 has one RGB output, two LVDS outputs and one | 108 | * R8A7790 has one RGB output, two LVDS outputs and one |
@@ -129,7 +129,7 @@ static const struct rcar_du_device_info rcar_du_r8a7791_info = { | |||
129 | .gen = 2, | 129 | .gen = 2, |
130 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 130 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
131 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, | 131 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, |
132 | .num_crtcs = 2, | 132 | .channels_mask = BIT(1) | BIT(0), |
133 | .routes = { | 133 | .routes = { |
134 | /* | 134 | /* |
135 | * R8A779[13] has one RGB output, one LVDS output and one | 135 | * R8A779[13] has one RGB output, one LVDS output and one |
@@ -151,7 +151,7 @@ static const struct rcar_du_device_info rcar_du_r8a7792_info = { | |||
151 | .gen = 2, | 151 | .gen = 2, |
152 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 152 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
153 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, | 153 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, |
154 | .num_crtcs = 2, | 154 | .channels_mask = BIT(1) | BIT(0), |
155 | .routes = { | 155 | .routes = { |
156 | /* R8A7792 has two RGB outputs. */ | 156 | /* R8A7792 has two RGB outputs. */ |
157 | [RCAR_DU_OUTPUT_DPAD0] = { | 157 | [RCAR_DU_OUTPUT_DPAD0] = { |
@@ -169,7 +169,7 @@ static const struct rcar_du_device_info rcar_du_r8a7794_info = { | |||
169 | .gen = 2, | 169 | .gen = 2, |
170 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 170 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
171 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, | 171 | | RCAR_DU_FEATURE_EXT_CTRL_REGS, |
172 | .num_crtcs = 2, | 172 | .channels_mask = BIT(1) | BIT(0), |
173 | .routes = { | 173 | .routes = { |
174 | /* | 174 | /* |
175 | * R8A7794 has two RGB outputs and one (currently unsupported) | 175 | * R8A7794 has two RGB outputs and one (currently unsupported) |
@@ -191,7 +191,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = { | |||
191 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 191 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
192 | | RCAR_DU_FEATURE_EXT_CTRL_REGS | 192 | | RCAR_DU_FEATURE_EXT_CTRL_REGS |
193 | | RCAR_DU_FEATURE_VSP1_SOURCE, | 193 | | RCAR_DU_FEATURE_VSP1_SOURCE, |
194 | .num_crtcs = 4, | 194 | .channels_mask = BIT(3) | BIT(2) | BIT(1) | BIT(0), |
195 | .routes = { | 195 | .routes = { |
196 | /* | 196 | /* |
197 | * R8A7795 has one RGB output, two HDMI outputs and one | 197 | * R8A7795 has one RGB output, two HDMI outputs and one |
@@ -215,7 +215,7 @@ static const struct rcar_du_device_info rcar_du_r8a7795_info = { | |||
215 | }, | 215 | }, |
216 | }, | 216 | }, |
217 | .num_lvds = 1, | 217 | .num_lvds = 1, |
218 | .dpll_ch = BIT(1) | BIT(2), | 218 | .dpll_ch = BIT(2) | BIT(1), |
219 | }; | 219 | }; |
220 | 220 | ||
221 | static const struct rcar_du_device_info rcar_du_r8a7796_info = { | 221 | static const struct rcar_du_device_info rcar_du_r8a7796_info = { |
@@ -223,7 +223,7 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = { | |||
223 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 223 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
224 | | RCAR_DU_FEATURE_EXT_CTRL_REGS | 224 | | RCAR_DU_FEATURE_EXT_CTRL_REGS |
225 | | RCAR_DU_FEATURE_VSP1_SOURCE, | 225 | | RCAR_DU_FEATURE_VSP1_SOURCE, |
226 | .num_crtcs = 3, | 226 | .channels_mask = BIT(2) | BIT(1) | BIT(0), |
227 | .routes = { | 227 | .routes = { |
228 | /* | 228 | /* |
229 | * R8A7796 has one RGB output, one LVDS output and one HDMI | 229 | * R8A7796 has one RGB output, one LVDS output and one HDMI |
@@ -246,12 +246,40 @@ static const struct rcar_du_device_info rcar_du_r8a7796_info = { | |||
246 | .dpll_ch = BIT(1), | 246 | .dpll_ch = BIT(1), |
247 | }; | 247 | }; |
248 | 248 | ||
249 | static const struct rcar_du_device_info rcar_du_r8a77965_info = { | ||
250 | .gen = 3, | ||
251 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | ||
252 | | RCAR_DU_FEATURE_EXT_CTRL_REGS | ||
253 | | RCAR_DU_FEATURE_VSP1_SOURCE, | ||
254 | .channels_mask = BIT(3) | BIT(1) | BIT(0), | ||
255 | .routes = { | ||
256 | /* | ||
257 | * R8A77965 has one RGB output, one LVDS output and one HDMI | ||
258 | * output. | ||
259 | */ | ||
260 | [RCAR_DU_OUTPUT_DPAD0] = { | ||
261 | .possible_crtcs = BIT(2), | ||
262 | .port = 0, | ||
263 | }, | ||
264 | [RCAR_DU_OUTPUT_HDMI0] = { | ||
265 | .possible_crtcs = BIT(1), | ||
266 | .port = 1, | ||
267 | }, | ||
268 | [RCAR_DU_OUTPUT_LVDS0] = { | ||
269 | .possible_crtcs = BIT(0), | ||
270 | .port = 2, | ||
271 | }, | ||
272 | }, | ||
273 | .num_lvds = 1, | ||
274 | .dpll_ch = BIT(1), | ||
275 | }; | ||
276 | |||
249 | static const struct rcar_du_device_info rcar_du_r8a77970_info = { | 277 | static const struct rcar_du_device_info rcar_du_r8a77970_info = { |
250 | .gen = 3, | 278 | .gen = 3, |
251 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | 279 | .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK |
252 | | RCAR_DU_FEATURE_EXT_CTRL_REGS | 280 | | RCAR_DU_FEATURE_EXT_CTRL_REGS |
253 | | RCAR_DU_FEATURE_VSP1_SOURCE, | 281 | | RCAR_DU_FEATURE_VSP1_SOURCE, |
254 | .num_crtcs = 1, | 282 | .channels_mask = BIT(0), |
255 | .routes = { | 283 | .routes = { |
256 | /* R8A77970 has one RGB output and one LVDS output. */ | 284 | /* R8A77970 has one RGB output and one LVDS output. */ |
257 | [RCAR_DU_OUTPUT_DPAD0] = { | 285 | [RCAR_DU_OUTPUT_DPAD0] = { |
@@ -277,6 +305,7 @@ static const struct of_device_id rcar_du_of_table[] = { | |||
277 | { .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info }, | 305 | { .compatible = "renesas,du-r8a7794", .data = &rcar_du_r8a7794_info }, |
278 | { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info }, | 306 | { .compatible = "renesas,du-r8a7795", .data = &rcar_du_r8a7795_info }, |
279 | { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info }, | 307 | { .compatible = "renesas,du-r8a7796", .data = &rcar_du_r8a7796_info }, |
308 | { .compatible = "renesas,du-r8a77965", .data = &rcar_du_r8a77965_info }, | ||
280 | { .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info }, | 309 | { .compatible = "renesas,du-r8a77970", .data = &rcar_du_r8a77970_info }, |
281 | { } | 310 | { } |
282 | }; | 311 | }; |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h index 131d8e88b06c..b3a25e8e07d0 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h | |||
@@ -52,7 +52,7 @@ struct rcar_du_output_routing { | |||
52 | * @gen: device generation (2 or 3) | 52 | * @gen: device generation (2 or 3) |
53 | * @features: device features (RCAR_DU_FEATURE_*) | 53 | * @features: device features (RCAR_DU_FEATURE_*) |
54 | * @quirks: device quirks (RCAR_DU_QUIRK_*) | 54 | * @quirks: device quirks (RCAR_DU_QUIRK_*) |
55 | * @num_crtcs: total number of CRTCs | 55 | * @channels_mask: bit mask of available DU channels |
56 | * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*) | 56 | * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*) |
57 | * @num_lvds: number of internal LVDS encoders | 57 | * @num_lvds: number of internal LVDS encoders |
58 | */ | 58 | */ |
@@ -60,7 +60,7 @@ struct rcar_du_device_info { | |||
60 | unsigned int gen; | 60 | unsigned int gen; |
61 | unsigned int features; | 61 | unsigned int features; |
62 | unsigned int quirks; | 62 | unsigned int quirks; |
63 | unsigned int num_crtcs; | 63 | unsigned int channels_mask; |
64 | struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX]; | 64 | struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX]; |
65 | unsigned int num_lvds; | 65 | unsigned int num_lvds; |
66 | unsigned int dpll_ch; | 66 | unsigned int dpll_ch; |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c index 2f37ea901873..d539cb290a35 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_group.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c | |||
@@ -46,10 +46,13 @@ void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) | |||
46 | 46 | ||
47 | static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp) | 47 | static void rcar_du_group_setup_pins(struct rcar_du_group *rgrp) |
48 | { | 48 | { |
49 | u32 defr6 = DEFR6_CODE | DEFR6_ODPM12_DISP; | 49 | u32 defr6 = DEFR6_CODE; |
50 | 50 | ||
51 | if (rgrp->num_crtcs > 1) | 51 | if (rgrp->channels_mask & BIT(0)) |
52 | defr6 |= DEFR6_ODPM22_DISP; | 52 | defr6 |= DEFR6_ODPM02_DISP; |
53 | |||
54 | if (rgrp->channels_mask & BIT(1)) | ||
55 | defr6 |= DEFR6_ODPM12_DISP; | ||
53 | 56 | ||
54 | rcar_du_group_write(rgrp, DEFR6, defr6); | 57 | rcar_du_group_write(rgrp, DEFR6, defr6); |
55 | } | 58 | } |
@@ -80,10 +83,11 @@ static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp) | |||
80 | * On Gen3 VSPD routing can't be configured, but DPAD routing | 83 | * On Gen3 VSPD routing can't be configured, but DPAD routing |
81 | * needs to be set despite having a single option available. | 84 | * needs to be set despite having a single option available. |
82 | */ | 85 | */ |
83 | u32 crtc = ffs(possible_crtcs) - 1; | 86 | unsigned int rgb_crtc = ffs(possible_crtcs) - 1; |
87 | struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc]; | ||
84 | 88 | ||
85 | if (crtc / 2 == rgrp->index) | 89 | if (crtc->index / 2 == rgrp->index) |
86 | defr8 |= DEFR8_DRGBS_DU(crtc); | 90 | defr8 |= DEFR8_DRGBS_DU(crtc->index); |
87 | } | 91 | } |
88 | 92 | ||
89 | rcar_du_group_write(rgrp, DEFR8, defr8); | 93 | rcar_du_group_write(rgrp, DEFR8, defr8); |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h index 5e3adc6b31b5..42105aedecc8 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_group.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h | |||
@@ -25,6 +25,7 @@ struct rcar_du_device; | |||
25 | * @dev: the DU device | 25 | * @dev: the DU device |
26 | * @mmio_offset: registers offset in the device memory map | 26 | * @mmio_offset: registers offset in the device memory map |
27 | * @index: group index | 27 | * @index: group index |
28 | * @channels_mask: bitmask of populated DU channels in this group | ||
28 | * @num_crtcs: number of CRTCs in this group (1 or 2) | 29 | * @num_crtcs: number of CRTCs in this group (1 or 2) |
29 | * @use_count: number of users of the group (rcar_du_group_(get|put)) | 30 | * @use_count: number of users of the group (rcar_du_group_(get|put)) |
30 | * @used_crtcs: number of CRTCs currently in use | 31 | * @used_crtcs: number of CRTCs currently in use |
@@ -39,6 +40,7 @@ struct rcar_du_group { | |||
39 | unsigned int mmio_offset; | 40 | unsigned int mmio_offset; |
40 | unsigned int index; | 41 | unsigned int index; |
41 | 42 | ||
43 | unsigned int channels_mask; | ||
42 | unsigned int num_crtcs; | 44 | unsigned int num_crtcs; |
43 | unsigned int use_count; | 45 | unsigned int use_count; |
44 | unsigned int used_crtcs; | 46 | unsigned int used_crtcs; |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c index f4ac0f884f00..f0bc7cc0e913 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c | |||
@@ -428,7 +428,7 @@ static int rcar_du_vsps_init(struct rcar_du_device *rcdu) | |||
428 | struct { | 428 | struct { |
429 | struct device_node *np; | 429 | struct device_node *np; |
430 | unsigned int crtcs_mask; | 430 | unsigned int crtcs_mask; |
431 | } vsps[RCAR_DU_MAX_VSPS] = { { 0, }, }; | 431 | } vsps[RCAR_DU_MAX_VSPS] = { { NULL, }, }; |
432 | unsigned int vsps_count = 0; | 432 | unsigned int vsps_count = 0; |
433 | unsigned int cells; | 433 | unsigned int cells; |
434 | unsigned int i; | 434 | unsigned int i; |
@@ -507,6 +507,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) | |||
507 | struct drm_fbdev_cma *fbdev; | 507 | struct drm_fbdev_cma *fbdev; |
508 | unsigned int num_encoders; | 508 | unsigned int num_encoders; |
509 | unsigned int num_groups; | 509 | unsigned int num_groups; |
510 | unsigned int swindex; | ||
511 | unsigned int hwindex; | ||
510 | unsigned int i; | 512 | unsigned int i; |
511 | int ret; | 513 | int ret; |
512 | 514 | ||
@@ -520,7 +522,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) | |||
520 | dev->mode_config.funcs = &rcar_du_mode_config_funcs; | 522 | dev->mode_config.funcs = &rcar_du_mode_config_funcs; |
521 | dev->mode_config.helper_private = &rcar_du_mode_config_helper; | 523 | dev->mode_config.helper_private = &rcar_du_mode_config_helper; |
522 | 524 | ||
523 | rcdu->num_crtcs = rcdu->info->num_crtcs; | 525 | rcdu->num_crtcs = hweight8(rcdu->info->channels_mask); |
524 | 526 | ||
525 | ret = rcar_du_properties_init(rcdu); | 527 | ret = rcar_du_properties_init(rcdu); |
526 | if (ret < 0) | 528 | if (ret < 0) |
@@ -530,7 +532,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) | |||
530 | * Initialize vertical blanking interrupts handling. Start with vblank | 532 | * Initialize vertical blanking interrupts handling. Start with vblank |
531 | * disabled for all CRTCs. | 533 | * disabled for all CRTCs. |
532 | */ | 534 | */ |
533 | ret = drm_vblank_init(dev, (1 << rcdu->info->num_crtcs) - 1); | 535 | ret = drm_vblank_init(dev, (1 << rcdu->num_crtcs) - 1); |
534 | if (ret < 0) | 536 | if (ret < 0) |
535 | return ret; | 537 | return ret; |
536 | 538 | ||
@@ -545,7 +547,10 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) | |||
545 | rgrp->dev = rcdu; | 547 | rgrp->dev = rcdu; |
546 | rgrp->mmio_offset = mmio_offsets[i]; | 548 | rgrp->mmio_offset = mmio_offsets[i]; |
547 | rgrp->index = i; | 549 | rgrp->index = i; |
548 | rgrp->num_crtcs = min(rcdu->num_crtcs - 2 * i, 2U); | 550 | /* Extract the channel mask for this group only. */ |
551 | rgrp->channels_mask = (rcdu->info->channels_mask >> (2 * i)) | ||
552 | & GENMASK(1, 0); | ||
553 | rgrp->num_crtcs = hweight8(rgrp->channels_mask); | ||
549 | 554 | ||
550 | /* | 555 | /* |
551 | * If we have more than one CRTCs in this group pre-associate | 556 | * If we have more than one CRTCs in this group pre-associate |
@@ -572,10 +577,16 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) | |||
572 | } | 577 | } |
573 | 578 | ||
574 | /* Create the CRTCs. */ | 579 | /* Create the CRTCs. */ |
575 | for (i = 0; i < rcdu->num_crtcs; ++i) { | 580 | for (swindex = 0, hwindex = 0; swindex < rcdu->num_crtcs; ++hwindex) { |
576 | struct rcar_du_group *rgrp = &rcdu->groups[i / 2]; | 581 | struct rcar_du_group *rgrp; |
582 | |||
583 | /* Skip unpopulated DU channels. */ | ||
584 | if (!(rcdu->info->channels_mask & BIT(hwindex))) | ||
585 | continue; | ||
586 | |||
587 | rgrp = &rcdu->groups[hwindex / 2]; | ||
577 | 588 | ||
578 | ret = rcar_du_crtc_create(rgrp, i); | 589 | ret = rcar_du_crtc_create(rgrp, swindex++, hwindex); |
579 | if (ret < 0) | 590 | if (ret < 0) |
580 | return ret; | 591 | return ret; |
581 | } | 592 | } |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_of.c b/drivers/gpu/drm/rcar-du/rcar_du_of.c index 68a0b82cb17e..afef69669bb4 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_of.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_of.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include "rcar_du_crtc.h" | 19 | #include "rcar_du_crtc.h" |
20 | #include "rcar_du_drv.h" | 20 | #include "rcar_du_drv.h" |
21 | #include "rcar_du_of.h" | ||
21 | 22 | ||
22 | /* ----------------------------------------------------------------------------- | 23 | /* ----------------------------------------------------------------------------- |
23 | * Generic Overlay Handling | 24 | * Generic Overlay Handling |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h index d5bae99d3cfe..9dfd220ceda1 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h +++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h | |||
@@ -187,14 +187,14 @@ | |||
187 | 187 | ||
188 | #define DEFR6 0x000e8 | 188 | #define DEFR6 0x000e8 |
189 | #define DEFR6_CODE (0x7778 << 16) | 189 | #define DEFR6_CODE (0x7778 << 16) |
190 | #define DEFR6_ODPM22_DSMR (0 << 10) | 190 | #define DEFR6_ODPM12_DSMR (0 << 10) |
191 | #define DEFR6_ODPM22_DISP (2 << 10) | 191 | #define DEFR6_ODPM12_DISP (2 << 10) |
192 | #define DEFR6_ODPM22_CDE (3 << 10) | 192 | #define DEFR6_ODPM12_CDE (3 << 10) |
193 | #define DEFR6_ODPM22_MASK (3 << 10) | 193 | #define DEFR6_ODPM12_MASK (3 << 10) |
194 | #define DEFR6_ODPM12_DSMR (0 << 8) | 194 | #define DEFR6_ODPM02_DSMR (0 << 8) |
195 | #define DEFR6_ODPM12_DISP (2 << 8) | 195 | #define DEFR6_ODPM02_DISP (2 << 8) |
196 | #define DEFR6_ODPM12_CDE (3 << 8) | 196 | #define DEFR6_ODPM02_CDE (3 << 8) |
197 | #define DEFR6_ODPM12_MASK (3 << 8) | 197 | #define DEFR6_ODPM02_MASK (3 << 8) |
198 | #define DEFR6_TCNE1 (1 << 6) | 198 | #define DEFR6_TCNE1 (1 << 6) |
199 | #define DEFR6_TCNE0 (1 << 4) | 199 | #define DEFR6_TCNE0 (1 << 4) |
200 | #define DEFR6_MLOS1 (1 << 2) | 200 | #define DEFR6_MLOS1 (1 << 2) |
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index b3bec0125696..27a440886b17 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <drm/drm_crtc_helper.h> | 17 | #include <drm/drm_crtc_helper.h> |
18 | #include <drm/drm_fb_cma_helper.h> | 18 | #include <drm/drm_fb_cma_helper.h> |
19 | #include <drm/drm_gem_cma_helper.h> | 19 | #include <drm/drm_gem_cma_helper.h> |
20 | #include <drm/drm_gem_framebuffer_helper.h> | ||
20 | #include <drm/drm_plane_helper.h> | 21 | #include <drm/drm_plane_helper.h> |
21 | 22 | ||
22 | #include <linux/bitops.h> | 23 | #include <linux/bitops.h> |
@@ -237,6 +238,10 @@ static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane, | |||
237 | } | 238 | } |
238 | } | 239 | } |
239 | 240 | ||
241 | ret = drm_gem_fb_prepare_fb(plane, state); | ||
242 | if (ret) | ||
243 | goto fail; | ||
244 | |||
240 | return 0; | 245 | return 0; |
241 | 246 | ||
242 | fail: | 247 | fail: |
@@ -299,18 +304,17 @@ static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = { | |||
299 | static struct drm_plane_state * | 304 | static struct drm_plane_state * |
300 | rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane) | 305 | rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane) |
301 | { | 306 | { |
302 | struct rcar_du_vsp_plane_state *state; | ||
303 | struct rcar_du_vsp_plane_state *copy; | 307 | struct rcar_du_vsp_plane_state *copy; |
304 | 308 | ||
305 | if (WARN_ON(!plane->state)) | 309 | if (WARN_ON(!plane->state)) |
306 | return NULL; | 310 | return NULL; |
307 | 311 | ||
308 | state = to_rcar_vsp_plane_state(plane->state); | 312 | copy = kzalloc(sizeof(*copy), GFP_KERNEL); |
309 | copy = kmemdup(state, sizeof(*state), GFP_KERNEL); | ||
310 | if (copy == NULL) | 313 | if (copy == NULL) |
311 | return NULL; | 314 | return NULL; |
312 | 315 | ||
313 | __drm_atomic_helper_plane_duplicate_state(plane, ©->state); | 316 | __drm_atomic_helper_plane_duplicate_state(plane, ©->state); |
317 | copy->alpha = to_rcar_vsp_plane_state(plane->state)->alpha; | ||
314 | 318 | ||
315 | return ©->state; | 319 | return ©->state; |
316 | } | 320 | } |