diff options
-rw-r--r-- | drivers/gpu/drm/arm/malidp_drv.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_hw.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_planes.c | 96 |
5 files changed, 92 insertions, 40 deletions
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index d53b625b14fe..ebf90c794eab 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c | |||
@@ -42,6 +42,7 @@ static int malidp_set_and_wait_config_valid(struct drm_device *drm) | |||
42 | struct malidp_hw_device *hwdev = malidp->dev; | 42 | struct malidp_hw_device *hwdev = malidp->dev; |
43 | int ret; | 43 | int ret; |
44 | 44 | ||
45 | atomic_set(&malidp->config_valid, 0); | ||
45 | hwdev->set_config_valid(hwdev); | 46 | hwdev->set_config_valid(hwdev); |
46 | /* don't wait for config_valid flag if we are in config mode */ | 47 | /* don't wait for config_valid flag if we are in config mode */ |
47 | if (hwdev->in_config_mode(hwdev)) | 48 | if (hwdev->in_config_mode(hwdev)) |
@@ -91,8 +92,7 @@ static void malidp_atomic_commit_tail(struct drm_atomic_state *state) | |||
91 | 92 | ||
92 | drm_atomic_helper_commit_modeset_disables(drm, state); | 93 | drm_atomic_helper_commit_modeset_disables(drm, state); |
93 | drm_atomic_helper_commit_modeset_enables(drm, state); | 94 | drm_atomic_helper_commit_modeset_enables(drm, state); |
94 | drm_atomic_helper_commit_planes(drm, state, | 95 | drm_atomic_helper_commit_planes(drm, state, 0); |
95 | DRM_PLANE_COMMIT_ACTIVE_ONLY); | ||
96 | 96 | ||
97 | malidp_atomic_commit_hw_done(state); | 97 | malidp_atomic_commit_hw_done(state); |
98 | 98 | ||
@@ -155,6 +155,12 @@ static int malidp_init(struct drm_device *drm) | |||
155 | return 0; | 155 | return 0; |
156 | } | 156 | } |
157 | 157 | ||
158 | static void malidp_fini(struct drm_device *drm) | ||
159 | { | ||
160 | malidp_de_planes_destroy(drm); | ||
161 | drm_mode_config_cleanup(drm); | ||
162 | } | ||
163 | |||
158 | static int malidp_irq_init(struct platform_device *pdev) | 164 | static int malidp_irq_init(struct platform_device *pdev) |
159 | { | 165 | { |
160 | int irq_de, irq_se, ret = 0; | 166 | int irq_de, irq_se, ret = 0; |
@@ -375,6 +381,8 @@ static int malidp_bind(struct device *dev) | |||
375 | if (ret < 0) | 381 | if (ret < 0) |
376 | goto irq_init_fail; | 382 | goto irq_init_fail; |
377 | 383 | ||
384 | drm->irq_enabled = true; | ||
385 | |||
378 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); | 386 | ret = drm_vblank_init(drm, drm->mode_config.num_crtc); |
379 | if (ret < 0) { | 387 | if (ret < 0) { |
380 | DRM_ERROR("failed to initialise vblank\n"); | 388 | DRM_ERROR("failed to initialise vblank\n"); |
@@ -400,6 +408,7 @@ fbdev_fail: | |||
400 | vblank_fail: | 408 | vblank_fail: |
401 | malidp_se_irq_fini(drm); | 409 | malidp_se_irq_fini(drm); |
402 | malidp_de_irq_fini(drm); | 410 | malidp_de_irq_fini(drm); |
411 | drm->irq_enabled = false; | ||
403 | irq_init_fail: | 412 | irq_init_fail: |
404 | component_unbind_all(dev, drm); | 413 | component_unbind_all(dev, drm); |
405 | bind_fail: | 414 | bind_fail: |
@@ -408,8 +417,7 @@ bind_fail: | |||
408 | port_fail: | 417 | port_fail: |
409 | drm_dev_unregister(drm); | 418 | drm_dev_unregister(drm); |
410 | register_fail: | 419 | register_fail: |
411 | malidp_de_planes_destroy(drm); | 420 | malidp_fini(drm); |
412 | drm_mode_config_cleanup(drm); | ||
413 | init_fail: | 421 | init_fail: |
414 | drm->dev_private = NULL; | 422 | drm->dev_private = NULL; |
415 | dev_set_drvdata(dev, NULL); | 423 | dev_set_drvdata(dev, NULL); |
@@ -442,8 +450,7 @@ static void malidp_unbind(struct device *dev) | |||
442 | of_node_put(malidp->crtc.port); | 450 | of_node_put(malidp->crtc.port); |
443 | malidp->crtc.port = NULL; | 451 | malidp->crtc.port = NULL; |
444 | drm_dev_unregister(drm); | 452 | drm_dev_unregister(drm); |
445 | malidp_de_planes_destroy(drm); | 453 | malidp_fini(drm); |
446 | drm_mode_config_cleanup(drm); | ||
447 | drm->dev_private = NULL; | 454 | drm->dev_private = NULL; |
448 | dev_set_drvdata(dev, NULL); | 455 | dev_set_drvdata(dev, NULL); |
449 | clk_disable_unprepare(hwdev->mclk); | 456 | clk_disable_unprepare(hwdev->mclk); |
diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h index 271d2fb9711c..9fc8a2e405e4 100644 --- a/drivers/gpu/drm/arm/malidp_drv.h +++ b/drivers/gpu/drm/arm/malidp_drv.h | |||
@@ -39,6 +39,9 @@ struct malidp_plane_state { | |||
39 | 39 | ||
40 | /* size of the required rotation memory if plane is rotated */ | 40 | /* size of the required rotation memory if plane is rotated */ |
41 | u32 rotmem_size; | 41 | u32 rotmem_size; |
42 | /* internal format ID */ | ||
43 | u8 format; | ||
44 | u8 n_planes; | ||
42 | }; | 45 | }; |
43 | 46 | ||
44 | #define to_malidp_plane(x) container_of(x, struct malidp_plane, base) | 47 | #define to_malidp_plane(x) container_of(x, struct malidp_plane, base) |
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index be815d0cc772..4bdf531f7844 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c | |||
@@ -125,6 +125,7 @@ static void malidp500_leave_config_mode(struct malidp_hw_device *hwdev) | |||
125 | { | 125 | { |
126 | u32 status, count = 100; | 126 | u32 status, count = 100; |
127 | 127 | ||
128 | malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP500_CONFIG_VALID); | ||
128 | malidp_hw_clearbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL); | 129 | malidp_hw_clearbits(hwdev, MALIDP500_DC_CONFIG_REQ, MALIDP500_DC_CONTROL); |
129 | while (count) { | 130 | while (count) { |
130 | status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); | 131 | status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); |
@@ -266,6 +267,7 @@ static void malidp550_leave_config_mode(struct malidp_hw_device *hwdev) | |||
266 | { | 267 | { |
267 | u32 status, count = 100; | 268 | u32 status, count = 100; |
268 | 269 | ||
270 | malidp_hw_clearbits(hwdev, MALIDP_CFG_VALID, MALIDP550_CONFIG_VALID); | ||
269 | malidp_hw_clearbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL); | 271 | malidp_hw_clearbits(hwdev, MALIDP550_DC_CONFIG_REQ, MALIDP550_DC_CONTROL); |
270 | while (count) { | 272 | while (count) { |
271 | status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); | 273 | status = malidp_hw_read(hwdev, hwdev->map.dc_base + MALIDP_REG_STATUS); |
@@ -436,6 +438,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { | |||
436 | }, | 438 | }, |
437 | .input_formats = malidp500_de_formats, | 439 | .input_formats = malidp500_de_formats, |
438 | .n_input_formats = ARRAY_SIZE(malidp500_de_formats), | 440 | .n_input_formats = ARRAY_SIZE(malidp500_de_formats), |
441 | .bus_align_bytes = 8, | ||
439 | }, | 442 | }, |
440 | .query_hw = malidp500_query_hw, | 443 | .query_hw = malidp500_query_hw, |
441 | .enter_config_mode = malidp500_enter_config_mode, | 444 | .enter_config_mode = malidp500_enter_config_mode, |
@@ -468,6 +471,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { | |||
468 | }, | 471 | }, |
469 | .input_formats = malidp550_de_formats, | 472 | .input_formats = malidp550_de_formats, |
470 | .n_input_formats = ARRAY_SIZE(malidp550_de_formats), | 473 | .n_input_formats = ARRAY_SIZE(malidp550_de_formats), |
474 | .bus_align_bytes = 8, | ||
471 | }, | 475 | }, |
472 | .query_hw = malidp550_query_hw, | 476 | .query_hw = malidp550_query_hw, |
473 | .enter_config_mode = malidp550_enter_config_mode, | 477 | .enter_config_mode = malidp550_enter_config_mode, |
@@ -501,6 +505,7 @@ const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES] = { | |||
501 | }, | 505 | }, |
502 | .input_formats = malidp550_de_formats, | 506 | .input_formats = malidp550_de_formats, |
503 | .n_input_formats = ARRAY_SIZE(malidp550_de_formats), | 507 | .n_input_formats = ARRAY_SIZE(malidp550_de_formats), |
508 | .bus_align_bytes = 16, | ||
504 | }, | 509 | }, |
505 | .query_hw = malidp650_query_hw, | 510 | .query_hw = malidp650_query_hw, |
506 | .enter_config_mode = malidp550_enter_config_mode, | 511 | .enter_config_mode = malidp550_enter_config_mode, |
diff --git a/drivers/gpu/drm/arm/malidp_hw.h b/drivers/gpu/drm/arm/malidp_hw.h index 141743e9f3a6..087e1202db3d 100644 --- a/drivers/gpu/drm/arm/malidp_hw.h +++ b/drivers/gpu/drm/arm/malidp_hw.h | |||
@@ -88,6 +88,9 @@ struct malidp_hw_regmap { | |||
88 | /* list of supported input formats for each layer */ | 88 | /* list of supported input formats for each layer */ |
89 | const struct malidp_input_format *input_formats; | 89 | const struct malidp_input_format *input_formats; |
90 | const u8 n_input_formats; | 90 | const u8 n_input_formats; |
91 | |||
92 | /* pitch alignment requirement in bytes */ | ||
93 | const u8 bus_align_bytes; | ||
91 | }; | 94 | }; |
92 | 95 | ||
93 | struct malidp_hw_device { | 96 | struct malidp_hw_device { |
@@ -229,6 +232,12 @@ void malidp_se_irq_fini(struct drm_device *drm); | |||
229 | u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map, | 232 | u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map, |
230 | u8 layer_id, u32 format); | 233 | u8 layer_id, u32 format); |
231 | 234 | ||
235 | static inline bool malidp_hw_pitch_valid(struct malidp_hw_device *hwdev, | ||
236 | unsigned int pitch) | ||
237 | { | ||
238 | return !(pitch & (hwdev->map.bus_align_bytes - 1)); | ||
239 | } | ||
240 | |||
232 | /* | 241 | /* |
233 | * background color components are defined as 12bits values, | 242 | * background color components are defined as 12bits values, |
234 | * they will be shifted right when stored on hardware that | 243 | * they will be shifted right when stored on hardware that |
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index abaca03b9d36..63eec8f37cfc 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c | |||
@@ -27,6 +27,10 @@ | |||
27 | #define LAYER_H_FLIP (1 << 10) | 27 | #define LAYER_H_FLIP (1 << 10) |
28 | #define LAYER_V_FLIP (1 << 11) | 28 | #define LAYER_V_FLIP (1 << 11) |
29 | #define LAYER_ROT_MASK (0xf << 8) | 29 | #define LAYER_ROT_MASK (0xf << 8) |
30 | #define LAYER_COMP_MASK (0x3 << 12) | ||
31 | #define LAYER_COMP_PIXEL (0x3 << 12) | ||
32 | #define LAYER_COMP_PLANE (0x2 << 12) | ||
33 | #define MALIDP_LAYER_COMPOSE 0x008 | ||
30 | #define MALIDP_LAYER_SIZE 0x00c | 34 | #define MALIDP_LAYER_SIZE 0x00c |
31 | #define LAYER_H_VAL(x) (((x) & 0x1fff) << 0) | 35 | #define LAYER_H_VAL(x) (((x) & 0x1fff) << 0) |
32 | #define LAYER_V_VAL(x) (((x) & 0x1fff) << 16) | 36 | #define LAYER_V_VAL(x) (((x) & 0x1fff) << 16) |
@@ -34,6 +38,14 @@ | |||
34 | #define MALIDP_LAYER_OFFSET 0x014 | 38 | #define MALIDP_LAYER_OFFSET 0x014 |
35 | #define MALIDP_LAYER_STRIDE 0x018 | 39 | #define MALIDP_LAYER_STRIDE 0x018 |
36 | 40 | ||
41 | /* | ||
42 | * This 4-entry look-up-table is used to determine the full 8-bit alpha value | ||
43 | * for formats with 1- or 2-bit alpha channels. | ||
44 | * We set it to give 100%/0% opacity for 1-bit formats and 100%/66%/33%/0% | ||
45 | * opacity for 2-bit formats. | ||
46 | */ | ||
47 | #define MALIDP_ALPHA_LUT 0xffaa5500 | ||
48 | |||
37 | static void malidp_de_plane_destroy(struct drm_plane *plane) | 49 | static void malidp_de_plane_destroy(struct drm_plane *plane) |
38 | { | 50 | { |
39 | struct malidp_plane *mp = to_malidp_plane(plane); | 51 | struct malidp_plane *mp = to_malidp_plane(plane); |
@@ -46,7 +58,8 @@ static void malidp_de_plane_destroy(struct drm_plane *plane) | |||
46 | devm_kfree(plane->dev->dev, mp); | 58 | devm_kfree(plane->dev->dev, mp); |
47 | } | 59 | } |
48 | 60 | ||
49 | struct drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane) | 61 | static struct |
62 | drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane) | ||
50 | { | 63 | { |
51 | struct malidp_plane_state *state, *m_state; | 64 | struct malidp_plane_state *state, *m_state; |
52 | 65 | ||
@@ -58,13 +71,15 @@ struct drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane) | |||
58 | m_state = to_malidp_plane_state(plane->state); | 71 | m_state = to_malidp_plane_state(plane->state); |
59 | __drm_atomic_helper_plane_duplicate_state(plane, &state->base); | 72 | __drm_atomic_helper_plane_duplicate_state(plane, &state->base); |
60 | state->rotmem_size = m_state->rotmem_size; | 73 | state->rotmem_size = m_state->rotmem_size; |
74 | state->format = m_state->format; | ||
75 | state->n_planes = m_state->n_planes; | ||
61 | } | 76 | } |
62 | 77 | ||
63 | return &state->base; | 78 | return &state->base; |
64 | } | 79 | } |
65 | 80 | ||
66 | void malidp_destroy_plane_state(struct drm_plane *plane, | 81 | static void malidp_destroy_plane_state(struct drm_plane *plane, |
67 | struct drm_plane_state *state) | 82 | struct drm_plane_state *state) |
68 | { | 83 | { |
69 | struct malidp_plane_state *m_state = to_malidp_plane_state(state); | 84 | struct malidp_plane_state *m_state = to_malidp_plane_state(state); |
70 | 85 | ||
@@ -75,6 +90,7 @@ void malidp_destroy_plane_state(struct drm_plane *plane, | |||
75 | static const struct drm_plane_funcs malidp_de_plane_funcs = { | 90 | static const struct drm_plane_funcs malidp_de_plane_funcs = { |
76 | .update_plane = drm_atomic_helper_update_plane, | 91 | .update_plane = drm_atomic_helper_update_plane, |
77 | .disable_plane = drm_atomic_helper_disable_plane, | 92 | .disable_plane = drm_atomic_helper_disable_plane, |
93 | .set_property = drm_atomic_helper_plane_set_property, | ||
78 | .destroy = malidp_de_plane_destroy, | 94 | .destroy = malidp_de_plane_destroy, |
79 | .reset = drm_atomic_helper_plane_reset, | 95 | .reset = drm_atomic_helper_plane_reset, |
80 | .atomic_duplicate_state = malidp_duplicate_plane_state, | 96 | .atomic_duplicate_state = malidp_duplicate_plane_state, |
@@ -86,17 +102,29 @@ static int malidp_de_plane_check(struct drm_plane *plane, | |||
86 | { | 102 | { |
87 | struct malidp_plane *mp = to_malidp_plane(plane); | 103 | struct malidp_plane *mp = to_malidp_plane(plane); |
88 | struct malidp_plane_state *ms = to_malidp_plane_state(state); | 104 | struct malidp_plane_state *ms = to_malidp_plane_state(state); |
89 | u8 format_id; | 105 | struct drm_framebuffer *fb; |
106 | int i; | ||
90 | u32 src_w, src_h; | 107 | u32 src_w, src_h; |
91 | 108 | ||
92 | if (!state->crtc || !state->fb) | 109 | if (!state->crtc || !state->fb) |
93 | return 0; | 110 | return 0; |
94 | 111 | ||
95 | format_id = malidp_hw_get_format_id(&mp->hwdev->map, mp->layer->id, | 112 | fb = state->fb; |
96 | state->fb->pixel_format); | 113 | |
97 | if (format_id == MALIDP_INVALID_FORMAT_ID) | 114 | ms->format = malidp_hw_get_format_id(&mp->hwdev->map, mp->layer->id, |
115 | fb->pixel_format); | ||
116 | if (ms->format == MALIDP_INVALID_FORMAT_ID) | ||
98 | return -EINVAL; | 117 | return -EINVAL; |
99 | 118 | ||
119 | ms->n_planes = drm_format_num_planes(fb->pixel_format); | ||
120 | for (i = 0; i < ms->n_planes; i++) { | ||
121 | if (!malidp_hw_pitch_valid(mp->hwdev, fb->pitches[i])) { | ||
122 | DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n", | ||
123 | fb->pitches[i], i); | ||
124 | return -EINVAL; | ||
125 | } | ||
126 | } | ||
127 | |||
100 | src_w = state->src_w >> 16; | 128 | src_w = state->src_w >> 16; |
101 | src_h = state->src_h >> 16; | 129 | src_h = state->src_h >> 16; |
102 | 130 | ||
@@ -135,17 +163,13 @@ static void malidp_de_plane_update(struct drm_plane *plane, | |||
135 | struct drm_gem_cma_object *obj; | 163 | struct drm_gem_cma_object *obj; |
136 | struct malidp_plane *mp; | 164 | struct malidp_plane *mp; |
137 | const struct malidp_hw_regmap *map; | 165 | const struct malidp_hw_regmap *map; |
138 | u8 format_id; | 166 | struct malidp_plane_state *ms = to_malidp_plane_state(plane->state); |
139 | u16 ptr; | 167 | u16 ptr; |
140 | u32 format, src_w, src_h, dest_w, dest_h, val = 0; | 168 | u32 src_w, src_h, dest_w, dest_h, val; |
141 | int num_planes, i; | 169 | int i; |
142 | 170 | ||
143 | mp = to_malidp_plane(plane); | 171 | mp = to_malidp_plane(plane); |
144 | |||
145 | map = &mp->hwdev->map; | 172 | map = &mp->hwdev->map; |
146 | format = plane->state->fb->pixel_format; | ||
147 | format_id = malidp_hw_get_format_id(map, mp->layer->id, format); | ||
148 | num_planes = drm_format_num_planes(format); | ||
149 | 173 | ||
150 | /* convert src values from Q16 fixed point to integer */ | 174 | /* convert src values from Q16 fixed point to integer */ |
151 | src_w = plane->state->src_w >> 16; | 175 | src_w = plane->state->src_w >> 16; |
@@ -158,9 +182,9 @@ static void malidp_de_plane_update(struct drm_plane *plane, | |||
158 | dest_h = plane->state->crtc_h; | 182 | dest_h = plane->state->crtc_h; |
159 | } | 183 | } |
160 | 184 | ||
161 | malidp_hw_write(mp->hwdev, format_id, mp->layer->base); | 185 | malidp_hw_write(mp->hwdev, ms->format, mp->layer->base); |
162 | 186 | ||
163 | for (i = 0; i < num_planes; i++) { | 187 | for (i = 0; i < ms->n_planes; i++) { |
164 | /* calculate the offset for the layer's plane registers */ | 188 | /* calculate the offset for the layer's plane registers */ |
165 | ptr = mp->layer->ptr + (i << 4); | 189 | ptr = mp->layer->ptr + (i << 4); |
166 | 190 | ||
@@ -181,9 +205,9 @@ static void malidp_de_plane_update(struct drm_plane *plane, | |||
181 | LAYER_V_VAL(plane->state->crtc_y), | 205 | LAYER_V_VAL(plane->state->crtc_y), |
182 | mp->layer->base + MALIDP_LAYER_OFFSET); | 206 | mp->layer->base + MALIDP_LAYER_OFFSET); |
183 | 207 | ||
184 | /* first clear the rotation bits in the register */ | 208 | /* first clear the rotation bits */ |
185 | malidp_hw_clearbits(mp->hwdev, LAYER_ROT_MASK, | 209 | val = malidp_hw_read(mp->hwdev, mp->layer->base + MALIDP_LAYER_CONTROL); |
186 | mp->layer->base + MALIDP_LAYER_CONTROL); | 210 | val &= ~LAYER_ROT_MASK; |
187 | 211 | ||
188 | /* setup the rotation and axis flip bits */ | 212 | /* setup the rotation and axis flip bits */ |
189 | if (plane->state->rotation & DRM_ROTATE_MASK) | 213 | if (plane->state->rotation & DRM_ROTATE_MASK) |
@@ -193,11 +217,18 @@ static void malidp_de_plane_update(struct drm_plane *plane, | |||
193 | if (plane->state->rotation & DRM_REFLECT_Y) | 217 | if (plane->state->rotation & DRM_REFLECT_Y) |
194 | val |= LAYER_H_FLIP; | 218 | val |= LAYER_H_FLIP; |
195 | 219 | ||
220 | /* | ||
221 | * always enable pixel alpha blending until we have a way to change | ||
222 | * blend modes | ||
223 | */ | ||
224 | val &= ~LAYER_COMP_MASK; | ||
225 | val |= LAYER_COMP_PIXEL; | ||
226 | |||
196 | /* set the 'enable layer' bit */ | 227 | /* set the 'enable layer' bit */ |
197 | val |= LAYER_ENABLE; | 228 | val |= LAYER_ENABLE; |
198 | 229 | ||
199 | malidp_hw_setbits(mp->hwdev, val, | 230 | malidp_hw_write(mp->hwdev, val, |
200 | mp->layer->base + MALIDP_LAYER_CONTROL); | 231 | mp->layer->base + MALIDP_LAYER_CONTROL); |
201 | } | 232 | } |
202 | 233 | ||
203 | static void malidp_de_plane_disable(struct drm_plane *plane, | 234 | static void malidp_de_plane_disable(struct drm_plane *plane, |
@@ -222,6 +253,8 @@ int malidp_de_planes_init(struct drm_device *drm) | |||
222 | struct malidp_plane *plane = NULL; | 253 | struct malidp_plane *plane = NULL; |
223 | enum drm_plane_type plane_type; | 254 | enum drm_plane_type plane_type; |
224 | unsigned long crtcs = 1 << drm->mode_config.num_crtc; | 255 | unsigned long crtcs = 1 << drm->mode_config.num_crtc; |
256 | unsigned long flags = DRM_ROTATE_0 | DRM_ROTATE_90 | DRM_ROTATE_180 | | ||
257 | DRM_ROTATE_270 | DRM_REFLECT_X | DRM_REFLECT_Y; | ||
225 | u32 *formats; | 258 | u32 *formats; |
226 | int ret, i, j, n; | 259 | int ret, i, j, n; |
227 | 260 | ||
@@ -254,23 +287,18 @@ int malidp_de_planes_init(struct drm_device *drm) | |||
254 | if (ret < 0) | 287 | if (ret < 0) |
255 | goto cleanup; | 288 | goto cleanup; |
256 | 289 | ||
257 | /* SMART layer can't be rotated */ | ||
258 | if (id != DE_SMART) { | ||
259 | unsigned long flags = DRM_ROTATE_0 | | ||
260 | DRM_ROTATE_90 | | ||
261 | DRM_ROTATE_180 | | ||
262 | DRM_ROTATE_270 | | ||
263 | DRM_REFLECT_X | | ||
264 | DRM_REFLECT_Y; | ||
265 | drm_plane_create_rotation_property(&plane->base, | ||
266 | DRM_ROTATE_0, | ||
267 | flags); | ||
268 | } | ||
269 | |||
270 | drm_plane_helper_add(&plane->base, | 290 | drm_plane_helper_add(&plane->base, |
271 | &malidp_de_plane_helper_funcs); | 291 | &malidp_de_plane_helper_funcs); |
272 | plane->hwdev = malidp->dev; | 292 | plane->hwdev = malidp->dev; |
273 | plane->layer = &map->layers[i]; | 293 | plane->layer = &map->layers[i]; |
294 | |||
295 | /* Skip the features which the SMART layer doesn't have */ | ||
296 | if (id == DE_SMART) | ||
297 | continue; | ||
298 | |||
299 | drm_plane_create_rotation_property(&plane->base, DRM_ROTATE_0, flags); | ||
300 | malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT, | ||
301 | plane->layer->base + MALIDP_LAYER_COMPOSE); | ||
274 | } | 302 | } |
275 | 303 | ||
276 | kfree(formats); | 304 | kfree(formats); |