xref: /linux/drivers/gpu/host1x/tegra114-mipi.c (revision 00c6649bafef628955569dd39a59e3170e48f7b5)
1 /*
2  * Copyright (C) 2013 NVIDIA Corporation
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22 
23 #include <linux/clk.h>
24 #include <linux/host1x.h>
25 #include <linux/io.h>
26 #include <linux/iopoll.h>
27 #include <linux/of_platform.h>
28 #include <linux/platform_device.h>
29 #include <linux/slab.h>
30 #include <linux/tegra-mipi-cal.h>
31 
32 #include "dev.h"
33 
34 #define MIPI_CAL_CTRL			0x00
35 #define MIPI_CAL_CTRL_NOISE_FILTER(x)	(((x) & 0xf) << 26)
36 #define MIPI_CAL_CTRL_PRESCALE(x)	(((x) & 0x3) << 24)
37 #define MIPI_CAL_CTRL_CLKEN_OVR		BIT(4)
38 #define MIPI_CAL_CTRL_START		BIT(0)
39 
40 #define MIPI_CAL_AUTOCAL_CTRL		0x01
41 
42 #define MIPI_CAL_STATUS			0x02
43 #define MIPI_CAL_STATUS_DONE		BIT(16)
44 #define MIPI_CAL_STATUS_ACTIVE		BIT(0)
45 
46 #define MIPI_CAL_CONFIG_CSIA		0x05
47 #define MIPI_CAL_CONFIG_CSIB		0x06
48 #define MIPI_CAL_CONFIG_CSIC		0x07
49 #define MIPI_CAL_CONFIG_CSID		0x08
50 #define MIPI_CAL_CONFIG_CSIE		0x09
51 #define MIPI_CAL_CONFIG_CSIF		0x0a
52 #define MIPI_CAL_CONFIG_DSIA		0x0e
53 #define MIPI_CAL_CONFIG_DSIB		0x0f
54 #define MIPI_CAL_CONFIG_DSIC		0x10
55 #define MIPI_CAL_CONFIG_DSID		0x11
56 
57 #define MIPI_CAL_CONFIG_DSIA_CLK	0x19
58 #define MIPI_CAL_CONFIG_DSIB_CLK	0x1a
59 #define MIPI_CAL_CONFIG_CSIAB_CLK	0x1b
60 #define MIPI_CAL_CONFIG_DSIC_CLK	0x1c
61 #define MIPI_CAL_CONFIG_CSICD_CLK	0x1c
62 #define MIPI_CAL_CONFIG_DSID_CLK	0x1d
63 #define MIPI_CAL_CONFIG_CSIE_CLK	0x1d
64 
65 /* for data and clock lanes */
66 #define MIPI_CAL_CONFIG_SELECT		BIT(21)
67 
68 /* for data lanes */
69 #define MIPI_CAL_CONFIG_HSPDOS(x)	(((x) & 0x1f) << 16)
70 #define MIPI_CAL_CONFIG_HSPUOS(x)	(((x) & 0x1f) <<  8)
71 #define MIPI_CAL_CONFIG_TERMOS(x)	(((x) & 0x1f) <<  0)
72 
73 /* for clock lanes */
74 #define MIPI_CAL_CONFIG_HSCLKPDOSD(x)	(((x) & 0x1f) <<  8)
75 #define MIPI_CAL_CONFIG_HSCLKPUOSD(x)	(((x) & 0x1f) <<  0)
76 
77 #define MIPI_CAL_BIAS_PAD_CFG0		0x16
78 #define MIPI_CAL_BIAS_PAD_PDVCLAMP	BIT(1)
79 #define MIPI_CAL_BIAS_PAD_E_VCLAMP_REF	BIT(0)
80 
81 #define MIPI_CAL_BIAS_PAD_CFG1		0x17
82 #define MIPI_CAL_BIAS_PAD_DRV_DN_REF(x) (((x) & 0x7) << 16)
83 #define MIPI_CAL_BIAS_PAD_DRV_UP_REF(x) (((x) & 0x7) << 8)
84 
85 #define MIPI_CAL_BIAS_PAD_CFG2		0x18
86 #define MIPI_CAL_BIAS_PAD_VCLAMP(x)	(((x) & 0x7) << 16)
87 #define MIPI_CAL_BIAS_PAD_VAUXP(x)	(((x) & 0x7) << 4)
88 #define MIPI_CAL_BIAS_PAD_PDVREG	BIT(1)
89 
90 struct tegra_mipi_pad {
91 	unsigned long data;
92 	unsigned long clk;
93 };
94 
95 struct tegra_mipi_soc {
96 	bool has_clk_lane;
97 	const struct tegra_mipi_pad *pads;
98 	unsigned int num_pads;
99 
100 	bool clock_enable_override;
101 	bool needs_vclamp_ref;
102 
103 	/* bias pad configuration settings */
104 	u8 pad_drive_down_ref;
105 	u8 pad_drive_up_ref;
106 
107 	u8 pad_vclamp_level;
108 	u8 pad_vauxp_level;
109 
110 	/* calibration settings for data lanes */
111 	u8 hspdos;
112 	u8 hspuos;
113 	u8 termos;
114 
115 	/* calibration settings for clock lanes */
116 	u8 hsclkpdos;
117 	u8 hsclkpuos;
118 };
119 
120 struct tegra_mipi {
121 	const struct tegra_mipi_soc *soc;
122 	struct device *dev;
123 	void __iomem *regs;
124 	struct mutex lock; /* for register access */
125 	struct clk *clk;
126 
127 	unsigned long usage_count;
128 };
129 
130 static inline u32 tegra_mipi_readl(struct tegra_mipi *mipi,
131 				   unsigned long offset)
132 {
133 	return readl(mipi->regs + (offset << 2));
134 }
135 
136 static inline void tegra_mipi_writel(struct tegra_mipi *mipi, u32 value,
137 				     unsigned long offset)
138 {
139 	writel(value, mipi->regs + (offset << 2));
140 }
141 
142 static int tegra114_mipi_power_up(struct tegra_mipi *mipi)
143 {
144 	u32 value;
145 	int err;
146 
147 	err = clk_enable(mipi->clk);
148 	if (err < 0)
149 		return err;
150 
151 	value = tegra_mipi_readl(mipi, MIPI_CAL_BIAS_PAD_CFG0);
152 	value &= ~MIPI_CAL_BIAS_PAD_PDVCLAMP;
153 
154 	if (mipi->soc->needs_vclamp_ref)
155 		value |= MIPI_CAL_BIAS_PAD_E_VCLAMP_REF;
156 
157 	tegra_mipi_writel(mipi, value, MIPI_CAL_BIAS_PAD_CFG0);
158 
159 	value = tegra_mipi_readl(mipi, MIPI_CAL_BIAS_PAD_CFG2);
160 	value &= ~MIPI_CAL_BIAS_PAD_PDVREG;
161 	tegra_mipi_writel(mipi, value, MIPI_CAL_BIAS_PAD_CFG2);
162 
163 	clk_disable(mipi->clk);
164 
165 	return 0;
166 }
167 
168 static int tegra114_mipi_power_down(struct tegra_mipi *mipi)
169 {
170 	u32 value;
171 	int err;
172 
173 	err = clk_enable(mipi->clk);
174 	if (err < 0)
175 		return err;
176 
177 	/*
178 	 * The MIPI_CAL_BIAS_PAD_PDVREG controls a voltage regulator that
179 	 * supplies the DSI pads. This must be kept enabled until none of the
180 	 * DSI lanes are used anymore.
181 	 */
182 	value = tegra_mipi_readl(mipi, MIPI_CAL_BIAS_PAD_CFG2);
183 	value |= MIPI_CAL_BIAS_PAD_PDVREG;
184 	tegra_mipi_writel(mipi, value, MIPI_CAL_BIAS_PAD_CFG2);
185 
186 	/*
187 	 * MIPI_CAL_BIAS_PAD_PDVCLAMP and MIPI_CAL_BIAS_PAD_E_VCLAMP_REF
188 	 * control a regulator that supplies current to the pre-driver logic.
189 	 * Powering down this regulator causes DSI to fail, so it must remain
190 	 * powered on until none of the DSI lanes are used anymore.
191 	 */
192 	value = tegra_mipi_readl(mipi, MIPI_CAL_BIAS_PAD_CFG0);
193 
194 	if (mipi->soc->needs_vclamp_ref)
195 		value &= ~MIPI_CAL_BIAS_PAD_E_VCLAMP_REF;
196 
197 	value |= MIPI_CAL_BIAS_PAD_PDVCLAMP;
198 	tegra_mipi_writel(mipi, value, MIPI_CAL_BIAS_PAD_CFG0);
199 
200 	return 0;
201 }
202 
203 static int tegra114_mipi_enable(struct tegra_mipi_device *mipidev)
204 {
205 	struct tegra_mipi *mipi = platform_get_drvdata(mipidev->pdev);
206 	int err = 0;
207 
208 	mutex_lock(&mipi->lock);
209 
210 	if (mipi->usage_count++ == 0)
211 		err = tegra114_mipi_power_up(mipi);
212 
213 	mutex_unlock(&mipi->lock);
214 
215 	return err;
216 }
217 
218 static int tegra114_mipi_disable(struct tegra_mipi_device *mipidev)
219 {
220 	struct tegra_mipi *mipi = platform_get_drvdata(mipidev->pdev);
221 	int err = 0;
222 
223 	mutex_lock(&mipi->lock);
224 
225 	if (--mipi->usage_count == 0)
226 		err = tegra114_mipi_power_down(mipi);
227 
228 	mutex_unlock(&mipi->lock);
229 
230 	return err;
231 }
232 
233 static int tegra114_mipi_finish_calibration(struct tegra_mipi_device *mipidev)
234 {
235 	struct tegra_mipi *mipi = platform_get_drvdata(mipidev->pdev);
236 	void __iomem *status_reg = mipi->regs + (MIPI_CAL_STATUS << 2);
237 	u32 value;
238 	int err;
239 
240 	err = readl_relaxed_poll_timeout(status_reg, value,
241 					 !(value & MIPI_CAL_STATUS_ACTIVE) &&
242 					 (value & MIPI_CAL_STATUS_DONE), 50,
243 					 250000);
244 	mutex_unlock(&mipi->lock);
245 	clk_disable(mipi->clk);
246 
247 	return err;
248 }
249 
250 static int tegra114_mipi_start_calibration(struct tegra_mipi_device *mipidev)
251 {
252 	struct tegra_mipi *mipi = platform_get_drvdata(mipidev->pdev);
253 	const struct tegra_mipi_soc *soc = mipi->soc;
254 	unsigned int i;
255 	u32 value;
256 	int err;
257 
258 	err = clk_enable(mipi->clk);
259 	if (err < 0)
260 		return err;
261 
262 	mutex_lock(&mipi->lock);
263 
264 	value = MIPI_CAL_BIAS_PAD_DRV_DN_REF(soc->pad_drive_down_ref) |
265 		MIPI_CAL_BIAS_PAD_DRV_UP_REF(soc->pad_drive_up_ref);
266 	tegra_mipi_writel(mipi, value, MIPI_CAL_BIAS_PAD_CFG1);
267 
268 	value = tegra_mipi_readl(mipi, MIPI_CAL_BIAS_PAD_CFG2);
269 	value &= ~MIPI_CAL_BIAS_PAD_VCLAMP(0x7);
270 	value &= ~MIPI_CAL_BIAS_PAD_VAUXP(0x7);
271 	value |= MIPI_CAL_BIAS_PAD_VCLAMP(soc->pad_vclamp_level);
272 	value |= MIPI_CAL_BIAS_PAD_VAUXP(soc->pad_vauxp_level);
273 	tegra_mipi_writel(mipi, value, MIPI_CAL_BIAS_PAD_CFG2);
274 
275 	for (i = 0; i < soc->num_pads; i++) {
276 		u32 clk = 0, data = 0;
277 
278 		if (mipidev->pads & BIT(i)) {
279 			data = MIPI_CAL_CONFIG_SELECT |
280 			       MIPI_CAL_CONFIG_HSPDOS(soc->hspdos) |
281 			       MIPI_CAL_CONFIG_HSPUOS(soc->hspuos) |
282 			       MIPI_CAL_CONFIG_TERMOS(soc->termos);
283 			clk = MIPI_CAL_CONFIG_SELECT |
284 			      MIPI_CAL_CONFIG_HSCLKPDOSD(soc->hsclkpdos) |
285 			      MIPI_CAL_CONFIG_HSCLKPUOSD(soc->hsclkpuos);
286 		}
287 
288 		tegra_mipi_writel(mipi, data, soc->pads[i].data);
289 
290 		if (soc->has_clk_lane && soc->pads[i].clk != 0)
291 			tegra_mipi_writel(mipi, clk, soc->pads[i].clk);
292 	}
293 
294 	value = tegra_mipi_readl(mipi, MIPI_CAL_CTRL);
295 	value &= ~MIPI_CAL_CTRL_NOISE_FILTER(0xf);
296 	value &= ~MIPI_CAL_CTRL_PRESCALE(0x3);
297 	value |= MIPI_CAL_CTRL_NOISE_FILTER(0xa);
298 	value |= MIPI_CAL_CTRL_PRESCALE(0x2);
299 
300 	if (!soc->clock_enable_override)
301 		value &= ~MIPI_CAL_CTRL_CLKEN_OVR;
302 	else
303 		value |= MIPI_CAL_CTRL_CLKEN_OVR;
304 
305 	tegra_mipi_writel(mipi, value, MIPI_CAL_CTRL);
306 
307 	/* clear any pending status bits */
308 	value = tegra_mipi_readl(mipi, MIPI_CAL_STATUS);
309 	tegra_mipi_writel(mipi, value, MIPI_CAL_STATUS);
310 
311 	value = tegra_mipi_readl(mipi, MIPI_CAL_CTRL);
312 	value |= MIPI_CAL_CTRL_START;
313 	tegra_mipi_writel(mipi, value, MIPI_CAL_CTRL);
314 
315 	/*
316 	 * Wait for min 72uS to let calibration logic finish calibration
317 	 * sequence codes before waiting for pads idle state to apply the
318 	 * results.
319 	 */
320 	usleep_range(75, 80);
321 
322 	return 0;
323 }
324 
325 static const struct tegra_mipi_ops tegra114_mipi_ops = {
326 	.enable = tegra114_mipi_enable,
327 	.disable = tegra114_mipi_disable,
328 	.start_calibration = tegra114_mipi_start_calibration,
329 	.finish_calibration = tegra114_mipi_finish_calibration,
330 };
331 
332 static const struct tegra_mipi_pad tegra114_mipi_pads[] = {
333 	{ .data = MIPI_CAL_CONFIG_CSIA },
334 	{ .data = MIPI_CAL_CONFIG_CSIB },
335 	{ .data = MIPI_CAL_CONFIG_CSIC },
336 	{ .data = MIPI_CAL_CONFIG_CSID },
337 	{ .data = MIPI_CAL_CONFIG_CSIE },
338 	{ .data = MIPI_CAL_CONFIG_DSIA },
339 	{ .data = MIPI_CAL_CONFIG_DSIB },
340 	{ .data = MIPI_CAL_CONFIG_DSIC },
341 	{ .data = MIPI_CAL_CONFIG_DSID },
342 };
343 
344 static const struct tegra_mipi_soc tegra114_mipi_soc = {
345 	.has_clk_lane = false,
346 	.pads = tegra114_mipi_pads,
347 	.num_pads = ARRAY_SIZE(tegra114_mipi_pads),
348 	.clock_enable_override = true,
349 	.needs_vclamp_ref = true,
350 	.pad_drive_down_ref = 0x2,
351 	.pad_drive_up_ref = 0x0,
352 	.pad_vclamp_level = 0x0,
353 	.pad_vauxp_level = 0x0,
354 	.hspdos = 0x0,
355 	.hspuos = 0x4,
356 	.termos = 0x5,
357 	.hsclkpdos = 0x0,
358 	.hsclkpuos = 0x4,
359 };
360 
361 static const struct tegra_mipi_pad tegra124_mipi_pads[] = {
362 	{ .data = MIPI_CAL_CONFIG_CSIA, .clk = MIPI_CAL_CONFIG_CSIAB_CLK },
363 	{ .data = MIPI_CAL_CONFIG_CSIB, .clk = MIPI_CAL_CONFIG_CSIAB_CLK },
364 	{ .data = MIPI_CAL_CONFIG_CSIC, .clk = MIPI_CAL_CONFIG_CSICD_CLK },
365 	{ .data = MIPI_CAL_CONFIG_CSID, .clk = MIPI_CAL_CONFIG_CSICD_CLK },
366 	{ .data = MIPI_CAL_CONFIG_CSIE, .clk = MIPI_CAL_CONFIG_CSIE_CLK  },
367 	{ .data = MIPI_CAL_CONFIG_DSIA, .clk = MIPI_CAL_CONFIG_DSIA_CLK  },
368 	{ .data = MIPI_CAL_CONFIG_DSIB, .clk = MIPI_CAL_CONFIG_DSIB_CLK  },
369 };
370 
371 static const struct tegra_mipi_soc tegra124_mipi_soc = {
372 	.has_clk_lane = true,
373 	.pads = tegra124_mipi_pads,
374 	.num_pads = ARRAY_SIZE(tegra124_mipi_pads),
375 	.clock_enable_override = true,
376 	.needs_vclamp_ref = true,
377 	.pad_drive_down_ref = 0x2,
378 	.pad_drive_up_ref = 0x0,
379 	.pad_vclamp_level = 0x0,
380 	.pad_vauxp_level = 0x0,
381 	.hspdos = 0x0,
382 	.hspuos = 0x0,
383 	.termos = 0x0,
384 	.hsclkpdos = 0x1,
385 	.hsclkpuos = 0x2,
386 };
387 
388 static const struct tegra_mipi_soc tegra132_mipi_soc = {
389 	.has_clk_lane = true,
390 	.pads = tegra124_mipi_pads,
391 	.num_pads = ARRAY_SIZE(tegra124_mipi_pads),
392 	.clock_enable_override = false,
393 	.needs_vclamp_ref = false,
394 	.pad_drive_down_ref = 0x0,
395 	.pad_drive_up_ref = 0x3,
396 	.pad_vclamp_level = 0x0,
397 	.pad_vauxp_level = 0x0,
398 	.hspdos = 0x0,
399 	.hspuos = 0x0,
400 	.termos = 0x0,
401 	.hsclkpdos = 0x3,
402 	.hsclkpuos = 0x2,
403 };
404 
405 static const struct tegra_mipi_pad tegra210_mipi_pads[] = {
406 	{ .data = MIPI_CAL_CONFIG_CSIA, .clk = 0 },
407 	{ .data = MIPI_CAL_CONFIG_CSIB, .clk = 0 },
408 	{ .data = MIPI_CAL_CONFIG_CSIC, .clk = 0 },
409 	{ .data = MIPI_CAL_CONFIG_CSID, .clk = 0 },
410 	{ .data = MIPI_CAL_CONFIG_CSIE, .clk = 0 },
411 	{ .data = MIPI_CAL_CONFIG_CSIF, .clk = 0 },
412 	{ .data = MIPI_CAL_CONFIG_DSIA, .clk = MIPI_CAL_CONFIG_DSIA_CLK },
413 	{ .data = MIPI_CAL_CONFIG_DSIB, .clk = MIPI_CAL_CONFIG_DSIB_CLK },
414 	{ .data = MIPI_CAL_CONFIG_DSIC, .clk = MIPI_CAL_CONFIG_DSIC_CLK },
415 	{ .data = MIPI_CAL_CONFIG_DSID, .clk = MIPI_CAL_CONFIG_DSID_CLK },
416 };
417 
418 static const struct tegra_mipi_soc tegra210_mipi_soc = {
419 	.has_clk_lane = true,
420 	.pads = tegra210_mipi_pads,
421 	.num_pads = ARRAY_SIZE(tegra210_mipi_pads),
422 	.clock_enable_override = true,
423 	.needs_vclamp_ref = false,
424 	.pad_drive_down_ref = 0x0,
425 	.pad_drive_up_ref = 0x3,
426 	.pad_vclamp_level = 0x1,
427 	.pad_vauxp_level = 0x1,
428 	.hspdos = 0x0,
429 	.hspuos = 0x2,
430 	.termos = 0x0,
431 	.hsclkpdos = 0x0,
432 	.hsclkpuos = 0x2,
433 };
434 
435 static const struct of_device_id tegra_mipi_of_match[] = {
436 	{ .compatible = "nvidia,tegra114-mipi", .data = &tegra114_mipi_soc },
437 	{ .compatible = "nvidia,tegra124-mipi", .data = &tegra124_mipi_soc },
438 	{ .compatible = "nvidia,tegra132-mipi", .data = &tegra132_mipi_soc },
439 	{ .compatible = "nvidia,tegra210-mipi", .data = &tegra210_mipi_soc },
440 	{ },
441 };
442 
443 static int tegra_mipi_probe(struct platform_device *pdev)
444 {
445 	const struct of_device_id *match;
446 	struct tegra_mipi *mipi;
447 
448 	match = of_match_node(tegra_mipi_of_match, pdev->dev.of_node);
449 	if (!match)
450 		return -ENODEV;
451 
452 	mipi = devm_kzalloc(&pdev->dev, sizeof(*mipi), GFP_KERNEL);
453 	if (!mipi)
454 		return -ENOMEM;
455 
456 	mipi->soc = match->data;
457 	mipi->dev = &pdev->dev;
458 
459 	mipi->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
460 	if (IS_ERR(mipi->regs))
461 		return PTR_ERR(mipi->regs);
462 
463 	mutex_init(&mipi->lock);
464 
465 	mipi->clk = devm_clk_get_prepared(&pdev->dev, NULL);
466 	if (IS_ERR(mipi->clk)) {
467 		dev_err(&pdev->dev, "failed to get clock\n");
468 		return PTR_ERR(mipi->clk);
469 	}
470 
471 	platform_set_drvdata(pdev, mipi);
472 
473 	return devm_tegra_mipi_add_provider(&pdev->dev, pdev->dev.of_node,
474 					    &tegra114_mipi_ops);
475 }
476 
477 struct platform_driver tegra_mipi_driver = {
478 	.driver = {
479 		.name = "tegra-mipi",
480 		.of_match_table = tegra_mipi_of_match,
481 	},
482 	.probe = tegra_mipi_probe,
483 };
484