2 * Copyright (C) 2013 NVIDIA Corporation
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.
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
23 #include <linux/clk.h>
24 #include <linux/host1x.h>
26 #include <linux/iopoll.h>
27 #include <linux/of_platform.h>
28 #include <linux/platform_device.h>
29 #include <linux/slab.h>
33 #define MIPI_CAL_CTRL 0x00
34 #define MIPI_CAL_CTRL_NOISE_FILTER(x) (((x) & 0xf) << 26)
35 #define MIPI_CAL_CTRL_PRESCALE(x) (((x) & 0x3) << 24)
36 #define MIPI_CAL_CTRL_CLKEN_OVR (1 << 4)
37 #define MIPI_CAL_CTRL_START (1 << 0)
39 #define MIPI_CAL_AUTOCAL_CTRL 0x01
41 #define MIPI_CAL_STATUS 0x02
42 #define MIPI_CAL_STATUS_DONE (1 << 16)
43 #define MIPI_CAL_STATUS_ACTIVE (1 << 0)
45 #define MIPI_CAL_CONFIG_CSIA 0x05
46 #define MIPI_CAL_CONFIG_CSIB 0x06
47 #define MIPI_CAL_CONFIG_CSIC 0x07
48 #define MIPI_CAL_CONFIG_CSID 0x08
49 #define MIPI_CAL_CONFIG_CSIE 0x09
50 #define MIPI_CAL_CONFIG_CSIF 0x0a
51 #define MIPI_CAL_CONFIG_DSIA 0x0e
52 #define MIPI_CAL_CONFIG_DSIB 0x0f
53 #define MIPI_CAL_CONFIG_DSIC 0x10
54 #define MIPI_CAL_CONFIG_DSID 0x11
56 #define MIPI_CAL_CONFIG_DSIA_CLK 0x19
57 #define MIPI_CAL_CONFIG_DSIB_CLK 0x1a
58 #define MIPI_CAL_CONFIG_CSIAB_CLK 0x1b
59 #define MIPI_CAL_CONFIG_DSIC_CLK 0x1c
60 #define MIPI_CAL_CONFIG_CSICD_CLK 0x1c
61 #define MIPI_CAL_CONFIG_DSID_CLK 0x1d
62 #define MIPI_CAL_CONFIG_CSIE_CLK 0x1d
64 /* for data and clock lanes */
65 #define MIPI_CAL_CONFIG_SELECT (1 << 21)
68 #define MIPI_CAL_CONFIG_HSPDOS(x) (((x) & 0x1f) << 16)
69 #define MIPI_CAL_CONFIG_HSPUOS(x) (((x) & 0x1f) << 8)
70 #define MIPI_CAL_CONFIG_TERMOS(x) (((x) & 0x1f) << 0)
73 #define MIPI_CAL_CONFIG_HSCLKPDOSD(x) (((x) & 0x1f) << 8)
74 #define MIPI_CAL_CONFIG_HSCLKPUOSD(x) (((x) & 0x1f) << 0)
76 #define MIPI_CAL_BIAS_PAD_CFG0 0x16
77 #define MIPI_CAL_BIAS_PAD_PDVCLAMP (1 << 1)
78 #define MIPI_CAL_BIAS_PAD_E_VCLAMP_REF (1 << 0)
80 #define MIPI_CAL_BIAS_PAD_CFG1 0x17
81 #define MIPI_CAL_BIAS_PAD_DRV_DN_REF(x) (((x) & 0x7) << 16)
82 #define MIPI_CAL_BIAS_PAD_DRV_UP_REF(x) (((x) & 0x7) << 8)
84 #define MIPI_CAL_BIAS_PAD_CFG2 0x18
85 #define MIPI_CAL_BIAS_PAD_VCLAMP(x) (((x) & 0x7) << 16)
86 #define MIPI_CAL_BIAS_PAD_VAUXP(x) (((x) & 0x7) << 4)
87 #define MIPI_CAL_BIAS_PAD_PDVREG (1 << 1)
89 struct tegra_mipi_pad
{
94 struct tegra_mipi_soc
{
96 const struct tegra_mipi_pad
*pads
;
97 unsigned int num_pads
;
99 bool clock_enable_override
;
100 bool needs_vclamp_ref
;
102 /* bias pad configuration settings */
103 u8 pad_drive_down_ref
;
109 /* calibration settings for data lanes */
114 /* calibration settings for clock lanes */
120 const struct tegra_mipi_soc
*soc
;
126 unsigned long usage_count
;
129 struct tegra_mipi_device
{
130 struct platform_device
*pdev
;
131 struct tegra_mipi
*mipi
;
132 struct device
*device
;
136 static inline u32
tegra_mipi_readl(struct tegra_mipi
*mipi
,
137 unsigned long offset
)
139 return readl(mipi
->regs
+ (offset
<< 2));
142 static inline void tegra_mipi_writel(struct tegra_mipi
*mipi
, u32 value
,
143 unsigned long offset
)
145 writel(value
, mipi
->regs
+ (offset
<< 2));
148 static int tegra_mipi_power_up(struct tegra_mipi
*mipi
)
153 err
= clk_enable(mipi
->clk
);
157 value
= tegra_mipi_readl(mipi
, MIPI_CAL_BIAS_PAD_CFG0
);
158 value
&= ~MIPI_CAL_BIAS_PAD_PDVCLAMP
;
160 if (mipi
->soc
->needs_vclamp_ref
)
161 value
|= MIPI_CAL_BIAS_PAD_E_VCLAMP_REF
;
163 tegra_mipi_writel(mipi
, value
, MIPI_CAL_BIAS_PAD_CFG0
);
165 value
= tegra_mipi_readl(mipi
, MIPI_CAL_BIAS_PAD_CFG2
);
166 value
&= ~MIPI_CAL_BIAS_PAD_PDVREG
;
167 tegra_mipi_writel(mipi
, value
, MIPI_CAL_BIAS_PAD_CFG2
);
169 clk_disable(mipi
->clk
);
174 static int tegra_mipi_power_down(struct tegra_mipi
*mipi
)
179 err
= clk_enable(mipi
->clk
);
184 * The MIPI_CAL_BIAS_PAD_PDVREG controls a voltage regulator that
185 * supplies the DSI pads. This must be kept enabled until none of the
186 * DSI lanes are used anymore.
188 value
= tegra_mipi_readl(mipi
, MIPI_CAL_BIAS_PAD_CFG2
);
189 value
|= MIPI_CAL_BIAS_PAD_PDVREG
;
190 tegra_mipi_writel(mipi
, value
, MIPI_CAL_BIAS_PAD_CFG2
);
193 * MIPI_CAL_BIAS_PAD_PDVCLAMP and MIPI_CAL_BIAS_PAD_E_VCLAMP_REF
194 * control a regulator that supplies current to the pre-driver logic.
195 * Powering down this regulator causes DSI to fail, so it must remain
196 * powered on until none of the DSI lanes are used anymore.
198 value
= tegra_mipi_readl(mipi
, MIPI_CAL_BIAS_PAD_CFG0
);
200 if (mipi
->soc
->needs_vclamp_ref
)
201 value
&= ~MIPI_CAL_BIAS_PAD_E_VCLAMP_REF
;
203 value
|= MIPI_CAL_BIAS_PAD_PDVCLAMP
;
204 tegra_mipi_writel(mipi
, value
, MIPI_CAL_BIAS_PAD_CFG0
);
209 struct tegra_mipi_device
*tegra_mipi_request(struct device
*device
,
210 struct device_node
*np
)
212 struct tegra_mipi_device
*dev
;
213 struct of_phandle_args args
;
216 err
= of_parse_phandle_with_args(np
, "nvidia,mipi-calibrate",
217 "#nvidia,mipi-calibrate-cells", 0,
222 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
228 dev
->pdev
= of_find_device_by_node(args
.np
);
234 dev
->mipi
= platform_get_drvdata(dev
->pdev
);
240 of_node_put(args
.np
);
242 dev
->pads
= args
.args
[0];
243 dev
->device
= device
;
248 platform_device_put(dev
->pdev
);
252 of_node_put(args
.np
);
255 EXPORT_SYMBOL(tegra_mipi_request
);
257 void tegra_mipi_free(struct tegra_mipi_device
*device
)
259 platform_device_put(device
->pdev
);
262 EXPORT_SYMBOL(tegra_mipi_free
);
264 int tegra_mipi_enable(struct tegra_mipi_device
*dev
)
268 mutex_lock(&dev
->mipi
->lock
);
270 if (dev
->mipi
->usage_count
++ == 0)
271 err
= tegra_mipi_power_up(dev
->mipi
);
273 mutex_unlock(&dev
->mipi
->lock
);
278 EXPORT_SYMBOL(tegra_mipi_enable
);
280 int tegra_mipi_disable(struct tegra_mipi_device
*dev
)
284 mutex_lock(&dev
->mipi
->lock
);
286 if (--dev
->mipi
->usage_count
== 0)
287 err
= tegra_mipi_power_down(dev
->mipi
);
289 mutex_unlock(&dev
->mipi
->lock
);
294 EXPORT_SYMBOL(tegra_mipi_disable
);
296 int tegra_mipi_finish_calibration(struct tegra_mipi_device
*device
)
298 struct tegra_mipi
*mipi
= device
->mipi
;
299 void __iomem
*status_reg
= mipi
->regs
+ (MIPI_CAL_STATUS
<< 2);
303 err
= readl_relaxed_poll_timeout(status_reg
, value
,
304 !(value
& MIPI_CAL_STATUS_ACTIVE
) &&
305 (value
& MIPI_CAL_STATUS_DONE
), 50,
307 mutex_unlock(&device
->mipi
->lock
);
308 clk_disable(device
->mipi
->clk
);
312 EXPORT_SYMBOL(tegra_mipi_finish_calibration
);
314 int tegra_mipi_start_calibration(struct tegra_mipi_device
*device
)
316 const struct tegra_mipi_soc
*soc
= device
->mipi
->soc
;
321 err
= clk_enable(device
->mipi
->clk
);
325 mutex_lock(&device
->mipi
->lock
);
327 value
= MIPI_CAL_BIAS_PAD_DRV_DN_REF(soc
->pad_drive_down_ref
) |
328 MIPI_CAL_BIAS_PAD_DRV_UP_REF(soc
->pad_drive_up_ref
);
329 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_BIAS_PAD_CFG1
);
331 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_BIAS_PAD_CFG2
);
332 value
&= ~MIPI_CAL_BIAS_PAD_VCLAMP(0x7);
333 value
&= ~MIPI_CAL_BIAS_PAD_VAUXP(0x7);
334 value
|= MIPI_CAL_BIAS_PAD_VCLAMP(soc
->pad_vclamp_level
);
335 value
|= MIPI_CAL_BIAS_PAD_VAUXP(soc
->pad_vauxp_level
);
336 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_BIAS_PAD_CFG2
);
338 for (i
= 0; i
< soc
->num_pads
; i
++) {
339 u32 clk
= 0, data
= 0;
341 if (device
->pads
& BIT(i
)) {
342 data
= MIPI_CAL_CONFIG_SELECT
|
343 MIPI_CAL_CONFIG_HSPDOS(soc
->hspdos
) |
344 MIPI_CAL_CONFIG_HSPUOS(soc
->hspuos
) |
345 MIPI_CAL_CONFIG_TERMOS(soc
->termos
);
346 clk
= MIPI_CAL_CONFIG_SELECT
|
347 MIPI_CAL_CONFIG_HSCLKPDOSD(soc
->hsclkpdos
) |
348 MIPI_CAL_CONFIG_HSCLKPUOSD(soc
->hsclkpuos
);
351 tegra_mipi_writel(device
->mipi
, data
, soc
->pads
[i
].data
);
353 if (soc
->has_clk_lane
&& soc
->pads
[i
].clk
!= 0)
354 tegra_mipi_writel(device
->mipi
, clk
, soc
->pads
[i
].clk
);
357 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_CTRL
);
358 value
&= ~MIPI_CAL_CTRL_NOISE_FILTER(0xf);
359 value
&= ~MIPI_CAL_CTRL_PRESCALE(0x3);
360 value
|= MIPI_CAL_CTRL_NOISE_FILTER(0xa);
361 value
|= MIPI_CAL_CTRL_PRESCALE(0x2);
363 if (!soc
->clock_enable_override
)
364 value
&= ~MIPI_CAL_CTRL_CLKEN_OVR
;
366 value
|= MIPI_CAL_CTRL_CLKEN_OVR
;
368 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_CTRL
);
370 /* clear any pending status bits */
371 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_STATUS
);
372 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_STATUS
);
374 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_CTRL
);
375 value
|= MIPI_CAL_CTRL_START
;
376 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_CTRL
);
379 * Wait for min 72uS to let calibration logic finish calibration
380 * sequence codes before waiting for pads idle state to apply the
383 usleep_range(75, 80);
387 EXPORT_SYMBOL(tegra_mipi_start_calibration
);
389 static const struct tegra_mipi_pad tegra114_mipi_pads
[] = {
390 { .data
= MIPI_CAL_CONFIG_CSIA
},
391 { .data
= MIPI_CAL_CONFIG_CSIB
},
392 { .data
= MIPI_CAL_CONFIG_CSIC
},
393 { .data
= MIPI_CAL_CONFIG_CSID
},
394 { .data
= MIPI_CAL_CONFIG_CSIE
},
395 { .data
= MIPI_CAL_CONFIG_DSIA
},
396 { .data
= MIPI_CAL_CONFIG_DSIB
},
397 { .data
= MIPI_CAL_CONFIG_DSIC
},
398 { .data
= MIPI_CAL_CONFIG_DSID
},
401 static const struct tegra_mipi_soc tegra114_mipi_soc
= {
402 .has_clk_lane
= false,
403 .pads
= tegra114_mipi_pads
,
404 .num_pads
= ARRAY_SIZE(tegra114_mipi_pads
),
405 .clock_enable_override
= true,
406 .needs_vclamp_ref
= true,
407 .pad_drive_down_ref
= 0x2,
408 .pad_drive_up_ref
= 0x0,
409 .pad_vclamp_level
= 0x0,
410 .pad_vauxp_level
= 0x0,
418 static const struct tegra_mipi_pad tegra124_mipi_pads
[] = {
419 { .data
= MIPI_CAL_CONFIG_CSIA
, .clk
= MIPI_CAL_CONFIG_CSIAB_CLK
},
420 { .data
= MIPI_CAL_CONFIG_CSIB
, .clk
= MIPI_CAL_CONFIG_CSIAB_CLK
},
421 { .data
= MIPI_CAL_CONFIG_CSIC
, .clk
= MIPI_CAL_CONFIG_CSICD_CLK
},
422 { .data
= MIPI_CAL_CONFIG_CSID
, .clk
= MIPI_CAL_CONFIG_CSICD_CLK
},
423 { .data
= MIPI_CAL_CONFIG_CSIE
, .clk
= MIPI_CAL_CONFIG_CSIE_CLK
},
424 { .data
= MIPI_CAL_CONFIG_DSIA
, .clk
= MIPI_CAL_CONFIG_DSIA_CLK
},
425 { .data
= MIPI_CAL_CONFIG_DSIB
, .clk
= MIPI_CAL_CONFIG_DSIB_CLK
},
428 static const struct tegra_mipi_soc tegra124_mipi_soc
= {
429 .has_clk_lane
= true,
430 .pads
= tegra124_mipi_pads
,
431 .num_pads
= ARRAY_SIZE(tegra124_mipi_pads
),
432 .clock_enable_override
= true,
433 .needs_vclamp_ref
= true,
434 .pad_drive_down_ref
= 0x2,
435 .pad_drive_up_ref
= 0x0,
436 .pad_vclamp_level
= 0x0,
437 .pad_vauxp_level
= 0x0,
445 static const struct tegra_mipi_soc tegra132_mipi_soc
= {
446 .has_clk_lane
= true,
447 .pads
= tegra124_mipi_pads
,
448 .num_pads
= ARRAY_SIZE(tegra124_mipi_pads
),
449 .clock_enable_override
= false,
450 .needs_vclamp_ref
= false,
451 .pad_drive_down_ref
= 0x0,
452 .pad_drive_up_ref
= 0x3,
453 .pad_vclamp_level
= 0x0,
454 .pad_vauxp_level
= 0x0,
462 static const struct tegra_mipi_pad tegra210_mipi_pads
[] = {
463 { .data
= MIPI_CAL_CONFIG_CSIA
, .clk
= 0 },
464 { .data
= MIPI_CAL_CONFIG_CSIB
, .clk
= 0 },
465 { .data
= MIPI_CAL_CONFIG_CSIC
, .clk
= 0 },
466 { .data
= MIPI_CAL_CONFIG_CSID
, .clk
= 0 },
467 { .data
= MIPI_CAL_CONFIG_CSIE
, .clk
= 0 },
468 { .data
= MIPI_CAL_CONFIG_CSIF
, .clk
= 0 },
469 { .data
= MIPI_CAL_CONFIG_DSIA
, .clk
= MIPI_CAL_CONFIG_DSIA_CLK
},
470 { .data
= MIPI_CAL_CONFIG_DSIB
, .clk
= MIPI_CAL_CONFIG_DSIB_CLK
},
471 { .data
= MIPI_CAL_CONFIG_DSIC
, .clk
= MIPI_CAL_CONFIG_DSIC_CLK
},
472 { .data
= MIPI_CAL_CONFIG_DSID
, .clk
= MIPI_CAL_CONFIG_DSID_CLK
},
475 static const struct tegra_mipi_soc tegra210_mipi_soc
= {
476 .has_clk_lane
= true,
477 .pads
= tegra210_mipi_pads
,
478 .num_pads
= ARRAY_SIZE(tegra210_mipi_pads
),
479 .clock_enable_override
= true,
480 .needs_vclamp_ref
= false,
481 .pad_drive_down_ref
= 0x0,
482 .pad_drive_up_ref
= 0x3,
483 .pad_vclamp_level
= 0x1,
484 .pad_vauxp_level
= 0x1,
492 static const struct of_device_id tegra_mipi_of_match
[] = {
493 { .compatible
= "nvidia,tegra114-mipi", .data
= &tegra114_mipi_soc
},
494 { .compatible
= "nvidia,tegra124-mipi", .data
= &tegra124_mipi_soc
},
495 { .compatible
= "nvidia,tegra132-mipi", .data
= &tegra132_mipi_soc
},
496 { .compatible
= "nvidia,tegra210-mipi", .data
= &tegra210_mipi_soc
},
500 static int tegra_mipi_probe(struct platform_device
*pdev
)
502 const struct of_device_id
*match
;
503 struct tegra_mipi
*mipi
;
504 struct resource
*res
;
507 match
= of_match_node(tegra_mipi_of_match
, pdev
->dev
.of_node
);
511 mipi
= devm_kzalloc(&pdev
->dev
, sizeof(*mipi
), GFP_KERNEL
);
515 mipi
->soc
= match
->data
;
516 mipi
->dev
= &pdev
->dev
;
518 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
519 mipi
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
520 if (IS_ERR(mipi
->regs
))
521 return PTR_ERR(mipi
->regs
);
523 mutex_init(&mipi
->lock
);
525 mipi
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
526 if (IS_ERR(mipi
->clk
)) {
527 dev_err(&pdev
->dev
, "failed to get clock\n");
528 return PTR_ERR(mipi
->clk
);
531 err
= clk_prepare(mipi
->clk
);
535 platform_set_drvdata(pdev
, mipi
);
540 static int tegra_mipi_remove(struct platform_device
*pdev
)
542 struct tegra_mipi
*mipi
= platform_get_drvdata(pdev
);
544 clk_unprepare(mipi
->clk
);
549 struct platform_driver tegra_mipi_driver
= {
551 .name
= "tegra-mipi",
552 .of_match_table
= tegra_mipi_of_match
,
554 .probe
= tegra_mipi_probe
,
555 .remove
= tegra_mipi_remove
,