1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2020 Rockchip Electronics Co., Ltd */
3
4 #include <linux/clk.h>
5 #include <linux/delay.h>
6 #include <linux/interrupt.h>
7 #include <linux/io.h>
8 #include <linux/iommu.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/of_graph.h>
12 #include <linux/of_platform.h>
13 #include <linux/of_reserved_mem.h>
14 #include <linux/pinctrl/consumer.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/reset.h>
17 #include <media/videobuf2-cma-sg.h>
18 #include <media/videobuf2-dma-sg.h>
19 #include <soc/rockchip/rockchip_iommu.h>
20
21 #include "common.h"
22 #include "dev.h"
23 #include "fec.h"
24 #include "hw.h"
25 #include "regs.h"
26
27 /*
28 * rkispp_hw share hardware resource with rkispp virtual device
29 * rkispp_device rkispp_device rkispp_device rkispp_device
30 * | | | |
31 * \ | | /
32 * -----------------------------------------
33 * |
34 * rkispp_hw
35 */
36
37 struct irqs_data {
38 const char *name;
39 irqreturn_t (*irq_hdl)(int irq, void *ctx);
40 };
41
rkispp_soft_reset(struct rkispp_hw_dev * hw)42 void rkispp_soft_reset(struct rkispp_hw_dev *hw)
43 {
44 writel(GLB_SOFT_RST_ALL, hw->base_addr + RKISPP_CTRL_RESET);
45 udelay(10);
46 writel(~GLB_SOFT_RST_ALL, hw->base_addr + RKISPP_CTRL_RESET);
47 if (hw->reset) {
48 reset_control_assert(hw->reset);
49 udelay(20);
50 reset_control_deassert(hw->reset);
51 udelay(20);
52 }
53
54 /* refresh iommu after reset */
55 if (hw->is_mmu) {
56 rockchip_iommu_disable(hw->dev);
57 rockchip_iommu_enable(hw->dev);
58 }
59 if (hw->ispp_ver == ISPP_V10) {
60 writel(SW_SCL_BYPASS, hw->base_addr + RKISPP_SCL0_CTRL);
61 writel(SW_SCL_BYPASS, hw->base_addr + RKISPP_SCL1_CTRL);
62 writel(SW_SCL_BYPASS, hw->base_addr + RKISPP_SCL2_CTRL);
63 writel(OTHER_FORCE_UPD, hw->base_addr + RKISPP_CTRL_UPDATE);
64 writel(GATE_DIS_ALL, hw->base_addr + RKISPP_CTRL_CLKGATE);
65 writel(SW_FEC2DDR_DIS, hw->base_addr + RKISPP_FEC_CORE_CTRL);
66 writel(NR_LOST_ERR | TNR_LOST_ERR | FBCH_EMPTY_NR |
67 FBCH_EMPTY_TNR | FBCD_DEC_ERR_NR | FBCD_DEC_ERR_TNR |
68 BUS_ERR_NR | BUS_ERR_TNR | SCL2_INT | SCL1_INT |
69 SCL0_INT | FEC_INT | ORB_INT | SHP_INT | NR_INT | TNR_INT,
70 hw->base_addr + RKISPP_CTRL_INT_MSK);
71 writel(GATE_DIS_NR, hw->base_addr + RKISPP_CTRL_CLKGATE);
72 } else if (hw->ispp_ver == ISPP_V20) {
73 writel(GATE_DIS_ALL, hw->base_addr + RKISPP_CTRL_CLKGATE);
74 writel(SW_FEC2DDR_DIS, hw->base_addr + RKISPP_FEC_CORE_CTRL);
75 writel(FEC_INT, hw->base_addr + RKISPP_CTRL_INT_MSK);
76 writel(GATE_DIS_FEC, hw->base_addr + RKISPP_CTRL_CLKGATE);
77 }
78
79 }
80
81 /* using default value if reg no write for multi device */
default_sw_reg_flag(struct rkispp_device * dev)82 static void default_sw_reg_flag(struct rkispp_device *dev)
83 {
84 if (dev->hw_dev->ispp_ver == ISPP_V10) {
85 u32 reg[] = {
86 RKISPP_TNR_CTRL,
87 RKISPP_TNR_CORE_CTRL,
88 RKISPP_NR_CTRL,
89 RKISPP_NR_UVNR_CTRL_PARA,
90 RKISPP_SHARP_CTRL,
91 RKISPP_SHARP_CORE_CTRL,
92 RKISPP_SCL0_CTRL,
93 RKISPP_SCL1_CTRL,
94 RKISPP_SCL2_CTRL,
95 RKISPP_ORB_CORE_CTRL,
96 RKISPP_FEC_CTRL,
97 RKISPP_FEC_CORE_CTRL
98 };
99 u32 i, *flag;
100
101 for (i = 0; i < ARRAY_SIZE(reg); i++) {
102 flag = dev->sw_base_addr + reg[i] + RKISP_ISPP_SW_REG_SIZE;
103 *flag = 0xffffffff;
104 }
105 } else if (dev->hw_dev->ispp_ver == ISPP_V20) {
106 u32 reg[] = {
107 RKISPP_FEC_CTRL,
108 RKISPP_FEC_CORE_CTRL
109 };
110 u32 i, *flag;
111
112 for (i = 0; i < ARRAY_SIZE(reg); i++) {
113 flag = dev->sw_base_addr + reg[i] + RKISP_ISPP_SW_REG_SIZE;
114 *flag = 0xffffffff;
115 }
116 }
117 }
118
is_iommu_enable(struct device * dev)119 static inline bool is_iommu_enable(struct device *dev)
120 {
121 struct device_node *iommu;
122
123 iommu = of_parse_phandle(dev->of_node, "iommus", 0);
124 if (!iommu) {
125 dev_info(dev, "no iommu attached, using non-iommu buffers\n");
126 return false;
127 } else if (!of_device_is_available(iommu)) {
128 dev_info(dev, "iommu is disabled, using non-iommu buffers\n");
129 of_node_put(iommu);
130 return false;
131 }
132 of_node_put(iommu);
133
134 return true;
135 }
136
disable_sys_clk(struct rkispp_hw_dev * dev)137 static void disable_sys_clk(struct rkispp_hw_dev *dev)
138 {
139 int i;
140
141 for (i = 0; i < dev->clks_num; i++)
142 clk_disable_unprepare(dev->clks[i]);
143 }
144
enable_sys_clk(struct rkispp_hw_dev * dev)145 static int enable_sys_clk(struct rkispp_hw_dev *dev)
146 {
147 struct rkispp_device *ispp = dev->ispp[dev->cur_dev_id];
148 int w, i, ret = -EINVAL;
149
150 for (i = 0; i < dev->clks_num; i++) {
151 ret = clk_prepare_enable(dev->clks[i]);
152 if (ret < 0)
153 goto err;
154 }
155
156 if (!ispp)
157 return ret;
158
159 w = dev->max_in.w ? dev->max_in.w : ispp->ispp_sdev.in_fmt.width;
160
161 for (i = 0; i < dev->clk_rate_tbl_num; i++)
162 if (w <= dev->clk_rate_tbl[i].refer_data)
163 break;
164 if (!dev->is_single)
165 i++;
166 if (i > dev->clk_rate_tbl_num - 1)
167 i = dev->clk_rate_tbl_num - 1;
168 dev->core_clk_max = dev->clk_rate_tbl[i].clk_rate * 1000000;
169 dev->core_clk_min = dev->clk_rate_tbl[0].clk_rate * 1000000;
170 rkispp_set_clk_rate(dev->clks[0], dev->core_clk_min);
171 dev_dbg(dev->dev, "set ispp clk:%luHz\n", clk_get_rate(dev->clks[0]));
172 return 0;
173 err:
174 for (--i; i >= 0; --i)
175 clk_disable_unprepare(dev->clks[i]);
176 return ret;
177 }
178
irq_hdl(int irq,void * ctx)179 static irqreturn_t irq_hdl(int irq, void *ctx)
180 {
181 struct device *dev = ctx;
182 struct rkispp_hw_dev *hw_dev = dev_get_drvdata(dev);
183 struct rkispp_device *ispp = hw_dev->ispp[hw_dev->cur_dev_id];
184 void __iomem *base = hw_dev->base_addr;
185 unsigned int mis_val;
186
187 spin_lock(&hw_dev->irq_lock);
188 mis_val = readl(base + RKISPP_CTRL_INT_STA);
189 writel(mis_val, base + RKISPP_CTRL_INT_CLR);
190 spin_unlock(&hw_dev->irq_lock);
191
192 if (IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_ISPP_FEC) && mis_val & FEC_INT) {
193 mis_val &= ~FEC_INT;
194 rkispp_fec_irq(hw_dev);
195 }
196
197 if (mis_val)
198 ispp->irq_hdl(mis_val, ispp);
199
200 return IRQ_HANDLED;
201 }
202
203 static const char * const rv1126_ispp_clks[] = {
204 "clk_ispp",
205 "aclk_ispp",
206 "hclk_ispp",
207 };
208
209 static const char * const rk3588_ispp_clks[] = {
210 "clk_ispp",
211 "aclk_ispp",
212 "hclk_ispp",
213 };
214
215 static const struct ispp_clk_info rv1126_ispp_clk_rate[] = {
216 {
217 .clk_rate = 150,
218 .refer_data = 0,
219 }, {
220 .clk_rate = 250,
221 .refer_data = 1920 //width
222 }, {
223 .clk_rate = 350,
224 .refer_data = 2688,
225 }, {
226 .clk_rate = 400,
227 .refer_data = 3072,
228 }, {
229 .clk_rate = 500,
230 .refer_data = 3840,
231 }
232 };
233
234 static const struct ispp_clk_info rk3588_ispp_clk_rate[] = {
235 {
236 .clk_rate = 300,
237 .refer_data = 1920, //width
238 }, {
239 .clk_rate = 400,
240 .refer_data = 2688,
241 }, {
242 .clk_rate = 500,
243 .refer_data = 3072,
244 }, {
245 .clk_rate = 600,
246 .refer_data = 3840,
247 }, {
248 .clk_rate = 702,
249 .refer_data = 4672,
250 }
251 };
252
253 static struct irqs_data rv1126_ispp_irqs[] = {
254 {"ispp_irq", irq_hdl},
255 {"fec_irq", irq_hdl},
256 };
257
258 static struct irqs_data rk3588_ispp_irqs[] = {
259 {"fec_irq", irq_hdl},
260 };
261
262 static const struct ispp_match_data rv1126_ispp_match_data = {
263 .clks = rv1126_ispp_clks,
264 .clks_num = ARRAY_SIZE(rv1126_ispp_clks),
265 .clk_rate_tbl = rv1126_ispp_clk_rate,
266 .clk_rate_tbl_num = ARRAY_SIZE(rv1126_ispp_clk_rate),
267 .irqs = rv1126_ispp_irqs,
268 .num_irqs = ARRAY_SIZE(rv1126_ispp_irqs),
269 .ispp_ver = ISPP_V10,
270 };
271
272 static const struct ispp_match_data rk3588_ispp_match_data = {
273 .clks = rk3588_ispp_clks,
274 .clks_num = ARRAY_SIZE(rk3588_ispp_clks),
275 .clk_rate_tbl = rk3588_ispp_clk_rate,
276 .clk_rate_tbl_num = ARRAY_SIZE(rk3588_ispp_clk_rate),
277 .irqs = rk3588_ispp_irqs,
278 .num_irqs = ARRAY_SIZE(rk3588_ispp_irqs),
279 .ispp_ver = ISPP_V20,
280 };
281
282 static const struct of_device_id rkispp_hw_of_match[] = {
283 {
284 .compatible = "rockchip,rv1126-rkispp",
285 .data = &rv1126_ispp_match_data,
286 }, {
287 .compatible = "rockchip,rk3588-rkispp",
288 .data = &rk3588_ispp_match_data,
289 },
290 {},
291 };
292
rkispp_hw_probe(struct platform_device * pdev)293 static int rkispp_hw_probe(struct platform_device *pdev)
294 {
295 const struct of_device_id *match;
296 const struct ispp_match_data *match_data;
297 struct device_node *node = pdev->dev.of_node;
298 struct device *dev = &pdev->dev;
299 struct rkispp_hw_dev *hw_dev;
300 struct resource *res;
301 int i, ret, irq;
302 bool is_mem_reserved = true;
303
304 match = of_match_node(rkispp_hw_of_match, node);
305 if (IS_ERR(match))
306 return PTR_ERR(match);
307
308 hw_dev = devm_kzalloc(dev, sizeof(*hw_dev), GFP_KERNEL);
309 if (!hw_dev)
310 return -ENOMEM;
311
312 dev_set_drvdata(dev, hw_dev);
313 hw_dev->dev = dev;
314 match_data = match->data;
315 hw_dev->match_data = match->data;
316 hw_dev->max_in.w = 0;
317 hw_dev->max_in.h = 0;
318 hw_dev->max_in.fps = 0;
319 of_property_read_u32_array(node, "max-input", &hw_dev->max_in.w, 3);
320 dev_info(dev, "max input:%dx%d@%dfps\n",
321 hw_dev->max_in.w, hw_dev->max_in.h, hw_dev->max_in.fps);
322 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
323 if (!res) {
324 dev_err(dev, "get resource failed\n");
325 ret = -EINVAL;
326 goto err;
327 }
328 hw_dev->base_addr = devm_ioremap_resource(dev, res);
329 if (PTR_ERR(hw_dev->base_addr) == -EBUSY) {
330 resource_size_t offset = res->start;
331 resource_size_t size = resource_size(res);
332
333 hw_dev->base_addr = devm_ioremap(dev, offset, size);
334 }
335 if (IS_ERR(hw_dev->base_addr)) {
336 dev_err(dev, "ioremap failed\n");
337 ret = PTR_ERR(hw_dev->base_addr);
338 goto err;
339 }
340
341 rkispp_monitor = device_property_read_bool(dev, "rockchip,restart-monitor-en");
342 res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
343 match_data->irqs[0].name);
344 if (res) {
345 /* there are irq names in dts */
346 for (i = 0; i < match_data->num_irqs; i++) {
347 irq = platform_get_irq_byname(pdev,
348 match_data->irqs[i].name);
349 if (irq < 0) {
350 dev_err(dev, "no irq %s in dts\n",
351 match_data->irqs[i].name);
352 ret = irq;
353 goto err;
354 }
355 ret = devm_request_irq(dev, irq,
356 match_data->irqs[i].irq_hdl,
357 IRQF_SHARED,
358 dev_driver_string(dev),
359 dev);
360 if (ret < 0) {
361 dev_err(dev, "request %s failed: %d\n",
362 match_data->irqs[i].name, ret);
363 goto err;
364 }
365 }
366 }
367
368 for (i = 0; i < match_data->clks_num; i++) {
369 struct clk *clk = devm_clk_get(dev, match_data->clks[i]);
370
371 if (IS_ERR(clk)) {
372 dev_err(dev, "failed to get %s\n",
373 match_data->clks[i]);
374 ret = PTR_ERR(clk);
375 goto err;
376 }
377 hw_dev->clks[i] = clk;
378 }
379 hw_dev->clks_num = match_data->clks_num;
380 hw_dev->clk_rate_tbl = match_data->clk_rate_tbl;
381 hw_dev->clk_rate_tbl_num = match_data->clk_rate_tbl_num;
382
383 hw_dev->reset = devm_reset_control_array_get(dev, false, false);
384 if (IS_ERR(hw_dev->reset)) {
385 dev_info(dev, "failed to get cru reset\n");
386 hw_dev->reset = NULL;
387 }
388
389 hw_dev->dev_num = 0;
390 hw_dev->cur_dev_id = 0;
391 hw_dev->ispp_ver = match_data->ispp_ver;
392 mutex_init(&hw_dev->dev_lock);
393 spin_lock_init(&hw_dev->irq_lock);
394 spin_lock_init(&hw_dev->buf_lock);
395 atomic_set(&hw_dev->refcnt, 0);
396 INIT_LIST_HEAD(&hw_dev->list);
397 hw_dev->is_idle = true;
398 hw_dev->is_single = true;
399 /* for frame end reset and config reg */
400 if (hw_dev->ispp_ver == ISPP_V10)
401 hw_dev->is_single = false;
402 hw_dev->is_fec_ext = false;
403 hw_dev->is_dma_contig = true;
404 hw_dev->is_dma_sg_ops = true;
405 hw_dev->is_shutdown = false;
406 hw_dev->is_first = true;
407 hw_dev->is_mmu = is_iommu_enable(dev);
408 ret = of_reserved_mem_device_init(dev);
409 if (ret) {
410 is_mem_reserved = false;
411 if (!hw_dev->is_mmu)
412 dev_info(dev, "No reserved memory region. default cma area!\n");
413 }
414 if (hw_dev->is_mmu && !is_mem_reserved)
415 hw_dev->is_dma_contig = false;
416 hw_dev->mem_ops = &vb2_cma_sg_memops;
417
418 rkispp_register_fec(hw_dev);
419 pm_runtime_enable(&pdev->dev);
420
421 return 0;
422 err:
423 return ret;
424 }
425
rkispp_hw_remove(struct platform_device * pdev)426 static int rkispp_hw_remove(struct platform_device *pdev)
427 {
428 struct rkispp_hw_dev *hw_dev = platform_get_drvdata(pdev);
429
430 pm_runtime_disable(&pdev->dev);
431 mutex_destroy(&hw_dev->dev_lock);
432 rkispp_unregister_fec(hw_dev);
433 return 0;
434 }
435
rkispp_hw_shutdown(struct platform_device * pdev)436 static void rkispp_hw_shutdown(struct platform_device *pdev)
437 {
438 struct rkispp_hw_dev *hw_dev = platform_get_drvdata(pdev);
439
440 hw_dev->is_shutdown = true;
441 if (pm_runtime_active(&pdev->dev)) {
442 writel(0, hw_dev->base_addr + RKISPP_CTRL_INT_MSK);
443 writel(GLB_SOFT_RST_ALL, hw_dev->base_addr + RKISPP_CTRL_RESET);
444 writel(~GLB_SOFT_RST_ALL, hw_dev->base_addr + RKISPP_CTRL_RESET);
445 }
446 dev_info(&pdev->dev, "%s\n", __func__);
447 }
448
rkispp_runtime_suspend(struct device * dev)449 static int __maybe_unused rkispp_runtime_suspend(struct device *dev)
450 {
451 struct rkispp_hw_dev *hw_dev = dev_get_drvdata(dev);
452
453 writel(0, hw_dev->base_addr + RKISPP_CTRL_INT_MSK);
454 disable_sys_clk(hw_dev);
455 return 0;
456 }
457
rkispp_runtime_resume(struct device * dev)458 static int __maybe_unused rkispp_runtime_resume(struct device *dev)
459 {
460 struct rkispp_hw_dev *hw_dev = dev_get_drvdata(dev);
461 void __iomem *base = hw_dev->base_addr;
462 int i;
463
464 enable_sys_clk(hw_dev);
465 rkispp_soft_reset(hw_dev);
466
467 for (i = 0; i < hw_dev->dev_num; i++) {
468 void *buf = hw_dev->ispp[i]->sw_base_addr;
469
470 memset(buf, 0, RKISP_ISPP_SW_MAX_SIZE);
471 memcpy_fromio(buf, base, RKISP_ISPP_SW_REG_SIZE);
472 default_sw_reg_flag(hw_dev->ispp[i]);
473 }
474 hw_dev->is_idle = true;
475 return 0;
476 }
477
478 static const struct dev_pm_ops rkispp_hw_pm_ops = {
479 SET_RUNTIME_PM_OPS(rkispp_runtime_suspend,
480 rkispp_runtime_resume, NULL)
481 };
482
483 static struct platform_driver rkispp_hw_drv = {
484 .driver = {
485 .name = "rkispp_hw",
486 .of_match_table = of_match_ptr(rkispp_hw_of_match),
487 .pm = &rkispp_hw_pm_ops,
488 },
489 .probe = rkispp_hw_probe,
490 .remove = rkispp_hw_remove,
491 .shutdown = rkispp_hw_shutdown,
492 };
493
rkispp_hw_drv_init(void)494 int __init rkispp_hw_drv_init(void)
495 {
496 int ret;
497
498 ret = platform_driver_register(&rkispp_hw_drv);
499 if (!ret)
500 ret = platform_driver_register(&rkispp_plat_drv);
501 return ret;
502 }
503
504 #if !(IS_BUILTIN(CONFIG_VIDEO_ROCKCHIP_ISP) && IS_BUILTIN(CONFIG_VIDEO_ROCKCHIP_ISPP))
505 module_init(rkispp_hw_drv_init);
506 #endif
507