#include <linux/of_graph.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_device.h>
#include <drm/drm_modeset_helper.h>
#include "dcss-dev.h"
+#include "dcss-kms.h"
static void dcss_clocks_enable(struct dcss_dev *dcss)
{
int dcss_dev_suspend(struct device *dev)
{
struct dcss_dev *dcss = dcss_drv_dev_to_dcss(dev);
+ struct drm_device *ddev = dcss_drv_dev_to_drm(dev);
+ struct dcss_kms_dev *kms = container_of(ddev, struct dcss_kms_dev, base);
int ret;
- drm_mode_config_helper_suspend(dcss_drv_dev_to_drm(dev));
+ drm_bridge_connector_disable_hpd(kms->connector);
+
+ drm_mode_config_helper_suspend(ddev);
if (pm_runtime_suspended(dev))
return 0;
int dcss_dev_resume(struct device *dev)
{
struct dcss_dev *dcss = dcss_drv_dev_to_dcss(dev);
+ struct drm_device *ddev = dcss_drv_dev_to_drm(dev);
+ struct dcss_kms_dev *kms = container_of(ddev, struct dcss_kms_dev, base);
if (pm_runtime_suspended(dev)) {
- drm_mode_config_helper_resume(dcss_drv_dev_to_drm(dev));
+ drm_mode_config_helper_resume(ddev);
return 0;
}
dcss_ctxld_resume(dcss->ctxld);
- drm_mode_config_helper_resume(dcss_drv_dev_to_drm(dev));
+ drm_mode_config_helper_resume(ddev);
+
+ drm_bridge_connector_enable_hpd(kms->connector);
return 0;
}
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge_connector.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h>
.destroy = drm_encoder_cleanup,
};
-static int dcss_kms_setup_encoder(struct dcss_kms_dev *kms)
+static int dcss_kms_bridge_connector_init(struct dcss_kms_dev *kms)
{
struct drm_device *ddev = &kms->base;
struct drm_encoder *encoder = &kms->encoder;
return ret;
}
- return drm_bridge_attach(encoder, bridge, NULL, 0);
+ ret = drm_bridge_attach(encoder, bridge, NULL,
+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+ if (ret < 0) {
+ dev_err(ddev->dev, "Unable to attach bridge %pOF\n",
+ bridge->of_node);
+ return ret;
+ }
+
+ kms->connector = drm_bridge_connector_init(ddev, encoder);
+ if (IS_ERR(kms->connector)) {
+ dev_err(ddev->dev, "Unable to create bridge connector.\n");
+ return PTR_ERR(kms->connector);
+ }
+
+ drm_connector_attach_encoder(kms->connector, encoder);
+
+ return 0;
}
struct dcss_kms_dev *dcss_kms_attach(struct dcss_dev *dcss)
drm->irq_enabled = true;
- ret = dcss_crtc_init(crtc, drm);
+ ret = dcss_kms_bridge_connector_init(kms);
if (ret)
goto cleanup_mode_config;
- ret = dcss_kms_setup_encoder(kms);
+ ret = dcss_crtc_init(crtc, drm);
if (ret)
- goto cleanup_crtc;
+ goto cleanup_mode_config;
drm_mode_config_reset(drm);
drm_kms_helper_poll_init(drm);
+ drm_bridge_connector_enable_hpd(kms->connector);
+
ret = drm_dev_register(drm, 0);
if (ret)
goto cleanup_crtc;
return kms;
cleanup_crtc:
+ drm_bridge_connector_disable_hpd(kms->connector);
drm_kms_helper_poll_fini(drm);
dcss_crtc_deinit(crtc, drm);
struct drm_device *drm = &kms->base;
drm_dev_unregister(drm);
+ drm_bridge_connector_disable_hpd(kms->connector);
drm_kms_helper_poll_fini(drm);
drm_atomic_helper_shutdown(drm);
drm_crtc_vblank_off(&kms->crtc.base);