diff options
Diffstat (limited to 'drivers/gpu/drm/mgag200')
-rw-r--r-- | drivers/gpu/drm/mgag200/Kconfig | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_ddc.c | 179 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_ddc.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_drv.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_drv.h | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200eh.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200er.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200ev.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200se.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_g200wb.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_i2c.c | 129 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_mode.c | 35 |
16 files changed, 257 insertions, 250 deletions
diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index 5e4d48df4854..3096944a8f0a 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -12,14 +12,12 @@ config DRM_MGAG200 of the modesetting userspace driver, and a version of mga driver that will fail on KMS enabled devices. -config DRM_MGAG200_IOBURST_WORKAROUND - bool "Disable buffer caching" - depends on DRM_MGAG200 && PREEMPT_RT && X86 +config DRM_MGAG200_DISABLE_WRITECOMBINE + bool "Disable Write Combine mapping of VRAM" + depends on DRM_MGAG200 && PREEMPT_RT help - Enable a workaround to avoid I/O bursts within the mgag200 driver at - the expense of overall display performance. - It restores the <v5.10 behavior, by mapping the framebuffer in system - RAM as Write-Combining, and flushing the cache after each write. - This is only useful on x86_64 if you want to run processes with - deterministic latency. - If unsure, say N. + The VRAM of the G200 is mapped with Write-Combine to improve + performances. This can interfere with real-time tasks; even if they + are running on other CPU cores than the graphics output. + Enable this option only if you run realtime tasks on a server with a + Matrox G200.
\ No newline at end of file diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile index 182e224c460d..0b919352046e 100644 --- a/drivers/gpu/drm/mgag200/Makefile +++ b/drivers/gpu/drm/mgag200/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only mgag200-y := \ mgag200_bmc.o \ + mgag200_ddc.o \ mgag200_drv.o \ mgag200_g200.o \ mgag200_g200eh.o \ @@ -10,7 +11,6 @@ mgag200-y := \ mgag200_g200ew3.o \ mgag200_g200se.o \ mgag200_g200wb.o \ - mgag200_i2c.o \ mgag200_mode.o obj-$(CONFIG_DRM_MGAG200) += mgag200.o diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.c b/drivers/gpu/drm/mgag200/mgag200_ddc.c new file mode 100644 index 000000000000..6d81ea8931e8 --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_ddc.c @@ -0,0 +1,179 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + */ +/* + * Authors: Dave Airlie <airlied@redhat.com> + */ + +#include <linux/export.h> +#include <linux/i2c-algo-bit.h> +#include <linux/i2c.h> +#include <linux/pci.h> + +#include <drm/drm_managed.h> + +#include "mgag200_ddc.h" +#include "mgag200_drv.h" + +struct mgag200_ddc { + struct mga_device *mdev; + + int data; + int clock; + + struct i2c_algo_bit_data bit; + struct i2c_adapter adapter; +}; + +static int mga_i2c_read_gpio(struct mga_device *mdev) +{ + WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA); + return RREG8(DAC_DATA); +} + +static void mga_i2c_set_gpio(struct mga_device *mdev, int mask, int val) +{ + int tmp; + + WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL); + tmp = (RREG8(DAC_DATA) & mask) | val; + WREG_DAC(MGA1064_GEN_IO_CTL, tmp); + WREG_DAC(MGA1064_GEN_IO_DATA, 0); +} + +static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state) +{ + if (state) + state = 0; + else + state = mask; + mga_i2c_set_gpio(mdev, ~mask, state); +} + +static void mgag200_ddc_algo_bit_data_setsda(void *data, int state) +{ + struct mgag200_ddc *ddc = data; + + mga_i2c_set(ddc->mdev, ddc->data, state); +} + +static void mgag200_ddc_algo_bit_data_setscl(void *data, int state) +{ + struct mgag200_ddc *ddc = data; + + mga_i2c_set(ddc->mdev, ddc->clock, state); +} + +static int mgag200_ddc_algo_bit_data_getsda(void *data) +{ + struct mgag200_ddc *ddc = data; + + return (mga_i2c_read_gpio(ddc->mdev) & ddc->data) ? 1 : 0; +} + +static int mgag200_ddc_algo_bit_data_getscl(void *data) +{ + struct mgag200_ddc *ddc = data; + + return (mga_i2c_read_gpio(ddc->mdev) & ddc->clock) ? 1 : 0; +} + +static int mgag200_ddc_algo_bit_data_pre_xfer(struct i2c_adapter *adapter) +{ + struct mgag200_ddc *ddc = i2c_get_adapdata(adapter); + struct mga_device *mdev = ddc->mdev; + + /* + * Protect access to I/O registers from concurrent modesetting + * by acquiring the I/O-register lock. + */ + mutex_lock(&mdev->rmmio_lock); + + return 0; +} + +static void mgag200_ddc_algo_bit_data_post_xfer(struct i2c_adapter *adapter) +{ + struct mgag200_ddc *ddc = i2c_get_adapdata(adapter); + struct mga_device *mdev = ddc->mdev; + + mutex_unlock(&mdev->rmmio_lock); +} + +static void mgag200_ddc_release(struct drm_device *dev, void *res) +{ + struct mgag200_ddc *ddc = res; + + i2c_del_adapter(&ddc->adapter); +} + +struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev) +{ + struct drm_device *dev = &mdev->base; + const struct mgag200_device_info *info = mdev->info; + struct mgag200_ddc *ddc; + struct i2c_algo_bit_data *bit; + struct i2c_adapter *adapter; + int ret; + + ddc = drmm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL); + if (!ddc) + return ERR_PTR(-ENOMEM); + + WREG_DAC(MGA1064_GEN_IO_CTL2, 1); + WREG_DAC(MGA1064_GEN_IO_DATA, 0xff); + WREG_DAC(MGA1064_GEN_IO_CTL, 0); + + ddc->mdev = mdev; + ddc->data = BIT(info->i2c.data_bit); + ddc->clock = BIT(info->i2c.clock_bit); + + bit = &ddc->bit; + bit->data = ddc; + bit->setsda = mgag200_ddc_algo_bit_data_setsda; + bit->setscl = mgag200_ddc_algo_bit_data_setscl; + bit->getsda = mgag200_ddc_algo_bit_data_getsda; + bit->getscl = mgag200_ddc_algo_bit_data_getscl; + bit->pre_xfer = mgag200_ddc_algo_bit_data_pre_xfer; + bit->post_xfer = mgag200_ddc_algo_bit_data_post_xfer; + bit->udelay = 10; + bit->timeout = usecs_to_jiffies(2200); + + adapter = &ddc->adapter; + adapter->owner = THIS_MODULE; + adapter->algo_data = bit; + adapter->dev.parent = dev->dev; + snprintf(adapter->name, sizeof(adapter->name), "Matrox DDC bus"); + i2c_set_adapdata(adapter, ddc); + + ret = i2c_bit_add_bus(adapter); + if (ret) + return ERR_PTR(ret); + + ret = drmm_add_action_or_reset(dev, mgag200_ddc_release, ddc); + if (ret) + return ERR_PTR(ret); + + return adapter; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.h b/drivers/gpu/drm/mgag200/mgag200_ddc.h new file mode 100644 index 000000000000..fa21d197cc78 --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_ddc.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __MGAG200_DDC_H__ +#define __MGAG200_DDC_H__ + +struct i2c_adapter; +struct mga_device; + +struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev); + +#endif diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 573dbe256aa8..62080cf0f2da 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -12,7 +12,7 @@ #include <drm/drm_aperture.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fbdev_generic.h> +#include <drm/drm_fbdev_shmem.h> #include <drm/drm_file.h> #include <drm/drm_ioctl.h> #include <drm/drm_managed.h> @@ -84,20 +84,6 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size) return offset - 65536; } -#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND) -static struct drm_gem_object *mgag200_create_object(struct drm_device *dev, size_t size) -{ - struct drm_gem_shmem_object *shmem; - - shmem = kzalloc(sizeof(*shmem), GFP_KERNEL); - if (!shmem) - return NULL; - - shmem->map_wc = true; - return &shmem->base; -} -#endif - /* * DRM driver */ @@ -113,9 +99,6 @@ static const struct drm_driver mgag200_driver = { .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, -#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND) - .gem_create_object = mgag200_create_object, -#endif DRM_GEM_SHMEM_DRIVER_OPS, }; @@ -163,12 +146,18 @@ int mgag200_device_preinit(struct mga_device *mdev) } mdev->vram_res = res; +#if defined(CONFIG_DRM_MGAG200_DISABLE_WRITECOMBINE) + mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res)); + if (!mdev->vram) + return -ENOMEM; +#else mdev->vram = devm_ioremap_wc(dev->dev, res->start, resource_size(res)); if (!mdev->vram) return -ENOMEM; /* Don't fail on errors, but performance might be reduced. */ devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res)); +#endif return 0; } @@ -285,7 +274,7 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * FIXME: A 24-bit color depth does not work with 24 bpp on * G200ER. Force 32 bpp. */ - drm_fbdev_generic_setup(dev, 32); + drm_fbdev_shmem_setup(dev, 32); return 0; } diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 58a0e62eaf18..20e3710e056b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -10,9 +10,6 @@ #ifndef __MGAG200_DRV_H__ #define __MGAG200_DRV_H__ -#include <linux/i2c-algo-bit.h> -#include <linux/i2c.h> - #include <video/vga.h> #include <drm/drm_connector.h> @@ -189,13 +186,6 @@ static inline struct mgag200_crtc_state *to_mgag200_crtc_state(struct drm_crtc_s return container_of(base, struct mgag200_crtc_state, base); } -struct mga_i2c_chan { - struct i2c_adapter adapter; - struct drm_device *dev; - struct i2c_algo_bit_data bit; - int data, clock; -}; - enum mga_type { G200_PCI, G200_AGP, @@ -294,7 +284,6 @@ struct mga_device { struct drm_plane primary_plane; struct drm_crtc crtc; struct drm_encoder encoder; - struct mga_i2c_chan i2c; struct drm_connector connector; }; @@ -431,10 +420,8 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st #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 + .get_modes = drm_connector_helper_get_modes #define MGAG200_VGA_CONNECTOR_FUNCS \ .reset = drm_atomic_helper_connector_reset, \ @@ -453,7 +440,4 @@ int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t vram_avail void mgag200_bmc_disable_vidrst(struct mga_device *mdev); void mgag200_bmc_enable_vidrst(struct mga_device *mdev); - /* mgag200_i2c.c */ -int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c); - #endif /* __MGAG200_DRV_H__ */ diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c index bf5d7fe525a3..39a29d8ffca6 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200.c @@ -9,6 +9,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" static int mgag200_g200_init_pci_options(struct pci_dev *pdev) @@ -201,8 +202,8 @@ static int mgag200_g200_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -238,16 +239,16 @@ static int mgag200_g200_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); 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); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c index fad62453a91d..619fee7ffdf5 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c @@ -9,6 +9,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" void mgag200_g200eh_init_registers(struct mga_device *mdev) @@ -200,8 +201,8 @@ static int mgag200_g200eh_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -237,16 +238,16 @@ static int mgag200_g200eh_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); 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); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c index 0f7d8112cd49..a172b8a4500a 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c @@ -8,6 +8,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" /* @@ -104,8 +105,8 @@ static int mgag200_g200eh3_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -141,16 +142,16 @@ static int mgag200_g200eh3_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); 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); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c index 8d4538b71047..a11c91331e43 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200er.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c @@ -9,6 +9,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" static void mgag200_g200er_init_registers(struct mga_device *mdev) @@ -243,8 +244,8 @@ static int mgag200_g200er_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -280,16 +281,16 @@ static int mgag200_g200er_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); 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); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c index 56e6f986bff3..dfb641b83842 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c @@ -9,6 +9,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" static void mgag200_g200ev_init_registers(struct mga_device *mdev) @@ -244,8 +245,8 @@ static int mgag200_g200ev_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -281,16 +282,16 @@ static int mgag200_g200ev_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); 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); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c index 170934414d7d..525b7f75e622 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c @@ -8,6 +8,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" static void mgag200_g200ew3_init_registers(struct mga_device *mdev) @@ -113,8 +114,8 @@ static int mgag200_g200ew3_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -150,16 +151,16 @@ static int mgag200_g200ew3_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); 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); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c index ff2b3c6622e7..ef7606b529ea 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200se.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c @@ -9,6 +9,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" static int mgag200_g200se_init_pci_options(struct pci_dev *pdev) @@ -375,8 +376,8 @@ static int mgag200_g200se_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -412,16 +413,16 @@ static int mgag200_g200se_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); 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); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c index 9baa727ac6f9..e4def62b1e57 100644 --- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c +++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c @@ -9,6 +9,7 @@ #include <drm/drm_gem_atomic_helper.h> #include <drm/drm_probe_helper.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" void mgag200_g200wb_init_registers(struct mga_device *mdev) @@ -247,8 +248,8 @@ static int mgag200_g200wb_pipeline_init(struct mga_device *mdev) 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; + struct i2c_adapter *ddc; int ret; ret = drm_universal_plane_init(dev, primary_plane, 0, @@ -284,16 +285,16 @@ static int mgag200_g200wb_pipeline_init(struct mga_device *mdev) return ret; } - ret = mgag200_i2c_init(mdev, i2c); - if (ret) { + ddc = mgag200_ddc_create(mdev); + if (IS_ERR(ddc)) { + ret = PTR_ERR(ddc); drm_err(dev, "failed to add DDC bus: %d\n", ret); return ret; } ret = drm_connector_init_with_ddc(dev, connector, &mgag200_g200wb_vga_connector_funcs, - DRM_MODE_CONNECTOR_VGA, - &i2c->adapter); + DRM_MODE_CONNECTOR_VGA, ddc); if (ret) { drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c deleted file mode 100644 index 423eb302be7e..000000000000 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2012 Red Hat Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - */ -/* - * Authors: Dave Airlie <airlied@redhat.com> - */ - -#include <linux/export.h> -#include <linux/i2c-algo-bit.h> -#include <linux/i2c.h> -#include <linux/pci.h> - -#include "mgag200_drv.h" - -static int mga_i2c_read_gpio(struct mga_device *mdev) -{ - WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA); - return RREG8(DAC_DATA); -} - -static void mga_i2c_set_gpio(struct mga_device *mdev, int mask, int val) -{ - int tmp; - - WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL); - tmp = (RREG8(DAC_DATA) & mask) | val; - WREG_DAC(MGA1064_GEN_IO_CTL, tmp); - WREG_DAC(MGA1064_GEN_IO_DATA, 0); -} - -static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state) -{ - if (state) - state = 0; - else - state = mask; - mga_i2c_set_gpio(mdev, ~mask, state); -} - -static void mga_gpio_setsda(void *data, int state) -{ - struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - mga_i2c_set(mdev, i2c->data, state); -} - -static void mga_gpio_setscl(void *data, int state) -{ - struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - mga_i2c_set(mdev, i2c->clock, state); -} - -static int mga_gpio_getsda(void *data) -{ - struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - return (mga_i2c_read_gpio(mdev) & i2c->data) ? 1 : 0; -} - -static int mga_gpio_getscl(void *data) -{ - struct mga_i2c_chan *i2c = data; - struct mga_device *mdev = to_mga_device(i2c->dev); - return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0; -} - -static void mgag200_i2c_release(void *res) -{ - struct mga_i2c_chan *i2c = res; - - i2c_del_adapter(&i2c->adapter); -} - -int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c) -{ - struct drm_device *dev = &mdev->base; - const struct mgag200_device_info *info = mdev->info; - int ret; - - WREG_DAC(MGA1064_GEN_IO_CTL2, 1); - WREG_DAC(MGA1064_GEN_IO_DATA, 0xff); - WREG_DAC(MGA1064_GEN_IO_CTL, 0); - - i2c->data = BIT(info->i2c.data_bit); - i2c->clock = BIT(info->i2c.clock_bit); - i2c->adapter.owner = THIS_MODULE; - i2c->adapter.dev.parent = dev->dev; - i2c->dev = dev; - i2c_set_adapdata(&i2c->adapter, i2c); - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "mga i2c"); - - i2c->adapter.algo_data = &i2c->bit; - - i2c->bit.udelay = 10; - i2c->bit.timeout = 2; - i2c->bit.data = i2c; - i2c->bit.setsda = mga_gpio_setsda; - i2c->bit.setscl = mga_gpio_setscl; - i2c->bit.getsda = mga_gpio_getsda; - i2c->bit.getscl = mga_gpio_getscl; - - ret = i2c_bit_add_bus(&i2c->adapter); - if (ret) - return ret; - - return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c); -} diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index fc54851d3384..bb6204002cb3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -13,7 +13,6 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> -#include <drm/drm_cache.h> #include <drm/drm_damage_helper.h> #include <drm/drm_edid.h> #include <drm/drm_format_helper.h> @@ -24,6 +23,7 @@ #include <drm/drm_panic.h> #include <drm/drm_print.h> +#include "mgag200_ddc.h" #include "mgag200_drv.h" /* @@ -438,13 +438,6 @@ static void mgag200_handle_damage(struct mga_device *mdev, const struct iosys_ma iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip)); drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip); - - /* Flushing the cache greatly improves latency on x86_64 */ -#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND) - if (!vmap->is_iomem) - drm_clflush_virt_range(vmap->vaddr + clip->y1 * fb->pitches[0], - drm_rect_height(clip) * fb->pitches[0]); -#endif } /* @@ -737,32 +730,6 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st } /* - * Connector - */ - -int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector) -{ - struct mga_device *mdev = to_mga_device(connector->dev); - const struct drm_edid *drm_edid; - int count; - - /* - * Protect access to I/O registers from concurrent modesetting - * by acquiring the I/O-register lock. - */ - mutex_lock(&mdev->rmmio_lock); - - drm_edid = drm_edid_read(connector); - drm_edid_connector_update(connector, drm_edid); - count = drm_edid_connector_add_modes(connector); - drm_edid_free(drm_edid); - - mutex_unlock(&mdev->rmmio_lock); - - return count; -} - -/* * Mode config */ |