diff options
Diffstat (limited to 'drivers/gpu/drm/mgag200/mgag200_g200se.c')
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200se.c | 111 |
1 files changed, 110 insertions, 1 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c index ca9ea26219ca..a28f5203a95a 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200se.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c @@ -4,7 +4,10 @@ #include <linux/pci.h> #include <drm/drm_atomic.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> +#include <drm/drm_gem_atomic_helper.h> +#include <drm/drm_probe_helper.h> #include "mgag200_drv.h" @@ -251,6 +254,106 @@ static void mgag200_g200se_04_pixpllc_atomic_update(struct drm_crtc *crtc, } /* + * Mode-setting pipeline + */ + +static const struct drm_plane_helper_funcs mgag200_g200se_primary_plane_helper_funcs = { + MGAG200_PRIMARY_PLANE_HELPER_FUNCS, +}; + +static const struct drm_plane_funcs mgag200_g200se_primary_plane_funcs = { + MGAG200_PRIMARY_PLANE_FUNCS, +}; + +static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { + MGAG200_CRTC_HELPER_FUNCS, +}; + +static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = { + MGAG200_CRTC_FUNCS, +}; + +static const struct drm_encoder_funcs mgag200_g200se_dac_encoder_funcs = { + MGAG200_DAC_ENCODER_FUNCS, +}; + +static const struct drm_connector_helper_funcs mgag200_g200se_vga_connector_helper_funcs = { + MGAG200_VGA_CONNECTOR_HELPER_FUNCS, +}; + +static const struct drm_connector_funcs mgag200_g200se_vga_connector_funcs = { + MGAG200_VGA_CONNECTOR_FUNCS, +}; + +static int mgag200_g200se_pipeline_init(struct mga_device *mdev) +{ + struct drm_device *dev = &mdev->base; + struct drm_plane *primary_plane = &mdev->primary_plane; + struct drm_crtc *crtc = &mdev->crtc; + struct drm_encoder *encoder = &mdev->encoder; + struct mga_i2c_chan *i2c = &mdev->i2c; + struct drm_connector *connector = &mdev->connector; + int ret; + + ret = drm_universal_plane_init(dev, primary_plane, 0, + &mgag200_g200se_primary_plane_funcs, + mgag200_primary_plane_formats, + mgag200_primary_plane_formats_size, + mgag200_primary_plane_fmtmods, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) { + drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret); + return ret; + } + drm_plane_helper_add(primary_plane, &mgag200_g200se_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &mgag200_g200se_crtc_funcs, NULL); + if (ret) { + drm_err(dev, "drm_crtc_init_with_planes() failed: %d\n", ret); + return ret; + } + drm_crtc_helper_add(crtc, &mgag200_g200se_crtc_helper_funcs); + + /* FIXME: legacy gamma tables, but atomic gamma doesn't work without */ + drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE); + drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE); + + encoder->possible_crtcs = drm_crtc_mask(crtc); + ret = drm_encoder_init(dev, encoder, &mgag200_g200se_dac_encoder_funcs, + DRM_MODE_ENCODER_DAC, NULL); + if (ret) { + drm_err(dev, "drm_encoder_init() failed: %d\n", ret); + return ret; + } + + ret = mgag200_i2c_init(mdev, i2c); + if (ret) { + drm_err(dev, "failed to add DDC bus: %d\n", ret); + return ret; + } + + ret = drm_connector_init_with_ddc(dev, connector, + &mgag200_g200se_vga_connector_funcs, + DRM_MODE_CONNECTOR_VGA, + &i2c->adapter); + if (ret) { + drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); + return ret; + } + drm_connector_helper_add(connector, &mgag200_g200se_vga_connector_helper_funcs); + + ret = drm_connector_attach_encoder(connector, encoder); + if (ret) { + drm_err(dev, "drm_connector_attach_encoder() failed: %d\n", ret); + return ret; + } + + return 0; +} + +/* * DRM device */ @@ -362,9 +465,15 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru vram_available = mgag200_device_probe_vram(mdev); - ret = mgag200_modeset_init(mdev, vram_available); + ret = mgag200_mode_config_init(mdev, vram_available); if (ret) return ERR_PTR(ret); + ret = mgag200_g200se_pipeline_init(mdev); + if (ret) + return ERR_PTR(ret); + + drm_mode_config_reset(dev); + return mdev; } |