Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ARC PGU DRM driver.
0004  *
0005  * Copyright (C) 2016 Synopsys, Inc. (www.synopsys.com)
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <drm/drm_atomic_helper.h>
0010 #include <drm/drm_debugfs.h>
0011 #include <drm/drm_device.h>
0012 #include <drm/drm_drv.h>
0013 #include <drm/drm_edid.h>
0014 #include <drm/drm_fb_cma_helper.h>
0015 #include <drm/drm_fb_helper.h>
0016 #include <drm/drm_fourcc.h>
0017 #include <drm/drm_framebuffer.h>
0018 #include <drm/drm_gem_cma_helper.h>
0019 #include <drm/drm_gem_framebuffer_helper.h>
0020 #include <drm/drm_module.h>
0021 #include <drm/drm_of.h>
0022 #include <drm/drm_probe_helper.h>
0023 #include <drm/drm_simple_kms_helper.h>
0024 #include <linux/dma-mapping.h>
0025 #include <linux/module.h>
0026 #include <linux/of_reserved_mem.h>
0027 #include <linux/platform_device.h>
0028 
0029 #define ARCPGU_REG_CTRL     0x00
0030 #define ARCPGU_REG_STAT     0x04
0031 #define ARCPGU_REG_FMT      0x10
0032 #define ARCPGU_REG_HSYNC    0x14
0033 #define ARCPGU_REG_VSYNC    0x18
0034 #define ARCPGU_REG_ACTIVE   0x1c
0035 #define ARCPGU_REG_BUF0_ADDR    0x40
0036 #define ARCPGU_REG_STRIDE   0x50
0037 #define ARCPGU_REG_START_SET    0x84
0038 
0039 #define ARCPGU_REG_ID       0x3FC
0040 
0041 #define ARCPGU_CTRL_ENABLE_MASK 0x02
0042 #define ARCPGU_CTRL_VS_POL_MASK 0x1
0043 #define ARCPGU_CTRL_VS_POL_OFST 0x3
0044 #define ARCPGU_CTRL_HS_POL_MASK 0x1
0045 #define ARCPGU_CTRL_HS_POL_OFST 0x4
0046 #define ARCPGU_MODE_XRGB8888    BIT(2)
0047 #define ARCPGU_STAT_BUSY_MASK   0x02
0048 
0049 struct arcpgu_drm_private {
0050     struct drm_device   drm;
0051     void __iomem        *regs;
0052     struct clk      *clk;
0053     struct drm_simple_display_pipe pipe;
0054     struct drm_connector    sim_conn;
0055 };
0056 
0057 #define dev_to_arcpgu(x) container_of(x, struct arcpgu_drm_private, drm)
0058 
0059 #define pipe_to_arcpgu_priv(x) container_of(x, struct arcpgu_drm_private, pipe)
0060 
0061 static inline void arc_pgu_write(struct arcpgu_drm_private *arcpgu,
0062                  unsigned int reg, u32 value)
0063 {
0064     iowrite32(value, arcpgu->regs + reg);
0065 }
0066 
0067 static inline u32 arc_pgu_read(struct arcpgu_drm_private *arcpgu,
0068                    unsigned int reg)
0069 {
0070     return ioread32(arcpgu->regs + reg);
0071 }
0072 
0073 #define XRES_DEF    640
0074 #define YRES_DEF    480
0075 
0076 #define XRES_MAX    8192
0077 #define YRES_MAX    8192
0078 
0079 static int arcpgu_drm_connector_get_modes(struct drm_connector *connector)
0080 {
0081     int count;
0082 
0083     count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
0084     drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
0085     return count;
0086 }
0087 
0088 static const struct drm_connector_helper_funcs
0089 arcpgu_drm_connector_helper_funcs = {
0090     .get_modes = arcpgu_drm_connector_get_modes,
0091 };
0092 
0093 static const struct drm_connector_funcs arcpgu_drm_connector_funcs = {
0094     .reset = drm_atomic_helper_connector_reset,
0095     .fill_modes = drm_helper_probe_single_connector_modes,
0096     .destroy = drm_connector_cleanup,
0097     .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
0098     .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
0099 };
0100 
0101 static int arcpgu_drm_sim_init(struct drm_device *drm, struct drm_connector *connector)
0102 {
0103     drm_connector_helper_add(connector, &arcpgu_drm_connector_helper_funcs);
0104     return drm_connector_init(drm, connector, &arcpgu_drm_connector_funcs,
0105                   DRM_MODE_CONNECTOR_VIRTUAL);
0106 }
0107 
0108 #define ENCODE_PGU_XY(x, y) ((((x) - 1) << 16) | ((y) - 1))
0109 
0110 static const u32 arc_pgu_supported_formats[] = {
0111     DRM_FORMAT_RGB565,
0112     DRM_FORMAT_XRGB8888,
0113     DRM_FORMAT_ARGB8888,
0114 };
0115 
0116 static void arc_pgu_set_pxl_fmt(struct arcpgu_drm_private *arcpgu)
0117 {
0118     const struct drm_framebuffer *fb = arcpgu->pipe.plane.state->fb;
0119     uint32_t pixel_format = fb->format->format;
0120     u32 format = DRM_FORMAT_INVALID;
0121     int i;
0122     u32 reg_ctrl;
0123 
0124     for (i = 0; i < ARRAY_SIZE(arc_pgu_supported_formats); i++) {
0125         if (arc_pgu_supported_formats[i] == pixel_format)
0126             format = arc_pgu_supported_formats[i];
0127     }
0128 
0129     if (WARN_ON(format == DRM_FORMAT_INVALID))
0130         return;
0131 
0132     reg_ctrl = arc_pgu_read(arcpgu, ARCPGU_REG_CTRL);
0133     if (format == DRM_FORMAT_RGB565)
0134         reg_ctrl &= ~ARCPGU_MODE_XRGB8888;
0135     else
0136         reg_ctrl |= ARCPGU_MODE_XRGB8888;
0137     arc_pgu_write(arcpgu, ARCPGU_REG_CTRL, reg_ctrl);
0138 }
0139 
0140 static enum drm_mode_status arc_pgu_mode_valid(struct drm_simple_display_pipe *pipe,
0141                            const struct drm_display_mode *mode)
0142 {
0143     struct arcpgu_drm_private *arcpgu = pipe_to_arcpgu_priv(pipe);
0144     long rate, clk_rate = mode->clock * 1000;
0145     long diff = clk_rate / 200; /* +-0.5% allowed by HDMI spec */
0146 
0147     rate = clk_round_rate(arcpgu->clk, clk_rate);
0148     if ((max(rate, clk_rate) - min(rate, clk_rate) < diff) && (rate > 0))
0149         return MODE_OK;
0150 
0151     return MODE_NOCLOCK;
0152 }
0153 
0154 static void arc_pgu_mode_set(struct arcpgu_drm_private *arcpgu)
0155 {
0156     struct drm_display_mode *m = &arcpgu->pipe.crtc.state->adjusted_mode;
0157     u32 val;
0158 
0159     arc_pgu_write(arcpgu, ARCPGU_REG_FMT,
0160               ENCODE_PGU_XY(m->crtc_htotal, m->crtc_vtotal));
0161 
0162     arc_pgu_write(arcpgu, ARCPGU_REG_HSYNC,
0163               ENCODE_PGU_XY(m->crtc_hsync_start - m->crtc_hdisplay,
0164                     m->crtc_hsync_end - m->crtc_hdisplay));
0165 
0166     arc_pgu_write(arcpgu, ARCPGU_REG_VSYNC,
0167               ENCODE_PGU_XY(m->crtc_vsync_start - m->crtc_vdisplay,
0168                     m->crtc_vsync_end - m->crtc_vdisplay));
0169 
0170     arc_pgu_write(arcpgu, ARCPGU_REG_ACTIVE,
0171               ENCODE_PGU_XY(m->crtc_hblank_end - m->crtc_hblank_start,
0172                     m->crtc_vblank_end - m->crtc_vblank_start));
0173 
0174     val = arc_pgu_read(arcpgu, ARCPGU_REG_CTRL);
0175 
0176     if (m->flags & DRM_MODE_FLAG_PVSYNC)
0177         val |= ARCPGU_CTRL_VS_POL_MASK << ARCPGU_CTRL_VS_POL_OFST;
0178     else
0179         val &= ~(ARCPGU_CTRL_VS_POL_MASK << ARCPGU_CTRL_VS_POL_OFST);
0180 
0181     if (m->flags & DRM_MODE_FLAG_PHSYNC)
0182         val |= ARCPGU_CTRL_HS_POL_MASK << ARCPGU_CTRL_HS_POL_OFST;
0183     else
0184         val &= ~(ARCPGU_CTRL_HS_POL_MASK << ARCPGU_CTRL_HS_POL_OFST);
0185 
0186     arc_pgu_write(arcpgu, ARCPGU_REG_CTRL, val);
0187     arc_pgu_write(arcpgu, ARCPGU_REG_STRIDE, 0);
0188     arc_pgu_write(arcpgu, ARCPGU_REG_START_SET, 1);
0189 
0190     arc_pgu_set_pxl_fmt(arcpgu);
0191 
0192     clk_set_rate(arcpgu->clk, m->crtc_clock * 1000);
0193 }
0194 
0195 static void arc_pgu_enable(struct drm_simple_display_pipe *pipe,
0196                struct drm_crtc_state *crtc_state,
0197                struct drm_plane_state *plane_state)
0198 {
0199     struct arcpgu_drm_private *arcpgu = pipe_to_arcpgu_priv(pipe);
0200 
0201     arc_pgu_mode_set(arcpgu);
0202 
0203     clk_prepare_enable(arcpgu->clk);
0204     arc_pgu_write(arcpgu, ARCPGU_REG_CTRL,
0205               arc_pgu_read(arcpgu, ARCPGU_REG_CTRL) |
0206               ARCPGU_CTRL_ENABLE_MASK);
0207 }
0208 
0209 static void arc_pgu_disable(struct drm_simple_display_pipe *pipe)
0210 {
0211     struct arcpgu_drm_private *arcpgu = pipe_to_arcpgu_priv(pipe);
0212 
0213     clk_disable_unprepare(arcpgu->clk);
0214     arc_pgu_write(arcpgu, ARCPGU_REG_CTRL,
0215                   arc_pgu_read(arcpgu, ARCPGU_REG_CTRL) &
0216                   ~ARCPGU_CTRL_ENABLE_MASK);
0217 }
0218 
0219 static void arc_pgu_update(struct drm_simple_display_pipe *pipe,
0220                struct drm_plane_state *state)
0221 {
0222     struct arcpgu_drm_private *arcpgu;
0223     struct drm_gem_cma_object *gem;
0224 
0225     if (!pipe->plane.state->fb)
0226         return;
0227 
0228     arcpgu = pipe_to_arcpgu_priv(pipe);
0229     gem = drm_fb_cma_get_gem_obj(pipe->plane.state->fb, 0);
0230     arc_pgu_write(arcpgu, ARCPGU_REG_BUF0_ADDR, gem->paddr);
0231 }
0232 
0233 static const struct drm_simple_display_pipe_funcs arc_pgu_pipe_funcs = {
0234     .update = arc_pgu_update,
0235     .mode_valid = arc_pgu_mode_valid,
0236     .enable = arc_pgu_enable,
0237     .disable = arc_pgu_disable,
0238 };
0239 
0240 static const struct drm_mode_config_funcs arcpgu_drm_modecfg_funcs = {
0241     .fb_create  = drm_gem_fb_create,
0242     .atomic_check = drm_atomic_helper_check,
0243     .atomic_commit = drm_atomic_helper_commit,
0244 };
0245 
0246 DEFINE_DRM_GEM_CMA_FOPS(arcpgu_drm_ops);
0247 
0248 static int arcpgu_load(struct arcpgu_drm_private *arcpgu)
0249 {
0250     struct platform_device *pdev = to_platform_device(arcpgu->drm.dev);
0251     struct device_node *encoder_node = NULL, *endpoint_node = NULL;
0252     struct drm_connector *connector = NULL;
0253     struct drm_device *drm = &arcpgu->drm;
0254     struct resource *res;
0255     int ret;
0256 
0257     arcpgu->clk = devm_clk_get(drm->dev, "pxlclk");
0258     if (IS_ERR(arcpgu->clk))
0259         return PTR_ERR(arcpgu->clk);
0260 
0261     ret = drmm_mode_config_init(drm);
0262     if (ret)
0263         return ret;
0264 
0265     drm->mode_config.min_width = 0;
0266     drm->mode_config.min_height = 0;
0267     drm->mode_config.max_width = 1920;
0268     drm->mode_config.max_height = 1080;
0269     drm->mode_config.funcs = &arcpgu_drm_modecfg_funcs;
0270 
0271     res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0272     arcpgu->regs = devm_ioremap_resource(&pdev->dev, res);
0273     if (IS_ERR(arcpgu->regs))
0274         return PTR_ERR(arcpgu->regs);
0275 
0276     dev_info(drm->dev, "arc_pgu ID: 0x%x\n",
0277          arc_pgu_read(arcpgu, ARCPGU_REG_ID));
0278 
0279     /* Get the optional framebuffer memory resource */
0280     ret = of_reserved_mem_device_init(drm->dev);
0281     if (ret && ret != -ENODEV)
0282         return ret;
0283 
0284     if (dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32)))
0285         return -ENODEV;
0286 
0287     /*
0288      * There is only one output port inside each device. It is linked with
0289      * encoder endpoint.
0290      */
0291     endpoint_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
0292     if (endpoint_node) {
0293         encoder_node = of_graph_get_remote_port_parent(endpoint_node);
0294         of_node_put(endpoint_node);
0295     } else {
0296         connector = &arcpgu->sim_conn;
0297         dev_info(drm->dev, "no encoder found. Assumed virtual LCD on simulation platform\n");
0298         ret = arcpgu_drm_sim_init(drm, connector);
0299         if (ret < 0)
0300             return ret;
0301     }
0302 
0303     ret = drm_simple_display_pipe_init(drm, &arcpgu->pipe, &arc_pgu_pipe_funcs,
0304                        arc_pgu_supported_formats,
0305                        ARRAY_SIZE(arc_pgu_supported_formats),
0306                        NULL, connector);
0307     if (ret)
0308         return ret;
0309 
0310     if (encoder_node) {
0311         struct drm_bridge *bridge;
0312 
0313         /* Locate drm bridge from the hdmi encoder DT node */
0314         bridge = of_drm_find_bridge(encoder_node);
0315         if (!bridge)
0316             return -EPROBE_DEFER;
0317 
0318         ret = drm_simple_display_pipe_attach_bridge(&arcpgu->pipe, bridge);
0319         if (ret)
0320             return ret;
0321     }
0322 
0323     drm_mode_config_reset(drm);
0324     drm_kms_helper_poll_init(drm);
0325 
0326     platform_set_drvdata(pdev, drm);
0327     return 0;
0328 }
0329 
0330 static int arcpgu_unload(struct drm_device *drm)
0331 {
0332     drm_kms_helper_poll_fini(drm);
0333     drm_atomic_helper_shutdown(drm);
0334 
0335     return 0;
0336 }
0337 
0338 #ifdef CONFIG_DEBUG_FS
0339 static int arcpgu_show_pxlclock(struct seq_file *m, void *arg)
0340 {
0341     struct drm_info_node *node = (struct drm_info_node *)m->private;
0342     struct drm_device *drm = node->minor->dev;
0343     struct arcpgu_drm_private *arcpgu = dev_to_arcpgu(drm);
0344     unsigned long clkrate = clk_get_rate(arcpgu->clk);
0345     unsigned long mode_clock = arcpgu->pipe.crtc.mode.crtc_clock * 1000;
0346 
0347     seq_printf(m, "hw  : %lu\n", clkrate);
0348     seq_printf(m, "mode: %lu\n", mode_clock);
0349     return 0;
0350 }
0351 
0352 static struct drm_info_list arcpgu_debugfs_list[] = {
0353     { "clocks", arcpgu_show_pxlclock, 0 },
0354 };
0355 
0356 static void arcpgu_debugfs_init(struct drm_minor *minor)
0357 {
0358     drm_debugfs_create_files(arcpgu_debugfs_list,
0359                  ARRAY_SIZE(arcpgu_debugfs_list),
0360                  minor->debugfs_root, minor);
0361 }
0362 #endif
0363 
0364 static const struct drm_driver arcpgu_drm_driver = {
0365     .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
0366     .name = "arcpgu",
0367     .desc = "ARC PGU Controller",
0368     .date = "20160219",
0369     .major = 1,
0370     .minor = 0,
0371     .patchlevel = 0,
0372     .fops = &arcpgu_drm_ops,
0373     DRM_GEM_CMA_DRIVER_OPS,
0374 #ifdef CONFIG_DEBUG_FS
0375     .debugfs_init = arcpgu_debugfs_init,
0376 #endif
0377 };
0378 
0379 static int arcpgu_probe(struct platform_device *pdev)
0380 {
0381     struct arcpgu_drm_private *arcpgu;
0382     int ret;
0383 
0384     arcpgu = devm_drm_dev_alloc(&pdev->dev, &arcpgu_drm_driver,
0385                     struct arcpgu_drm_private, drm);
0386     if (IS_ERR(arcpgu))
0387         return PTR_ERR(arcpgu);
0388 
0389     ret = arcpgu_load(arcpgu);
0390     if (ret)
0391         return ret;
0392 
0393     ret = drm_dev_register(&arcpgu->drm, 0);
0394     if (ret)
0395         goto err_unload;
0396 
0397     drm_fbdev_generic_setup(&arcpgu->drm, 16);
0398 
0399     return 0;
0400 
0401 err_unload:
0402     arcpgu_unload(&arcpgu->drm);
0403 
0404     return ret;
0405 }
0406 
0407 static int arcpgu_remove(struct platform_device *pdev)
0408 {
0409     struct drm_device *drm = platform_get_drvdata(pdev);
0410 
0411     drm_dev_unregister(drm);
0412     arcpgu_unload(drm);
0413 
0414     return 0;
0415 }
0416 
0417 static const struct of_device_id arcpgu_of_table[] = {
0418     {.compatible = "snps,arcpgu"},
0419     {}
0420 };
0421 
0422 MODULE_DEVICE_TABLE(of, arcpgu_of_table);
0423 
0424 static struct platform_driver arcpgu_platform_driver = {
0425     .probe = arcpgu_probe,
0426     .remove = arcpgu_remove,
0427     .driver = {
0428            .name = "arcpgu",
0429            .of_match_table = arcpgu_of_table,
0430            },
0431 };
0432 
0433 drm_module_platform_driver(arcpgu_platform_driver);
0434 
0435 MODULE_AUTHOR("Carlos Palminha <palminha@synopsys.com>");
0436 MODULE_DESCRIPTION("ARC PGU DRM driver");
0437 MODULE_LICENSE("GPL");