diff options
author | james qian wang (Arm Technology China) <james.qian.wang@arm.com> | 2019-01-22 04:23:49 -0500 |
---|---|---|
committer | Liviu Dudau <Liviu.Dudau@arm.com> | 2019-04-01 13:07:43 -0400 |
commit | 71c420b7bf8a9303ae9b6b40d11ff23b4595e5aa (patch) | |
tree | 23a2a8ef57c4ea97cc22c71738ed62fd226f189d | |
parent | 1f2367a39f17bd553a75e179a747f9b257bc9478 (diff) |
drm/komeda: Add d71 layer
1. Add detailed layer/layer_state definitions
2. Add d71_layer_init to report layer features and capabilities according
to D71 layer block.
3. Add d71_layer_updat/disable
v2: Rebase.
Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
[removed d71_layer_dump() from this commit]
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
-rw-r--r-- | drivers/gpu/drm/arm/display/include/malidp_utils.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/display/komeda/d71/d71_component.c | 162 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h | 10 |
3 files changed, 185 insertions, 4 deletions
diff --git a/drivers/gpu/drm/arm/display/include/malidp_utils.h b/drivers/gpu/drm/arm/display/include/malidp_utils.h index 9096e40facfa..8cfd91196e15 100644 --- a/drivers/gpu/drm/arm/display/include/malidp_utils.h +++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h | |||
@@ -27,4 +27,21 @@ | |||
27 | num_tries; \ | 27 | num_tries; \ |
28 | }) | 28 | }) |
29 | 29 | ||
30 | /* the restriction of range is [start, end] */ | ||
31 | struct malidp_range { | ||
32 | u32 start; | ||
33 | u32 end; | ||
34 | }; | ||
35 | |||
36 | static inline void set_range(struct malidp_range *rg, u32 start, u32 end) | ||
37 | { | ||
38 | rg->start = start; | ||
39 | rg->end = end; | ||
40 | } | ||
41 | |||
42 | static inline bool in_range(struct malidp_range *rg, u32 v) | ||
43 | { | ||
44 | return (v >= rg->start) && (v <= rg->end); | ||
45 | } | ||
46 | |||
30 | #endif /* _MALIDP_UTILS_ */ | 47 | #endif /* _MALIDP_UTILS_ */ |
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c index c30a440e7b57..22324ac0881f 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c | |||
@@ -9,11 +9,171 @@ | |||
9 | #include "d71_dev.h" | 9 | #include "d71_dev.h" |
10 | #include "komeda_kms.h" | 10 | #include "komeda_kms.h" |
11 | #include "malidp_io.h" | 11 | #include "malidp_io.h" |
12 | #include "komeda_framebuffer.h" | ||
13 | |||
14 | static void get_resources_id(u32 hw_id, u32 *pipe_id, u32 *comp_id) | ||
15 | { | ||
16 | u32 id = BLOCK_INFO_BLK_ID(hw_id); | ||
17 | u32 pipe = id; | ||
18 | |||
19 | switch (BLOCK_INFO_BLK_TYPE(hw_id)) { | ||
20 | case D71_BLK_TYPE_LPU_WB_LAYER: | ||
21 | id = KOMEDA_COMPONENT_WB_LAYER; | ||
22 | break; | ||
23 | case D71_BLK_TYPE_CU_SPLITTER: | ||
24 | id = KOMEDA_COMPONENT_SPLITTER; | ||
25 | break; | ||
26 | case D71_BLK_TYPE_CU_SCALER: | ||
27 | pipe = id / D71_PIPELINE_MAX_SCALERS; | ||
28 | id %= D71_PIPELINE_MAX_SCALERS; | ||
29 | id += KOMEDA_COMPONENT_SCALER0; | ||
30 | break; | ||
31 | case D71_BLK_TYPE_CU: | ||
32 | id += KOMEDA_COMPONENT_COMPIZ0; | ||
33 | break; | ||
34 | case D71_BLK_TYPE_LPU_LAYER: | ||
35 | pipe = id / D71_PIPELINE_MAX_LAYERS; | ||
36 | id %= D71_PIPELINE_MAX_LAYERS; | ||
37 | id += KOMEDA_COMPONENT_LAYER0; | ||
38 | break; | ||
39 | case D71_BLK_TYPE_DOU_IPS: | ||
40 | id += KOMEDA_COMPONENT_IPS0; | ||
41 | break; | ||
42 | case D71_BLK_TYPE_CU_MERGER: | ||
43 | id = KOMEDA_COMPONENT_MERGER; | ||
44 | break; | ||
45 | case D71_BLK_TYPE_DOU: | ||
46 | id = KOMEDA_COMPONENT_TIMING_CTRLR; | ||
47 | break; | ||
48 | default: | ||
49 | id = 0xFFFFFFFF; | ||
50 | } | ||
51 | |||
52 | if (comp_id) | ||
53 | *comp_id = id; | ||
54 | |||
55 | if (pipe_id) | ||
56 | *pipe_id = pipe; | ||
57 | } | ||
58 | |||
59 | static u32 get_valid_inputs(struct block_header *blk) | ||
60 | { | ||
61 | u32 valid_inputs = 0, comp_id; | ||
62 | int i; | ||
63 | |||
64 | for (i = 0; i < PIPELINE_INFO_N_VALID_INPUTS(blk->pipeline_info); i++) { | ||
65 | get_resources_id(blk->input_ids[i], NULL, &comp_id); | ||
66 | if (comp_id == 0xFFFFFFFF) | ||
67 | continue; | ||
68 | valid_inputs |= BIT(comp_id); | ||
69 | } | ||
70 | |||
71 | return valid_inputs; | ||
72 | } | ||
73 | |||
74 | static u32 to_rot_ctrl(u32 rot) | ||
75 | { | ||
76 | u32 lr_ctrl = 0; | ||
77 | |||
78 | switch (rot & DRM_MODE_ROTATE_MASK) { | ||
79 | case DRM_MODE_ROTATE_0: | ||
80 | lr_ctrl |= L_ROT(L_ROT_R0); | ||
81 | break; | ||
82 | case DRM_MODE_ROTATE_90: | ||
83 | lr_ctrl |= L_ROT(L_ROT_R90); | ||
84 | break; | ||
85 | case DRM_MODE_ROTATE_180: | ||
86 | lr_ctrl |= L_ROT(L_ROT_R180); | ||
87 | break; | ||
88 | case DRM_MODE_ROTATE_270: | ||
89 | lr_ctrl |= L_ROT(L_ROT_R270); | ||
90 | break; | ||
91 | } | ||
92 | |||
93 | if (rot & DRM_MODE_REFLECT_X) | ||
94 | lr_ctrl |= L_HFLIP; | ||
95 | if (rot & DRM_MODE_REFLECT_Y) | ||
96 | lr_ctrl |= L_VFLIP; | ||
97 | |||
98 | return lr_ctrl; | ||
99 | } | ||
100 | |||
101 | static void d71_layer_disable(struct komeda_component *c) | ||
102 | { | ||
103 | malidp_write32_mask(c->reg, BLK_CONTROL, L_EN, 0); | ||
104 | } | ||
105 | |||
106 | static void d71_layer_update(struct komeda_component *c, | ||
107 | struct komeda_component_state *state) | ||
108 | { | ||
109 | struct komeda_layer_state *st = to_layer_st(state); | ||
110 | struct drm_plane_state *plane_st = state->plane->state; | ||
111 | struct drm_framebuffer *fb = plane_st->fb; | ||
112 | struct komeda_fb *kfb = to_kfb(fb); | ||
113 | u32 __iomem *reg = c->reg; | ||
114 | u32 ctrl_mask = L_EN | L_ROT(L_ROT_R270) | L_HFLIP | L_VFLIP | L_TBU_EN; | ||
115 | u32 ctrl = L_EN | to_rot_ctrl(st->rot); | ||
116 | int i; | ||
117 | |||
118 | for (i = 0; i < fb->format->num_planes; i++) { | ||
119 | malidp_write32(reg, | ||
120 | BLK_P0_PTR_LOW + i * LAYER_PER_PLANE_REGS * 4, | ||
121 | lower_32_bits(st->addr[i])); | ||
122 | malidp_write32(reg, | ||
123 | BLK_P0_PTR_HIGH + i * LAYER_PER_PLANE_REGS * 4, | ||
124 | upper_32_bits(st->addr[i])); | ||
125 | if (i >= 2) | ||
126 | break; | ||
127 | |||
128 | malidp_write32(reg, | ||
129 | BLK_P0_STRIDE + i * LAYER_PER_PLANE_REGS * 4, | ||
130 | fb->pitches[i] & 0xFFFF); | ||
131 | } | ||
132 | |||
133 | malidp_write32(reg, LAYER_FMT, kfb->format_caps->hw_id); | ||
134 | malidp_write32(reg, BLK_IN_SIZE, HV_SIZE(st->hsize, st->vsize)); | ||
135 | |||
136 | malidp_write32_mask(reg, BLK_CONTROL, ctrl_mask, ctrl); | ||
137 | } | ||
138 | |||
139 | static struct komeda_component_funcs d71_layer_funcs = { | ||
140 | .update = d71_layer_update, | ||
141 | .disable = d71_layer_disable, | ||
142 | }; | ||
12 | 143 | ||
13 | static int d71_layer_init(struct d71_dev *d71, | 144 | static int d71_layer_init(struct d71_dev *d71, |
14 | struct block_header *blk, u32 __iomem *reg) | 145 | struct block_header *blk, u32 __iomem *reg) |
15 | { | 146 | { |
16 | DRM_DEBUG("Detect D71_Layer.\n"); | 147 | struct komeda_component *c; |
148 | struct komeda_layer *layer; | ||
149 | u32 pipe_id, layer_id, layer_info; | ||
150 | |||
151 | get_resources_id(blk->block_info, &pipe_id, &layer_id); | ||
152 | c = komeda_component_add(&d71->pipes[pipe_id]->base, sizeof(*layer), | ||
153 | layer_id, | ||
154 | BLOCK_INFO_INPUT_ID(blk->block_info), | ||
155 | &d71_layer_funcs, 0, | ||
156 | get_valid_inputs(blk), | ||
157 | 1, reg, "LPU%d_LAYER%d", pipe_id, layer_id); | ||
158 | if (IS_ERR(c)) { | ||
159 | DRM_ERROR("Failed to add layer component\n"); | ||
160 | return PTR_ERR(c); | ||
161 | } | ||
162 | |||
163 | layer = to_layer(c); | ||
164 | layer_info = malidp_read32(reg, LAYER_INFO); | ||
165 | |||
166 | if (layer_info & L_INFO_RF) | ||
167 | layer->layer_type = KOMEDA_FMT_RICH_LAYER; | ||
168 | else | ||
169 | layer->layer_type = KOMEDA_FMT_SIMPLE_LAYER; | ||
170 | |||
171 | set_range(&layer->hsize_in, 4, d71->max_line_size); | ||
172 | set_range(&layer->vsize_in, 4, d71->max_vsize); | ||
173 | |||
174 | malidp_write32(reg, LAYER_PALPHA, D71_PALPHA_DEF_MAP); | ||
175 | |||
176 | layer->supported_rots = DRM_MODE_ROTATE_MASK | DRM_MODE_REFLECT_MASK; | ||
17 | 177 | ||
18 | return 0; | 178 | return 0; |
19 | } | 179 | } |
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index 8c950bc8ae96..03525330efe8 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h | |||
@@ -207,16 +207,20 @@ static inline u16 component_changed_inputs(struct komeda_component_state *st) | |||
207 | #define to_comp(__c) (((__c) == NULL) ? NULL : &((__c)->base)) | 207 | #define to_comp(__c) (((__c) == NULL) ? NULL : &((__c)->base)) |
208 | #define to_cpos(__c) ((struct komeda_component **)&(__c)) | 208 | #define to_cpos(__c) ((struct komeda_component **)&(__c)) |
209 | 209 | ||
210 | /* these structures are going to be filled in in uture patches */ | ||
211 | struct komeda_layer { | 210 | struct komeda_layer { |
212 | struct komeda_component base; | 211 | struct komeda_component base; |
213 | /* layer specific features and caps */ | 212 | /* accepted h/v input range before rotation */ |
214 | int layer_type; /* RICH, SIMPLE or WB */ | 213 | struct malidp_range hsize_in, vsize_in; |
214 | u32 layer_type; /* RICH, SIMPLE or WB */ | ||
215 | u32 supported_rots; | ||
215 | }; | 216 | }; |
216 | 217 | ||
217 | struct komeda_layer_state { | 218 | struct komeda_layer_state { |
218 | struct komeda_component_state base; | 219 | struct komeda_component_state base; |
219 | /* layer specific configuration state */ | 220 | /* layer specific configuration state */ |
221 | u16 hsize, vsize; | ||
222 | u32 rot; | ||
223 | dma_addr_t addr[3]; | ||
220 | }; | 224 | }; |
221 | 225 | ||
222 | struct komeda_compiz { | 226 | struct komeda_compiz { |