Skip to content

Commit 26bd43a

Browse files
jamwandliviu
authored andcommitted
drm/komeda: Build komeda to be a platform module
Implement a simple wrapper for platform module to build komeda to module, Also add a very simple D71 layer code to show how to discover a product. Komeda driver direct bind the product ENTRY function xxx_identity to DT compatible name like: d71_product = { .product_id = MALIDP_D71_PRODUCT_ID, .identify = d71_identify, }, const struct of_device_id komeda_of_match[] = { { .compatible = "arm,mali-d71", .data = &d71_product, }, {}, }; Then when linux found a matched DT node and call driver to probe, we can easily get the of data, and call into the product to do the identify: komeda_bind() { ... product = of_device_get_match_data(dev); product->identify(); ... } Changes in v4: - Replaced kzalloc with devm_kzalloc Changes in v3: - Fixed style problem found by checkpatch.pl --strict. Signed-off-by: James Qian Wang (Arm Technology China) <[email protected]> Acked-by: Liviu Dudau <[email protected]> Signed-off-by: Liviu Dudau <[email protected]>
1 parent df766e4 commit 26bd43a

File tree

5 files changed

+215
-1
lines changed

5 files changed

+215
-1
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4+
* Author: James.Qian.Wang <[email protected]>
5+
*
6+
*/
7+
#ifndef _MALIDP_IO_H_
8+
#define _MALIDP_IO_H_
9+
10+
#include <linux/io.h>
11+
12+
static inline u32
13+
malidp_read32(u32 __iomem *base, u32 offset)
14+
{
15+
return readl((base + (offset >> 2)));
16+
}
17+
18+
static inline void
19+
malidp_write32(u32 __iomem *base, u32 offset, u32 v)
20+
{
21+
writel(v, (base + (offset >> 2)));
22+
}
23+
24+
static inline void
25+
malidp_write32_mask(u32 __iomem *base, u32 offset, u32 m, u32 v)
26+
{
27+
u32 tmp = malidp_read32(base, offset);
28+
29+
tmp &= (~m);
30+
malidp_write32(base, offset, v | tmp);
31+
}
32+
33+
static inline void
34+
malidp_write_group(u32 __iomem *base, u32 offset, int num, const u32 *values)
35+
{
36+
int i;
37+
38+
for (i = 0; i < num; i++)
39+
malidp_write32(base, offset + i * 4, values[i]);
40+
}
41+
42+
#endif /*_MALIDP_IO_H_*/

drivers/gpu/drm/arm/display/komeda/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ ccflags-y := \
55
-I$(src)
66

77
komeda-y := \
8+
komeda_drv.o \
89
komeda_dev.o \
9-
komeda_pipeline.o \
10+
komeda_pipeline.o
11+
12+
komeda-y += \
13+
d71/d71_dev.o
1014

1115
obj-$(CONFIG_DRM_KOMEDA) += komeda.o
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4+
* Author: James.Qian.Wang <[email protected]>
5+
*
6+
*/
7+
#include "malidp_io.h"
8+
#include "komeda_dev.h"
9+
10+
static int d71_enum_resources(struct komeda_dev *mdev)
11+
{
12+
/* TODO add enum resources */
13+
return -1;
14+
}
15+
16+
static struct komeda_dev_funcs d71_chip_funcs = {
17+
.enum_resources = d71_enum_resources,
18+
.cleanup = NULL,
19+
};
20+
21+
#define GLB_ARCH_ID 0x000
22+
#define GLB_CORE_ID 0x004
23+
#define GLB_CORE_INFO 0x008
24+
25+
struct komeda_dev_funcs *
26+
d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
27+
{
28+
chip->arch_id = malidp_read32(reg_base, GLB_ARCH_ID);
29+
chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
30+
chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
31+
32+
return &d71_chip_funcs;
33+
}

drivers/gpu/drm/arm/display/komeda/komeda_dev.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ komeda_product_match(struct komeda_dev *mdev, u32 target)
9292
return MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id) == target;
9393
}
9494

