diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2022-09-06 10:56:03 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2022-09-06 10:56:04 +0200 |
commit | 8284bae723f025cb6a8431566757a3854a3c53eb (patch) | |
tree | 91c86c11413d12add21973c46b0a58f72ad103e0 /drivers/gpu/drm/mgag200/mgag200_g200ew3.c | |
parent | 2c2d7a67defa198a8b8148dbaddc9e5554efebc8 (diff) | |
parent | 8869fa666a9e6782c3c896c1fa57d65adca23249 (diff) |
Merge tag 'drm-misc-next-2022-08-20-1' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.1:
UAPI Changes:
Cross-subsystem Changes:
- DMA-buf: documentation updates.
- Assorted small fixes to vga16fb
- Fix fbdev drivers to use the aperture helpers.
- Make removal of conflicting drivers work correctly without fbdev enabled.
Core Changes:
- bridge, scheduler, dp-mst: Assorted small fixes.
- Add more format helpers to fourcc, and use it to replace the cpp usage.
- Add DRM_FORMAT_Cxx, DRM_FORMAT_Rxx (single channel), and DRM_FORMAT_Dxx
("darkness", inverted single channel)
- Add packed AYUV8888 and XYUV8888 formats.
- Assorted documentation updates.
- Rename ttm_bo_init to ttm_bo_init_validate.
- Allow TTM bo's to exist without backing store.
- Convert drm selftests to kunit.
- Add managed init functions for (panel) bridge, crtc, encoder and connector.
- Fix endianness handling in various format conversion helpers.
- Make tests pass on big-endian platforms, and add test for rgb888 -> rgb565
- Move DRM_PLANE_HELPER_NO_SCALING to atomic helpers and rename, so
drm_plane_helper is no longer needed in most drivers.
- Use idr_init_base instead of idr_init.
- Rename FB and GEM CMA helpers to DMA helpers.
- Rework XRGB8888 related conversion helpers, and add drm_fb_blit() that
takes a iosys_map. Make drm_fb_memcpy take an iosys_map too.
- Move edid luminance calculation to core, and use it in i915.
Driver Changes:
- bridge/{adv7511,ti-sn65dsi86,parade-ps8640}, panel/{simple,nt35510,tc358767},
nouveau, sun4i, mipi-dsi, mgag200, bochs, arm, komeda, vmwgfx, pl111:
Assorted small fixes and doc updates.
- vc4: Rework hdmi power up, and depend on PM.
- panel/simple: Add Samsung LTL101AL01.
- ingenic: Add JZ4760(B) support, avoid a modeset when sharpness property
is unchanged, and use the new PM ops.
- Revert some amdgpu commits that cause garbaged graphics when starting
X, and reapply them with the real problem fixed.
- Completely rework vc4 init to use managed helpers.
- Rename via_drv to via_dri1, and move all stuff there only used by the
dri1 implementation in preperation for atomic modeset.
- Use regmap bulk write in ssd130x.
- Power sequence and clock updates to it6505.
- Split panel-sitrox-st7701 init sequence and rework mode programming code.
- virtio: Improve error and edge conditions handling, and convert to use managed
helpers.
- Add Samsung LTL101AL01, B120XAN01.0, R140NWF5 RH, DMT028VGHMCMI-1A T, panels.
- Add generic fbdev support to komeda.
- Split mgag200 modeset handling to make it more model-specific.
- Convert simpledrm to use atomic helpers.
- Improve udl suspend/disconnect handling.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/f0c71766-61e8-19b7-763a-5fbcdefc633d@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/mgag200/mgag200_g200ew3.c')
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 192 |
1 files changed, 188 insertions, 4 deletions
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c index 3bfc1324cf78..170934414d7d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c @@ -2,10 +2,179 @@ #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" +static void mgag200_g200ew3_init_registers(struct mga_device *mdev) +{ + mgag200_g200wb_init_registers(mdev); // same as G200WB + + WREG_ECRT(0x34, 0x5); // G200EW3 specific +} + +/* + * PIXPLLC + */ + +static int mgag200_g200ew3_pixpllc_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_state *new_state) +{ + static const unsigned int vcomax = 800000; + static const unsigned int vcomin = 400000; + static const unsigned int pllreffreq = 25000; + + struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc); + struct mgag200_crtc_state *new_mgag200_crtc_state = to_mgag200_crtc_state(new_crtc_state); + long clock = new_crtc_state->mode.clock; + struct mgag200_pll_values *pixpllc = &new_mgag200_crtc_state->pixpllc; + unsigned int delta, tmpdelta; + unsigned int testp, testm, testn, testp2; + unsigned int p, m, n, s; + unsigned int computed; + + m = n = p = s = 0; + delta = 0xffffffff; + + for (testp = 1; testp < 8; testp++) { + for (testp2 = 1; testp2 < 8; testp2++) { + if (testp < testp2) + continue; + if ((clock * testp * testp2) > vcomax) + continue; + if ((clock * testp * testp2) < vcomin) + continue; + for (testm = 1; testm < 26; testm++) { + for (testn = 32; testn < 2048 ; testn++) { + computed = (pllreffreq * testn) / (testm * testp * testp2); + if (computed > clock) + tmpdelta = computed - clock; + else + tmpdelta = clock - computed; + if (tmpdelta < delta) { + delta = tmpdelta; + m = testm + 1; + n = testn + 1; + p = testp + 1; + s = testp2; + } + } + } + } + } + + pixpllc->m = m; + pixpllc->n = n; + pixpllc->p = p; + pixpllc->s = s; + + return 0; +} + +/* + * 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 */ @@ -13,6 +182,13 @@ static const struct mgag200_device_info mgag200_g200ew3_device_info = MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, true, 0, 1, false); +static const struct mgag200_device_funcs mgag200_g200ew3_device_funcs = { + .disable_vidrst = mgag200_bmc_disable_vidrst, + .enable_vidrst = mgag200_bmc_enable_vidrst, + .pixpllc_atomic_check = mgag200_g200ew3_pixpllc_atomic_check, + .pixpllc_atomic_update = mgag200_g200wb_pixpllc_atomic_update, // same as G200WB +}; + static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev) { resource_size_t vram_size = resource_size(mdev->vram_res); @@ -23,8 +199,7 @@ static resource_size_t mgag200_g200ew3_device_probe_vram(struct mga_device *mdev } struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, - const struct drm_driver *drv, - enum mga_type type) + const struct drm_driver *drv) { struct mga_device *mdev; struct drm_device *dev; @@ -46,15 +221,24 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, if (ret) return ERR_PTR(ret); - ret = mgag200_device_init(mdev, type, &mgag200_g200ew3_device_info); + ret = mgag200_device_init(mdev, &mgag200_g200ew3_device_info, + &mgag200_g200ew3_device_funcs); if (ret) return ERR_PTR(ret); + mgag200_g200ew3_init_registers(mdev); + 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; } |