Commit 871409e95fe05ff9319e3fe8568855f47bfc8b89

Authored by BJ DevOps Team

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 Inline Diff

drivers/video/nxp/imx/imx_lcdifv3.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright 2019 NXP 3 * Copyright 2019 NXP
4 */ 4 */
5 5
6 #include <common.h> 6 #include <common.h>
7 #include <malloc.h> 7 #include <malloc.h>
8 #include <video.h> 8 #include <video.h>
9 #include <video_fb.h> 9 #include <video_fb.h>
10 #include <video_bridge.h> 10 #include <video_bridge.h>
11 #include <video_link.h> 11 #include <video_link.h>
12 12
13 #include <asm/arch/imx-regs.h> 13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/clock.h> 14 #include <asm/arch/clock.h>
15 #include <asm/arch/sys_proto.h> 15 #include <asm/arch/sys_proto.h>
16 #include <linux/err.h> 16 #include <linux/err.h>
17 #include <asm/io.h> 17 #include <asm/io.h>
18 18
19 #include "../../videomodes.h" 19 #include "../../videomodes.h"
20 #include <linux/string.h> 20 #include <linux/string.h>
21 #include <linux/list.h> 21 #include <linux/list.h>
22 #include <linux/fb.h> 22 #include <linux/fb.h>
23 #include "lcdifv3-regs.h" 23 #include "lcdifv3-regs.h"
24 #include <dm.h> 24 #include <dm.h>
25 #include <dm/device-internal.h> 25 #include <dm/device-internal.h>
26 26
27 #define PS2KHZ(ps) (1000000000UL / (ps)) 27 #define PS2KHZ(ps) (1000000000UL / (ps))
28 #define HZ2PS(hz) (1000000000UL / ((hz) / 1000)) 28 #define HZ2PS(hz) (1000000000UL / ((hz) / 1000))
29 29
30 struct lcdifv3_priv { 30 struct lcdifv3_priv {
31 fdt_addr_t reg_base; 31 fdt_addr_t reg_base;
32 struct udevice *disp_dev; 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 static int lcdifv3_set_pix_fmt(struct lcdifv3_priv *priv, unsigned int format) 40 static int lcdifv3_set_pix_fmt(struct lcdifv3_priv *priv, unsigned int format)
36 { 41 {
37 uint32_t ctrldescl0_5 = 0; 42 uint32_t ctrldescl0_5 = 0;
38 43
39 ctrldescl0_5 = readl((ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5)); 44 ctrldescl0_5 = readl((ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5));
40 45
41 WARN_ON(ctrldescl0_5 & CTRLDESCL0_5_SHADOW_LOAD_EN); 46 WARN_ON(ctrldescl0_5 & CTRLDESCL0_5_SHADOW_LOAD_EN);
42 47
43 ctrldescl0_5 &= ~(CTRLDESCL0_5_BPP(0xf) | CTRLDESCL0_5_YUV_FORMAT(0x3)); 48 ctrldescl0_5 &= ~(CTRLDESCL0_5_BPP(0xf) | CTRLDESCL0_5_YUV_FORMAT(0x3));
44 49
45 switch (format) { 50 switch (format) {
46 case GDF_16BIT_565RGB: 51 case GDF_16BIT_565RGB:
47 ctrldescl0_5 |= CTRLDESCL0_5_BPP(BPP16_RGB565); 52 ctrldescl0_5 |= CTRLDESCL0_5_BPP(BPP16_RGB565);
48 break; 53 break;
49 case GDF_32BIT_X888RGB: 54 case GDF_32BIT_X888RGB:
50 ctrldescl0_5 |= CTRLDESCL0_5_BPP(BPP32_ARGB8888); 55 ctrldescl0_5 |= CTRLDESCL0_5_BPP(BPP32_ARGB8888);
51 break; 56 break;
52 default: 57 default:
53 printf("unsupported pixel format: %u\n", format); 58 printf("unsupported pixel format: %u\n", format);
54 return -EINVAL; 59 return -EINVAL;
55 } 60 }
56 61
57 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5)); 62 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5));
58 63
59 return 0; 64 return 0;
60 } 65 }
61 66
62 67
63 static void lcdifv3_set_mode(struct lcdifv3_priv *priv, 68 static void lcdifv3_set_mode(struct lcdifv3_priv *priv,
64 struct ctfb_res_modes *mode) 69 struct ctfb_res_modes *mode)
65 { 70 {
66 u32 disp_size, hsyn_para, vsyn_para, vsyn_hsyn_width, ctrldescl0_1; 71 u32 disp_size, hsyn_para, vsyn_para, vsyn_hsyn_width, ctrldescl0_1;
67 72
68 /* config display timings */ 73 /* config display timings */
69 disp_size = DISP_SIZE_DELTA_Y(mode->yres) | 74 disp_size = DISP_SIZE_DELTA_Y(mode->yres) |
70 DISP_SIZE_DELTA_X(mode->xres); 75 DISP_SIZE_DELTA_X(mode->xres);
71 writel(disp_size, (ulong)(priv->reg_base + LCDIFV3_DISP_SIZE)); 76 writel(disp_size, (ulong)(priv->reg_base + LCDIFV3_DISP_SIZE));
72 77
73 hsyn_para = HSYN_PARA_BP_H(mode->left_margin) | 78 hsyn_para = HSYN_PARA_BP_H(mode->left_margin) |
74 HSYN_PARA_FP_H(mode->right_margin); 79 HSYN_PARA_FP_H(mode->right_margin);
75 writel(hsyn_para, (ulong)(priv->reg_base + LCDIFV3_HSYN_PARA)); 80 writel(hsyn_para, (ulong)(priv->reg_base + LCDIFV3_HSYN_PARA));
76 81
77 vsyn_para = VSYN_PARA_BP_V(mode->upper_margin) | 82 vsyn_para = VSYN_PARA_BP_V(mode->upper_margin) |
78 VSYN_PARA_FP_V(mode->lower_margin); 83 VSYN_PARA_FP_V(mode->lower_margin);
79 writel(vsyn_para, (ulong)(priv->reg_base + LCDIFV3_VSYN_PARA)); 84 writel(vsyn_para, (ulong)(priv->reg_base + LCDIFV3_VSYN_PARA));
80 85
81 vsyn_hsyn_width = VSYN_HSYN_WIDTH_PW_V(mode->vsync_len) | 86 vsyn_hsyn_width = VSYN_HSYN_WIDTH_PW_V(mode->vsync_len) |
82 VSYN_HSYN_WIDTH_PW_H(mode->hsync_len); 87 VSYN_HSYN_WIDTH_PW_H(mode->hsync_len);
83 writel(vsyn_hsyn_width, (ulong)(priv->reg_base + LCDIFV3_VSYN_HSYN_WIDTH)); 88 writel(vsyn_hsyn_width, (ulong)(priv->reg_base + LCDIFV3_VSYN_HSYN_WIDTH));
84 89
85 /* config layer size */ 90 /* config layer size */
86 /* TODO: 32bits alignment for width */ 91 /* TODO: 32bits alignment for width */
87 ctrldescl0_1 = CTRLDESCL0_1_HEIGHT(mode->yres) | 92 ctrldescl0_1 = CTRLDESCL0_1_HEIGHT(mode->yres) |
88 CTRLDESCL0_1_WIDTH(mode->xres); 93 CTRLDESCL0_1_WIDTH(mode->xres);
89 writel(ctrldescl0_1, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_1)); 94 writel(ctrldescl0_1, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_1));
90 95
91 /* Polarities */ 96 /* Polarities */
92 writel(CTRL_INV_HS, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR)); 97 writel(CTRL_INV_HS, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR));
93 writel(CTRL_INV_VS, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR)); 98 writel(CTRL_INV_VS, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR));
94 99
95 /* SEC MIPI DSI specific */ 100 /* SEC MIPI DSI specific */
96 writel(CTRL_INV_PXCK, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR)); 101 writel(CTRL_INV_PXCK, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR));
97 writel(CTRL_INV_DE, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR)); 102 writel(CTRL_INV_DE, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR));
98 103
99 } 104 }
100 105
101 static void lcdifv3_set_bus_fmt(struct lcdifv3_priv *priv) 106 static void lcdifv3_set_bus_fmt(struct lcdifv3_priv *priv)
102 { 107 {
103 uint32_t disp_para = 0; 108 uint32_t disp_para = 0;
104 109
105 disp_para = readl((ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); 110 disp_para = readl((ulong)(priv->reg_base + LCDIFV3_DISP_PARA));
106 disp_para &= DISP_PARA_LINE_PATTERN(0xf); 111 disp_para &= DISP_PARA_LINE_PATTERN(0xf);
107 112
108 /* Fixed to 24 bits output */ 113 /* Fixed to 24 bits output */
109 disp_para |= DISP_PARA_LINE_PATTERN(LP_RGB888_OR_YUV444); 114 disp_para |= DISP_PARA_LINE_PATTERN(LP_RGB888_OR_YUV444);
110 115
111 /* config display mode: default is normal mode */ 116 /* config display mode: default is normal mode */
112 disp_para &= DISP_PARA_DISP_MODE(3); 117 disp_para &= DISP_PARA_DISP_MODE(3);
113 disp_para |= DISP_PARA_DISP_MODE(0); 118 disp_para |= DISP_PARA_DISP_MODE(0);
114 writel(disp_para, (ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); 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 static void lcdifv3_enable_controller(struct lcdifv3_priv *priv) 154 static void lcdifv3_enable_controller(struct lcdifv3_priv *priv)
118 { 155 {
119 u32 disp_para, ctrldescl0_5; 156 u32 disp_para, ctrldescl0_5;
120 157
121 disp_para = readl((ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); 158 disp_para = readl((ulong)(priv->reg_base + LCDIFV3_DISP_PARA));
122 ctrldescl0_5 = readl((ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5)); 159 ctrldescl0_5 = readl((ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5));
123 160
124 /* disp on */ 161 /* disp on */
125 disp_para |= DISP_PARA_DISP_ON; 162 disp_para |= DISP_PARA_DISP_ON;
126 writel(disp_para, (ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); 163 writel(disp_para, (ulong)(priv->reg_base + LCDIFV3_DISP_PARA));
127 164
128 /* enable shadow load */ 165 /* enable shadow load */
129 ctrldescl0_5 |= CTRLDESCL0_5_SHADOW_LOAD_EN; 166 ctrldescl0_5 |= CTRLDESCL0_5_SHADOW_LOAD_EN;
130 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5)); 167 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5));
131 168
132 /* enable layer dma */ 169 /* enable layer dma */
133 ctrldescl0_5 |= CTRLDESCL0_5_EN; 170 ctrldescl0_5 |= CTRLDESCL0_5_EN;
134 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5)); 171 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5));
135 } 172 }
136 173
137 static void lcdifv3_disable_controller(struct lcdifv3_priv *priv) 174 static void lcdifv3_disable_controller(struct lcdifv3_priv *priv)
138 { 175 {
139 u32 disp_para, ctrldescl0_5; 176 u32 disp_para, ctrldescl0_5;
140 177
141 disp_para = readl((ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); 178 disp_para = readl((ulong)(priv->reg_base + LCDIFV3_DISP_PARA));
142 ctrldescl0_5 = readl((ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5)); 179 ctrldescl0_5 = readl((ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5));
143 180
144 /* dma off */ 181 /* dma off */
145 ctrldescl0_5 &= ~CTRLDESCL0_5_EN; 182 ctrldescl0_5 &= ~CTRLDESCL0_5_EN;
146 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5)); 183 writel(ctrldescl0_5, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_5));
147 184
148 /* disp off */ 185 /* disp off */
149 disp_para &= ~DISP_PARA_DISP_ON; 186 disp_para &= ~DISP_PARA_DISP_ON;
150 writel(disp_para, (ulong)(priv->reg_base + LCDIFV3_DISP_PARA)); 187 writel(disp_para, (ulong)(priv->reg_base + LCDIFV3_DISP_PARA));
151 } 188 }
152 189
153 static void lcdifv3_init(struct udevice *dev, 190 static void lcdifv3_init(struct udevice *dev,
154 struct ctfb_res_modes *mode, unsigned int format) 191 struct ctfb_res_modes *mode, unsigned int format)
155 { 192 {
156 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 193 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
157 struct lcdifv3_priv *priv = dev_get_priv(dev); 194 struct lcdifv3_priv *priv = dev_get_priv(dev);
158 int ret; 195 int ret;
159 196
160 /* Kick in the LCDIF clock */ 197 /* Kick in the LCDIF clock */
161 mxs_set_lcdclk(priv->reg_base, PS2KHZ(mode->pixclock)); 198 mxs_set_lcdclk(priv->reg_base, PS2KHZ(mode->pixclock));
162 199
163 writel(CTRL_SW_RESET, (ulong)(priv->reg_base + LCDIFV3_CTRL_CLR)); 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 lcdifv3_set_mode(priv, mode); 205 lcdifv3_set_mode(priv, mode);
166 206
167 lcdifv3_set_bus_fmt(priv); 207 lcdifv3_set_bus_fmt(priv);
168 208
169 ret = lcdifv3_set_pix_fmt(priv, format); 209 ret = lcdifv3_set_pix_fmt(priv, format);
170 if (ret) { 210 if (ret) {
171 printf("Fail to init lcdifv3, wrong format %u\n", format); 211 printf("Fail to init lcdifv3, wrong format %u\n", format);
172 return; 212 return;
173 } 213 }
174 214
175 /* Set fb address to primary layer */ 215 /* Set fb address to primary layer */
176 writel(plat->base, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL_LOW0_4)); 216 writel(plat->base, (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL_LOW0_4));
177 217
178 writel(CTRLDESCL0_3_P_SIZE(1) |CTRLDESCL0_3_T_SIZE(1) | CTRLDESCL0_3_PITCH(mode->xres * 4), 218 writel(CTRLDESCL0_3_P_SIZE(1) |CTRLDESCL0_3_T_SIZE(1) | CTRLDESCL0_3_PITCH(mode->xres * 4),
179 (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_3)); 219 (ulong)(priv->reg_base + LCDIFV3_CTRLDESCL0_3));
180 220
181 lcdifv3_enable_controller(priv); 221 lcdifv3_enable_controller(priv);
182 } 222 }
183 223
184 void lcdifv3_power_down(struct lcdifv3_priv *priv) 224 void lcdifv3_power_down(struct lcdifv3_priv *priv)
185 { 225 {
186 int timeout = 1000000; 226 int timeout = 1000000;
187 227
188 /* Disable LCDIF during VBLANK */ 228 /* Disable LCDIF during VBLANK */
189 writel(INT_STATUS_D0_VS_BLANK, 229 writel(INT_STATUS_D0_VS_BLANK,
190 (ulong)(priv->reg_base + LCDIFV3_INT_STATUS_D0)); 230 (ulong)(priv->reg_base + LCDIFV3_INT_STATUS_D0));
191 while (--timeout) { 231 while (--timeout) {
192 if (readl((ulong)(priv->reg_base + LCDIFV3_INT_STATUS_D0)) & 232 if (readl((ulong)(priv->reg_base + LCDIFV3_INT_STATUS_D0)) &
193 INT_STATUS_D0_VS_BLANK) 233 INT_STATUS_D0_VS_BLANK)
194 break; 234 break;
195 udelay(1); 235 udelay(1);
196 } 236 }
197 237
198 lcdifv3_disable_controller(priv); 238 lcdifv3_disable_controller(priv);
199 } 239 }
200 240
201 static int lcdifv3_of_get_timings(struct udevice *dev, 241 static int lcdifv3_of_get_timings(struct udevice *dev,
202 struct display_timing *timings) 242 struct display_timing *timings)
203 { 243 {
204 int ret = 0; 244 int ret = 0;
205 struct lcdifv3_priv *priv = dev_get_priv(dev); 245 struct lcdifv3_priv *priv = dev_get_priv(dev);
206 246
207 priv->disp_dev = video_link_get_next_device(dev); 247 priv->disp_dev = video_link_get_next_device(dev);
208 if (!priv->disp_dev || 248 if (!priv->disp_dev ||
209 (device_get_uclass_id(priv->disp_dev) != UCLASS_VIDEO_BRIDGE 249 (device_get_uclass_id(priv->disp_dev) != UCLASS_VIDEO_BRIDGE
210 && device_get_uclass_id(priv->disp_dev) != UCLASS_DISPLAY)) { 250 && device_get_uclass_id(priv->disp_dev) != UCLASS_DISPLAY)) {
211 251
212 printf("fail to find output device\n"); 252 printf("fail to find output device\n");
213 return -ENODEV; 253 return -ENODEV;
214 } 254 }
215 255
216 debug("disp_dev %s\n", priv->disp_dev->name); 256 debug("disp_dev %s\n", priv->disp_dev->name);
217 257
218 ret = video_link_get_display_timings(timings); 258 ret = video_link_get_display_timings(timings);
219 if (ret) { 259 if (ret) {
220 printf("fail to get display timings\n"); 260 printf("fail to get display timings\n");
221 return ret; 261 return ret;
222 } 262 }
223 263
224 return ret; 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 static int lcdifv3_video_probe(struct udevice *dev) 315 static int lcdifv3_video_probe(struct udevice *dev)
228 { 316 {
229 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 317 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
230 struct video_priv *uc_priv = dev_get_uclass_priv(dev); 318 struct video_priv *uc_priv = dev_get_uclass_priv(dev);
231 struct lcdifv3_priv *priv = dev_get_priv(dev); 319 struct lcdifv3_priv *priv = dev_get_priv(dev);
232 320
233 struct ctfb_res_modes mode; 321 struct ctfb_res_modes mode;
234 struct display_timing timings; 322 struct display_timing timings;
235 323
236 u32 fb_start, fb_end; 324 u32 fb_start, fb_end;
237 int ret; 325 int ret;
238 326
239 debug("%s() plat: base 0x%lx, size 0x%x\n", 327 debug("%s() plat: base 0x%lx, size 0x%x\n",
240 __func__, plat->base, plat->size); 328 __func__, plat->base, plat->size);
241 329
242 priv->reg_base = dev_read_addr(dev); 330 priv->reg_base = dev_read_addr(dev);
243 if (priv->reg_base == FDT_ADDR_T_NONE) { 331 if (priv->reg_base == FDT_ADDR_T_NONE) {
244 dev_err(dev, "lcdif base address is not found\n"); 332 dev_err(dev, "lcdif base address is not found\n");
245 return -EINVAL; 333 return -EINVAL;
246 } 334 }
247 335
248 ret = lcdifv3_of_get_timings(dev, &timings); 336 ret = lcdifv3_of_get_timings(dev, &timings);
249 if (ret) 337 if (ret)
250 return ret; 338 return ret;
339
340 lcdifv3_of_parse_thres(dev);
251 341
252 if (priv->disp_dev) { 342 if (priv->disp_dev) {
253 #if IS_ENABLED(CONFIG_VIDEO_BRIDGE) 343 #if IS_ENABLED(CONFIG_VIDEO_BRIDGE)
254 if (device_get_uclass_id(priv->disp_dev) == UCLASS_VIDEO_BRIDGE) { 344 if (device_get_uclass_id(priv->disp_dev) == UCLASS_VIDEO_BRIDGE) {
255 ret = video_bridge_attach(priv->disp_dev); 345 ret = video_bridge_attach(priv->disp_dev);
256 if (ret) { 346 if (ret) {
257 dev_err(dev, "fail to attach bridge\n"); 347 dev_err(dev, "fail to attach bridge\n");
258 return ret; 348 return ret;
259 } 349 }
260 350
261 ret = video_bridge_set_backlight(priv->disp_dev, 80); 351 ret = video_bridge_set_backlight(priv->disp_dev, 80);
262 if (ret) { 352 if (ret) {
263 dev_err(dev, "fail to set backlight\n"); 353 dev_err(dev, "fail to set backlight\n");
264 return ret; 354 return ret;
265 } 355 }
266 } 356 }
267 #endif 357 #endif
268 } 358 }
269 359
270 mode.xres = timings.hactive.typ; 360 mode.xres = timings.hactive.typ;
271 mode.yres = timings.vactive.typ; 361 mode.yres = timings.vactive.typ;
272 mode.left_margin = timings.hback_porch.typ; 362 mode.left_margin = timings.hback_porch.typ;
273 mode.right_margin = timings.hfront_porch.typ; 363 mode.right_margin = timings.hfront_porch.typ;
274 mode.upper_margin = timings.vback_porch.typ; 364 mode.upper_margin = timings.vback_porch.typ;
275 mode.lower_margin = timings.vfront_porch.typ; 365 mode.lower_margin = timings.vfront_porch.typ;
276 mode.hsync_len = timings.hsync_len.typ; 366 mode.hsync_len = timings.hsync_len.typ;
277 mode.vsync_len = timings.vsync_len.typ; 367 mode.vsync_len = timings.vsync_len.typ;
278 mode.pixclock = HZ2PS(timings.pixelclock.typ); 368 mode.pixclock = HZ2PS(timings.pixelclock.typ);
279 369
280 lcdifv3_init(dev, &mode, GDF_32BIT_X888RGB); 370 lcdifv3_init(dev, &mode, GDF_32BIT_X888RGB);
281 371
282 uc_priv->bpix = VIDEO_BPP32; /* only support 32 BPP now */ 372 uc_priv->bpix = VIDEO_BPP32; /* only support 32 BPP now */
283 uc_priv->xsize = mode.xres; 373 uc_priv->xsize = mode.xres;
284 uc_priv->ysize = mode.yres; 374 uc_priv->ysize = mode.yres;
285 375
286 /* Enable dcache for the frame buffer */ 376 /* Enable dcache for the frame buffer */
287 fb_start = plat->base & ~(MMU_SECTION_SIZE - 1); 377 fb_start = plat->base & ~(MMU_SECTION_SIZE - 1);
288 fb_end = plat->base + plat->size; 378 fb_end = plat->base + plat->size;
289 fb_end = ALIGN(fb_end, 1 << MMU_SECTION_SHIFT); 379 fb_end = ALIGN(fb_end, 1 << MMU_SECTION_SHIFT);
290 mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start, 380 mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start,
291 DCACHE_WRITEBACK); 381 DCACHE_WRITEBACK);
292 video_set_flush_dcache(dev, true); 382 video_set_flush_dcache(dev, true);
293 gd->fb_base = plat->base; 383 gd->fb_base = plat->base;
294 384
295 return ret; 385 return ret;
296 } 386 }
297 387
298 static int lcdifv3_video_bind(struct udevice *dev) 388 static int lcdifv3_video_bind(struct udevice *dev)
299 { 389 {
300 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); 390 struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
301 391
302 /* Max size supported by LCDIF, because in bind, we can't probe panel */ 392 /* Max size supported by LCDIF, because in bind, we can't probe panel */
303 plat->size = 1920 * 1080 *4 * 2; 393 plat->size = 1920 * 1080 *4 * 2;
304 394
305 return 0; 395 return 0;
306 } 396 }
307 397
308 static int lcdifv3_video_remove(struct udevice *dev) 398 static int lcdifv3_video_remove(struct udevice *dev)
309 { 399 {
310 struct lcdifv3_priv *priv = dev_get_priv(dev); 400 struct lcdifv3_priv *priv = dev_get_priv(dev);
311 401
312 debug("%s\n", __func__); 402 debug("%s\n", __func__);
313 403
314 if (priv->disp_dev) 404 if (priv->disp_dev)
315 device_remove(priv->disp_dev, DM_REMOVE_NORMAL); 405 device_remove(priv->disp_dev, DM_REMOVE_NORMAL);
316 406
317 lcdifv3_power_down(priv); 407 lcdifv3_power_down(priv);
318 408
319 return 0; 409 return 0;
320 } 410 }
321 411
322 static const struct udevice_id lcdifv3_video_ids[] = { 412 static const struct udevice_id lcdifv3_video_ids[] = {
323 { .compatible = "fsl,imx8mp-lcdif1" }, 413 { .compatible = "fsl,imx8mp-lcdif1" },
324 { /* sentinel */ } 414 { /* sentinel */ }
325 }; 415 };
326 416
327 U_BOOT_DRIVER(lcdifv3_video) = { 417 U_BOOT_DRIVER(lcdifv3_video) = {
328 .name = "lcdifv3_video", 418 .name = "lcdifv3_video",
329 .id = UCLASS_VIDEO, 419 .id = UCLASS_VIDEO,
330 .of_match = lcdifv3_video_ids, 420 .of_match = lcdifv3_video_ids,
331 .bind = lcdifv3_video_bind, 421 .bind = lcdifv3_video_bind,
332 .probe = lcdifv3_video_probe, 422 .probe = lcdifv3_video_probe,
333 .remove = lcdifv3_video_remove, 423 .remove = lcdifv3_video_remove,
334 .flags = DM_FLAG_PRE_RELOC | DM_FLAG_OS_PREPARE, 424 .flags = DM_FLAG_PRE_RELOC | DM_FLAG_OS_PREPARE,
335 .priv_auto_alloc_size = sizeof(struct lcdifv3_priv), 425 .priv_auto_alloc_size = sizeof(struct lcdifv3_priv),
336 }; 426 };
337 427