95+
struct komeda_dev_funcs *
96+
d71_identify(u32 __iomem *reg, struct komeda_chip_info *chip);
97+
9598
struct komeda_dev *komeda_dev_create(struct device *dev);
9699
void komeda_dev_destroy(struct komeda_dev *mdev);
97100

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4+
* Author: James.Qian.Wang <[email protected]>
5+
*
6+
*/
7+
#include <linux/module.h>
8+
#include <linux/kernel.h>
9+
#include <linux/platform_device.h>
10+
#include <linux/component.h>
11+
#include <drm/drm_of.h>
12+
#include "komeda_dev.h"
13+
14+
struct komeda_drv {
15+
struct komeda_dev *mdev;
16+
};
17+
18+
static void komeda_unbind(struct device *dev)
19+
{
20+
struct komeda_drv *mdrv = dev_get_drvdata(dev);
21+
22+
if (!mdrv)
23+
return;
24+
25+
komeda_dev_destroy(mdrv->mdev);
26+
27+
dev_set_drvdata(dev, NULL);
28+
devm_kfree(dev, mdrv);
29+
}
30+
31+
static int komeda_bind(struct device *dev)
32+
{
33+
struct komeda_drv *mdrv;
34+
int err;
35+
36+
mdrv = devm_kzalloc(dev, sizeof(*mdrv), GFP_KERNEL);
37+
if (!mdrv)
38+
return -ENOMEM;
39+
40+
mdrv->mdev = komeda_dev_create(dev);
41+
if (IS_ERR(mdrv->mdev)) {
42+
err = PTR_ERR(mdrv->mdev);
43+
goto free_mdrv;
44+
}
45+
46+
dev_set_drvdata(dev, mdrv);
47+
48+
return 0;
49+
50+
free_mdrv:
51+
devm_kfree(dev, mdrv);
52+
return err;
53+
}
54+
55+
static const struct component_master_ops komeda_master_ops = {
56+
.bind = komeda_bind,
57+
.unbind = komeda_unbind,
58+
};
59+
60+
static int compare_of(struct device *dev, void *data)
61+
{
62+
return dev->of_node == data;
63+
}
64+
65+
static void komeda_add_slave(struct device *master,
66+
struct component_match **match,
67+
struct device_node *np, int port)
68+
{
69+
struct device_node *remote;
70+
71+
remote = of_graph_get_remote_node(np, port, 0);
72+
if (remote) {
73+
drm_of_component_match_add(master, match, compare_of, remote);
74+
of_node_put(remote);
75+
}
76+
}
77+
78+
static int komeda_platform_probe(struct platform_device *pdev)
79+
{
80+
struct device *dev = &pdev->dev;
81+
struct component_match *match = NULL;
82+
struct device_node *child;
83+
84+
if (!dev->of_node)
85+
return -ENODEV;
86+
87+
for_each_available_child_of_node(dev->of_node, child) {
88+
if (of_node_cmp(child->name, "pipeline") != 0)
89+
continue;
90+
91+
/* add connector */
92+
komeda_add_slave(dev, &match, child, KOMEDA_OF_PORT_OUTPUT);
93+
}
94+
95+
return component_master_add_with_match(dev, &komeda_master_ops, match);
96+
}
97+
98+
static int komeda_platform_remove(struct platform_device *pdev)
99+
{
100+
component_master_del(&pdev->dev, &komeda_master_ops);
101+
return 0;
102+
}
103+
104+
static const struct komeda_product_data komeda_products[] = {
105+
[MALI_D71] = {
106+
.product_id = MALIDP_D71_PRODUCT_ID,
107+
.identify = d71_identify,
108+
},
109+
};
110+
111+
const struct of_device_id komeda_of_match[] = {
112+
{ .compatible = "arm,mali-d71", .data = &komeda_products[MALI_D71], },
113+
{},
114+
};
115+
116+
MODULE_DEVICE_TABLE(of, komeda_of_match);
117+
118+
static struct platform_driver komeda_platform_driver = {
119+
.probe = komeda_platform_probe,
120+
.remove = komeda_platform_remove,
121+
.driver = {
122+
.name = "komeda",
123+
.of_match_table = komeda_of_match,
124+
.pm = NULL,
125+
},
126+
};
127+
128+
module_platform_driver(komeda_platform_driver);
129+
130+
MODULE_AUTHOR("James.Qian.Wang <[email protected]>");
131+
MODULE_DESCRIPTION("Komeda KMS driver");
132+
MODULE_LICENSE("GPL v2");

0 commit comments

Comments
 (0)