diff options
| author | Thomas Zimmermann <tzimmermann@suse.de> | 2022-07-28 14:41:01 +0200 |
|---|---|---|
| committer | Thomas Zimmermann <tzimmermann@suse.de> | 2022-07-29 16:01:47 +0200 |
| commit | bc8350409ca5147d432f869209ee13fa079625df (patch) | |
| tree | 3e8ce2984180d55f31058fc0ca2c3e35faf96c3f /drivers | |
| parent | 877507bb954e7d0a4f2d3ba9957127a83c03e447 (diff) | |
| download | linux-bc8350409ca5147d432f869209ee13fa079625df.tar.gz linux-bc8350409ca5147d432f869209ee13fa079625df.tar.bz2 linux-bc8350409ca5147d432f869209ee13fa079625df.zip | |
drm/mgag200: Move mode-config to model-specific code
Move the mode-config code into model-specific code and call the
plane/CRTC helpers as needed. This will help with providing per-
model implementations of individual helpers.
Duplication of the pipeline init function is accepted. Some macros
simplify this for shared helpers.
v3:
* clean up style
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Tested-by: Jocelyn Falempe <jfalempe@redhat.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220728124103.30159-13-tzimmermann@suse.de
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_drv.h | 78 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200eh.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200er.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200ev.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200se.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200wb.c | 111 | ||||
| -rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_mode.c | 185 |
10 files changed, 977 insertions, 174 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index cc14028df395..1e7de8b12e75 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -152,6 +152,8 @@ /* 0x40: */ 0, 0, 0, 0, 0, 0, 0, 0, \ /* 0x48: */ 0, 0, 0, 0, 0, 0, 0, 0 \ +#define MGAG200_LUT_SIZE 256 + #define MGAG200_MAX_FB_HEIGHT 4096 #define MGAG200_MAX_FB_WIDTH 4096 @@ -363,10 +365,82 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, const struct drm_driver *drv, enum mga_type type); - /* mgag200_mode.c */ +/* + * mgag200_mode.c + */ + +struct drm_crtc; +struct drm_crtc_state; +struct drm_display_mode; +struct drm_plane; +struct drm_atomic_state; + +extern const uint32_t mgag200_primary_plane_formats[]; +extern const size_t mgag200_primary_plane_formats_size; +extern const uint64_t mgag200_primary_plane_fmtmods[]; + +int mgag200_primary_plane_helper_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *new_state); +void mgag200_primary_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *old_state); +void mgag200_primary_plane_helper_atomic_disable(struct drm_plane *plane, + struct drm_atomic_state *old_state); +#define MGAG200_PRIMARY_PLANE_HELPER_FUNCS \ + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, \ + .atomic_check = mgag200_primary_plane_helper_atomic_check, \ + .atomic_update = mgag200_primary_plane_helper_atomic_update, \ + .atomic_disable = mgag200_primary_plane_helper_atomic_disable + +#define MGAG200_PRIMARY_PLANE_FUNCS \ + .update_plane = drm_atomic_helper_update_plane, \ + .disable_plane = drm_atomic_helper_disable_plane, \ + .destroy = drm_plane_cleanup, \ + DRM_GEM_SHADOW_PLANE_FUNCS + +enum drm_mode_status mgag200_crtc_helper_mode_valid(struct drm_crtc *crtc, + const struct drm_display_mode *mode); +int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *new_state); +void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state); +void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); +void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); + +#define MGAG200_CRTC_HELPER_FUNCS \ + .mode_valid = mgag200_crtc_helper_mode_valid, \ + .atomic_check = mgag200_crtc_helper_atomic_check, \ + .atomic_flush = mgag200_crtc_helper_atomic_flush, \ + .atomic_enable = mgag200_crtc_helper_atomic_enable, \ + .atomic_disable = mgag200_crtc_helper_atomic_disable + +void mgag200_crtc_reset(struct drm_crtc *crtc); +struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc); +void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); + +#define MGAG200_CRTC_FUNCS \ + .reset = mgag200_crtc_reset, \ + .destroy = drm_crtc_cleanup, \ + .set_config = drm_atomic_helper_set_config, \ + .page_flip = drm_atomic_helper_page_flip, \ + .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ + .atomic_destroy_state = mgag200_crtc_atomic_destroy_state + +#define MGAG200_DAC_ENCODER_FUNCS \ + .destroy = drm_encoder_cleanup + +int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector); + +#define MGAG200_VGA_CONNECTOR_HELPER_FUNCS \ + .get_modes = mgag200_vga_connector_helper_get_modes + +#define MGAG200_VGA_CONNECTOR_FUNCS \ + .reset = drm_atomic_helper_connector_reset, \ + .fill_modes = drm_helper_probe_single_connector_modes, \ + .destroy = drm_connector_cleanup, \ + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \ + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state + resource_size_t mgag200_device_probe_vram(struct mga_device *mdev); void mgag200_init_registers(struct mga_device *mdev); -int mgag200_modeset_init(struct mga_device *mdev, resource_size_t vram_fb_available); +int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_available); /* mgag200_bmc.c */ void mgag200_bmc_disable_vidrst(struct mga_device *mdev); diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c index ae1669d208f8..dffcfa83ae74 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200.c @@ -4,7 +4,10 @@ #include <linux/vmalloc.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" @@ -161,6 +164,106 @@ static void mgag200_g200_pixpllc_atomic_update(struct drm_crtc *crtc, } /* + * Mode-setting pipeline + */ + +static const struct drm_plane_helper_funcs mgag200_g200_primary_plane_helper_funcs = { + MGAG200_PRIMARY_PLANE_HELPER_FUNCS, +}; + +static const struct drm_plane_funcs mgag200_g200_primary_plane_funcs = { + MGAG200_PRIMARY_PLANE_FUNCS, +}; + +static const struct drm_crtc_helper_funcs mgag200_g200_crtc_helper_funcs = { + MGAG200_CRTC_HELPER_FUNCS, +}; + +static const struct drm_crtc_funcs mgag200_g200_crtc_funcs = { + MGAG200_CRTC_FUNCS, +}; + +static const struct drm_encoder_funcs mgag200_g200_dac_encoder_funcs = { + MGAG200_DAC_ENCODER_FUNCS, +}; + +static const struct drm_connector_helper_funcs mgag200_g200_vga_connector_helper_funcs = { + MGAG200_VGA_CONNECTOR_HELPER_FUNCS, +}; + +static const struct drm_connector_funcs mgag200_g200_vga_connector_funcs = { + MGAG200_VGA_CONNECTOR_FUNCS, +}; + +static int mgag200_g200_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_g200_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_g200_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &mgag200_g200_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_g200_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_g200_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_g200_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_g200_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 */ @@ -331,9 +434,15 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct 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_g200_pipeline_init(mdev); + if (ret) + return ERR_PTR(ret); + + drm_mode_config_reset(dev); + return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c index fd44d19c729a..54568d1f603a 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.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" @@ -160,6 +163,106 @@ void mgag200_g200eh_pixpllc_atomic_update(struct drm_crtc *crtc, } /* + * Mode-setting pipeline + */ + +static const struct drm_plane_helper_funcs mgag200_g200eh_primary_plane_helper_funcs = { + MGAG200_PRIMARY_PLANE_HELPER_FUNCS, +}; + +static const struct drm_plane_funcs mgag200_g200eh_primary_plane_funcs = { + MGAG200_PRIMARY_PLANE_FUNCS, +}; + +static const struct drm_crtc_helper_funcs mgag200_g200eh_crtc_helper_funcs = { + MGAG200_CRTC_HELPER_FUNCS, +}; + +static const struct drm_crtc_funcs mgag200_g200eh_crtc_funcs = { + MGAG200_CRTC_FUNCS, +}; + +static const struct drm_encoder_funcs mgag200_g200eh_dac_encoder_funcs = { + MGAG200_DAC_ENCODER_FUNCS, +}; + +static const struct drm_connector_helper_funcs mgag200_g200eh_vga_connector_helper_funcs = { + MGAG200_VGA_CONNECTOR_HELPER_FUNCS, +}; + +static const struct drm_connector_funcs mgag200_g200eh_vga_connector_funcs = { + MGAG200_VGA_CONNECTOR_FUNCS, +}; + +static int mgag200_g200eh_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_g200eh_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_g200eh_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &mgag200_g200eh_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_g200eh_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_g200eh_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_g200eh_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_g200eh_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 */ @@ -203,9 +306,15 @@ struct mga_device *mgag200_g200eh_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_g200eh_pipeline_init(mdev); + if (ret) + return ERR_PTR(ret); + + drm_mode_config_reset(dev); + return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c index b47b100d219d..3e2929fd6145 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c @@ -3,7 +3,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" @@ -64,6 +67,106 @@ static int mgag200_g200eh3_pixpllc_atomic_check(struct drm_crtc *crtc, } /* + * Mode-setting pipeline + */ + +static const struct drm_plane_helper_funcs mgag200_g200eh3_primary_plane_helper_funcs = { + MGAG200_PRIMARY_PLANE_HELPER_FUNCS, +}; + +static const struct drm_plane_funcs mgag200_g200eh3_primary_plane_funcs = { + MGAG200_PRIMARY_PLANE_FUNCS, +}; + +static const struct drm_crtc_helper_funcs mgag200_g200eh3_crtc_helper_funcs = { + MGAG200_CRTC_HELPER_FUNCS, +}; + +static const struct drm_crtc_funcs mgag200_g200eh3_crtc_funcs = { + MGAG200_CRTC_FUNCS, +}; + +static const struct drm_encoder_funcs mgag200_g200eh3_dac_encoder_funcs = { + MGAG200_DAC_ENCODER_FUNCS, +}; + +static const struct drm_connector_helper_funcs mgag200_g200eh3_vga_connector_helper_funcs = { + MGAG200_VGA_CONNECTOR_HELPER_FUNCS, +}; + +static const struct drm_connector_funcs mgag200_g200eh3_vga_connector_funcs = { + MGAG200_VGA_CONNECTOR_FUNCS, +}; + +static int mgag200_g200eh3_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_g200eh3_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_g200eh3_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &mgag200_g200eh3_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_g200eh3_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_g200eh3_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_g200eh3_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_g200eh3_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 */ @@ -108,9 +211,15 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, 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_g200eh3_pipeline_init(mdev); + if (ret) + return ERR_PTR(ret); + + drm_mode_config_reset(dev); + return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c index 8a85fd034e3d..399f2443cb47 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200er.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200er.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" @@ -150,6 +153,106 @@ static void mgag200_g200er_pixpllc_atomic_update(struct drm_crtc *crtc, } /* + * Mode-setting pipeline + */ + +static const struct drm_plane_helper_funcs mgag200_g200er_primary_plane_helper_funcs = { + MGAG200_PRIMARY_PLANE_HELPER_FUNCS, +}; + +static const struct drm_plane_funcs mgag200_g200er_primary_plane_funcs = { + MGAG200_PRIMARY_PLANE_FUNCS, +}; + +static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = { + MGAG200_CRTC_HELPER_FUNCS, +}; + +static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = { + MGAG200_CRTC_FUNCS, +}; + +static const struct drm_encoder_funcs mgag200_g200er_dac_encoder_funcs = { + MGAG200_DAC_ENCODER_FUNCS, +}; + +static const struct drm_connector_helper_funcs mgag200_g200er_vga_connector_helper_funcs = { + MGAG200_VGA_CONNECTOR_HELPER_FUNCS, +}; + +static const struct drm_connector_funcs mgag200_g200er_vga_connector_funcs = { + MGAG200_VGA_CONNECTOR_FUNCS, +}; + +static int mgag200_g200er_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_g200er_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_g200er_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &mgag200_g200er_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_g200er_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_g200er_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_g200er_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_g200er_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 */ @@ -189,9 +292,15 @@ struct mga_device *mgag200_g200er_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_g200er_pipeline_init(mdev); + if (ret) + return ERR_PTR(ret); + + drm_mode_config_reset(dev); + return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c index 54c80562900d..2165ec7d63e8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.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" @@ -162,6 +165,106 @@ static void mgag200_g200ev_pixpllc_atomic_update(struct drm_crtc *crtc, } /* + * Mode-setting pipeline + */ + +static const struct drm_plane_helper_funcs mgag200_g200ev_primary_plane_helper_funcs = { + MGAG200_PRIMARY_PLANE_HELPER_FUNCS, +}; + +static const struct drm_plane_funcs mgag200_g200ev_primary_plane_funcs = { + MGAG200_PRIMARY_PLANE_FUNCS, +}; + +static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = { + MGAG200_CRTC_HELPER_FUNCS, +}; + +static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = { + MGAG200_CRTC_FUNCS, +}; + +static const struct drm_encoder_funcs mgag200_g200ev_dac_encoder_funcs = { + MGAG200_DAC_ENCODER_FUNCS, +}; + +static const struct drm_connector_helper_funcs mgag200_g200ev_vga_connector_helper_funcs = { + MGAG200_VGA_CONNECTOR_HELPER_FUNCS, +}; + +static const struct drm_connector_funcs mgag200_g200ev_vga_connector_funcs = { + MGAG200_VGA_CONNECTOR_FUNCS, +}; + +static int mgag200_g200ev_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_g200ev_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_g200ev_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &mgag200_g200ev_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_g200ev_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_g200ev_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_g200ev_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_g200ev_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 */ @@ -205,9 +308,15 @@ struct mga_device *mgag200_g200ev_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_g200ev_pipeline_init(mdev); + if (ret) + return ERR_PTR(ret); + + drm_mode_config_reset(dev); + return mdev; } diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c index 29aa8a3d4522..25b7bce31e0b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c @@ -3,7 +3,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" @@ -73,6 +76,106 @@ static int mgag200_g200ew3_pixpllc_atomic_check(struct drm_crtc *crtc, } /* + * Mode-setting pipeline + */ + +static const struct drm_plane_helper_funcs mgag200_g200ew3_primary_plane_helper_funcs = { + MGAG200_PRIMARY_PLANE_HELPER_FUNCS, +}; + +static const struct drm_plane_funcs mgag200_g200ew3_primary_plane_funcs = { + MGAG200_PRIMARY_PLANE_FUNCS, +}; + +static const struct drm_crtc_helper_funcs mgag200_g200ew3_crtc_helper_funcs = { + MGAG200_CRTC_HELPER_FUNCS, +}; + +static const struct drm_crtc_funcs mgag200_g200ew3_crtc_funcs = { + MGAG200_CRTC_FUNCS, +}; + +static const struct drm_encoder_funcs mgag200_g200ew3_dac_encoder_funcs = { + MGAG200_DAC_ENCODER_FUNCS, +}; + +static const struct drm_connector_helper_funcs mgag200_g200ew3_vga_connector_helper_funcs = { + MGAG200_VGA_CONNECTOR_HELPER_FUNCS, +}; + +static const struct drm_connector_funcs mgag200_g200ew3_vga_connector_funcs = { + MGAG200_VGA_CONNECTOR_FUNCS, +}; + +static int mgag200_g200ew3_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_g200ew3_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_g200ew3_primary_plane_helper_funcs); + drm_plane_enable_fb_damage_clips(primary_plane); + + ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, + &mgag200_g200ew3_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_g200ew3_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_g200ew3_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_g200ew3_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_g200ew3_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 */ @@ -128,9 +231,15 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, vram_available = mgag200_g200ew3_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_g200ew3_pipeline_init(mdev); + if (ret) + return ERR_PTR(ret); + + drm_mode_config_reset(dev); + return mdev; } 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, +}; |
