Commit 871409e95fe05ff9319e3fe8568855f47bfc8b89
Exists in
smarc_8mq_lf_v2020.04
and in
4 other branches
Merge remote-tracking branch 'origin/imx_v2020.04' into lf_v2020.04
* origin/imx_v2020.04: MLK-25320 video: imx_lcdifv3: Add memory priority threshold setting
Showing 1 changed file Side-by-side Diff
drivers/video/nxp/imx/imx_lcdifv3.c
... | ... | @@ -30,6 +30,11 @@ |
30 | 30 | struct lcdifv3_priv { |
31 | 31 | fdt_addr_t reg_base; |
32 | 32 | struct udevice *disp_dev; |
33 | + | |
34 | + u32 thres_low_mul; | |
35 | + u32 thres_low_div; | |
36 | + u32 thres_high_mul; | |
37 | + u32 thres_high_div; | |
33 | 38 | }; |
34 | 39 | |
35 | 40 | static int lcdifv3_set_pix_fmt(struct lcdifv3_priv *priv, unsigned int format) |
... | ... | @@ -114,6 +119,38 @@ |
114 | 119 | writel(disp_para, (ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); |
115 | 120 | } |
116 | 121 | |
122 | +static void lcdifv3_enable_plane_panic(struct lcdifv3_priv *priv) | |
123 | +{ | |
124 | + u32 panic_thres, thres_low, thres_high; | |
125 | + | |
126 | + /* apb clock has been enabled */ | |
127 | + | |
128 | + /* As suggestion, the thres_low should be 1/3 FIFO, | |
129 | + * and thres_high should be 2/3 FIFO (The FIFO size | |
130 | + * is 8KB = 512 * 128bit). | |
131 | + * threshold = n * 128bit (n: 0 ~ 511) | |
132 | + */ | |
133 | + thres_low = DIV_ROUND_UP(511 * priv->thres_low_mul, | |
134 | + priv->thres_low_div); | |
135 | + thres_high = DIV_ROUND_UP(511 * priv->thres_high_mul, | |
136 | + priv->thres_high_div); | |
137 | + | |
138 | + panic_thres = PANIC0_THRES_PANIC_THRES_LOW(thres_low) | | |
139 | + PANIC0_THRES_PANIC_THRES_HIGH(thres_high); | |
140 | + | |
141 | + writel(panic_thres, priv->reg_base + LCDIFV3_PANIC0_THRES); | |
142 | + | |
143 | + /* Enable Panic: | |
144 | + * | |
145 | + * As designed, the panic won't trigger an irq, | |
146 | + * so it is unnecessary to handle this as an irq | |
147 | + * and NoC + QoS modules will handle panic | |
148 | + * automatically. | |
149 | + */ | |
150 | + writel(INT_ENABLE_D1_PLANE_PANIC_EN, | |
151 | + priv->reg_base + LCDIFV3_INT_ENABLE_D1); | |
152 | +} | |
153 | + | |
117 | 154 | static void lcdifv3_enable_controller(struct lcdifv3_priv *priv) |
118 | 155 | { |
119 | 156 | u32 disp_para, ctrldescl0_5; |
... | ... | @@ -162,6 +199,9 @@ |
162 | 199 | |
163 | 200 | writel(CTRL_SW_RESET, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR)); |
164 | 201 | |
202 | + /* enable plane FIFO panic */ | |
203 | + lcdifv3_enable_plane_panic(priv); | |
204 | + | |
165 | 205 | lcdifv3_set_mode(priv, mode); |
166 | 206 | |
167 | 207 | lcdifv3_set_bus_fmt(priv); |
... | ... | @@ -224,6 +264,54 @@ |
224 | 264 | return ret; |
225 | 265 | } |
226 | 266 | |
267 | +static int lcdifv3_check_thres_value(u32 mul, u32 div) | |
268 | +{ | |
269 | + if (!div) | |
270 | + return -EINVAL; | |
271 | + | |
272 | + if (mul > div) | |
273 | + return -EINVAL; | |
274 | + | |
275 | + return 0; | |
276 | +} | |
277 | + | |
278 | +static void lcdifv3_of_parse_thres(struct udevice *dev) | |
279 | +{ | |
280 | + int ret; | |
281 | + u32 thres_low[2], thres_high[2]; | |
282 | + struct lcdifv3_priv *priv = dev_get_priv(dev); | |
283 | + | |
284 | + | |
285 | + /* default 'thres-low' value: FIFO * 1/3; | |
286 | + * default 'thres-high' value: FIFO * 2/3. | |
287 | + */ | |
288 | + priv->thres_low_mul = 1; | |
289 | + priv->thres_low_div = 3; | |
290 | + priv->thres_high_mul = 2; | |
291 | + priv->thres_high_div = 3; | |
292 | + | |
293 | + ret = dev_read_u32_array(dev, "thres-low", thres_low, 2); | |
294 | + if (!ret) { | |
295 | + /* check the value effectiveness */ | |
296 | + ret = lcdifv3_check_thres_value(thres_low[0], thres_low[1]); | |
297 | + if (!ret) { | |
298 | + priv->thres_low_mul = thres_low[0]; | |
299 | + priv->thres_low_div = thres_low[1]; | |
300 | + } | |
301 | + } | |
302 | + | |
303 | + ret = dev_read_u32_array(dev, "thres-high", thres_high, 2); | |
304 | + if (!ret) { | |
305 | + /* check the value effectiveness */ | |
306 | + ret = lcdifv3_check_thres_value(thres_high[0], thres_high[1]); | |
307 | + if (!ret) { | |
308 | + priv->thres_high_mul = thres_high[0]; | |
309 | + priv->thres_high_div = thres_high[1]; | |
310 | + } | |
311 | + } | |
312 | +} | |
313 | + | |
314 | + | |
227 | 315 | static int lcdifv3_video_probe(struct udevice *dev) |
228 | 316 | { |
229 | 317 | struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); |
... | ... | @@ -248,6 +336,8 @@ |
248 | 336 | ret = lcdifv3_of_get_timings(dev, &timings); |
249 | 337 | if (ret) |
250 | 338 | return ret; |
339 | + | |
340 | + lcdifv3_of_parse_thres(dev); | |
251 | 341 | |
252 | 342 | if (priv->disp_dev) { |
253 | 343 | #if IS_ENABLED(CONFIG_VIDEO_BRIDGE) |