Commit db05f8d3 authored by Thomas Zimmermann's avatar Thomas Zimmermann

drm/mgag200: Split MISC register update into PLL selection, SYNC and I/O

Set different fields in MISC in their rsp location in the code. This
patch also fixes a bug in the original code where the mode's SYNC flags
were never written into the MISC register.

v2:
	* use u8 instead of uint8_t
	* define MGAREG_MISC_CLK_SEL_MASK
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Tested-by: default avatarJohn Donnelly <John.p.donnelly@oracle.com>
Acked-by: default avatarSam Ravnborg <sam@ravnborg.org>
Acked-by: default avatarEmil Velikov <emil.velikov@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200515083233.32036-6-tzimmermann@suse.de
parent a6edae07
...@@ -704,6 +704,8 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) ...@@ -704,6 +704,8 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock)
static int mga_crtc_set_plls(struct mga_device *mdev, long clock) static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
{ {
u8 misc;
switch(mdev->type) { switch(mdev->type) {
case G200_SE_A: case G200_SE_A:
case G200_SE_B: case G200_SE_B:
...@@ -724,6 +726,12 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock) ...@@ -724,6 +726,12 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock)
return mga_g200er_set_plls(mdev, clock); return mga_g200er_set_plls(mdev, clock);
break; break;
} }
misc = RREG8(MGA_MISC_IN);
misc &= ~MGAREG_MISC_CLK_SEL_MASK;
misc |= MGAREG_MISC_CLK_SEL_MGA_MSK;
WREG8(MGA_MISC_OUT, misc);
return 0; return 0;
} }
...@@ -916,8 +924,7 @@ static void mgag200_set_mode_regs(struct mga_device *mdev, ...@@ -916,8 +924,7 @@ static void mgag200_set_mode_regs(struct mga_device *mdev,
{ {
unsigned int hdisplay, hsyncstart, hsyncend, htotal; unsigned int hdisplay, hsyncstart, hsyncend, htotal;
unsigned int vdisplay, vsyncstart, vsyncend, vtotal; unsigned int vdisplay, vsyncstart, vsyncend, vtotal;
u8 misc = 0; u8 misc, crtcext1, crtcext2, crtcext5;
u8 crtcext1, crtcext2, crtcext5;
hdisplay = mode->hdisplay / 8 - 1; hdisplay = mode->hdisplay / 8 - 1;
hsyncstart = mode->hsync_start / 8 - 1; hsyncstart = mode->hsync_start / 8 - 1;
...@@ -933,10 +940,17 @@ static void mgag200_set_mode_regs(struct mga_device *mdev, ...@@ -933,10 +940,17 @@ static void mgag200_set_mode_regs(struct mga_device *mdev,
vsyncend = mode->vsync_end - 1; vsyncend = mode->vsync_end - 1;
vtotal = mode->vtotal - 2; vtotal = mode->vtotal - 2;
misc = RREG8(MGA_MISC_IN);
if (mode->flags & DRM_MODE_FLAG_NHSYNC) if (mode->flags & DRM_MODE_FLAG_NHSYNC)
misc |= 0x40; misc |= MGAREG_MISC_HSYNCPOL;
else
misc &= ~MGAREG_MISC_HSYNCPOL;
if (mode->flags & DRM_MODE_FLAG_NVSYNC) if (mode->flags & DRM_MODE_FLAG_NVSYNC)
misc |= 0x80; misc |= MGAREG_MISC_VSYNCPOL;
else
misc &= ~MGAREG_MISC_VSYNCPOL;
crtcext1 = (((htotal - 4) & 0x100) >> 8) | crtcext1 = (((htotal - 4) & 0x100) >> 8) |
((hdisplay & 0x100) >> 7) | ((hdisplay & 0x100) >> 7) |
...@@ -982,6 +996,10 @@ static void mgag200_set_mode_regs(struct mga_device *mdev, ...@@ -982,6 +996,10 @@ static void mgag200_set_mode_regs(struct mga_device *mdev,
WREG_ECRT(0x01, crtcext1); WREG_ECRT(0x01, crtcext1);
WREG_ECRT(0x02, crtcext2); WREG_ECRT(0x02, crtcext2);
WREG_ECRT(0x05, crtcext5); WREG_ECRT(0x05, crtcext5);
WREG8(MGA_MISC_OUT, misc);
mga_crtc_set_plls(mdev, mode->clock);
} }
static int mga_crtc_mode_set(struct drm_crtc *crtc, static int mga_crtc_mode_set(struct drm_crtc *crtc,
...@@ -1140,12 +1158,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1140,12 +1158,6 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
ext_vga[3] = ((1 << bppshift) - 1) | 0x80; ext_vga[3] = ((1 << bppshift) - 1) | 0x80;
ext_vga[4] = 0; ext_vga[4] = 0;
/* Set pixel clocks */
misc = 0x2d;
WREG8(MGA_MISC_OUT, misc);
mga_crtc_set_plls(mdev, mode->clock);
WREG_ECRT(0, ext_vga[0]); WREG_ECRT(0, ext_vga[0]);
WREG_ECRT(3, ext_vga[3]); WREG_ECRT(3, ext_vga[3]);
WREG_ECRT(4, ext_vga[4]); WREG_ECRT(4, ext_vga[4]);
...@@ -1161,9 +1173,11 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1161,9 +1173,11 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc,
} }
WREG_ECRT(0, ext_vga[0]); WREG_ECRT(0, ext_vga[0]);
/* Enable mga pixel clock */
misc = 0x2d;
misc = RREG8(MGA_MISC_IN);
misc |= MGAREG_MISC_IOADSEL |
MGAREG_MISC_RAMMAPEN |
MGAREG_MISC_HIGH_PG_SEL;
WREG8(MGA_MISC_OUT, misc); WREG8(MGA_MISC_OUT, misc);
mga_crtc_do_set_base(mdev, fb, old_fb); mga_crtc_do_set_base(mdev, fb, old_fb);
......
...@@ -16,10 +16,11 @@ ...@@ -16,10 +16,11 @@
* MGA1064SG Mystique register file * MGA1064SG Mystique register file
*/ */
#ifndef _MGA_REG_H_ #ifndef _MGA_REG_H_
#define _MGA_REG_H_ #define _MGA_REG_H_
#include <linux/bits.h>
#define MGAREG_DWGCTL 0x1c00 #define MGAREG_DWGCTL 0x1c00
#define MGAREG_MACCESS 0x1c04 #define MGAREG_MACCESS 0x1c04
/* the following is a mystique only register */ /* the following is a mystique only register */
...@@ -221,12 +222,15 @@ ...@@ -221,12 +222,15 @@
#define MGAREG_MISC_IOADSEL (0x1 << 0) #define MGAREG_MISC_IOADSEL (0x1 << 0)
#define MGAREG_MISC_RAMMAPEN (0x1 << 1) #define MGAREG_MISC_RAMMAPEN (0x1 << 1)
#define MGAREG_MISC_CLK_SEL_MASK GENMASK(3, 2)
#define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2) #define MGAREG_MISC_CLK_SEL_VGA25 (0x0 << 2)
#define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2) #define MGAREG_MISC_CLK_SEL_VGA28 (0x1 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2) #define MGAREG_MISC_CLK_SEL_MGA_PIX (0x2 << 2)
#define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2) #define MGAREG_MISC_CLK_SEL_MGA_MSK (0x3 << 2)
#define MGAREG_MISC_VIDEO_DIS (0x1 << 4) #define MGAREG_MISC_VIDEO_DIS (0x1 << 4)
#define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5) #define MGAREG_MISC_HIGH_PG_SEL (0x1 << 5)
#define MGAREG_MISC_HSYNCPOL BIT(6)
#define MGAREG_MISC_VSYNCPOL BIT(7)
/* MMIO VGA registers */ /* MMIO VGA registers */
#define MGAREG_SEQ_INDEX 0x1fc4 #define MGAREG_SEQ_INDEX 0x1fc4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment