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_client_setup.h>
11 #include <drm/drm_debugfs.h>
12 #include <drm/drm_device.h>
13 #include <drm/drm_drv.h>
14 #include <drm/drm_edid.h>
15 #include <drm/drm_fb_dma_helper.h>
16 #include <drm/drm_fbdev_dma.h>
17 #include <drm/drm_fourcc.h>
18 #include <drm/drm_framebuffer.h>
19 #include <drm/drm_gem_dma_helper.h>
20 #include <drm/drm_gem_framebuffer_helper.h>
21 #include <drm/drm_module.h>
22 #include <drm/drm_of.h>
23 #include <drm/drm_probe_helper.h>
24 #include <drm/drm_simple_kms_helper.h>
25 #include <linux/dma-mapping.h>
26 #include <linux/module.h>
27 #include <linux/of_reserved_mem.h>
28 #include <linux/platform_device.h>
30 #define ARCPGU_REG_CTRL 0x00
31 #define ARCPGU_REG_STAT 0x04
32 #define ARCPGU_REG_FMT 0x10
33 #define ARCPGU_REG_HSYNC 0x14
34 #define ARCPGU_REG_VSYNC 0x18
35 #define ARCPGU_REG_ACTIVE 0x1c
36 #define ARCPGU_REG_BUF0_ADDR 0x40
37 #define ARCPGU_REG_STRIDE 0x50
38 #define ARCPGU_REG_START_SET 0x84
40 #define ARCPGU_REG_ID 0x3FC
42 #define ARCPGU_CTRL_ENABLE_MASK 0x02
43 #define ARCPGU_CTRL_VS_POL_MASK 0x1
44 #define ARCPGU_CTRL_VS_POL_OFST 0x3
45 #define ARCPGU_CTRL_HS_POL_MASK 0x1
46 #define ARCPGU_CTRL_HS_POL_OFST 0x4
47 #define ARCPGU_MODE_XRGB8888 BIT(2)
48 #define ARCPGU_STAT_BUSY_MASK 0x02
50 struct arcpgu_drm_private
{
51 struct drm_device drm
;
54 struct drm_simple_display_pipe pipe
;
55 struct drm_connector sim_conn
;
58 #define dev_to_arcpgu(x) container_of(x, struct arcpgu_drm_private, drm)
60 #define pipe_to_arcpgu_priv(x) container_of(x, struct arcpgu_drm_private, pipe)
62 static inline void arc_pgu_write(struct arcpgu_drm_private
*arcpgu
,
63 unsigned int reg
, u32 value
)
65 iowrite32(value
, arcpgu
->regs
+ reg
);
68 static inline u32
arc_pgu_read(struct arcpgu_drm_private
*arcpgu
,
71 return ioread32(arcpgu
->regs
+ reg
);
80 static int arcpgu_drm_connector_get_modes(struct drm_connector
*connector
)
84 count
= drm_add_modes_noedid(connector
, XRES_MAX
, YRES_MAX
);
85 drm_set_preferred_mode(connector
, XRES_DEF
, YRES_DEF
);
89 static const struct drm_connector_helper_funcs
90 arcpgu_drm_connector_helper_funcs
= {
91 .get_modes
= arcpgu_drm_connector_get_modes
,
94 static const struct drm_connector_funcs arcpgu_drm_connector_funcs
= {
95 .reset
= drm_atomic_helper_connector_reset
,
96 .fill_modes
= drm_helper_probe_single_connector_modes
,
97 .destroy
= drm_connector_cleanup
,
98 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
99 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
102 static int arcpgu_drm_sim_init(struct drm_device
*drm
, struct drm_connector
*connector
)
104 drm_connector_helper_add(connector
, &arcpgu_drm_connector_helper_funcs
);
105 return drm_connector_init(drm
, connector
, &arcpgu_drm_connector_funcs
,
106 DRM_MODE_CONNECTOR_VIRTUAL
);
109 #define ENCODE_PGU_XY(x, y) ((((x) - 1) << 16) | ((y) - 1))
111 static const u32 arc_pgu_supported_formats
[] = {
117 static void arc_pgu_set_pxl_fmt(struct arcpgu_drm_private
*arcpgu
)
119 const struct drm_framebuffer
*fb
= arcpgu
->pipe
.plane
.state
->fb
;
120 uint32_t pixel_format
= fb
->format
->format
;
121 u32 format
= DRM_FORMAT_INVALID
;
125 for (i
= 0; i
< ARRAY_SIZE(arc_pgu_supported_formats
); i
++) {
126 if (arc_pgu_supported_formats
[i
] == pixel_format
)
127 format
= arc_pgu_supported_formats
[i
];
130 if (WARN_ON(format
== DRM_FORMAT_INVALID
))
133 reg_ctrl
= arc_pgu_read(arcpgu
, ARCPGU_REG_CTRL
);
134 if (format
== DRM_FORMAT_RGB565
)
135 reg_ctrl
&= ~ARCPGU_MODE_XRGB8888
;
137 reg_ctrl
|= ARCPGU_MODE_XRGB8888
;
138 arc_pgu_write(arcpgu
, ARCPGU_REG_CTRL
, reg_ctrl
);
141 static enum drm_mode_status
arc_pgu_mode_valid(struct drm_simple_display_pipe
*pipe
,
142 const struct drm_display_mode
*mode
)
144 struct arcpgu_drm_private
*arcpgu
= pipe_to_arcpgu_priv(pipe
);
145 long rate
, clk_rate
= mode
->clock
* 1000;
146 long diff
= clk_rate
/ 200; /* +-0.5% allowed by HDMI spec */
148 rate
= clk_round_rate(arcpgu
->clk
, clk_rate
);
149 if ((max(rate
, clk_rate
) - min(rate
, clk_rate
) < diff
) && (rate
> 0))
155 static void arc_pgu_mode_set(struct arcpgu_drm_private
*arcpgu
)
157 struct drm_display_mode
*m
= &arcpgu
->pipe
.crtc
.state
->adjusted_mode
;
160 arc_pgu_write(arcpgu
, ARCPGU_REG_FMT
,
161 ENCODE_PGU_XY(m
->crtc_htotal
, m
->crtc_vtotal
));
163 arc_pgu_write(arcpgu
, ARCPGU_REG_HSYNC
,
164 ENCODE_PGU_XY(m
->crtc_hsync_start
- m
->crtc_hdisplay
,
165 m
->crtc_hsync_end
- m
->crtc_hdisplay
));
167 arc_pgu_write(arcpgu
, ARCPGU_REG_VSYNC
,
168 ENCODE_PGU_XY(m
->crtc_vsync_start
- m
->crtc_vdisplay
,
169 m
->crtc_vsync_end
- m
->crtc_vdisplay
));
171 arc_pgu_write(arcpgu
, ARCPGU_REG_ACTIVE
,
172 ENCODE_PGU_XY(m
->crtc_hblank_end
- m
->crtc_hblank_start
,
173 m
->crtc_vblank_end
- m
->crtc_vblank_start
));
175 val
= arc_pgu_read(arcpgu
, ARCPGU_REG_CTRL
);
177 if (m
->flags
& DRM_MODE_FLAG_PVSYNC
)
178 val
|= ARCPGU_CTRL_VS_POL_MASK
<< ARCPGU_CTRL_VS_POL_OFST
;
180 val
&= ~(ARCPGU_CTRL_VS_POL_MASK
<< ARCPGU_CTRL_VS_POL_OFST
);
182 if (m
->flags
& DRM_MODE_FLAG_PHSYNC
)
183 val
|= ARCPGU_CTRL_HS_POL_MASK
<< ARCPGU_CTRL_HS_POL_OFST
;
185 val
&= ~(ARCPGU_CTRL_HS_POL_MASK
<< ARCPGU_CTRL_HS_POL_OFST
);
187 arc_pgu_write(arcpgu
, ARCPGU_REG_CTRL
, val
);
188 arc_pgu_write(arcpgu
, ARCPGU_REG_STRIDE
, 0);
189 arc_pgu_write(arcpgu
, ARCPGU_REG_START_SET
, 1);
191 arc_pgu_set_pxl_fmt(arcpgu
);
193 clk_set_rate(arcpgu
->clk
, m
->crtc_clock
* 1000);
196 static void arc_pgu_enable(struct drm_simple_display_pipe
*pipe
,
197 struct drm_crtc_state
*crtc_state
,
198 struct drm_plane_state
*plane_state
)
200 struct arcpgu_drm_private
*arcpgu
= pipe_to_arcpgu_priv(pipe
);
202 arc_pgu_mode_set(arcpgu
);
204 clk_prepare_enable(arcpgu
->clk
);
205 arc_pgu_write(arcpgu
, ARCPGU_REG_CTRL
,
206 arc_pgu_read(arcpgu
, ARCPGU_REG_CTRL
) |
207 ARCPGU_CTRL_ENABLE_MASK
);
210 static void arc_pgu_disable(struct drm_simple_display_pipe
*pipe
)
212 struct arcpgu_drm_private
*arcpgu
= pipe_to_arcpgu_priv(pipe
);
214 clk_disable_unprepare(arcpgu
->clk
);
215 arc_pgu_write(arcpgu
, ARCPGU_REG_CTRL
,
216 arc_pgu_read(arcpgu
, ARCPGU_REG_CTRL
) &
217 ~ARCPGU_CTRL_ENABLE_MASK
);
220 static void arc_pgu_update(struct drm_simple_display_pipe
*pipe
,
221 struct drm_plane_state
*state
)
223 struct arcpgu_drm_private
*arcpgu
;
224 struct drm_gem_dma_object
*gem
;
226 if (!pipe
->plane
.state
->fb
)
229 arcpgu
= pipe_to_arcpgu_priv(pipe
);
230 gem
= drm_fb_dma_get_gem_obj(pipe
->plane
.state
->fb
, 0);
231 arc_pgu_write(arcpgu
, ARCPGU_REG_BUF0_ADDR
, gem
->dma_addr
);
234 static const struct drm_simple_display_pipe_funcs arc_pgu_pipe_funcs
= {
235 .update
= arc_pgu_update
,
236 .mode_valid
= arc_pgu_mode_valid
,
237 .enable
= arc_pgu_enable
,
238 .disable
= arc_pgu_disable
,
241 static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs
= {
242 .fb_create
= drm_gem_fb_create
,
243 .atomic_check
= drm_atomic_helper_check
,
244 .atomic_commit
= drm_atomic_helper_commit
,
247 DEFINE_DRM_GEM_DMA_FOPS(arcpgu_drm_ops
);
249 static int arcpgu_load(struct arcpgu_drm_private
*arcpgu
)
251 struct platform_device
*pdev
= to_platform_device(arcpgu
->drm
.dev
);
252 struct device_node
*encoder_node
= NULL
, *endpoint_node
= NULL
;
253 struct drm_connector
*connector
= NULL
;
254 struct drm_device
*drm
= &arcpgu
->drm
;
255 struct resource
*res
;
258 arcpgu
->clk
= devm_clk_get(drm
->dev
, "pxlclk");
259 if (IS_ERR(arcpgu
->clk
))
260 return PTR_ERR(arcpgu
->clk
);
262 ret
= drmm_mode_config_init(drm
);
266 drm
->mode_config
.min_width
= 0;
267 drm
->mode_config
.min_height
= 0;
268 drm
->mode_config
.max_width
= 1920;
269 drm
->mode_config
.max_height
= 1080;
270 drm
->mode_config
.funcs
= &arcpgu_drm_modecfg_funcs
;
272 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
273 arcpgu
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
274 if (IS_ERR(arcpgu
->regs
))
275 return PTR_ERR(arcpgu
->regs
);
277 dev_info(drm
->dev
, "arc_pgu ID: 0x%x\n",
278 arc_pgu_read(arcpgu
, ARCPGU_REG_ID
));
280 /* Get the optional framebuffer memory resource */
281 ret
= of_reserved_mem_device_init(drm
->dev
);
282 if (ret
&& ret
!= -ENODEV
)
285 if (dma_set_mask_and_coherent(drm
->dev
, DMA_BIT_MASK(32)))
289 * There is only one output port inside each device. It is linked with
292 endpoint_node
= of_graph_get_next_endpoint(pdev
->dev
.of_node
, NULL
);
294 encoder_node
= of_graph_get_remote_port_parent(endpoint_node
);
295 of_node_put(endpoint_node
);
297 connector
= &arcpgu
->sim_conn
;
298 dev_info(drm
->dev
, "no encoder found. Assumed virtual LCD on simulation platform\n");
299 ret
= arcpgu_drm_sim_init(drm
, connector
);
304 ret
= drm_simple_display_pipe_init(drm
, &arcpgu
->pipe
, &arc_pgu_pipe_funcs
,
305 arc_pgu_supported_formats
,
306 ARRAY_SIZE(arc_pgu_supported_formats
),
312 struct drm_bridge
*bridge
;
314 /* Locate drm bridge from the hdmi encoder DT node */
315 bridge
= of_drm_find_bridge(encoder_node
);
317 return -EPROBE_DEFER
;
319 ret
= drm_simple_display_pipe_attach_bridge(&arcpgu
->pipe
, bridge
);
324 drm_mode_config_reset(drm
);
325 drm_kms_helper_poll_init(drm
);
327 platform_set_drvdata(pdev
, drm
);
331 static int arcpgu_unload(struct drm_device
*drm
)
333 drm_kms_helper_poll_fini(drm
);
334 drm_atomic_helper_shutdown(drm
);
339 #ifdef CONFIG_DEBUG_FS
340 static int arcpgu_show_pxlclock(struct seq_file
*m
, void *arg
)
342 struct drm_info_node
*node
= (struct drm_info_node
*)m
->private;
343 struct drm_device
*drm
= node
->minor
->dev
;
344 struct arcpgu_drm_private
*arcpgu
= dev_to_arcpgu(drm
);
345 unsigned long clkrate
= clk_get_rate(arcpgu
->clk
);
346 unsigned long mode_clock
= arcpgu
->pipe
.crtc
.mode
.crtc_clock
* 1000;
348 seq_printf(m
, "hw : %lu\n", clkrate
);
349 seq_printf(m
, "mode: %lu\n", mode_clock
);
353 static struct drm_info_list arcpgu_debugfs_list
[] = {
354 { "clocks", arcpgu_show_pxlclock
, 0 },
357 static void arcpgu_debugfs_init(struct drm_minor
*minor
)
359 drm_debugfs_create_files(arcpgu_debugfs_list
,
360 ARRAY_SIZE(arcpgu_debugfs_list
),
361 minor
->debugfs_root
, minor
);
365 static const struct drm_driver arcpgu_drm_driver
= {
366 .driver_features
= DRIVER_MODESET
| DRIVER_GEM
| DRIVER_ATOMIC
,
368 .desc
= "ARC PGU Controller",
373 .fops
= &arcpgu_drm_ops
,
374 DRM_GEM_DMA_DRIVER_OPS
,
375 DRM_FBDEV_DMA_DRIVER_OPS
,
376 #ifdef CONFIG_DEBUG_FS
377 .debugfs_init
= arcpgu_debugfs_init
,
381 static int arcpgu_probe(struct platform_device
*pdev
)
383 struct arcpgu_drm_private
*arcpgu
;
386 arcpgu
= devm_drm_dev_alloc(&pdev
->dev
, &arcpgu_drm_driver
,
387 struct arcpgu_drm_private
, drm
);
389 return PTR_ERR(arcpgu
);
391 ret
= arcpgu_load(arcpgu
);
395 ret
= drm_dev_register(&arcpgu
->drm
, 0);
399 drm_client_setup_with_fourcc(&arcpgu
->drm
, DRM_FORMAT_RGB565
);
404 arcpgu_unload(&arcpgu
->drm
);
409 static void arcpgu_remove(struct platform_device
*pdev
)
411 struct drm_device
*drm
= platform_get_drvdata(pdev
);
413 drm_dev_unregister(drm
);
417 static const struct of_device_id arcpgu_of_table
[] = {
418 {.compatible
= "snps,arcpgu"},
422 MODULE_DEVICE_TABLE(of
, arcpgu_of_table
);
424 static struct platform_driver arcpgu_platform_driver
= {
425 .probe
= arcpgu_probe
,
426 .remove
= arcpgu_remove
,
429 .of_match_table
= arcpgu_of_table
,
433 drm_module_platform_driver(arcpgu_platform_driver
);
435 MODULE_AUTHOR("Carlos Palminha <palminha@synopsys.com>");
436 MODULE_DESCRIPTION("ARC PGU DRM driver");
437 MODULE_LICENSE("GPL");