1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/device.h>
19#include <linux/err.h>
20#include <linux/io.h>
21#include <linux/of.h>
22#include <linux/of_address.h>
23#include <linux/slab.h>
24
25#include "xilinx_drm_drv.h"
26
27#include "xilinx_cresample.h"
28
29
30
31#define CRESAMPLE_CONTROL 0x0000
32
33
34#define CRESAMPLE_ACTIVE_SIZE 0x0020
35
36
37#define CRESAMPLE_CTL_EN (1 << 0)
38#define CRESAMPLE_CTL_RU (1 << 1)
39#define CRESAMPLE_CTL_RESET (1 << 31)
40
41struct xilinx_cresample {
42 void __iomem *base;
43 const char *input_format_name;
44 const char *output_format_name;
45};
46
47
48void xilinx_cresample_enable(struct xilinx_cresample *cresample)
49{
50 u32 reg;
51
52 reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
53 xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
54 reg | CRESAMPLE_CTL_EN);
55}
56
57
58void xilinx_cresample_disable(struct xilinx_cresample *cresample)
59{
60 u32 reg;
61
62 reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
63 xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
64 reg & ~CRESAMPLE_CTL_EN);
65}
66
67
68void xilinx_cresample_configure(struct xilinx_cresample *cresample,
69 int hactive, int vactive)
70{
71
72 xilinx_drm_writel(cresample->base, CRESAMPLE_ACTIVE_SIZE,
73 (vactive << 16) | hactive);
74}
75
76
77void xilinx_cresample_reset(struct xilinx_cresample *cresample)
78{
79 u32 reg;
80
81 xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
82 CRESAMPLE_CTL_RESET);
83
84
85 reg = xilinx_drm_readl(cresample->base, CRESAMPLE_CONTROL);
86 xilinx_drm_writel(cresample->base, CRESAMPLE_CONTROL,
87 reg | CRESAMPLE_CTL_RU);
88}
89
90
91const char *
92xilinx_cresample_get_input_format_name(struct xilinx_cresample *cresample)
93{
94 return cresample->input_format_name;
95}
96
97
98const char *
99xilinx_cresample_get_output_format_name(struct xilinx_cresample *cresample)
100{
101 return cresample->output_format_name;
102}
103
104static const struct of_device_id xilinx_cresample_of_match[] = {
105 { .compatible = "xlnx,v-cresample-3.01.a" },
106 { },
107};
108
109struct xilinx_cresample *xilinx_cresample_probe(struct device *dev,
110 struct device_node *node)
111{
112 struct xilinx_cresample *cresample;
113 const struct of_device_id *match;
114 struct resource res;
115 int ret;
116
117 match = of_match_node(xilinx_cresample_of_match, node);
118 if (!match) {
119 dev_err(dev, "failed to match the device node\n");
120 return ERR_PTR(-ENODEV);
121 }
122
123 cresample = devm_kzalloc(dev, sizeof(*cresample), GFP_KERNEL);
124 if (!cresample)
125 return ERR_PTR(-ENOMEM);
126
127 ret = of_address_to_resource(node, 0, &res);
128 if (ret) {
129 dev_err(dev, "failed to of_address_to_resource\n");
130 return ERR_PTR(ret);
131 }
132
133 cresample->base = devm_ioremap_resource(dev, &res);
134 if (IS_ERR(cresample->base))
135 return ERR_CAST(cresample->base);
136
137 ret = of_property_read_string(node, "xlnx,input-format",
138 &cresample->input_format_name);
139 if (ret) {
140 dev_warn(dev, "failed to get an input format prop\n");
141 return ERR_PTR(ret);
142 }
143
144 ret = of_property_read_string(node, "xlnx,output-format",
145 &cresample->output_format_name);
146 if (ret) {
147 dev_warn(dev, "failed to get an output format prop\n");
148 return ERR_PTR(ret);
149 }
150
151 xilinx_cresample_reset(cresample);
152
153 return cresample;
154}
155