aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_crtc.c3
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c24
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.h14
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c4
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c15
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c21
6 files changed, 58 insertions, 23 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index a9d24e4bf792..fbf4be316d0b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -371,7 +371,6 @@ static int rcar_du_crtc_mode_set(struct drm_crtc *crtc,
371 goto error; 371 goto error;
372 372
373 rcrtc->plane->format = format; 373 rcrtc->plane->format = format;
374 rcrtc->plane->pitch = crtc->fb->pitches[0];
375 374
376 rcrtc->plane->src_x = x; 375 rcrtc->plane->src_x = x;
377 rcrtc->plane->src_y = y; 376 rcrtc->plane->src_y = y;
@@ -413,7 +412,7 @@ static int rcar_du_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
413 rcrtc->plane->src_x = x; 412 rcrtc->plane->src_x = x;
414 rcrtc->plane->src_y = y; 413 rcrtc->plane->src_y = y;
415 414
416 rcar_du_crtc_update_base(to_rcar_crtc(crtc)); 415 rcar_du_crtc_update_base(rcrtc);
417 416
418 return 0; 417 return 0;
419} 418}
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 4ec6272a1c11..792fd1d20e86 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -251,8 +251,8 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = {
251}; 251};
252 252
253static const struct rcar_du_device_info rcar_du_r8a7790_info = { 253static const struct rcar_du_device_info rcar_du_r8a7790_info = {
254 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_ALIGN_128B 254 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
255 | RCAR_DU_FEATURE_DEFR8, 255 .quirks = RCAR_DU_QUIRK_ALIGN_128B | RCAR_DU_QUIRK_LVDS_LANES,
256 .num_crtcs = 3, 256 .num_crtcs = 3,
257 .routes = { 257 .routes = {
258 /* R8A7790 has one RGB output, two LVDS outputs and one 258 /* R8A7790 has one RGB output, two LVDS outputs and one
@@ -274,9 +274,29 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = {
274 .num_lvds = 2, 274 .num_lvds = 2,
275}; 275};
276 276
277static const struct rcar_du_device_info rcar_du_r8a7791_info = {
278 .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_DEFR8,
279 .num_crtcs = 2,
280 .routes = {
281 /* R8A7791 has one RGB output, one LVDS output and one
282 * (currently unsupported) TCON output.
283 */
284 [RCAR_DU_OUTPUT_DPAD0] = {
285 .possible_crtcs = BIT(1),
286 .encoder_type = DRM_MODE_ENCODER_NONE,
287 },
288 [RCAR_DU_OUTPUT_LVDS0] = {
289 .possible_crtcs = BIT(0),
290 .encoder_type = DRM_MODE_ENCODER_LVDS,
291 },
292 },
293 .num_lvds = 1,
294};
295
277static const struct platform_device_id rcar_du_id_table[] = { 296static const struct platform_device_id rcar_du_id_table[] = {
278 { "rcar-du-r8a7779", (kernel_ulong_t)&rcar_du_r8a7779_info }, 297 { "rcar-du-r8a7779", (kernel_ulong_t)&rcar_du_r8a7779_info },
279 { "rcar-du-r8a7790", (kernel_ulong_t)&rcar_du_r8a7790_info }, 298 { "rcar-du-r8a7790", (kernel_ulong_t)&rcar_du_r8a7790_info },
299 { "rcar-du-r8a7791", (kernel_ulong_t)&rcar_du_r8a7791_info },
280 { } 300 { }
281}; 301};
282 302
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 65d2d636b002..e31b735d3f25 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -28,8 +28,10 @@ struct rcar_du_device;
28struct rcar_du_lvdsenc; 28struct rcar_du_lvdsenc;
29 29
30#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */ 30#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */
31#define RCAR_DU_FEATURE_ALIGN_128B (1 << 1) /* Align pitches to 128 bytes */ 31#define RCAR_DU_FEATURE_DEFR8 (1 << 1) /* Has DEFR8 register */
32#define RCAR_DU_FEATURE_DEFR8 (1 << 2) /* Has DEFR8 register */ 32
33#define RCAR_DU_QUIRK_ALIGN_128B (1 << 0) /* Align pitches to 128 bytes */
34#define RCAR_DU_QUIRK_LVDS_LANES (1 << 1) /* LVDS lanes 1 and 3 inverted */
33 35
34/* 36/*
35 * struct rcar_du_output_routing - Output routing specification 37 * struct rcar_du_output_routing - Output routing specification
@@ -48,12 +50,14 @@ struct rcar_du_output_routing {
48/* 50/*
49 * struct rcar_du_device_info - DU model-specific information 51 * struct rcar_du_device_info - DU model-specific information
50 * @features: device features (RCAR_DU_FEATURE_*) 52 * @features: device features (RCAR_DU_FEATURE_*)
53 * @quirks: device quirks (RCAR_DU_QUIRK_*)
51 * @num_crtcs: total number of CRTCs 54 * @num_crtcs: total number of CRTCs
52 * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*) 55 * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*)
53 * @num_lvds: number of internal LVDS encoders 56 * @num_lvds: number of internal LVDS encoders
54 */ 57 */
55struct rcar_du_device_info { 58struct rcar_du_device_info {
56 unsigned int features; 59 unsigned int features;
60 unsigned int quirks;
57 unsigned int num_crtcs; 61 unsigned int num_crtcs;
58 struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX]; 62 struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
59 unsigned int num_lvds; 63 unsigned int num_lvds;
@@ -84,6 +88,12 @@ static inline bool rcar_du_has(struct rcar_du_device *rcdu,
84 return rcdu->info->features & feature; 88 return rcdu->info->features & feature;
85} 89}
86 90
91static inline bool rcar_du_needs(struct rcar_du_device *rcdu,
92 unsigned int quirk)
93{
94 return rcdu->info->quirks & quirk;
95}
96
87static inline u32 rcar_du_read(struct rcar_du_device *rcdu, u32 reg) 97static inline u32 rcar_du_read(struct rcar_du_device *rcdu, u32 reg)
88{ 98{
89 return ioread32(rcdu->mmio + reg); 99 return ioread32(rcdu->mmio + reg);
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index b31ac080c4a7..fbeabd9a281f 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -119,7 +119,7 @@ int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
119 /* The R8A7779 DU requires a 16 pixels pitch alignment as documented, 119 /* The R8A7779 DU requires a 16 pixels pitch alignment as documented,
120 * but the R8A7790 DU seems to require a 128 bytes pitch alignment. 120 * but the R8A7790 DU seems to require a 128 bytes pitch alignment.
121 */ 121 */
122 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_ALIGN_128B)) 122 if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
123 align = 128; 123 align = 128;
124 else 124 else
125 align = 16 * args->bpp / 8; 125 align = 16 * args->bpp / 8;
@@ -144,7 +144,7 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv,
144 return ERR_PTR(-EINVAL); 144 return ERR_PTR(-EINVAL);
145 } 145 }
146 146
147 if (rcar_du_has(rcdu, RCAR_DU_FEATURE_ALIGN_128B)) 147 if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
148 align = 128; 148 align = 128;
149 else 149 else
150 align = 16 * format->bpp / 8; 150 align = 16 * format->bpp / 8;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
index fe1f6f59f539..df30a075d793 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c
@@ -44,6 +44,7 @@ static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds,
44 const struct drm_display_mode *mode = &rcrtc->crtc.mode; 44 const struct drm_display_mode *mode = &rcrtc->crtc.mode;
45 unsigned int freq = mode->clock; 45 unsigned int freq = mode->clock;
46 u32 lvdcr0; 46 u32 lvdcr0;
47 u32 lvdhcr;
47 u32 pllcr; 48 u32 pllcr;
48 int ret; 49 int ret;
49 50
@@ -72,15 +73,19 @@ static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds,
72 * VSYNC -> CTRL1 73 * VSYNC -> CTRL1
73 * DISP -> CTRL2 74 * DISP -> CTRL2
74 * 0 -> CTRL3 75 * 0 -> CTRL3
75 *
76 * Channels 1 and 3 are switched on ES1.
77 */ 76 */
78 rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO | 77 rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO |
79 LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC | 78 LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC |
80 LVDCTRCR_CTR0SEL_HSYNC); 79 LVDCTRCR_CTR0SEL_HSYNC);
81 rcar_lvds_write(lvds, LVDCHCR, 80
82 LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 3) | 81 if (rcar_du_needs(lvds->dev, RCAR_DU_QUIRK_LVDS_LANES))
83 LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 1)); 82 lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 3)
83 | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 1);
84 else
85 lvdhcr = LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 1)
86 | LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 3);
87
88 rcar_lvds_write(lvds, LVDCHCR, lvdhcr);
84 89
85 /* Select the input, hardcode mode 0, enable LVDS operation and turn 90 /* Select the input, hardcode mode 0, enable LVDS operation and turn
86 * bias circuitry on. 91 * bias circuitry on.
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index 53000644733f..3fb69d9ae61b 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -104,6 +104,15 @@ void rcar_du_plane_update_base(struct rcar_du_plane *plane)
104{ 104{
105 struct rcar_du_group *rgrp = plane->group; 105 struct rcar_du_group *rgrp = plane->group;
106 unsigned int index = plane->hwindex; 106 unsigned int index = plane->hwindex;
107 u32 mwr;
108
109 /* Memory pitch (expressed in pixels) */
110 if (plane->format->planes == 2)
111 mwr = plane->pitch;
112 else
113 mwr = plane->pitch * 8 / plane->format->bpp;
114
115 rcar_du_plane_write(rgrp, index, PnMWR, mwr);
107 116
108 /* The Y position is expressed in raster line units and must be doubled 117 /* The Y position is expressed in raster line units and must be doubled
109 * for 32bpp formats, according to the R8A7790 datasheet. No mention of 118 * for 32bpp formats, according to the R8A7790 datasheet. No mention of
@@ -133,6 +142,8 @@ void rcar_du_plane_compute_base(struct rcar_du_plane *plane,
133{ 142{
134 struct drm_gem_cma_object *gem; 143 struct drm_gem_cma_object *gem;
135 144
145 plane->pitch = fb->pitches[0];
146
136 gem = drm_fb_cma_get_gem_obj(fb, 0); 147 gem = drm_fb_cma_get_gem_obj(fb, 0);
137 plane->dma[0] = gem->paddr + fb->offsets[0]; 148 plane->dma[0] = gem->paddr + fb->offsets[0];
138 149
@@ -209,7 +220,6 @@ static void __rcar_du_plane_setup(struct rcar_du_plane *plane,
209 struct rcar_du_group *rgrp = plane->group; 220 struct rcar_du_group *rgrp = plane->group;
210 u32 ddcr2 = PnDDCR2_CODE; 221 u32 ddcr2 = PnDDCR2_CODE;
211 u32 ddcr4; 222 u32 ddcr4;
212 u32 mwr;
213 223
214 /* Data format 224 /* Data format
215 * 225 *
@@ -240,14 +250,6 @@ static void __rcar_du_plane_setup(struct rcar_du_plane *plane,
240 rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2); 250 rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2);
241 rcar_du_plane_write(rgrp, index, PnDDCR4, ddcr4); 251 rcar_du_plane_write(rgrp, index, PnDDCR4, ddcr4);
242 252
243 /* Memory pitch (expressed in pixels) */
244 if (plane->format->planes == 2)
245 mwr = plane->pitch;
246 else
247 mwr = plane->pitch * 8 / plane->format->bpp;
248
249 rcar_du_plane_write(rgrp, index, PnMWR, mwr);
250
251 /* Destination position and size */ 253 /* Destination position and size */
252 rcar_du_plane_write(rgrp, index, PnDSXR, plane->width); 254 rcar_du_plane_write(rgrp, index, PnDSXR, plane->width);
253 rcar_du_plane_write(rgrp, index, PnDSYR, plane->height); 255 rcar_du_plane_write(rgrp, index, PnDSYR, plane->height);
@@ -309,7 +311,6 @@ rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc,
309 311
310 rplane->crtc = crtc; 312 rplane->crtc = crtc;
311 rplane->format = format; 313 rplane->format = format;
312 rplane->pitch = fb->pitches[0];
313 314
314 rplane->src_x = src_x >> 16; 315 rplane->src_x = src_x >> 16;
315 rplane->src_y = src_y >> 16; 316 rplane->src_y = src_y >> 16;