0001
0002
0003
0004
0005
0006 #include <linux/component.h>
0007 #include <linux/dma-mapping.h>
0008 #include <linux/module.h>
0009 #include <linux/mutex.h>
0010 #include <linux/of_graph.h>
0011 #include <linux/of_platform.h>
0012
0013 #include <drm/drm_atomic_helper.h>
0014 #include <drm/drm_crtc_helper.h>
0015 #include <drm/drm_drv.h>
0016 #include <drm/drm_gem_cma_helper.h>
0017 #include <drm/drm_gem_framebuffer_helper.h>
0018 #include <drm/drm_of.h>
0019 #include <drm/drm_probe_helper.h>
0020 #include <drm/drm_vblank.h>
0021
0022 #include "sprd_drm.h"
0023
0024 #define DRIVER_NAME "sprd"
0025 #define DRIVER_DESC "Spreadtrum SoCs' DRM Driver"
0026 #define DRIVER_DATE "20200201"
0027 #define DRIVER_MAJOR 1
0028 #define DRIVER_MINOR 0
0029
0030 static const struct drm_mode_config_helper_funcs sprd_drm_mode_config_helper = {
0031 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
0032 };
0033
0034 static const struct drm_mode_config_funcs sprd_drm_mode_config_funcs = {
0035 .fb_create = drm_gem_fb_create,
0036 .atomic_check = drm_atomic_helper_check,
0037 .atomic_commit = drm_atomic_helper_commit,
0038 };
0039
0040 static void sprd_drm_mode_config_init(struct drm_device *drm)
0041 {
0042 drm->mode_config.min_width = 0;
0043 drm->mode_config.min_height = 0;
0044 drm->mode_config.max_width = 8192;
0045 drm->mode_config.max_height = 8192;
0046
0047 drm->mode_config.funcs = &sprd_drm_mode_config_funcs;
0048 drm->mode_config.helper_private = &sprd_drm_mode_config_helper;
0049 }
0050
0051 DEFINE_DRM_GEM_CMA_FOPS(sprd_drm_fops);
0052
0053 static struct drm_driver sprd_drm_drv = {
0054 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
0055 .fops = &sprd_drm_fops,
0056
0057
0058 DRM_GEM_CMA_DRIVER_OPS,
0059
0060 .name = DRIVER_NAME,
0061 .desc = DRIVER_DESC,
0062 .date = DRIVER_DATE,
0063 .major = DRIVER_MAJOR,
0064 .minor = DRIVER_MINOR,
0065 };
0066
0067 static int sprd_drm_bind(struct device *dev)
0068 {
0069 struct platform_device *pdev = to_platform_device(dev);
0070 struct drm_device *drm;
0071 struct sprd_drm *sprd;
0072 int ret;
0073
0074 sprd = devm_drm_dev_alloc(dev, &sprd_drm_drv, struct sprd_drm, drm);
0075 if (IS_ERR(sprd))
0076 return PTR_ERR(sprd);
0077
0078 drm = &sprd->drm;
0079 platform_set_drvdata(pdev, drm);
0080
0081 ret = drmm_mode_config_init(drm);
0082 if (ret)
0083 return ret;
0084
0085 sprd_drm_mode_config_init(drm);
0086
0087
0088 ret = component_bind_all(drm->dev, drm);
0089 if (ret) {
0090 drm_err(drm, "failed to bind all component.\n");
0091 return ret;
0092 }
0093
0094
0095 ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
0096 if (ret) {
0097 drm_err(drm, "failed to initialize vblank.\n");
0098 goto err_unbind_all;
0099 }
0100
0101
0102 drm_mode_config_reset(drm);
0103
0104
0105 drm_kms_helper_poll_init(drm);
0106
0107 ret = drm_dev_register(drm, 0);
0108 if (ret < 0)
0109 goto err_kms_helper_poll_fini;
0110
0111 return 0;
0112
0113 err_kms_helper_poll_fini:
0114 drm_kms_helper_poll_fini(drm);
0115 err_unbind_all:
0116 component_unbind_all(drm->dev, drm);
0117 return ret;
0118 }
0119
0120 static void sprd_drm_unbind(struct device *dev)
0121 {
0122 struct drm_device *drm = dev_get_drvdata(dev);
0123
0124 drm_dev_unregister(drm);
0125
0126 drm_kms_helper_poll_fini(drm);
0127
0128 component_unbind_all(drm->dev, drm);
0129 }
0130
0131 static const struct component_master_ops drm_component_ops = {
0132 .bind = sprd_drm_bind,
0133 .unbind = sprd_drm_unbind,
0134 };
0135
0136 static int sprd_drm_probe(struct platform_device *pdev)
0137 {
0138 return drm_of_component_probe(&pdev->dev, component_compare_of, &drm_component_ops);
0139 }
0140
0141 static int sprd_drm_remove(struct platform_device *pdev)
0142 {
0143 component_master_del(&pdev->dev, &drm_component_ops);
0144 return 0;
0145 }
0146
0147 static void sprd_drm_shutdown(struct platform_device *pdev)
0148 {
0149 struct drm_device *drm = platform_get_drvdata(pdev);
0150
0151 if (!drm) {
0152 dev_warn(&pdev->dev, "drm device is not available, no shutdown\n");
0153 return;
0154 }
0155
0156 drm_atomic_helper_shutdown(drm);
0157 }
0158
0159 static const struct of_device_id drm_match_table[] = {
0160 { .compatible = "sprd,display-subsystem", },
0161 { },
0162 };
0163 MODULE_DEVICE_TABLE(of, drm_match_table);
0164
0165 static struct platform_driver sprd_drm_driver = {
0166 .probe = sprd_drm_probe,
0167 .remove = sprd_drm_remove,
0168 .shutdown = sprd_drm_shutdown,
0169 .driver = {
0170 .name = "sprd-drm-drv",
0171 .of_match_table = drm_match_table,
0172 },
0173 };
0174
0175 static struct platform_driver *sprd_drm_drivers[] = {
0176 &sprd_drm_driver,
0177 &sprd_dpu_driver,
0178 &sprd_dsi_driver,
0179 };
0180
0181 static int __init sprd_drm_init(void)
0182 {
0183 if (drm_firmware_drivers_only())
0184 return -ENODEV;
0185
0186 return platform_register_drivers(sprd_drm_drivers,
0187 ARRAY_SIZE(sprd_drm_drivers));
0188 }
0189
0190 static void __exit sprd_drm_exit(void)
0191 {
0192 platform_unregister_drivers(sprd_drm_drivers,
0193 ARRAY_SIZE(sprd_drm_drivers));
0194 }
0195
0196 module_init(sprd_drm_init);
0197 module_exit(sprd_drm_exit);
0198
0199 MODULE_AUTHOR("Leon He <leon.he@unisoc.com>");
0200 MODULE_AUTHOR("Kevin Tang <kevin.tang@unisoc.com>");
0201 MODULE_DESCRIPTION("Unisoc DRM KMS Master Driver");
0202 MODULE_LICENSE("GPL v2");