0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #include <linux/amba/bus.h>
0040 #include <linux/dma-buf.h>
0041 #include <linux/module.h>
0042 #include <linux/of.h>
0043 #include <linux/of_graph.h>
0044 #include <linux/of_reserved_mem.h>
0045 #include <linux/shmem_fs.h>
0046 #include <linux/slab.h>
0047
0048 #include <drm/drm_atomic_helper.h>
0049 #include <drm/drm_bridge.h>
0050 #include <drm/drm_drv.h>
0051 #include <drm/drm_fb_cma_helper.h>
0052 #include <drm/drm_fb_helper.h>
0053 #include <drm/drm_fourcc.h>
0054 #include <drm/drm_gem_cma_helper.h>
0055 #include <drm/drm_gem_framebuffer_helper.h>
0056 #include <drm/drm_of.h>
0057 #include <drm/drm_panel.h>
0058 #include <drm/drm_probe_helper.h>
0059 #include <drm/drm_vblank.h>
0060
0061 #include "pl111_drm.h"
0062 #include "pl111_versatile.h"
0063 #include "pl111_nomadik.h"
0064
0065 #define DRIVER_DESC "DRM module for PL111"
0066
0067 static const struct drm_mode_config_funcs mode_config_funcs = {
0068 .fb_create = drm_gem_fb_create,
0069 .atomic_check = drm_atomic_helper_check,
0070 .atomic_commit = drm_atomic_helper_commit,
0071 };
0072
0073 static int pl111_modeset_init(struct drm_device *dev)
0074 {
0075 struct drm_mode_config *mode_config;
0076 struct pl111_drm_dev_private *priv = dev->dev_private;
0077 struct device_node *np = dev->dev->of_node;
0078 struct device_node *remote;
0079 struct drm_panel *panel = NULL;
0080 struct drm_bridge *bridge = NULL;
0081 bool defer = false;
0082 int ret;
0083 int i;
0084
0085 ret = drmm_mode_config_init(dev);
0086 if (ret)
0087 return ret;
0088
0089 mode_config = &dev->mode_config;
0090 mode_config->funcs = &mode_config_funcs;
0091 mode_config->min_width = 1;
0092 mode_config->max_width = 1024;
0093 mode_config->min_height = 1;
0094 mode_config->max_height = 768;
0095
0096 i = 0;
0097 for_each_endpoint_of_node(np, remote) {
0098 struct drm_panel *tmp_panel;
0099 struct drm_bridge *tmp_bridge;
0100
0101 dev_dbg(dev->dev, "checking endpoint %d\n", i);
0102
0103 ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
0104 0, i,
0105 &tmp_panel,
0106 &tmp_bridge);
0107 if (ret) {
0108 if (ret == -EPROBE_DEFER) {
0109
0110
0111
0112
0113
0114 defer = true;
0115 } else if (ret != -ENODEV) {
0116
0117 dev_err(dev->dev,
0118 "endpoint %d returns %d\n", i, ret);
0119 }
0120 }
0121
0122 if (tmp_panel) {
0123 dev_info(dev->dev,
0124 "found panel on endpoint %d\n", i);
0125 panel = tmp_panel;
0126 }
0127 if (tmp_bridge) {
0128 dev_info(dev->dev,
0129 "found bridge on endpoint %d\n", i);
0130 bridge = tmp_bridge;
0131 }
0132
0133 i++;
0134 }
0135
0136
0137
0138
0139
0140
0141 if ((!panel && !bridge) && defer)
0142 return -EPROBE_DEFER;
0143
0144 if (panel) {
0145 bridge = drm_panel_bridge_add_typed(panel,
0146 DRM_MODE_CONNECTOR_Unknown);
0147 if (IS_ERR(bridge)) {
0148 ret = PTR_ERR(bridge);
0149 goto finish;
0150 }
0151 } else if (bridge) {
0152 dev_info(dev->dev, "Using non-panel bridge\n");
0153 } else {
0154 dev_err(dev->dev, "No bridge, exiting\n");
0155 return -ENODEV;
0156 }
0157
0158 priv->bridge = bridge;
0159 if (panel) {
0160 priv->panel = panel;
0161 priv->connector = drm_panel_bridge_connector(bridge);
0162 }
0163
0164 ret = pl111_display_init(dev);
0165 if (ret != 0) {
0166 dev_err(dev->dev, "Failed to init display\n");
0167 goto out_bridge;
0168 }
0169
0170 ret = drm_simple_display_pipe_attach_bridge(&priv->pipe,
0171 bridge);
0172 if (ret)
0173 return ret;
0174
0175 if (!priv->variant->broken_vblank) {
0176 ret = drm_vblank_init(dev, 1);
0177 if (ret != 0) {
0178 dev_err(dev->dev, "Failed to init vblank\n");
0179 goto out_bridge;
0180 }
0181 }
0182
0183 drm_mode_config_reset(dev);
0184
0185 drm_kms_helper_poll_init(dev);
0186
0187 goto finish;
0188
0189 out_bridge:
0190 if (panel)
0191 drm_panel_bridge_remove(bridge);
0192 finish:
0193 return ret;
0194 }
0195
0196 static struct drm_gem_object *
0197 pl111_gem_import_sg_table(struct drm_device *dev,
0198 struct dma_buf_attachment *attach,
0199 struct sg_table *sgt)
0200 {
0201 struct pl111_drm_dev_private *priv = dev->dev_private;
0202
0203
0204
0205
0206
0207
0208 if (priv->use_device_memory)
0209 return ERR_PTR(-EINVAL);
0210
0211 return drm_gem_cma_prime_import_sg_table(dev, attach, sgt);
0212 }
0213
0214 DEFINE_DRM_GEM_CMA_FOPS(drm_fops);
0215
0216 static const struct drm_driver pl111_drm_driver = {
0217 .driver_features =
0218 DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
0219 .ioctls = NULL,
0220 .fops = &drm_fops,
0221 .name = "pl111",
0222 .desc = DRIVER_DESC,
0223 .date = "20170317",
0224 .major = 1,
0225 .minor = 0,
0226 .patchlevel = 0,
0227 .dumb_create = drm_gem_cma_dumb_create,
0228 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
0229 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
0230 .gem_prime_import_sg_table = pl111_gem_import_sg_table,
0231 .gem_prime_mmap = drm_gem_prime_mmap,
0232
0233 #if defined(CONFIG_DEBUG_FS)
0234 .debugfs_init = pl111_debugfs_init,
0235 #endif
0236 };
0237
0238 static int pl111_amba_probe(struct amba_device *amba_dev,
0239 const struct amba_id *id)
0240 {
0241 struct device *dev = &amba_dev->dev;
0242 struct pl111_drm_dev_private *priv;
0243 const struct pl111_variant_data *variant = id->data;
0244 struct drm_device *drm;
0245 int ret;
0246
0247 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0248 if (!priv)
0249 return -ENOMEM;
0250
0251 drm = drm_dev_alloc(&pl111_drm_driver, dev);
0252 if (IS_ERR(drm))
0253 return PTR_ERR(drm);
0254 amba_set_drvdata(amba_dev, drm);
0255 priv->drm = drm;
0256 drm->dev_private = priv;
0257 priv->variant = variant;
0258
0259 ret = of_reserved_mem_device_init(dev);
0260 if (!ret) {
0261 dev_info(dev, "using device-specific reserved memory\n");
0262 priv->use_device_memory = true;
0263 }
0264
0265 if (of_property_read_u32(dev->of_node, "max-memory-bandwidth",
0266 &priv->memory_bw)) {
0267 dev_info(dev, "no max memory bandwidth specified, assume unlimited\n");
0268 priv->memory_bw = 0;
0269 }
0270
0271
0272 if (variant->is_pl110 || variant->is_lcdc) {
0273 priv->ienb = CLCD_PL110_IENB;
0274 priv->ctrl = CLCD_PL110_CNTL;
0275 } else {
0276 priv->ienb = CLCD_PL111_IENB;
0277 priv->ctrl = CLCD_PL111_CNTL;
0278 }
0279
0280 priv->regs = devm_ioremap_resource(dev, &amba_dev->res);
0281 if (IS_ERR(priv->regs)) {
0282 dev_err(dev, "%s failed mmio\n", __func__);
0283 ret = PTR_ERR(priv->regs);
0284 goto dev_put;
0285 }
0286
0287
0288 ret = pl111_versatile_init(dev, priv);
0289 if (ret)
0290 goto dev_put;
0291
0292 pl111_nomadik_init(dev);
0293
0294
0295 writel(0, priv->regs + priv->ienb);
0296
0297 ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0,
0298 variant->name, priv);
0299 if (ret != 0) {
0300 dev_err(dev, "%s failed irq %d\n", __func__, ret);
0301 return ret;
0302 }
0303
0304 ret = pl111_modeset_init(drm);
0305 if (ret != 0)
0306 goto dev_put;
0307
0308 ret = drm_dev_register(drm, 0);
0309 if (ret < 0)
0310 goto dev_put;
0311
0312 drm_fbdev_generic_setup(drm, priv->variant->fb_bpp);
0313
0314 return 0;
0315
0316 dev_put:
0317 drm_dev_put(drm);
0318 of_reserved_mem_device_release(dev);
0319
0320 return ret;
0321 }
0322
0323 static void pl111_amba_remove(struct amba_device *amba_dev)
0324 {
0325 struct device *dev = &amba_dev->dev;
0326 struct drm_device *drm = amba_get_drvdata(amba_dev);
0327 struct pl111_drm_dev_private *priv = drm->dev_private;
0328
0329 drm_dev_unregister(drm);
0330 if (priv->panel)
0331 drm_panel_bridge_remove(priv->bridge);
0332 drm_dev_put(drm);
0333 of_reserved_mem_device_release(dev);
0334 }
0335
0336
0337
0338
0339 static const u32 pl110_pixel_formats[] = {
0340 DRM_FORMAT_ABGR8888,
0341 DRM_FORMAT_XBGR8888,
0342 DRM_FORMAT_ARGB8888,
0343 DRM_FORMAT_XRGB8888,
0344 DRM_FORMAT_ABGR1555,
0345 DRM_FORMAT_XBGR1555,
0346 DRM_FORMAT_ARGB1555,
0347 DRM_FORMAT_XRGB1555,
0348 };
0349
0350 static const struct pl111_variant_data pl110_variant = {
0351 .name = "PL110",
0352 .is_pl110 = true,
0353 .formats = pl110_pixel_formats,
0354 .nformats = ARRAY_SIZE(pl110_pixel_formats),
0355 .fb_bpp = 16,
0356 };
0357
0358
0359 static const u32 pl111_pixel_formats[] = {
0360 DRM_FORMAT_ABGR8888,
0361 DRM_FORMAT_XBGR8888,
0362 DRM_FORMAT_ARGB8888,
0363 DRM_FORMAT_XRGB8888,
0364 DRM_FORMAT_BGR565,
0365 DRM_FORMAT_RGB565,
0366 DRM_FORMAT_ABGR1555,
0367 DRM_FORMAT_XBGR1555,
0368 DRM_FORMAT_ARGB1555,
0369 DRM_FORMAT_XRGB1555,
0370 DRM_FORMAT_ABGR4444,
0371 DRM_FORMAT_XBGR4444,
0372 DRM_FORMAT_ARGB4444,
0373 DRM_FORMAT_XRGB4444,
0374 };
0375
0376 static const struct pl111_variant_data pl111_variant = {
0377 .name = "PL111",
0378 .formats = pl111_pixel_formats,
0379 .nformats = ARRAY_SIZE(pl111_pixel_formats),
0380 .fb_bpp = 32,
0381 };
0382
0383 static const u32 pl110_nomadik_pixel_formats[] = {
0384 DRM_FORMAT_RGB888,
0385 DRM_FORMAT_BGR888,
0386 DRM_FORMAT_ABGR8888,
0387 DRM_FORMAT_XBGR8888,
0388 DRM_FORMAT_ARGB8888,
0389 DRM_FORMAT_XRGB8888,
0390 DRM_FORMAT_BGR565,
0391 DRM_FORMAT_RGB565,
0392 DRM_FORMAT_ABGR1555,
0393 DRM_FORMAT_XBGR1555,
0394 DRM_FORMAT_ARGB1555,
0395 DRM_FORMAT_XRGB1555,
0396 DRM_FORMAT_ABGR4444,
0397 DRM_FORMAT_XBGR4444,
0398 DRM_FORMAT_ARGB4444,
0399 DRM_FORMAT_XRGB4444,
0400 };
0401
0402 static const struct pl111_variant_data pl110_nomadik_variant = {
0403 .name = "LCDC (PL110 Nomadik)",
0404 .formats = pl110_nomadik_pixel_formats,
0405 .nformats = ARRAY_SIZE(pl110_nomadik_pixel_formats),
0406 .is_lcdc = true,
0407 .st_bitmux_control = true,
0408 .broken_vblank = true,
0409 .fb_bpp = 16,
0410 };
0411
0412 static const struct amba_id pl111_id_table[] = {
0413 {
0414 .id = 0x00041110,
0415 .mask = 0x000fffff,
0416 .data = (void *)&pl110_variant,
0417 },
0418 {
0419 .id = 0x00180110,
0420 .mask = 0x00fffffe,
0421 .data = (void *)&pl110_nomadik_variant,
0422 },
0423 {
0424 .id = 0x00041111,
0425 .mask = 0x000fffff,
0426 .data = (void *)&pl111_variant,
0427 },
0428 {0, 0},
0429 };
0430 MODULE_DEVICE_TABLE(amba, pl111_id_table);
0431
0432 static struct amba_driver pl111_amba_driver __maybe_unused = {
0433 .drv = {
0434 .name = "drm-clcd-pl111",
0435 },
0436 .probe = pl111_amba_probe,
0437 .remove = pl111_amba_remove,
0438 .id_table = pl111_id_table,
0439 };
0440
0441 #ifdef CONFIG_ARM_AMBA
0442 module_amba_driver(pl111_amba_driver);
0443 #endif
0444
0445 MODULE_DESCRIPTION(DRIVER_DESC);
0446 MODULE_AUTHOR("ARM Ltd.");
0447 MODULE_LICENSE("GPL");