drivers/gpu/drm/via/via_dac.c | 72 +++++++++++++++++++++++++++++++++++++- drivers/gpu/drm/via/via_display.c | 71 ------------------------------------- drivers/gpu/drm/via/via_drv.c | 9 +--- drivers/gpu/drm/via/via_drv.h | 6 +-- drivers/gpu/drm/via/via_ioctl.c | 4 -- drivers/gpu/drm/via/via_lvds.c | 58 ++++++++++++++++++++++++++++++ drivers/gpu/drm/via/via_object.c | 15 +++---- drivers/gpu/drm/via/via_tmds.c | 53 +++++++++++++++++++++++++++ 8 files changed, 193 insertions(+), 95 deletions(-)
New commits: commit 53ebc0e97c37088271a608bdacc5e184cfecb8d2 Author: Kevin Brace <kevinbr...@bracecomputerlab.com> Date: Mon Jun 20 11:45:12 2022 -0500 drm/via: Version bumped to 3.5.2 Signed-off-by: Kevin Brace <kevinbr...@bracecomputerlab.com> diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index b077e786d8bd..330ab8905417 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h @@ -50,10 +50,10 @@ #define DRIVER_MAJOR 3 #define DRIVER_MINOR 5 -#define DRIVER_PATCHLEVEL 1 +#define DRIVER_PATCHLEVEL 2 #define DRIVER_NAME "via" #define DRIVER_DESC "OpenChrome DRM for VIA Technologies Chrome IGP" -#define DRIVER_DATE "20220618" +#define DRIVER_DATE "20220620" #define DRIVER_AUTHOR "OpenChrome Project" commit 79eda72f3642ef2f3dc65bb67f5bdb175d495fad Author: Kevin Brace <kevinbr...@bracecomputerlab.com> Date: Mon Jun 20 11:35:44 2022 -0500 drm/via: Miscellaneous cleanups related to via_bo_create() Signed-off-by: Kevin Brace <kevinbr...@bracecomputerlab.com> diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index b38b92dda18a..25d7967c938b 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c @@ -103,13 +103,8 @@ static int via_driver_dumb_create(struct drm_file *file_priv, pitch = args->width * ((args->bpp + 7) >> 3); size = pitch * args->height; - ret = via_bo_create(dev, - &dev_priv->bdev, - size, - ttm_bo_type_device, - TTM_PL_VRAM, - false, - &bo); + ret = via_bo_create(dev, &dev_priv->bdev, size, + ttm_bo_type_device, TTM_PL_VRAM, false, &bo); if (ret) { goto exit; } diff --git a/drivers/gpu/drm/via/via_ioctl.c b/drivers/gpu/drm/via/via_ioctl.c index 6910b4aa6ef4..24d72bf4d53a 100644 --- a/drivers/gpu/drm/via/via_ioctl.c +++ b/drivers/gpu/drm/via/via_ioctl.c @@ -48,9 +48,7 @@ static int via_gem_create_ioctl(struct drm_device *dev, DRM_DEBUG_KMS("Entered %s.\n", __func__); ret = via_bo_create(dev, &dev_priv->bdev, args->size, - ttm_bo_type_device, args->domain, false, - &bo); - + ttm_bo_type_device, args->domain, false, &bo); if (ret) { goto exit; } diff --git a/drivers/gpu/drm/via/via_object.c b/drivers/gpu/drm/via/via_object.c index 0f96df8da786..96fb2934d0de 100644 --- a/drivers/gpu/drm/via/via_object.c +++ b/drivers/gpu/drm/via/via_object.c @@ -166,12 +166,12 @@ void via_bo_unpin(struct via_bo *bo) } int via_bo_create(struct drm_device *dev, - struct ttm_device *bdev, - uint64_t size, - enum ttm_bo_type type, - uint32_t ttm_domain, - bool kmap, - struct via_bo **bo_ptr) + struct ttm_device *bdev, + uint64_t size, + enum ttm_bo_type type, + uint32_t ttm_domain, + bool kmap, + struct via_bo **bo_ptr) { struct ttm_buffer_object *ttm_bo; struct via_drm_priv *dev_priv = to_via_drm_priv(dev); @@ -180,7 +180,6 @@ int via_bo_create(struct drm_device *dev, DRM_DEBUG_KMS("Entered %s.\n", __func__); -// bo = kzalloc(sizeof(struct via_bo), GFP_KERNEL); bo = kzalloc(sizeof(*bo), GFP_KERNEL); if (!bo) { DRM_ERROR("Cannot allocate a TTM buffer object.\n"); @@ -191,7 +190,7 @@ int via_bo_create(struct drm_device *dev, ttm_bo = &bo->ttm_bo; /* - * It is imperative to page align the requested buffer size + * It is an imperative to page align the requested buffer size * prior to a memory allocation request, or various memory * allocation related system instabilities may occur. */ commit eae4afc1d49a13231e77f0f5c121cb8bcc91bc3f Author: Kevin Brace <kevinbr...@bracecomputerlab.com> Date: Mon Jun 20 11:35:41 2022 -0500 drm/via: Delete via_connector_mode_valid() No one is using it anymore. Retiring legacy code. Signed-off-by: Kevin Brace <kevinbr...@bracecomputerlab.com> diff --git a/drivers/gpu/drm/via/via_display.c b/drivers/gpu/drm/via/via_display.c index a98c6d53189b..2f82764038c0 100644 --- a/drivers/gpu/drm/via/via_display.c +++ b/drivers/gpu/drm/via/via_display.c @@ -42,19 +42,6 @@ void via_encoder_cleanup(struct drm_encoder *encoder) kfree(enc); } -int via_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - /* Check Clock Range */ - if (mode->clock > 400000) - return MODE_CLOCK_HIGH; - - if (mode->clock < 25000) - return MODE_CLOCK_LOW; - - return MODE_OK; -} - void via_connector_destroy(struct drm_connector *connector) { struct via_connector *con = container_of(connector, struct via_connector, base); diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h index 8993844d6b74..b077e786d8bd 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h @@ -417,8 +417,6 @@ int via_crtc_init(struct via_drm_priv *dev_priv, uint32_t index); void via_encoder_cleanup(struct drm_encoder *encoder); /* connectors */ -int via_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode); void via_connector_destroy(struct drm_connector *connector); void via_dac_probe(struct drm_device *dev); commit 1aef9f9522a998593b67af3143ecb32b2a039d95 Author: Kevin Brace <kevinbr...@bracecomputerlab.com> Date: Mon Jun 20 11:35:39 2022 -0500 drm/via: Check DVI speed limit before allowing a given DVI dot clock I believe single channel DVI is limited to 165 MHz by its specification, so check for that before allowing a given DVI dot clock. This only affects CX700(M/M2) / VX700(M/M2) / VX800 chipsets since only these models have the support for the compatible integrated TMDS transmitter. Signed-off-by: Kevin Brace <kevinbr...@bracecomputerlab.com> diff --git a/drivers/gpu/drm/via/via_tmds.c b/drivers/gpu/drm/via/via_tmds.c index 11c29c69239e..5404fc7f8b64 100644 --- a/drivers/gpu/drm/via/via_tmds.c +++ b/drivers/gpu/drm/via/via_tmds.c @@ -357,6 +357,57 @@ static const struct drm_connector_funcs via_dvi_connector_funcs = { drm_atomic_helper_connector_destroy_state, }; +static enum drm_mode_status via_tmds_mode_valid( + struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct drm_device *dev = connector->dev; + struct pci_dev *pdev = to_pci_dev(dev->dev); + int min_clock, max_clock; + enum drm_mode_status status = MODE_OK; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + min_clock = 25000; + switch (pdev->device) { + /* CX700(M/M2) / VX700(M/M2) Chipset */ + case PCI_DEVICE_ID_VIA_VT3157: + /* VX800 / VX820 Chipset */ + case PCI_DEVICE_ID_VIA_VT1122: + max_clock = 165000; + break; + /* Illegal condition (should never get here) */ + default: + max_clock = 0; + break; + } + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) { + status = MODE_NO_INTERLACE; + goto exit; + } + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { + status = MODE_NO_DBLESCAN; + goto exit; + } + + if (mode->clock < min_clock) { + status = MODE_CLOCK_LOW; + goto exit; + } + + if (mode->clock > max_clock) { + status = MODE_CLOCK_HIGH; + goto exit; + } + +exit: + DRM_DEBUG_KMS("status: %u\n", status); + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return status; +} + static int via_tmds_get_modes(struct drm_connector *connector) { struct via_connector *con = container_of(connector, struct via_connector, base); @@ -392,7 +443,7 @@ static int via_tmds_get_modes(struct drm_connector *connector) static const struct drm_connector_helper_funcs via_dvi_connector_helper_funcs = { - .mode_valid = via_connector_mode_valid, + .mode_valid = via_tmds_mode_valid, .get_modes = via_tmds_get_modes, }; commit 0029941c178dd4951076b756b8e4b0aa6c4c9c13 Author: Kevin Brace <kevinbr...@bracecomputerlab.com> Date: Mon Jun 20 11:35:37 2022 -0500 drm/via: Check DAC speed limit before allowing a given VGA dot clock The DAC speed depends on hardware generation, so check its DAC speed limit before allowing a given VGA dot clock. Signed-off-by: Kevin Brace <kevinbr...@bracecomputerlab.com> diff --git a/drivers/gpu/drm/via/via_dac.c b/drivers/gpu/drm/via/via_dac.c index 32184e6a01f3..4921c93d1089 100644 --- a/drivers/gpu/drm/via/via_dac.c +++ b/drivers/gpu/drm/via/via_dac.c @@ -283,6 +283,76 @@ static const struct drm_connector_funcs via_dac_connector_funcs = { drm_atomic_helper_connector_destroy_state, }; +static enum drm_mode_status via_dac_mode_valid( + struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct drm_device *dev = connector->dev; + struct pci_dev *pdev = to_pci_dev(dev->dev); + int min_clock, max_clock; + enum drm_mode_status status = MODE_OK; + + DRM_DEBUG_KMS("Entered %s.\n", __func__); + + min_clock = 25000; + switch (pdev->device) { + /* CLE266 Chipset */ + case PCI_DEVICE_ID_VIA_CLE266: + /* KM400(A) / KN400(A) / P4M800 Chipset */ + case PCI_DEVICE_ID_VIA_KM400: + max_clock = 250000; + break; + /* K8M800(A) / K8N800(A) Chipset */ + case PCI_DEVICE_ID_VIA_K8M800: + /* P4M800 Pro / P4M800CE / VN800 / CN700 / CN333 / CN400 Chipset */ + case PCI_DEVICE_ID_VIA_CN700: + max_clock = 300000; + break; + /* PM800 / PN800 / PM880 / PN880 Chipset */ + case PCI_DEVICE_ID_VIA_PM800: + /* P4M890 / P4N890 Chipset */ + case PCI_DEVICE_ID_VIA_VT3343: + /* K8M890 / K8N890 Chipset */ + case PCI_DEVICE_ID_VIA_K8M890: + /* P4M900 / VN896 / CN896 Chipset */ + case PCI_DEVICE_ID_VIA_P4M900: + /* CX700(M/M2) / VX700(M/M2) Chipset */ + case PCI_DEVICE_ID_VIA_VT3157: + /* VX800 / VX820 Chipset */ + case PCI_DEVICE_ID_VIA_VT1122: + /* VX855 / VX875 Chipset */ + case PCI_DEVICE_ID_VIA_VX875: + /* VX900(H) Chipset */ + case PCI_DEVICE_ID_VIA_VX900_VGA: + max_clock = 350000; + break; + /* Illegal condition (should never get here) */ + default: + max_clock = 0; + break; + } + + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { + status = MODE_NO_DBLESCAN; + goto exit; + } + + if (mode->clock < min_clock) { + status = MODE_CLOCK_LOW; + goto exit; + } + + if (mode->clock > max_clock) { + status = MODE_CLOCK_HIGH; + goto exit; + } + +exit: + DRM_DEBUG_KMS("status: %u\n", status); + DRM_DEBUG_KMS("Exiting %s.\n", __func__); + return status; +} + static int via_dac_get_modes(struct drm_connector *connector) { struct via_connector *con = container_of(connector, @@ -340,7 +410,7 @@ exit: static const struct drm_connector_helper_funcs via_dac_connector_helper_funcs = { - .mode_valid = via_connector_mode_valid, + .mode_valid = via_dac_mode_valid, .get_modes = via_dac_get_modes, }; commit 3249656b37911b92566bc9f66bad1c08165bfe69 Author: Kevin Brace <kevinbr...@bracecomputerlab.com> Date: Mon Jun 20 11:35:35 2022 -0500 drm/via: Set FP power on / off timing registers after FP is initialized Signed-off-by: Kevin Brace <kevinbr...@bracecomputerlab.com> diff --git a/drivers/gpu/drm/via/via_display.c b/drivers/gpu/drm/via/via_display.c index 6c6b902c828e..a98c6d53189b 100644 --- a/drivers/gpu/drm/via/via_display.c +++ b/drivers/gpu/drm/via/via_display.c @@ -69,61 +69,6 @@ void via_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } -/* Power sequence relations */ -struct td_timer { - struct vga_regset tdRegs[2]; -}; - -static struct td_timer td_timer_regs[] = { - /* td_timer0 */ - { { { VGA_CRT_IC, 0x8B, 0, 7 }, { VGA_CRT_IC, 0x8F, 0, 3 } } }, - /* td_timer1 */ - { { { VGA_CRT_IC, 0x8C, 0, 7 }, { VGA_CRT_IC, 0x8F, 4, 7 } } }, - /* td_timer2 */ - { { { VGA_CRT_IC, 0x8D, 0, 7 }, { VGA_CRT_IC, 0x90, 0, 3 } } }, - /* td_timer3 */ - { { { VGA_CRT_IC, 0x8E, 0, 7 }, { VGA_CRT_IC, 0x90, 4, 7 } } } -}; - -/* - * Function Name: via_init_td_timing_regs - * Description: Init TD timing register (power sequence) - */ -static void via_init_td_timing_regs(struct drm_device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev->dev); - struct via_drm_priv *dev_priv = to_via_drm_priv(dev); - unsigned int td_timer[4] = { 500, 50, 0, 510 }, i; - struct vga_registers timings; - u32 reg_value; - - /* Fill primary power sequence */ - for (i = 0; i < 4; i++) { - /* Calculate TD Timer, every step is 572.1uSec */ - reg_value = td_timer[i] * 10000 / 5721; - - timings.count = ARRAY_SIZE(td_timer_regs[i].tdRegs); - timings.regs = td_timer_regs[i].tdRegs; - load_value_to_registers(VGABASE, &timings, reg_value); - } - - /* Note: VT3353 have two hardware power sequences - * other chips only have one hardware power sequence */ - if (pdev->device == PCI_DEVICE_ID_VIA_VT1122) { - /* set CRD4[0] to "1" to select 2nd LCD power sequence. */ - svga_wcrt_mask(VGABASE, 0xD4, BIT(0), BIT(0)); - /* Fill secondary power sequence */ - for (i = 0; i < 4; i++) { - /* Calculate TD Timer, every step is 572.1uSec */ - reg_value = td_timer[i] * 10000 / 5721; - - timings.count = ARRAY_SIZE(td_timer_regs[i].tdRegs); - timings.regs = td_timer_regs[i].tdRegs; - load_value_to_registers(VGABASE, &timings, reg_value); - } - } -} - int via_modeset_init(struct drm_device *dev) { struct pci_dev *pdev = to_pci_dev(dev->dev); @@ -137,9 +82,6 @@ int via_modeset_init(struct drm_device *dev) dev_priv->number_fp = 0; dev_priv->number_dvi = 0; - /* Init TD timing register (power sequence) */ - via_init_td_timing_regs(dev); - via_i2c_reg_init(dev_priv); ret = via_i2c_init(dev); if (ret) { diff --git a/drivers/gpu/drm/via/via_lvds.c b/drivers/gpu/drm/via/via_lvds.c index c8ec693d3ad2..44f80cc0d6ef 100644 --- a/drivers/gpu/drm/via/via_lvds.c +++ b/drivers/gpu/drm/via/via_lvds.c @@ -63,6 +63,61 @@ static via_lvds_info via_lvds_info_table[] = { {1600, 1200} }; +/* Power sequence relations */ +struct td_timer { + struct vga_regset tdRegs[2]; +}; + +static struct td_timer td_timer_regs[] = { + /* td_timer0 */ + { { { VGA_CRT_IC, 0x8B, 0, 7 }, { VGA_CRT_IC, 0x8F, 0, 3 } } }, + /* td_timer1 */ + { { { VGA_CRT_IC, 0x8C, 0, 7 }, { VGA_CRT_IC, 0x8F, 4, 7 } } }, + /* td_timer2 */ + { { { VGA_CRT_IC, 0x8D, 0, 7 }, { VGA_CRT_IC, 0x90, 0, 3 } } }, + /* td_timer3 */ + { { { VGA_CRT_IC, 0x8E, 0, 7 }, { VGA_CRT_IC, 0x90, 4, 7 } } } +}; + +/* + * Function Name: via_init_td_timing_regs + * Description: Init TD timing register (power sequence) + */ +static void via_init_td_timing_regs(struct drm_device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev->dev); + struct via_drm_priv *dev_priv = to_via_drm_priv(dev); + unsigned int td_timer[4] = { 500, 50, 0, 510 }, i; + struct vga_registers timings; + u32 reg_value; + + /* Fill primary power sequence */ + for (i = 0; i < 4; i++) { + /* Calculate TD Timer, every step is 572.1uSec */ + reg_value = td_timer[i] * 10000 / 5721; + + timings.count = ARRAY_SIZE(td_timer_regs[i].tdRegs); + timings.regs = td_timer_regs[i].tdRegs; + load_value_to_registers(VGABASE, &timings, reg_value); + } + + /* Note: VT3353 have two hardware power sequences + * other chips only have one hardware power sequence */ + if (pdev->device == PCI_DEVICE_ID_VIA_VT1122) { + /* set CRD4[0] to "1" to select 2nd LCD power sequence. */ + svga_wcrt_mask(VGABASE, 0xD4, BIT(0), BIT(0)); + /* Fill secondary power sequence */ + for (i = 0; i < 4; i++) { + /* Calculate TD Timer, every step is 572.1uSec */ + reg_value = td_timer[i] * 10000 / 5721; + + timings.count = ARRAY_SIZE(td_timer_regs[i].tdRegs); + timings.regs = td_timer_regs[i].tdRegs; + load_value_to_registers(VGABASE, &timings, reg_value); + } + } +} + static bool via_fp_probe_edid(struct i2c_adapter *i2c_bus) { u8 out = 0x0; @@ -1356,6 +1411,9 @@ void via_lvds_init(struct drm_device *dev) /* Put it all together */ drm_connector_attach_encoder(&con->base, &enc->base); + + /* Init TD timing register (power sequence) */ + via_init_td_timing_regs(dev); exit: DRM_DEBUG_KMS("Exiting %s.\n", __func__); return;