diff options
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_kms.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_plane.c | 21 |
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 | ||
253 | static const struct rcar_du_device_info rcar_du_r8a7790_info = { | 253 | static 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 | ||
277 | static 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 | |||
277 | static const struct platform_device_id rcar_du_id_table[] = { | 296 | static 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; | |||
28 | struct rcar_du_lvdsenc; | 28 | struct 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 | */ |
55 | struct rcar_du_device_info { | 58 | struct 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 | ||
91 | static inline bool rcar_du_needs(struct rcar_du_device *rcdu, | ||
92 | unsigned int quirk) | ||
93 | { | ||
94 | return rcdu->info->quirks & quirk; | ||
95 | } | ||
96 | |||
87 | static inline u32 rcar_du_read(struct rcar_du_device *rcdu, u32 reg) | 97 | static 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; |