aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjames qian wang (Arm Technology China) <james.qian.wang@arm.com>2019-01-03 06:39:48 -0500
committerLiviu Dudau <Liviu.Dudau@arm.com>2019-01-14 06:09:23 -0500
commitbd628c1bed7902ec1f24ba0fe70758949146abbe (patch)
tree103461a1622a7d62b26d7b41d784f621a074ca74
parent37fc9bb022c654e261c5a7d2ce600c6ce26c022d (diff)
drm/komeda: komeda_dev/pipeline/component definition and initialzation
1. Added a brief definition of komeda_dev/pipeline/component, this change didn't add the detailed component features and capabilities, which will be added in the following changes. 2. Corresponding resources discovery and initialzation functions. Changes in v4: - Deleted unnecessary headers Changes in v3: - Fixed style problem found by checkpatch.pl --strict. Changes in v2: - Unified abbreviation of "pipeline" to "pipe". Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
-rw-r--r--drivers/gpu/drm/arm/Kconfig2
-rw-r--r--drivers/gpu/drm/arm/Makefile1
-rw-r--r--drivers/gpu/drm/arm/display/Kbuild3
-rw-r--r--drivers/gpu/drm/arm/display/Kconfig14
-rw-r--r--drivers/gpu/drm/arm/display/include/malidp_product.h23
-rw-r--r--drivers/gpu/drm/arm/display/include/malidp_utils.h16
-rw-r--r--drivers/gpu/drm/arm/display/komeda/Makefile11
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_dev.c114
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_dev.h98
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c196
-rw-r--r--drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h348
11 files changed, 826 insertions, 0 deletions
diff --git a/drivers/gpu/drm/arm/Kconfig b/drivers/gpu/drm/arm/Kconfig
index f9f7761cb2f4..a204103b3efb 100644
--- a/drivers/gpu/drm/arm/Kconfig
+++ b/drivers/gpu/drm/arm/Kconfig
@@ -37,4 +37,6 @@ config DRM_MALI_DISPLAY
37 37
38 If compiled as a module it will be called mali-dp. 38 If compiled as a module it will be called mali-dp.
39 39
40source "drivers/gpu/drm/arm/display/Kconfig"
41
40endmenu 42endmenu
diff --git a/drivers/gpu/drm/arm/Makefile b/drivers/gpu/drm/arm/Makefile
index 3bf31d1a4722..120bef801fcf 100644
--- a/drivers/gpu/drm/arm/Makefile
+++ b/drivers/gpu/drm/arm/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_DRM_HDLCD) += hdlcd.o
3mali-dp-y := malidp_drv.o malidp_hw.o malidp_planes.o malidp_crtc.o 3mali-dp-y := malidp_drv.o malidp_hw.o malidp_planes.o malidp_crtc.o
4mali-dp-y += malidp_mw.o 4mali-dp-y += malidp_mw.o
5obj-$(CONFIG_DRM_MALI_DISPLAY) += mali-dp.o 5obj-$(CONFIG_DRM_MALI_DISPLAY) += mali-dp.o
6obj-$(CONFIG_DRM_KOMEDA) += display/
diff --git a/drivers/gpu/drm/arm/display/Kbuild b/drivers/gpu/drm/arm/display/Kbuild
new file mode 100644
index 000000000000..382f1ca831e4
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/Kbuild
@@ -0,0 +1,3 @@
1# SPDX-License-Identifier: GPL-2.0
2
3obj-$(CONFIG_DRM_KOMEDA) += komeda/
diff --git a/drivers/gpu/drm/arm/display/Kconfig b/drivers/gpu/drm/arm/display/Kconfig
new file mode 100644
index 000000000000..cec0639e3aa1
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/Kconfig
@@ -0,0 +1,14 @@
1# SPDX-License-Identifier: GPL-2.0
2config DRM_KOMEDA
3 tristate "ARM Komeda display driver"
4 depends on DRM && OF
5 depends on COMMON_CLK
6 select DRM_KMS_HELPER
7 select DRM_KMS_CMA_HELPER
8 select DRM_GEM_CMA_HELPER
9 select VIDEOMODE_HELPERS
10 help
11 Choose this option if you want to compile the ARM Komeda display
12 Processor driver. It supports the D71 variants of the hardware.
13
14 If compiled as a module it will be called komeda.
diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h b/drivers/gpu/drm/arm/display/include/malidp_product.h
new file mode 100644
index 000000000000..b35fc5db866b
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
@@ -0,0 +1,23 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
5 *
6 */
7#ifndef _MALIDP_PRODUCT_H_
8#define _MALIDP_PRODUCT_H_
9
10/* Product identification */
11#define MALIDP_CORE_ID(__product, __major, __minor, __status) \
12 ((((__product) & 0xFFFF) << 16) | (((__major) & 0xF) << 12) | \
13 (((__minor) & 0xF) << 8) | ((__status) & 0xFF))
14
15#define MALIDP_CORE_ID_PRODUCT_ID(__core_id) ((__u32)(__core_id) >> 16)
16#define MALIDP_CORE_ID_MAJOR(__core_id) (((__u32)(__core_id) >> 12) & 0xF)
17#define MALIDP_CORE_ID_MINOR(__core_id) (((__u32)(__core_id) >> 8) & 0xF)
18#define MALIDP_CORE_ID_STATUS(__core_id) (((__u32)(__core_id)) & 0xFF)
19
20/* Mali-display product IDs */
21#define MALIDP_D71_PRODUCT_ID 0x0071
22
23#endif /* _MALIDP_PRODUCT_H_ */
diff --git a/drivers/gpu/drm/arm/display/include/malidp_utils.h b/drivers/gpu/drm/arm/display/include/malidp_utils.h
new file mode 100644
index 000000000000..63cc47cefcf8
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h
@@ -0,0 +1,16 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
5 *
6 */
7#ifndef _MALIDP_UTILS_
8#define _MALIDP_UTILS_
9
10#define has_bit(nr, mask) (BIT(nr) & (mask))
11#define has_bits(bits, mask) (((bits) & (mask)) == (bits))
12
13#define dp_for_each_set_bit(bit, mask) \
14 for_each_set_bit((bit), ((unsigned long *)&(mask)), sizeof(mask) * 8)
15
16#endif /* _MALIDP_UTILS_ */
diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile b/drivers/gpu/drm/arm/display/komeda/Makefile
new file mode 100644
index 000000000000..5b44e36509b1
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/Makefile
@@ -0,0 +1,11 @@
1# SPDX-License-Identifier: GPL-2.0
2
3ccflags-y := \
4 -I$(src)/../include \
5 -I$(src)
6
7komeda-y := \
8 komeda_dev.o \
9 komeda_pipeline.o \
10
11obj-$(CONFIG_DRM_KOMEDA) += komeda.o
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
new file mode 100644
index 000000000000..4dec259cecac
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -0,0 +1,114 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
5 *
6 */
7#include <linux/platform_device.h>
8#include <linux/of_device.h>
9#include <linux/of_graph.h>
10#include "komeda_dev.h"
11
12struct komeda_dev *komeda_dev_create(struct device *dev)
13{
14 struct platform_device *pdev = to_platform_device(dev);
15 const struct komeda_product_data *product;
16 struct komeda_dev *mdev;
17 struct resource *io_res;
18 int err = 0;
19
20 product = of_device_get_match_data(dev);
21 if (!product)
22 return ERR_PTR(-ENODEV);
23
24 io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
25 if (!io_res) {
26 DRM_ERROR("No registers defined.\n");
27 return ERR_PTR(-ENODEV);
28 }
29
30 mdev = devm_kzalloc(dev, sizeof(*mdev), GFP_KERNEL);
31 if (!mdev)
32 return ERR_PTR(-ENOMEM);
33
34 mdev->dev = dev;
35 mdev->reg_base = devm_ioremap_resource(dev, io_res);
36 if (IS_ERR(mdev->reg_base)) {
37 DRM_ERROR("Map register space failed.\n");
38 err = PTR_ERR(mdev->reg_base);
39 mdev->reg_base = NULL;
40 goto err_cleanup;
41 }
42
43 mdev->pclk = devm_clk_get(dev, "pclk");
44 if (IS_ERR(mdev->pclk)) {
45 DRM_ERROR("Get APB clk failed.\n");
46 err = PTR_ERR(mdev->pclk);
47 mdev->pclk = NULL;
48 goto err_cleanup;
49 }
50
51 /* Enable APB clock to access the registers */
52 clk_prepare_enable(mdev->pclk);
53
54 mdev->funcs = product->identify(mdev->reg_base, &mdev->chip);
55 if (!komeda_product_match(mdev, product->product_id)) {
56 DRM_ERROR("DT configured %x mismatch with real HW %x.\n",
57 product->product_id,
58 MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id));
59 err = -ENODEV;
60 goto err_cleanup;
61 }
62
63 DRM_INFO("Found ARM Mali-D%x version r%dp%d\n",
64 MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id),
65 MALIDP_CORE_ID_MAJOR(mdev->chip.core_id),
66 MALIDP_CORE_ID_MINOR(mdev->chip.core_id));
67
68 err = mdev->funcs->enum_resources(mdev);
69 if (err) {
70 DRM_ERROR("enumerate display resource failed.\n");
71 goto err_cleanup;
72 }
73
74 return mdev;
75
76err_cleanup:
77 komeda_dev_destroy(mdev);
78 return ERR_PTR(err);
79}
80
81void komeda_dev_destroy(struct komeda_dev *mdev)
82{
83 struct device *dev = mdev->dev;
84 struct komeda_dev_funcs *funcs = mdev->funcs;
85 int i;
86
87 for (i = 0; i < mdev->n_pipelines; i++) {
88 komeda_pipeline_destroy(mdev, mdev->pipelines[i]);
89 mdev->pipelines[i] = NULL;
90 }
91
92 mdev->n_pipelines = 0;
93
94 if (funcs && funcs->cleanup)
95 funcs->cleanup(mdev);
96
97 if (mdev->reg_base) {
98 devm_iounmap(dev, mdev->reg_base);
99 mdev->reg_base = NULL;
100 }
101
102 if (mdev->mclk) {
103 devm_clk_put(dev, mdev->mclk);
104 mdev->mclk = NULL;
105 }
106
107 if (mdev->pclk) {
108 clk_disable_unprepare(mdev->pclk);
109 devm_clk_put(dev, mdev->pclk);
110 mdev->pclk = NULL;
111 }
112
113 devm_kfree(dev, mdev);
114}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
new file mode 100644
index 000000000000..03b8703736c2
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -0,0 +1,98 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
5 *
6 */
7#ifndef _KOMEDA_DEV_H_
8#define _KOMEDA_DEV_H_
9
10#include <linux/device.h>
11#include <linux/clk.h>
12#include "komeda_pipeline.h"
13#include "malidp_product.h"
14
15/* malidp device id */
16enum {
17 MALI_D71 = 0,
18};
19
20/* pipeline DT ports */
21enum {
22 KOMEDA_OF_PORT_OUTPUT = 0,
23 KOMEDA_OF_PORT_COPROC = 1,
24};
25
26struct komeda_chip_info {
27 u32 arch_id;
28 u32 core_id;
29 u32 core_info;
30 u32 bus_width;
31};
32
33struct komeda_product_data {
34 u32 product_id;
35 struct komeda_dev_funcs *(*identify)(u32 __iomem *reg,
36 struct komeda_chip_info *info);
37};
38
39struct komeda_dev;
40
41/**
42 * struct komeda_dev_funcs
43 *
44 * Supplied by chip level and returned by the chip entry function xxx_identify,
45 */
46struct komeda_dev_funcs {
47 /**
48 * @enum_resources:
49 *
50 * for CHIP to report or add pipeline and component resources to CORE
51 */
52 int (*enum_resources)(struct komeda_dev *mdev);
53 /** @cleanup: call to chip to cleanup komeda_dev->chip data */
54 void (*cleanup)(struct komeda_dev *mdev);
55};
56
57/**
58 * struct komeda_dev
59 *
60 * Pipeline and component are used to describe how to handle the pixel data.
61 * komeda_device is for describing the whole view of the device, and the
62 * control-abilites of device.
63 */
64struct komeda_dev {
65 struct device *dev;
66 u32 __iomem *reg_base;
67
68 struct komeda_chip_info chip;
69
70 /** @pclk: APB clock for register access */
71 struct clk *pclk;
72 /** @mck: HW main engine clk */
73 struct clk *mclk;
74
75 int n_pipelines;
76 struct komeda_pipeline *pipelines[KOMEDA_MAX_PIPELINES];
77
78 /** @funcs: chip funcs to access to HW */
79 struct komeda_dev_funcs *funcs;
80 /**
81 * @chip_data:
82 *
83 * chip data will be added by &komeda_dev_funcs.enum_resources() and
84 * destroyed by &komeda_dev_funcs.cleanup()
85 */
86 void *chip_data;
87};
88
89static inline bool
90komeda_product_match(struct komeda_dev *mdev, u32 target)
91{
92 return MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id) == target;
93}
94
95struct komeda_dev *komeda_dev_create(struct device *dev);
96void komeda_dev_destroy(struct komeda_dev *mdev);
97
98#endif /*_KOMEDA_DEV_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
new file mode 100644
index 000000000000..179122fc93ff
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -0,0 +1,196 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
5 *
6 */
7#include "komeda_dev.h"
8#include "komeda_pipeline.h"
9
10/** komeda_pipeline_add - Add a pipeline to &komeda_dev */
11struct komeda_pipeline *
12komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
13 struct komeda_pipeline_funcs *funcs)
14{
15 struct komeda_pipeline *pipe;
16
17 if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) {
18 DRM_ERROR("Exceed max support %d pipelines.\n",
19 KOMEDA_MAX_PIPELINES);
20 return NULL;
21 }
22
23 if (size < sizeof(*pipe)) {
24 DRM_ERROR("Request pipeline size too small.\n");
25 return NULL;
26 }
27
28 pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
29 if (!pipe)
30 return NULL;
31
32 pipe->mdev = mdev;
33 pipe->id = mdev->n_pipelines;
34 pipe->funcs = funcs;
35
36 mdev->pipelines[mdev->n_pipelines] = pipe;
37 mdev->n_pipelines++;
38
39 return pipe;
40}
41
42void komeda_pipeline_destroy(struct komeda_dev *mdev,
43 struct komeda_pipeline *pipe)
44{
45 struct komeda_component *c;
46 int i;
47
48 dp_for_each_set_bit(i, pipe->avail_comps) {
49 c = komeda_pipeline_get_component(pipe, i);
50 komeda_component_destroy(mdev, c);
51 }
52
53 clk_put(pipe->pxlclk);
54 clk_put(pipe->aclk);
55
56 devm_kfree(mdev->dev, pipe);
57}
58
59struct komeda_component **
60komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
61{
62 struct komeda_dev *mdev = pipe->mdev;
63 struct komeda_pipeline *temp = NULL;
64 struct komeda_component **pos = NULL;
65
66 switch (id) {
67 case KOMEDA_COMPONENT_LAYER0:
68 case KOMEDA_COMPONENT_LAYER1:
69 case KOMEDA_COMPONENT_LAYER2:
70 case KOMEDA_COMPONENT_LAYER3:
71 pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]);
72 break;
73 case KOMEDA_COMPONENT_WB_LAYER:
74 pos = to_cpos(pipe->wb_layer);
75 break;
76 case KOMEDA_COMPONENT_COMPIZ0:
77 case KOMEDA_COMPONENT_COMPIZ1:
78 temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0];
79 if (!temp) {
80 DRM_ERROR("compiz-%d doesn't exist.\n", id);
81 return NULL;
82 }
83 pos = to_cpos(temp->compiz);
84 break;
85 case KOMEDA_COMPONENT_SCALER0:
86 case KOMEDA_COMPONENT_SCALER1:
87 pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
88 break;
89 case KOMEDA_COMPONENT_IPS0:
90 case KOMEDA_COMPONENT_IPS1:
91 temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
92 if (!temp) {
93 DRM_ERROR("ips-%d doesn't exist.\n", id);
94 return NULL;
95 }
96 pos = to_cpos(temp->improc);
97 break;
98 case KOMEDA_COMPONENT_TIMING_CTRLR:
99 pos = to_cpos(pipe->ctrlr);
100 break;
101 default:
102 pos = NULL;
103 DRM_ERROR("Unknown pipeline resource ID: %d.\n", id);
104 break;
105 }
106
107 return pos;
108}
109
110struct komeda_component *
111komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
112{
113 struct komeda_component **pos = NULL;
114 struct komeda_component *c = NULL;
115
116 pos = komeda_pipeline_get_component_pos(pipe, id);
117 if (pos)
118 c = *pos;
119
120 return c;
121}
122
123/** komeda_component_add - Add a component to &komeda_pipeline */
124struct komeda_component *
125komeda_component_add(struct komeda_pipeline *pipe,
126 size_t comp_sz, u32 id, u32 hw_id,
127 struct komeda_component_funcs *funcs,
128 u8 max_active_inputs, u32 supported_inputs,
129 u8 max_active_outputs, u32 __iomem *reg,
130 const char *name_fmt, ...)
131{
132 struct komeda_component **pos;
133 struct komeda_component *c;
134 int idx, *num = NULL;
135
136 if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) {
137 WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n",
138 max_active_inputs);
139 return NULL;
140 }
141
142 pos = komeda_pipeline_get_component_pos(pipe, id);
143 if (!pos || (*pos))
144 return NULL;
145
146 if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
147 idx = id - KOMEDA_COMPONENT_LAYER0;
148 num = &pipe->n_layers;
149 if (idx != pipe->n_layers) {
150 DRM_ERROR("please add Layer by id sequence.\n");
151 return NULL;
152 }
153 } else if (has_bit(id, KOMEDA_PIPELINE_SCALERS)) {
154 idx = id - KOMEDA_COMPONENT_SCALER0;
155 num = &pipe->n_scalers;
156 if (idx != pipe->n_scalers) {
157 DRM_ERROR("please add Scaler by id sequence.\n");
158 return NULL;
159 }
160 }
161
162 c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL);
163 if (!c)
164 return NULL;
165
166 c->id = id;
167 c->hw_id = hw_id;
168 c->reg = reg;
169 c->pipeline = pipe;
170 c->max_active_inputs = max_active_inputs;
171 c->max_active_outputs = max_active_outputs;
172 c->supported_inputs = supported_inputs;
173 c->funcs = funcs;
174
175 if (name_fmt) {
176 va_list args;
177
178 va_start(args, name_fmt);
179 vsnprintf(c->name, sizeof(c->name), name_fmt, args);
180 va_end(args);
181 }
182
183 if (num)
184 *num = *num + 1;
185
186 pipe->avail_comps |= BIT(c->id);
187 *pos = c;
188
189 return c;
190}
191
192void komeda_component_destroy(struct komeda_dev *mdev,
193 struct komeda_component *c)
194{
195 devm_kfree(mdev->dev, c);
196}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
new file mode 100644
index 000000000000..7daba0e1946b
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -0,0 +1,348 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
5 *
6 */
7#ifndef _KOMEDA_PIPELINE_H_
8#define _KOMEDA_PIPELINE_H_
9
10#include <linux/types.h>
11#include <drm/drm_atomic.h>
12#include <drm/drm_atomic_helper.h>
13#include "malidp_utils.h"
14
15#define KOMEDA_MAX_PIPELINES 2
16#define KOMEDA_PIPELINE_MAX_LAYERS 4
17#define KOMEDA_PIPELINE_MAX_SCALERS 2
18#define KOMEDA_COMPONENT_N_INPUTS 5
19
20/* pipeline component IDs */
21enum {
22 KOMEDA_COMPONENT_LAYER0 = 0,
23 KOMEDA_COMPONENT_LAYER1 = 1,
24 KOMEDA_COMPONENT_LAYER2 = 2,
25 KOMEDA_COMPONENT_LAYER3 = 3,
26 KOMEDA_COMPONENT_WB_LAYER = 7, /* write back layer */
27 KOMEDA_COMPONENT_SCALER0 = 8,
28 KOMEDA_COMPONENT_SCALER1 = 9,
29 KOMEDA_COMPONENT_SPLITTER = 12,
30 KOMEDA_COMPONENT_MERGER = 14,
31 KOMEDA_COMPONENT_COMPIZ0 = 16, /* compositor */
32 KOMEDA_COMPONENT_COMPIZ1 = 17,
33 KOMEDA_COMPONENT_IPS0 = 20, /* post image processor */
34 KOMEDA_COMPONENT_IPS1 = 21,
35 KOMEDA_COMPONENT_TIMING_CTRLR = 22, /* timing controller */
36};
37
38#define KOMEDA_PIPELINE_LAYERS (BIT(KOMEDA_COMPONENT_LAYER0) |\
39 BIT(KOMEDA_COMPONENT_LAYER1) |\
40 BIT(KOMEDA_COMPONENT_LAYER2) |\
41 BIT(KOMEDA_COMPONENT_LAYER3))
42
43#define KOMEDA_PIPELINE_SCALERS (BIT(KOMEDA_COMPONENT_SCALER0) |\
44 BIT(KOMEDA_COMPONENT_SCALER1))
45
46#define KOMEDA_PIPELINE_COMPIZS (BIT(KOMEDA_COMPONENT_COMPIZ0) |\
47 BIT(KOMEDA_COMPONENT_COMPIZ1))
48
49#define KOMEDA_PIPELINE_IMPROCS (BIT(KOMEDA_COMPONENT_IPS0) |\
50 BIT(KOMEDA_COMPONENT_IPS1))
51struct komeda_component;
52struct komeda_component_state;
53
54/** komeda_component_funcs - component control functions */
55struct komeda_component_funcs {
56 /** @validate: optional,
57 * component may has special requirements or limitations, this function
58 * supply HW the ability to do the further HW specific check.
59 */
60 int (*validate)(struct komeda_component *c,
61 struct komeda_component_state *state);
62 /** @update: update is a active update */
63 void (*update)(struct komeda_component *c,
64 struct komeda_component_state *state);
65 /** @disable: disable component */
66 void (*disable)(struct komeda_component *c);
67 /** @dump_register: Optional, dump registers to seq_file */
68 void (*dump_register)(struct komeda_component *c, struct seq_file *seq);
69};
70
71/**
72 * struct komeda_component
73 *
74 * struct komeda_component describe the data flow capabilities for how to link a
75 * component into the display pipeline.
76 * all specified components are subclass of this structure.
77 */
78struct komeda_component {
79 /** @obj: treat component as private obj */
80 struct drm_private_obj obj;
81 /** @pipeline: the komeda pipeline this component belongs to */
82 struct komeda_pipeline *pipeline;
83 /** @name: component name */
84 char name[32];
85 /**
86 * @reg:
87 * component register base,
88 * which is initialized by chip and used by chip only
89 */
90 u32 __iomem *reg;
91 /** @id: component id */
92 u32 id;
93 /** @hw_ic: component hw id,
94 * which is initialized by chip and used by chip only
95 */
96 u32 hw_id;
97
98 /**
99 * @max_active_inputs:
100 * @max_active_outpus:
101 *
102 * maximum number of inputs/outputs that can be active in the same time
103 * Note:
104 * the number isn't the bit number of @supported_inputs or
105 * @supported_outputs, but may be less than it, since component may not
106 * support enabling all @supported_inputs/outputs at the same time.
107 */
108 u8 max_active_inputs;
109 u8 max_active_outputs;
110 /**
111 * @supported_inputs:
112 * @supported_outputs:
113 *
114 * bitmask of BIT(component->id) for the supported inputs/outputs
115 * describes the possibilities of how a component is linked into a
116 * pipeline.
117 */
118 u32 supported_inputs;
119 u32 supported_outputs;
120
121 /**
122 * @funcs: chip functions to access HW
123 */
124 struct komeda_component_funcs *funcs;
125};
126
127/**
128 * struct komeda_component_output
129 *
130 * a component has multiple outputs, if want to know where the data
131 * comes from, only know the component is not enough, we still need to know
132 * its output port
133 */
134struct komeda_component_output {
135 /** @component: indicate which component the data comes from */
136 struct komeda_component *component;
137 /** @output_port:
138 * the output port of the &komeda_component_output.component
139 */
140 u8 output_port;
141};
142
143/**
144 * struct komeda_component_state
145 *
146 * component_state is the data flow configuration of the component, and it's
147 * the superclass of all specific component_state like @komeda_layer_state,
148 * @komeda_scaler_state
149 */
150struct komeda_component_state {
151 /** @obj: tracking component_state by drm_atomic_state */
152 struct drm_private_state obj;
153 struct komeda_component *component;
154 /**
155 * @binding_user:
156 * currently bound user, the user can be crtc/plane/wb_conn, which is
157 * valid decided by @component and @inputs
158 *
159 * - Layer: its user always is plane.
160 * - compiz/improc/timing_ctrlr: the user is crtc.
161 * - wb_layer: wb_conn;
162 * - scaler: plane when input is layer, wb_conn if input is compiz.
163 */
164 union {
165 struct drm_crtc *crtc;
166 struct drm_plane *plane;
167 struct drm_connector *wb_conn;
168 void *binding_user;
169 };
170 /**
171 * @active_inputs:
172 *
173 * active_inputs is bitmask of @inputs index
174 *
175 * - active_inputs = changed_active_inputs + unchanged_active_inputs
176 * - affected_inputs = old->active_inputs + new->active_inputs;
177 * - disabling_inputs = affected_inputs ^ active_inputs;
178 * - changed_inputs = disabling_inputs + changed_active_inputs;
179 *
180 * NOTE:
181 * changed_inputs doesn't include all active_input but only
182 * @changed_active_inputs, and this bitmask can be used in chip
183 * level for dirty update.
184 */
185 u16 active_inputs;
186 u16 changed_active_inputs;
187 u16 affected_inputs;
188 /**
189 * @inputs:
190 *
191 * the specific inputs[i] only valid on BIT(i) has been set in
192 * @active_inputs, if not the inputs[i] is undefined.
193 */
194 struct komeda_component_output inputs[KOMEDA_COMPONENT_N_INPUTS];
195};
196
197static inline u16 component_disabling_inputs(struct komeda_component_state *st)
198{
199 return st->affected_inputs ^ st->active_inputs;
200}
201
202static inline u16 component_changed_inputs(struct komeda_component_state *st)
203{
204 return component_disabling_inputs(st) | st->changed_active_inputs;
205}
206
207#define to_comp(__c) (((__c) == NULL) ? NULL : &((__c)->base))
208#define to_cpos(__c) ((struct komeda_component **)&(__c))
209
210/* these structures are going to be filled in in uture patches */
211struct komeda_layer {
212 struct komeda_component base;
213 /* layer specific features and caps */
214};
215
216struct komeda_layer_state {
217 struct komeda_component_state base;
218 /* layer specific configuration state */
219};
220
221struct komeda_compiz {
222 struct komeda_component base;
223 /* compiz specific features and caps */
224};
225
226struct komeda_compiz_state {
227 struct komeda_component_state base;
228 /* compiz specific configuration state */
229};
230
231struct komeda_scaler {
232 struct komeda_component base;
233 /* scaler features and caps */
234};
235
236struct komeda_scaler_state {
237 struct komeda_component_state base;
238};
239
240struct komeda_improc {
241 struct komeda_component base;
242};
243
244struct komeda_improc_state {
245 struct komeda_component_state base;
246};
247
248/* display timing controller */
249struct komeda_timing_ctrlr {
250 struct komeda_component base;
251};
252
253struct komeda_timing_ctrlr_state {
254 struct komeda_component_state base;
255};
256
257/** struct komeda_pipeline_funcs */
258struct komeda_pipeline_funcs {
259 /* dump_register: Optional, dump registers to seq_file */
260 void (*dump_register)(struct komeda_pipeline *pipe,
261 struct seq_file *sf);
262};
263
264/**
265 * struct komeda_pipeline
266 *
267 * Represent a complete display pipeline and hold all functional components.
268 */
269struct komeda_pipeline {
270 /** @obj: link pipeline as private obj of drm_atomic_state */
271 struct drm_private_obj obj;
272 /** @mdev: the parent komeda_dev */
273 struct komeda_dev *mdev;
274 /** @pxlclk: pixel clock */
275 struct clk *pxlclk;
276 /** @aclk: AXI clock */
277 struct clk *aclk;
278 /** @id: pipeline id */
279 int id;
280 /** @avail_comps: available components mask of pipeline */
281 u32 avail_comps;
282 int n_layers;
283 struct komeda_layer *layers[KOMEDA_PIPELINE_MAX_LAYERS];
284 int n_scalers;
285 struct komeda_scaler *scalers[KOMEDA_PIPELINE_MAX_SCALERS];
286 struct komeda_compiz *compiz;
287 struct komeda_layer *wb_layer;
288 struct komeda_improc *improc;
289 struct komeda_timing_ctrlr *ctrlr;
290 struct komeda_pipeline_funcs *funcs; /* private pipeline functions */
291};
292
293/**
294 * struct komeda_pipeline_state
295 *
296 * NOTE:
297 * Unlike the pipeline, pipeline_state doesn’t gather any component_state
298 * into it. It because all component will be managed by drm_atomic_state.
299 */
300struct komeda_pipeline_state {
301 /** @obj: tracking pipeline_state by drm_atomic_state */
302 struct drm_private_state obj;
303 struct komeda_pipeline *pipe;
304 /** @crtc: currently bound crtc */
305 struct drm_crtc *crtc;
306 /**
307 * @active_comps:
308 *
309 * bitmask - BIT(component->id) of active components
310 */
311 u32 active_comps;
312};
313
314#define to_layer(c) container_of(c, struct komeda_layer, base)
315#define to_compiz(c) container_of(c, struct komeda_compiz, base)
316#define to_scaler(c) container_of(c, struct komeda_scaler, base)
317#define to_improc(c) container_of(c, struct komeda_improc, base)
318#define to_ctrlr(c) container_of(c, struct komeda_timing_ctrlr, base)
319
320#define to_layer_st(c) container_of(c, struct komeda_layer_state, base)
321#define to_compiz_st(c) container_of(c, struct komeda_compiz_state, base)
322#define to_scaler_st(c) container_of(c, struct komeda_scaler_state, base)
323#define to_improc_st(c) container_of(c, struct komeda_improc_state, base)
324#define to_ctrlr_st(c) container_of(c, struct komeda_timing_ctrlr_state, base)
325
326/* pipeline APIs */
327struct komeda_pipeline *
328komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
329 struct komeda_pipeline_funcs *funcs);
330void komeda_pipeline_destroy(struct komeda_dev *mdev,
331 struct komeda_pipeline *pipe);
332
333struct komeda_component *
334komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id);
335
336/* component APIs */
337struct komeda_component *
338komeda_component_add(struct komeda_pipeline *pipe,
339 size_t comp_sz, u32 id, u32 hw_id,
340 struct komeda_component_funcs *funcs,
341 u8 max_active_inputs, u32 supported_inputs,
342 u8 max_active_outputs, u32 __iomem *reg,
343 const char *name_fmt, ...);
344
345void komeda_component_destroy(struct komeda_dev *mdev,
346 struct komeda_component *c);
347
348#endif /* _KOMEDA_PIPELINE_H_*/