video: tegra: dsi: Enable MIPI auto calibration
[linux-3.10.git] / drivers / video / tegra / dc / mipi_cal.c
1 /*
2  * drivers/video/tegra/dc/mipi_cal.c
3  *
4  * Copyright (c) 2012-2013, NVIDIA CORPORATION, All rights reserved.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16
17 #include <linux/ioport.h>
18 #include <linux/gfp.h>
19 #include "dc_priv.h"
20 #include "mipi_cal.h"
21 #include "mipi_cal_regs.h"
22 #include "dsi.h"
23
24 int tegra_mipi_cal_init_hw(struct tegra_mipi_cal *mipi_cal)
25 {
26         unsigned cnt = MIPI_CAL_MIPI_CAL_CTRL_0;
27
28         BUG_ON(IS_ERR_OR_NULL(mipi_cal));
29
30         mutex_lock(&mipi_cal->lock);
31
32         tegra_mipi_cal_clk_enable(mipi_cal);
33
34         for (; cnt <= MIPI_CAL_MIPI_BIAS_PAD_CFG2_0; cnt += 4)
35                 tegra_mipi_cal_write(mipi_cal, 0, cnt);
36
37         /* Clear MIPI cal status register */
38         tegra_mipi_cal_write(mipi_cal,
39                         MIPI_AUTO_CAL_DONE_DSID(0x1) |
40                         MIPI_AUTO_CAL_DONE_DSIC(0x1) |
41                         MIPI_AUTO_CAL_DONE_DSIB(0x1) |
42                         MIPI_AUTO_CAL_DONE_DSIA(0x1) |
43                         MIPI_AUTO_CAL_DONE_CSIE(0x1) |
44                         MIPI_AUTO_CAL_DONE_CSID(0x1) |
45                         MIPI_AUTO_CAL_DONE_CSIC(0x1) |
46                         MIPI_AUTO_CAL_DONE_CSIB(0x1) |
47                         MIPI_AUTO_CAL_DONE_CSIA(0x1) |
48                         MIPI_AUTO_CAL_DONE(0x1) |
49                         MIPI_CAL_DRIV_DN_ADJ(0x0) |
50                         MIPI_CAL_DRIV_UP_ADJ(0x0) |
51                         MIPI_CAL_TERMADJ(0x0) |
52                         MIPI_CAL_ACTIVE(0x0),
53                 MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
54
55         tegra_mipi_cal_clk_disable(mipi_cal);
56         mutex_unlock(&mipi_cal->lock);
57
58         return 0;
59 }
60 EXPORT_SYMBOL(tegra_mipi_cal_init_hw);
61
62 struct tegra_mipi_cal *tegra_mipi_cal_init_sw(struct tegra_dc *dc)
63 {
64         struct tegra_mipi_cal *mipi_cal;
65         struct resource *res;
66         struct clk *clk;
67         struct clk *fixed_clk;
68         void __iomem *base;
69         int err = 0;
70
71         mipi_cal = devm_kzalloc(&dc->ndev->dev, sizeof(*mipi_cal), GFP_KERNEL);
72         if (!mipi_cal) {
73                 dev_err(&dc->ndev->dev, "mipi_cal: memory allocation fail\n");
74                 err = -ENOMEM;
75                 goto fail;
76         }
77
78         res = platform_get_resource_byname(dc->ndev,
79                                 IORESOURCE_MEM, "mipi_cal");
80         if (!res) {
81                 dev_err(&dc->ndev->dev, "mipi_cal: no entry in resource\n");
82                 err = -ENOENT;
83                 goto fail_free_mipi_cal;
84         }
85
86         base = devm_request_and_ioremap(&dc->ndev->dev, res);
87         if (!base) {
88                 dev_err(&dc->ndev->dev, "mipi_cal: bus to virtual mapping failed\n");
89                 err = -EBUSY;
90                 goto fail_free_res;
91         }
92
93         clk = clk_get_sys("mipi-cal", NULL);
94         if (IS_ERR_OR_NULL(clk)) {
95                 dev_err(&dc->ndev->dev, "mipi_cal: clk get failed\n");
96                 err = PTR_ERR(clk);
97                 goto fail_free_map;
98         }
99         fixed_clk = clk_get_sys("mipi-cal-fixed", NULL);
100         if (IS_ERR_OR_NULL(fixed_clk)) {
101                 dev_err(&dc->ndev->dev, "mipi_cal: fixed clk get failed\n");
102                 err = PTR_ERR(fixed_clk);
103                 goto fail_free_map;
104         }
105
106         mutex_init(&mipi_cal->lock);
107         mipi_cal->dc = dc;
108         mipi_cal->res = res;
109         mipi_cal->base = base;
110         mipi_cal->clk = clk;
111         mipi_cal->fixed_clk = fixed_clk;
112
113         return mipi_cal;
114
115 fail_free_map:
116         devm_iounmap(&dc->ndev->dev, base);
117         devm_release_mem_region(&dc->ndev->dev, res->start, resource_size(res));
118 fail_free_res:
119         release_resource(res);
120 fail_free_mipi_cal:
121         devm_kfree(&dc->ndev->dev, mipi_cal);
122 fail:
123         return ERR_PTR(err);
124 }
125 EXPORT_SYMBOL(tegra_mipi_cal_init_sw);
126
127 void tegra_mipi_cal_destroy(struct tegra_dc *dc)
128 {
129         struct tegra_mipi_cal *mipi_cal =
130                 ((struct tegra_dc_dsi_data *)
131                 (tegra_dc_get_outdata(dc)))->mipi_cal;
132
133         BUG_ON(IS_ERR_OR_NULL(mipi_cal));
134
135         mutex_lock(&mipi_cal->lock);
136
137         clk_put(mipi_cal->clk);
138         devm_iounmap(&dc->ndev->dev, mipi_cal->base);
139         devm_release_mem_region(&dc->ndev->dev, mipi_cal->res->start,
140                                         resource_size(mipi_cal->res));
141         release_resource(mipi_cal->res);
142
143         mutex_unlock(&mipi_cal->lock);
144
145         mutex_destroy(&mipi_cal->lock);
146         devm_kfree(&dc->ndev->dev, mipi_cal);
147 }
148 EXPORT_SYMBOL(tegra_mipi_cal_destroy);
149