]> git.ipfire.org Git - thirdparty/linux.git/blobdiff - drivers/gpu/drm/meson/meson_drv.c
Merge tag 'drm-next-2020-06-02' of git://anongit.freedesktop.org/drm/drm
[thirdparty/linux.git] / drivers / gpu / drm / meson / meson_drv.c
index 8c2e1b47e81a59c582b4556ed7cde3f7c4df2452..4c5aafcec7991bec654f03145f05a60c13db51c7 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/component.h>
 #include <linux/module.h>
 #include <linux/of_graph.h>
+#include <linux/sys_soc.h>
 #include <linux/platform_device.h>
 #include <linux/soc/amlogic/meson-canvas.h>
 
@@ -183,6 +184,24 @@ static void meson_remove_framebuffers(void)
        kfree(ap);
 }
 
+struct meson_drm_soc_attr {
+       struct meson_drm_soc_limits limits;
+       const struct soc_device_attribute *attrs;
+};
+
+static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = {
+       /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */
+       {
+               .limits = {
+                       .max_hdmi_phy_freq = 1650000,
+               },
+               .attrs = (const struct soc_device_attribute []) {
+                       { .soc_id = "GXL (S805*)", },
+                       { /* sentinel */ },
+               }
+       },
+};
+
 static int meson_drv_bind_master(struct device *dev, bool has_components)
 {
        struct platform_device *pdev = to_platform_device(dev);
@@ -191,7 +210,7 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
        struct drm_device *drm;
        struct resource *res;
        void __iomem *regs;
-       int ret;
+       int ret, i;
 
        /* Checks if an output connector is available */
        if (!meson_vpu_has_available_connectors(dev)) {
@@ -281,10 +300,20 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
        if (ret)
                goto free_drm;
 
+       /* Assign limits per soc revision/package */
+       for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) {
+               if (soc_device_match(meson_drm_soc_attrs[i].attrs)) {
+                       priv->limits = &meson_drm_soc_attrs[i].limits;
+                       break;
+               }
+       }
+
        /* Remove early framebuffers (ie. simplefb) */
        meson_remove_framebuffers();
 
-       drm_mode_config_init(drm);
+       ret = drmm_mode_config_init(drm);
+       if (ret)
+               goto free_drm;
        drm->mode_config.max_width = 3840;
        drm->mode_config.max_height = 2160;
        drm->mode_config.funcs = &meson_mode_config_funcs;
@@ -379,7 +408,6 @@ static void meson_drv_unbind(struct device *dev)
        drm_dev_unregister(drm);
        drm_irq_uninstall(drm);
        drm_kms_helper_poll_fini(drm);
-       drm_mode_config_cleanup(drm);
        drm_dev_put(drm);
 }