Merge tag 'lsk-v4.4-16.06-android'
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / rk_camsys / camsys_mipicsi_phy.c
1 #include "camsys_soc_priv.h"
2 #include "camsys_mipicsi_phy.h"
3
4 unsigned int CHIP_TYPE;
5 unsigned long rk_grf_base;
6 unsigned long rk_cru_base;
7 unsigned long rk_isp_base;
8
9 static int camsys_mipiphy_clkin_cb(void *ptr, unsigned int on)
10 {
11         camsys_mipiphy_clk_t *clk;
12         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
13         unsigned int i, phycnt;
14
15         if (camsys_dev->mipiphy != NULL) {
16                 phycnt = camsys_dev->mipiphy[0].phycnt;
17
18                 for (i = 0; i < phycnt; i++) {
19                         if (camsys_dev->mipiphy[i].clk != NULL) {
20                                 clk = (camsys_mipiphy_clk_t *)
21                                         camsys_dev->mipiphy[i].clk;
22                                 if (on && !clk->on) {
23                                         if (!IS_ERR_OR_NULL(clk->hclk))
24                                                 clk_prepare_enable(clk->hclk);
25                                         clk->on = on;
26                                 } else if (!on && clk->on) {
27                                         if (!IS_ERR_OR_NULL(clk->hclk))
28                                                 clk_disable_unprepare
29                                                 (clk->hclk);
30                                         clk->on = on;
31                                 }
32                         }
33                 }
34         }
35         if (on)
36                 camsys_trace(1, "%s mipi phy clk in turn on",
37                 dev_name(camsys_dev->miscdev.this_device));
38         else
39                 camsys_trace(1, "%s mipi phy clk in turn off",
40                 dev_name(camsys_dev->miscdev.this_device));
41
42         return 0;
43 }
44
45 static int camsys_mipiphy_ops(void *ptr, camsys_mipiphy_t *phy)
46 {
47         camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
48         camsys_mipiphy_soc_para_t para;
49         camsys_soc_priv_t *soc;
50
51         if (camsys_dev->soc) {
52                 soc = (camsys_soc_priv_t *)camsys_dev->soc;
53                 if (soc->soc_cfg) {
54                         para.camsys_dev = camsys_dev;
55                         para.phy = phy;
56                         (soc->soc_cfg)(camsys_dev, Mipi_Phy_Cfg, (void *)&para);
57                 } else {
58                         camsys_err("camsys_dev->soc->soc_cfg is NULL!");
59                 }
60         } else {
61                 camsys_err("camsys_dev->soc is NULL!");
62         }
63
64         return 0;
65 }
66
67 static int camsys_mipiphy_remove_cb(struct platform_device *pdev)
68 {
69         camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
70         camsys_mipiphy_clk_t *phyclk;
71         unsigned int i = 0;
72         unsigned long vir_base = camsys_dev->mipiphy[i].reg->vir_base;
73
74         if (camsys_dev->mipiphy != NULL) {
75                 for (i = 0; i < camsys_dev->mipiphy[0].phycnt; i++) {
76                         if (camsys_dev->mipiphy[i].reg != NULL) {
77                                 if (camsys_dev->mipiphy[i].reg->vir_base != 0) {
78                                         iounmap((void __iomem *)vir_base);
79                                         vir_base = 0;
80                                 }
81                                 kfree(camsys_dev->mipiphy[i].reg);
82                                 camsys_dev->mipiphy[i].reg = NULL;
83                         }
84
85                         if (camsys_dev->mipiphy[i].clk != NULL) {
86                                 phyclk =
87                                         (camsys_mipiphy_clk_t *)
88                                         camsys_dev->mipiphy[i].clk;
89                                 devm_clk_put(&pdev->dev, phyclk->hclk);
90
91                                 kfree(camsys_dev->mipiphy[i].clk);
92                                 camsys_dev->mipiphy[i].clk = NULL;
93                         }
94                 }
95         }
96         if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366 || CHIP_TYPE == 3399) {
97                 if (camsys_dev->csiphy_reg != NULL) {
98                         kfree(camsys_dev->csiphy_reg);
99                         camsys_dev->csiphy_reg = NULL;
100                 }
101
102                 if (camsys_dev->dsiphy_reg != NULL) {
103                         kfree(camsys_dev->dsiphy_reg);
104                         camsys_dev->dsiphy_reg = NULL;
105                 }
106         }
107
108         return 0;
109 }
110
111 int camsys_mipiphy_probe_cb(
112 struct platform_device *pdev, camsys_dev_t *camsys_dev)
113 {
114         struct device *dev = &pdev->dev;
115         camsys_meminfo_t *meminfo;
116         camsys_phyinfo_t *mipiphy;
117         unsigned int mipiphy_cnt, phyreg[2];
118         char str[31];
119         struct clk *clk;
120         camsys_mipiphy_clk_t *phyclk;
121         int err, i;
122         struct device_node *node;
123
124         err = of_property_read_u32(dev->of_node,
125                 "rockchip,isp,mipiphy", &mipiphy_cnt);
126         if (err < 0) {
127                 camsys_err("get property(rockchip,isp,mipiphy) failed!");
128                 goto fail;
129         } else {
130                 camsys_trace(2, "%s have %d mipi phy\n",
131                         dev_name(&pdev->dev), mipiphy_cnt);
132         }
133
134         mipiphy = kzalloc(sizeof(camsys_phyinfo_t)*mipiphy_cnt, GFP_KERNEL);
135         if (mipiphy == NULL) {
136                 err = -ENOMEM;
137                 camsys_err("malloc camsys_phyinfo_t failed!");
138                 goto fail;
139         }
140
141         camsys_dev->mipiphy = mipiphy;
142
143         memset(str, 0x00, sizeof(str));
144         for (i = 0; i < mipiphy_cnt; i++) {
145                 meminfo = NULL;
146                 sprintf(str, "rockchip,isp,mipiphy%d,reg", i);
147                 if (of_property_read_u32_array(
148                                 dev->of_node, str, phyreg, 2
149                                 ) == 0
150                         ) {
151                         meminfo = kzalloc(sizeof(camsys_meminfo_t), GFP_KERNEL);
152                         if (meminfo == NULL) {
153                                 camsys_err(
154                                 "malloc camsys_meminfo_t for mipiphy%d failed!",
155                                 i);
156                         } else {
157                                 meminfo->vir_base =
158                                         (unsigned long)
159                                         ioremap(phyreg[0], phyreg[1]);
160                                 if (!meminfo->vir_base) {
161                                         camsys_err("%s ioremap %s failed",
162                                                 dev_name(&pdev->dev), str);
163                                 } else {
164                                         strlcpy(meminfo->name,
165                                                 CAMSYS_MIPIPHY_MEM_NAME,
166                                                 sizeof(meminfo->name));
167                                         meminfo->phy_base = phyreg[0];
168                                         meminfo->size = phyreg[1];
169                                 }
170                                 camsys_dev->mipiphy[i].reg = meminfo;
171                         }
172                 }
173
174                 memset(str, sizeof(str), 0x00);
175                 sprintf(str, "hclk_mipiphy%d", i);
176
177                 clk = devm_clk_get(&pdev->dev, str);
178                 if (!IS_ERR_OR_NULL(clk)) {
179                         phyclk =
180                                 kzalloc(sizeof(camsys_mipiphy_clk_t),
181                                 GFP_KERNEL);
182                         if (phyclk == NULL) {
183                                 camsys_err("malloc camsys_mipiphy_clk_t for %s failed!",
184                                         str);
185                         } else {
186                                 phyclk->hclk = clk;
187                         }
188
189                         camsys_dev->mipiphy[i].clk = (void *)phyclk;
190                 }
191
192                 camsys_dev->mipiphy[i].phycnt = mipiphy_cnt;
193                 camsys_dev->mipiphy[i].clkin_cb = camsys_mipiphy_clkin_cb;
194                 camsys_dev->mipiphy[i].ops = camsys_mipiphy_ops;
195                 camsys_dev->mipiphy[i].remove = camsys_mipiphy_remove_cb;
196
197                 if (meminfo != NULL) {
198                         camsys_trace(1, "%s mipi phy%d probe success "
199                                 "(reg_phy: 0x%lx  reg_vir: 0x%lx  size: 0x%x)\n",
200                                 dev_name(&pdev->dev), i, meminfo->phy_base,
201                                 meminfo->vir_base, meminfo->size);
202                 } else {
203                         camsys_trace(1, "%s mipi phy%d probe success "
204                                 "(reg_phy: 0x%x  reg_vir: 0x%x  size: 0x%x)\n",
205                                 dev_name(&pdev->dev), i, 0, 0, 0);
206                 }
207
208         }
209
210         if (CHIP_TYPE == 3368 || CHIP_TYPE == 3366 || CHIP_TYPE == 3399) {
211
212                 if (CHIP_TYPE == 3399) {
213                         camsys_dev->dsiphy_reg =
214                                 kzalloc(sizeof(camsys_meminfo_t), GFP_KERNEL);
215                         if (camsys_dev->dsiphy_reg == NULL) {
216                                 camsys_err("malloc camsys_meminfo_t for dsiphy_reg failed!");
217                         }
218
219                         if (of_property_read_u32_array(
220                                         dev->of_node,
221                                         "rockchip,isp,dsiphy,reg", phyreg, 2
222                                         ) == 0
223                                 ) {
224                                         camsys_dev->dsiphy_reg->vir_base =
225                                                 (unsigned long)
226                                                 ioremap(phyreg[0], phyreg[1]);
227                                 if (!camsys_dev->dsiphy_reg->vir_base) {
228                                         camsys_err("%s ioremap %s failed",
229                                                 dev_name(&pdev->dev),
230                                                 "rockchip,isp,dsiphy,reg");
231                                 } else {
232                                 strlcpy(camsys_dev->dsiphy_reg->name,
233                                         "Dsi-DPHY",
234                                         sizeof(camsys_dev->dsiphy_reg->name));
235                                 camsys_dev->dsiphy_reg->phy_base = phyreg[0];
236                                 camsys_dev->dsiphy_reg->size = phyreg[1];
237                                 }
238                         }
239
240         } else {
241                         camsys_dev->csiphy_reg =
242                                 kzalloc(sizeof(camsys_meminfo_t), GFP_KERNEL);
243                         if (camsys_dev->csiphy_reg == NULL) {
244                                 camsys_err("malloc camsys_meminfo_t for csiphy_reg failed!");
245                         }
246
247                         if (of_property_read_u32_array(
248                                         dev->of_node,
249                                         "rockchip,isp,csiphy,reg", phyreg, 2
250                                         ) == 0
251                                 ) {
252                                 camsys_dev->csiphy_reg->vir_base =
253                                         (unsigned long)
254                                         ioremap(phyreg[0], phyreg[1]);
255                                 if (!camsys_dev->csiphy_reg->vir_base) {
256                                         camsys_err("%s ioremap %s failed",
257                                                 dev_name(&pdev->dev),
258                                                 "rockchip,isp,csiphy,reg");
259                                 } else {
260                                         strlcpy(camsys_dev->csiphy_reg->name,
261                                         "Csi-DPHY",
262                                         sizeof(camsys_dev->csiphy_reg->name));
263                                         camsys_dev->csiphy_reg->phy_base =
264                                                 phyreg[0];
265                                         camsys_dev->csiphy_reg->size =
266                                                 phyreg[1];
267                                 }
268                         }
269                 }
270
271                 /* get cru base */
272                 node = of_parse_phandle(dev->of_node, "rockchip,cru", 0);
273                 camsys_dev->rk_cru_base = (unsigned long)of_iomap(node, 0);
274                 camsys_trace(1, "rk_cru_base=0x%lx", camsys_dev->rk_cru_base);
275                 /* get grf base */
276                 node = of_parse_phandle(dev->of_node, "rockchip,grf", 0);
277                 camsys_dev->rk_grf_base = (unsigned long)of_iomap(node, 0);
278                 camsys_trace(1, "rk_grf_base=0x%lx", camsys_dev->rk_grf_base);
279         }
280
281         return 0;
282
283 fail:
284
285         return err;
286 }
287