1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com)
9 #include <drm/drm_atomic_helper.h>
10 #include <drm/drm_debugfs.h>
11 #include <drm/drm_device.h>
12 #include <drm/drm_drv.h>
13 #include <drm/drm_fb_cma_helper.h>
14 #include <drm/drm_fb_helper.h>
15 #include <drm/drm_gem_cma_helper.h>
16 #include <drm/drm_gem_framebuffer_helper.h>
17 #include <drm/drm_of.h>
18 #include <drm/drm_probe_helper.h>
19 #include <linux/dma-mapping.h>
20 #include <linux/module.h>
21 #include <linux/of_reserved_mem.h>
22 #include <linux/platform_device.h>
25 #include "arcpgu_regs.h"
27 static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs
= {
28 .fb_create
= drm_gem_fb_create
,
29 .atomic_check
= drm_atomic_helper_check
,
30 .atomic_commit
= drm_atomic_helper_commit
,
33 static void arcpgu_setup_mode_config(struct drm_device
*drm
)
35 drm_mode_config_init(drm
);
36 drm
->mode_config
.min_width
= 0;
37 drm
->mode_config
.min_height
= 0;
38 drm
->mode_config
.max_width
= 1920;
39 drm
->mode_config
.max_height
= 1080;
40 drm
->mode_config
.funcs
= &arcpgu_drm_modecfg_funcs
;
43 DEFINE_DRM_GEM_CMA_FOPS(arcpgu_drm_ops
);
45 static int arcpgu_load(struct drm_device
*drm
)
47 struct platform_device
*pdev
= to_platform_device(drm
->dev
);
48 struct arcpgu_drm_private
*arcpgu
;
49 struct device_node
*encoder_node
= NULL
, *endpoint_node
= NULL
;
53 arcpgu
= devm_kzalloc(&pdev
->dev
, sizeof(*arcpgu
), GFP_KERNEL
);
57 drm
->dev_private
= arcpgu
;
59 arcpgu
->clk
= devm_clk_get(drm
->dev
, "pxlclk");
60 if (IS_ERR(arcpgu
->clk
))
61 return PTR_ERR(arcpgu
->clk
);
63 arcpgu_setup_mode_config(drm
);
65 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
66 arcpgu
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
67 if (IS_ERR(arcpgu
->regs
))
68 return PTR_ERR(arcpgu
->regs
);
70 dev_info(drm
->dev
, "arc_pgu ID: 0x%x\n",
71 arc_pgu_read(arcpgu
, ARCPGU_REG_ID
));
73 /* Get the optional framebuffer memory resource */
74 ret
= of_reserved_mem_device_init(drm
->dev
);
75 if (ret
&& ret
!= -ENODEV
)
78 if (dma_set_mask_and_coherent(drm
->dev
, DMA_BIT_MASK(32)))
81 if (arc_pgu_setup_crtc(drm
) < 0)
85 * There is only one output port inside each device. It is linked with
88 endpoint_node
= of_graph_get_next_endpoint(pdev
->dev
.of_node
, NULL
);
90 encoder_node
= of_graph_get_remote_port_parent(endpoint_node
);
91 of_node_put(endpoint_node
);
95 ret
= arcpgu_drm_hdmi_init(drm
, encoder_node
);
96 of_node_put(encoder_node
);
100 dev_info(drm
->dev
, "no encoder found. Assumed virtual LCD on simulation platform\n");
101 ret
= arcpgu_drm_sim_init(drm
, NULL
);
106 drm_mode_config_reset(drm
);
107 drm_kms_helper_poll_init(drm
);
109 platform_set_drvdata(pdev
, drm
);
113 static int arcpgu_unload(struct drm_device
*drm
)
115 drm_kms_helper_poll_fini(drm
);
116 drm_atomic_helper_shutdown(drm
);
117 drm_mode_config_cleanup(drm
);
122 #ifdef CONFIG_DEBUG_FS
123 static int arcpgu_show_pxlclock(struct seq_file
*m
, void *arg
)
125 struct drm_info_node
*node
= (struct drm_info_node
*)m
->private;
126 struct drm_device
*drm
= node
->minor
->dev
;
127 struct arcpgu_drm_private
*arcpgu
= drm
->dev_private
;
128 unsigned long clkrate
= clk_get_rate(arcpgu
->clk
);
129 unsigned long mode_clock
= arcpgu
->crtc
.mode
.crtc_clock
* 1000;
131 seq_printf(m
, "hw : %lu\n", clkrate
);
132 seq_printf(m
, "mode: %lu\n", mode_clock
);
136 static struct drm_info_list arcpgu_debugfs_list
[] = {
137 { "clocks", arcpgu_show_pxlclock
, 0 },
140 static void arcpgu_debugfs_init(struct drm_minor
*minor
)
142 drm_debugfs_create_files(arcpgu_debugfs_list
,
143 ARRAY_SIZE(arcpgu_debugfs_list
),
144 minor
->debugfs_root
, minor
);
148 static struct drm_driver arcpgu_drm_driver
= {
149 .driver_features
= DRIVER_MODESET
| DRIVER_GEM
| DRIVER_ATOMIC
,
151 .desc
= "ARC PGU Controller",
156 .fops
= &arcpgu_drm_ops
,
157 DRM_GEM_CMA_DRIVER_OPS
,
158 #ifdef CONFIG_DEBUG_FS
159 .debugfs_init
= arcpgu_debugfs_init
,
163 static int arcpgu_probe(struct platform_device
*pdev
)
165 struct drm_device
*drm
;
168 drm
= drm_dev_alloc(&arcpgu_drm_driver
, &pdev
->dev
);
172 ret
= arcpgu_load(drm
);
176 ret
= drm_dev_register(drm
, 0);
180 drm_fbdev_generic_setup(drm
, 16);
193 static int arcpgu_remove(struct platform_device
*pdev
)
195 struct drm_device
*drm
= platform_get_drvdata(pdev
);
197 drm_dev_unregister(drm
);
204 static const struct of_device_id arcpgu_of_table
[] = {
205 {.compatible
= "snps,arcpgu"},
209 MODULE_DEVICE_TABLE(of
, arcpgu_of_table
);
211 static struct platform_driver arcpgu_platform_driver
= {
212 .probe
= arcpgu_probe
,
213 .remove
= arcpgu_remove
,
216 .of_match_table
= arcpgu_of_table
,
220 module_platform_driver(arcpgu_platform_driver
);
222 MODULE_AUTHOR("Carlos Palminha <palminha@synopsys.com>");
223 MODULE_DESCRIPTION("ARC PGU DRM driver");
224 MODULE_LICENSE("GPL");