2 * drivers/video/tegra/dc/mipi_cal.c
4 * Copyright (c) 2012-2015, NVIDIA CORPORATION, All rights reserved.
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.
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.
17 #include <linux/debugfs.h>
18 #include <linux/ioport.h>
19 #include <linux/gfp.h>
20 #include <linux/export.h>
23 #include "mipi_cal_regs.h"
25 #include <linux/of_address.h>
27 #include "../../../../arch/arm/mach-tegra/iomap.h"
29 #ifdef CONFIG_DEBUG_FS
30 static int dbg_dsi_mipi_show(struct seq_file *s, void *unused)
32 struct tegra_mipi_cal *mipi_cal = s->private;
36 /* If gated quitely return */
37 if (!tegra_dc_is_powered(mipi_cal->dc))
40 BUG_ON(IS_ERR_OR_NULL(mipi_cal));
41 mutex_lock(&mipi_cal->lock);
42 tegra_mipi_cal_clk_enable(mipi_cal);
45 for (col = 0, i = 0; i <= MIPI_VALID_REG_LIMIT ; i += 4) {
47 seq_printf(s, "%08lX:", TEGRA_MIPI_CAL_BASE + i);
48 seq_printf(s, "%c%08lX", col == 2 ? '-' : ' ',
49 tegra_mipi_cal_read(mipi_cal, i));
58 tegra_mipi_cal_clk_disable(mipi_cal);
59 mutex_unlock(&mipi_cal->lock);
63 static int dbg_dsi_mipi_open(struct inode *inode, struct file *file)
65 return single_open(file, dbg_dsi_mipi_show, inode->i_private);
68 static const struct file_operations dbg_fops = {
69 .open = dbg_dsi_mipi_open,
72 .release = single_release,
75 static struct dentry *mipidir;
77 static void dbg_dsi_mipi_dir_create(struct tegra_mipi_cal *mipi_cal)
79 struct dentry *retval;
81 mipidir = debugfs_create_dir("tegra_mipi_cal", NULL);
84 retval = debugfs_create_file("regs", S_IRUGO, mipidir, mipi_cal,
90 debugfs_remove_recursive(mipidir);
95 static inline void dbg_dsi_mipi_dir_create(struct tegra_mipi_cal *mipi_cal)
99 int tegra_mipi_cal_init_hw(struct tegra_mipi_cal *mipi_cal)
101 BUG_ON(IS_ERR_OR_NULL(mipi_cal));
103 mutex_lock(&mipi_cal->lock);
105 tegra_mipi_cal_clk_enable(mipi_cal);
107 /* Clear MIPI cal status register */
108 tegra_mipi_cal_write(mipi_cal,
109 MIPI_AUTO_CAL_DONE_DSID(0x1) |
110 MIPI_AUTO_CAL_DONE_DSIC(0x1) |
111 MIPI_AUTO_CAL_DONE_DSIB(0x1) |
112 MIPI_AUTO_CAL_DONE_DSIA(0x1) |
113 MIPI_AUTO_CAL_DONE_CSIE(0x1) |
114 MIPI_AUTO_CAL_DONE_CSID(0x1) |
115 MIPI_AUTO_CAL_DONE_CSIC(0x1) |
116 MIPI_AUTO_CAL_DONE_CSIB(0x1) |
117 MIPI_AUTO_CAL_DONE_CSIA(0x1) |
118 MIPI_AUTO_CAL_DONE(0x1) |
119 MIPI_CAL_DRIV_DN_ADJ(0x0) |
120 MIPI_CAL_DRIV_UP_ADJ(0x0) |
121 MIPI_CAL_TERMADJ(0x0) |
122 MIPI_CAL_ACTIVE(0x0),
123 MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
125 tegra_mipi_cal_clk_disable(mipi_cal);
126 mutex_unlock(&mipi_cal->lock);
130 EXPORT_SYMBOL(tegra_mipi_cal_init_hw);
132 struct tegra_mipi_cal *tegra_mipi_cal_init_sw(struct tegra_dc *dc)
134 struct tegra_mipi_cal *mipi_cal;
135 struct resource *res;
136 struct resource mipi_res;
137 struct resource *base_res;
139 struct clk *fixed_clk;
143 struct device_node *np_mipi_cal =
144 of_find_node_by_path("/mipical");
146 struct device_node *np_mipi_cal = NULL;
148 mipi_cal = devm_kzalloc(&dc->ndev->dev, sizeof(*mipi_cal), GFP_KERNEL);
150 dev_err(&dc->ndev->dev, "mipi_cal: memory allocation fail\n");
155 if (np_mipi_cal && of_device_is_available(np_mipi_cal)) {
156 of_address_to_resource(
157 np_mipi_cal, 0, &mipi_res);
160 res = platform_get_resource_byname(dc->ndev,
161 IORESOURCE_MEM, "mipi_cal");
164 dev_err(&dc->ndev->dev, "mipi_cal: no entry in resource\n");
166 goto fail_free_mipi_cal;
169 base_res = devm_request_mem_region(&dc->ndev->dev, res->start,
170 resource_size(res), dc->ndev->name);
171 base = devm_ioremap(&dc->ndev->dev, res->start,
174 dev_err(&dc->ndev->dev, "mipi_cal: bus to virtual mapping failed\n");
179 clk = clk_get_sys("mipi-cal", NULL);
180 if (IS_ERR_OR_NULL(clk)) {
181 dev_err(&dc->ndev->dev, "mipi_cal: clk get failed\n");
185 fixed_clk = clk_get_sys("mipi-cal-fixed", NULL);
186 if (IS_ERR_OR_NULL(fixed_clk)) {
187 dev_err(&dc->ndev->dev, "mipi_cal: fixed clk get failed\n");
188 err = PTR_ERR(fixed_clk);
192 mutex_init(&mipi_cal->lock);
195 mipi_cal->base = base;
196 mipi_cal->base_res = base_res;
198 mipi_cal->fixed_clk = fixed_clk;
199 dbg_dsi_mipi_dir_create(mipi_cal);
203 devm_iounmap(&dc->ndev->dev, base);
204 devm_release_mem_region(&dc->ndev->dev,
205 res->start, resource_size(res));
207 if (!np_mipi_cal || !of_device_is_available(np_mipi_cal))
208 release_resource(res);
210 devm_kfree(&dc->ndev->dev, mipi_cal);
214 EXPORT_SYMBOL(tegra_mipi_cal_init_sw);
216 void tegra_mipi_cal_destroy(struct tegra_dc *dc)
219 struct device_node *np_mipi_cal =
220 of_find_node_by_path("/mipical");
222 struct device_node *np_mipi_cal = NULL;
224 struct tegra_mipi_cal *mipi_cal =
225 ((struct tegra_dc_dsi_data *)
226 (tegra_dc_get_outdata(dc)))->mipi_cal;
228 BUG_ON(IS_ERR_OR_NULL(mipi_cal));
230 mutex_lock(&mipi_cal->lock);
232 clk_put(mipi_cal->clk);
233 devm_iounmap(&dc->ndev->dev, mipi_cal->base);
234 devm_release_mem_region(&dc->ndev->dev,
235 mipi_cal->res->start,
236 resource_size(mipi_cal->res));
238 if (!np_mipi_cal || !of_device_is_available(np_mipi_cal))
239 release_resource(mipi_cal->res);
241 mutex_unlock(&mipi_cal->lock);
243 mutex_destroy(&mipi_cal->lock);
244 devm_kfree(&dc->ndev->dev, mipi_cal);
245 #ifdef CONFIG_DEBUG_FS
246 debugfs_remove_recursive(mipidir);
249 EXPORT_SYMBOL(tegra_mipi_cal_destroy);