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/delay.h>
25 #include <linux/host1x.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
)
211 struct device_node
*np
= device
->of_node
;
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 static int tegra_mipi_wait(struct tegra_mipi
*mipi
)
298 unsigned long timeout
= jiffies
+ msecs_to_jiffies(250);
301 while (time_before(jiffies
, timeout
)) {
302 value
= tegra_mipi_readl(mipi
, MIPI_CAL_STATUS
);
303 if ((value
& MIPI_CAL_STATUS_ACTIVE
) == 0 &&
304 (value
& MIPI_CAL_STATUS_DONE
) != 0)
307 usleep_range(10, 50);
313 int tegra_mipi_calibrate(struct tegra_mipi_device
*device
)
315 const struct tegra_mipi_soc
*soc
= device
->mipi
->soc
;
320 err
= clk_enable(device
->mipi
->clk
);
324 mutex_lock(&device
->mipi
->lock
);
326 value
= MIPI_CAL_BIAS_PAD_DRV_DN_REF(soc
->pad_drive_down_ref
) |
327 MIPI_CAL_BIAS_PAD_DRV_UP_REF(soc
->pad_drive_up_ref
);
328 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_BIAS_PAD_CFG1
);
330 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_BIAS_PAD_CFG2
);
331 value
&= ~MIPI_CAL_BIAS_PAD_VCLAMP(0x7);
332 value
&= ~MIPI_CAL_BIAS_PAD_VAUXP(0x7);
333 value
|= MIPI_CAL_BIAS_PAD_VCLAMP(soc
->pad_vclamp_level
);
334 value
|= MIPI_CAL_BIAS_PAD_VAUXP(soc
->pad_vauxp_level
);
335 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_BIAS_PAD_CFG2
);
337 for (i
= 0; i
< soc
->num_pads
; i
++) {
338 u32 clk
= 0, data
= 0;
340 if (device
->pads
& BIT(i
)) {
341 data
= MIPI_CAL_CONFIG_SELECT
|
342 MIPI_CAL_CONFIG_HSPDOS(soc
->hspdos
) |
343 MIPI_CAL_CONFIG_HSPUOS(soc
->hspuos
) |
344 MIPI_CAL_CONFIG_TERMOS(soc
->termos
);
345 clk
= MIPI_CAL_CONFIG_SELECT
|
346 MIPI_CAL_CONFIG_HSCLKPDOSD(soc
->hsclkpdos
) |
347 MIPI_CAL_CONFIG_HSCLKPUOSD(soc
->hsclkpuos
);
350 tegra_mipi_writel(device
->mipi
, data
, soc
->pads
[i
].data
);
352 if (soc
->has_clk_lane
&& soc
->pads
[i
].clk
!= 0)
353 tegra_mipi_writel(device
->mipi
, clk
, soc
->pads
[i
].clk
);
356 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_CTRL
);
357 value
&= ~MIPI_CAL_CTRL_NOISE_FILTER(0xf);
358 value
&= ~MIPI_CAL_CTRL_PRESCALE(0x3);
359 value
|= MIPI_CAL_CTRL_NOISE_FILTER(0xa);
360 value
|= MIPI_CAL_CTRL_PRESCALE(0x2);
362 if (!soc
->clock_enable_override
)
363 value
&= ~MIPI_CAL_CTRL_CLKEN_OVR
;
365 value
|= MIPI_CAL_CTRL_CLKEN_OVR
;
367 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_CTRL
);
369 /* clear any pending status bits */
370 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_STATUS
);
371 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_STATUS
);
373 value
= tegra_mipi_readl(device
->mipi
, MIPI_CAL_CTRL
);
374 value
|= MIPI_CAL_CTRL_START
;
375 tegra_mipi_writel(device
->mipi
, value
, MIPI_CAL_CTRL
);
377 err
= tegra_mipi_wait(device
->mipi
);
379 mutex_unlock(&device
->mipi
->lock
);
380 clk_disable(device
->mipi
->clk
);
384 EXPORT_SYMBOL(tegra_mipi_calibrate
);
386 static const struct tegra_mipi_pad tegra114_mipi_pads
[] = {
387 { .data
= MIPI_CAL_CONFIG_CSIA
},
388 { .data
= MIPI_CAL_CONFIG_CSIB
},
389 { .data
= MIPI_CAL_CONFIG_CSIC
},
390 { .data
= MIPI_CAL_CONFIG_CSID
},
391 { .data
= MIPI_CAL_CONFIG_CSIE
},
392 { .data
= MIPI_CAL_CONFIG_DSIA
},
393 { .data
= MIPI_CAL_CONFIG_DSIB
},
394 { .data
= MIPI_CAL_CONFIG_DSIC
},
395 { .data
= MIPI_CAL_CONFIG_DSID
},
398 static const struct tegra_mipi_soc tegra114_mipi_soc
= {
399 .has_clk_lane
= false,
400 .pads
= tegra114_mipi_pads
,
401 .num_pads
= ARRAY_SIZE(tegra114_mipi_pads
),
402 .clock_enable_override
= true,
403 .needs_vclamp_ref
= true,
404 .pad_drive_down_ref
= 0x2,
405 .pad_drive_up_ref
= 0x0,
406 .pad_vclamp_level
= 0x0,
407 .pad_vauxp_level
= 0x0,
415 static const struct tegra_mipi_pad tegra124_mipi_pads
[] = {
416 { .data
= MIPI_CAL_CONFIG_CSIA
, .clk
= MIPI_CAL_CONFIG_CSIAB_CLK
},
417 { .data
= MIPI_CAL_CONFIG_CSIB
, .clk
= MIPI_CAL_CONFIG_CSIAB_CLK
},
418 { .data
= MIPI_CAL_CONFIG_CSIC
, .clk
= MIPI_CAL_CONFIG_CSICD_CLK
},
419 { .data
= MIPI_CAL_CONFIG_CSID
, .clk
= MIPI_CAL_CONFIG_CSICD_CLK
},
420 { .data
= MIPI_CAL_CONFIG_CSIE
, .clk
= MIPI_CAL_CONFIG_CSIE_CLK
},
421 { .data
= MIPI_CAL_CONFIG_DSIA
, .clk
= MIPI_CAL_CONFIG_DSIA_CLK
},
422 { .data
= MIPI_CAL_CONFIG_DSIB
, .clk
= MIPI_CAL_CONFIG_DSIB_CLK
},
425 static const struct tegra_mipi_soc tegra124_mipi_soc
= {
426 .has_clk_lane
= true,
427 .pads
= tegra124_mipi_pads
,
428 .num_pads
= ARRAY_SIZE(tegra124_mipi_pads
),
429 .clock_enable_override
= true,
430 .needs_vclamp_ref
= true,
431 .pad_drive_down_ref
= 0x2,
432 .pad_drive_up_ref
= 0x0,
433 .pad_vclamp_level
= 0x0,
434 .pad_vauxp_level
= 0x0,
442 static const struct tegra_mipi_soc tegra132_mipi_soc
= {
443 .has_clk_lane
= true,
444 .pads
= tegra124_mipi_pads
,
445 .num_pads
= ARRAY_SIZE(tegra124_mipi_pads
),
446 .clock_enable_override
= false,
447 .needs_vclamp_ref
= false,
448 .pad_drive_down_ref
= 0x0,
449 .pad_drive_up_ref
= 0x3,
450 .pad_vclamp_level
= 0x0,
451 .pad_vauxp_level
= 0x0,
459 static const struct tegra_mipi_pad tegra210_mipi_pads
[] = {
460 { .data
= MIPI_CAL_CONFIG_CSIA
, .clk
= 0 },
461 { .data
= MIPI_CAL_CONFIG_CSIB
, .clk
= 0 },
462 { .data
= MIPI_CAL_CONFIG_CSIC
, .clk
= 0 },
463 { .data
= MIPI_CAL_CONFIG_CSID
, .clk
= 0 },
464 { .data
= MIPI_CAL_CONFIG_CSIE
, .clk
= 0 },
465 { .data
= MIPI_CAL_CONFIG_CSIF
, .clk
= 0 },
466 { .data
= MIPI_CAL_CONFIG_DSIA
, .clk
= MIPI_CAL_CONFIG_DSIA_CLK
},
467 { .data
= MIPI_CAL_CONFIG_DSIB
, .clk
= MIPI_CAL_CONFIG_DSIB_CLK
},
468 { .data
= MIPI_CAL_CONFIG_DSIC
, .clk
= MIPI_CAL_CONFIG_DSIC_CLK
},
469 { .data
= MIPI_CAL_CONFIG_DSID
, .clk
= MIPI_CAL_CONFIG_DSID_CLK
},
472 static const struct tegra_mipi_soc tegra210_mipi_soc
= {
473 .has_clk_lane
= true,
474 .pads
= tegra210_mipi_pads
,
475 .num_pads
= ARRAY_SIZE(tegra210_mipi_pads
),
476 .clock_enable_override
= true,
477 .needs_vclamp_ref
= false,
478 .pad_drive_down_ref
= 0x0,
479 .pad_drive_up_ref
= 0x3,
480 .pad_vclamp_level
= 0x1,
481 .pad_vauxp_level
= 0x1,
489 static const struct of_device_id tegra_mipi_of_match
[] = {
490 { .compatible
= "nvidia,tegra114-mipi", .data
= &tegra114_mipi_soc
},
491 { .compatible
= "nvidia,tegra124-mipi", .data
= &tegra124_mipi_soc
},
492 { .compatible
= "nvidia,tegra132-mipi", .data
= &tegra132_mipi_soc
},
493 { .compatible
= "nvidia,tegra210-mipi", .data
= &tegra210_mipi_soc
},
497 static int tegra_mipi_probe(struct platform_device
*pdev
)
499 const struct of_device_id
*match
;
500 struct tegra_mipi
*mipi
;
501 struct resource
*res
;
504 match
= of_match_node(tegra_mipi_of_match
, pdev
->dev
.of_node
);
508 mipi
= devm_kzalloc(&pdev
->dev
, sizeof(*mipi
), GFP_KERNEL
);
512 mipi
->soc
= match
->data
;
513 mipi
->dev
= &pdev
->dev
;
515 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
516 mipi
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
517 if (IS_ERR(mipi
->regs
))
518 return PTR_ERR(mipi
->regs
);
520 mutex_init(&mipi
->lock
);
522 mipi
->clk
= devm_clk_get(&pdev
->dev
, NULL
);
523 if (IS_ERR(mipi
->clk
)) {
524 dev_err(&pdev
->dev
, "failed to get clock\n");
525 return PTR_ERR(mipi
->clk
);
528 err
= clk_prepare(mipi
->clk
);
532 platform_set_drvdata(pdev
, mipi
);
537 static int tegra_mipi_remove(struct platform_device
*pdev
)
539 struct tegra_mipi
*mipi
= platform_get_drvdata(pdev
);
541 clk_unprepare(mipi
->clk
);
546 struct platform_driver tegra_mipi_driver
= {
548 .name
= "tegra-mipi",
549 .of_match_table
= tegra_mipi_of_match
,
551 .probe
= tegra_mipi_probe
,
552 .remove
= tegra_mipi_remove
,