1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2016 MediaTek Inc.
4  * Author: Ming Hsiu Tsai <minghsiu.tsai@mediatek.com>
5  */
6 
7 #include <linux/clk.h>
8 #include <linux/device.h>
9 #include <linux/of.h>
10 #include <linux/of_address.h>
11 #include <linux/of_platform.h>
12 
13 #include "mtk_mdp_comp.h"
14 
15 
16 void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
17 {
18 	int i, err;
19 
20 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
21 		if (IS_ERR(comp->clk[i]))
22 			continue;
23 		err = clk_prepare_enable(comp->clk[i]);
24 		if (err)
25 			dev_err(dev,
26 			"failed to enable clock, err %d. type:%d i:%d\n",
27 				err, comp->type, i);
28 	}
29 }
30 
31 void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
32 {
33 	int i;
34 
35 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
36 		if (IS_ERR(comp->clk[i]))
37 			continue;
38 		clk_disable_unprepare(comp->clk[i]);
39 	}
40 }
41 
42 int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
43 		      struct mtk_mdp_comp *comp,
44 		      enum mtk_mdp_comp_type comp_type)
45 {
46 	int ret;
47 	int i;
48 
49 	comp->dev_node = of_node_get(node);
50 	comp->type = comp_type;
51 
52 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
53 		comp->clk[i] = of_clk_get(node, i);
54 		if (IS_ERR(comp->clk[i])) {
55 			if (PTR_ERR(comp->clk[i]) != -EPROBE_DEFER)
56 				dev_err(dev, "Failed to get clock\n");
57 			ret = PTR_ERR(comp->clk[i]);
58 			goto put_dev;
59 		}
60 
61 		/* Only RDMA needs two clocks */
62 		if (comp->type != MTK_MDP_RDMA)
63 			break;
64 	}
65 
66 	return 0;
67 
68 put_dev:
69 	of_node_put(comp->dev_node);
70 
71 	return ret;
72 }
73 
74 void mtk_mdp_comp_deinit(struct device *dev, struct mtk_mdp_comp *comp)
75 {
76 	of_node_put(comp->dev_node);
77 }
78