^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * linux/drivers/video/kyro/STG4000Ramdac.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2002 STMicroelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * License. See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <video/kyro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "STG4000Reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "STG4000Interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static u32 STG_PIXEL_BUS_WIDTH = 128; /* 128 bit bus width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static u32 REF_CLOCK = 14318;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) int InitialiseRamdac(volatile STG4000REG __iomem * pSTGReg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u32 displayDepth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u32 displayWidth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) u32 displayHeight,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) s32 HSyncPolarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) s32 VSyncPolarity, u32 * pixelClock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u32 tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u32 F = 0, R = 0, P = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u32 stride = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) u32 ulPdiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 physicalPixelDepth = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Make sure DAC is in Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) tmp = STG_READ_REG(SoftwareReset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (tmp & 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) CLEAR_BIT(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) STG_WRITE_REG(SoftwareReset, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /* Set Pixel Format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) tmp = STG_READ_REG(DACPixelFormat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) CLEAR_BITS_FRM_TO(0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Set LUT not used from 16bpp to 32 bpp ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) CLEAR_BITS_FRM_TO(8, 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) switch (displayDepth) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) physicalPixelDepth = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) tmp |= _16BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Set for 32 bits per pixel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) physicalPixelDepth = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) tmp |= _32BPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) STG_WRITE_REG(DACPixelFormat, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* Workout Bus transfer bandwidth according to pixel format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ulPdiv = STG_PIXEL_BUS_WIDTH / physicalPixelDepth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Get Screen Stride in pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) stride = displayWidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Set Primary size info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) tmp = STG_READ_REG(DACPrimSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) CLEAR_BITS_FRM_TO(0, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) CLEAR_BITS_FRM_TO(12, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) tmp |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ((((displayHeight - 1) << 12) | (((displayWidth / ulPdiv) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 1) << 23))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) | (stride / ulPdiv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) STG_WRITE_REG(DACPrimSize, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Set Pixel Clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) *pixelClock = ProgramClock(REF_CLOCK, *pixelClock, &F, &R, &P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* Set DAC PLL Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) tmp = STG_READ_REG(DACPLLMode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) CLEAR_BITS_FRM_TO(0, 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* tmp |= ((P-1) | ((F-2) << 2) | ((R-2) << 11)); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) tmp |= ((P) | ((F - 2) << 2) | ((R - 2) << 11));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) STG_WRITE_REG(DACPLLMode, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Set Prim Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) tmp = STG_READ_REG(DACPrimAddress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) CLEAR_BITS_FRM_TO(0, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) CLEAR_BITS_FRM_TO(20, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) STG_WRITE_REG(DACPrimAddress, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Set Cursor details with HW Cursor disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) tmp = STG_READ_REG(DACCursorCtrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) tmp &= ~SET_BIT(31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) STG_WRITE_REG(DACCursorCtrl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) tmp = STG_READ_REG(DACCursorAddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) CLEAR_BITS_FRM_TO(0, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) STG_WRITE_REG(DACCursorAddr, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Set Video Window */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) tmp = STG_READ_REG(DACVidWinStart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) CLEAR_BITS_FRM_TO(0, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) CLEAR_BITS_FRM_TO(16, 26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) STG_WRITE_REG(DACVidWinStart, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) tmp = STG_READ_REG(DACVidWinEnd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) CLEAR_BITS_FRM_TO(0, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) CLEAR_BITS_FRM_TO(16, 26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) STG_WRITE_REG(DACVidWinEnd, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /* Set DAC Border Color to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) tmp = STG_READ_REG(DACBorderColor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) CLEAR_BITS_FRM_TO(0, 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) STG_WRITE_REG(DACBorderColor, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Set Graphics and Overlay Burst Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) STG_WRITE_REG(DACBurstCtrl, 0x0404);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Set CRC Trigger to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) tmp = STG_READ_REG(DACCrcTrigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) CLEAR_BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) STG_WRITE_REG(DACCrcTrigger, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) /* Set Video Port Control to default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) tmp = STG_READ_REG(DigVidPortCtrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) CLEAR_BIT(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) CLEAR_BITS_FRM_TO(16, 27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) CLEAR_BITS_FRM_TO(1, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) CLEAR_BITS_FRM_TO(10, 11);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) STG_WRITE_REG(DigVidPortCtrl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Ramdac control, turning output to the screen on and off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) void DisableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Disable DAC for Graphics Stream Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) tmp = (STG_READ_REG(DACStreamCtrl)) & ~SET_BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) STG_WRITE_REG(DACStreamCtrl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) void EnableRamdacOutput(volatile STG4000REG __iomem * pSTGReg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Enable DAC for Graphics Stream Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) tmp = (STG_READ_REG(DACStreamCtrl)) | SET_BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) STG_WRITE_REG(DACStreamCtrl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }