Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  *  linux/drivers/video/kyro/STG4000InitDevice.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  Copyright (C) 2000 Imagination Technologies Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2002 STMicroelectronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * License.  See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "STG4000Reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "STG4000Interface.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) /* SDRAM fixed settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define SDRAM_CFG_0   0x49A1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define SDRAM_CFG_1   0xA732
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define SDRAM_CFG_2   0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define SDRAM_ARB_CFG 0xA0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define SDRAM_REFRESH 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* Reset values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define PMX2_SOFTRESET_DAC_RST		0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define PMX2_SOFTRESET_C1_RST		0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define PMX2_SOFTRESET_C2_RST		0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define PMX2_SOFTRESET_3D_RST		0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define PMX2_SOFTRESET_VIDIN_RST	0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define PMX2_SOFTRESET_TLB_RST		0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define PMX2_SOFTRESET_SD_RST		0x0080
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define PMX2_SOFTRESET_VGA_RST		0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define PMX2_SOFTRESET_ROM_RST		0x0200	/* reserved bit, do not reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define PMX2_SOFTRESET_TA_RST		0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define PMX2_SOFTRESET_REG_RST		0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define PMX2_SOFTRESET_ALL		0x7fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) /* Core clock freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define CORE_PLL_FREQ 1000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) /* Reference Clock freq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define REF_FREQ 14318
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /* PCI Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static u16 CorePllControl = 0x70;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define	PCI_CONFIG_SUBSYS_ID	0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* Misc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define CORE_PLL_MODE_REG_0_7      3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define CORE_PLL_MODE_REG_8_15     2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define CORE_PLL_MODE_CONFIG_REG   1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define DAC_PLL_CONFIG_REG         0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define STG_MAX_VCO 500000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define STG_MIN_VCO 100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) /* PLL Clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define    STG4K3_PLL_SCALER      8	/* scale numbers by 2^8 for fixed point calc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define    STG4K3_PLL_MIN_R       2	/* Minimum multiplier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define    STG4K3_PLL_MAX_R       33	/* Max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define    STG4K3_PLL_MIN_F       2	/* Minimum divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define    STG4K3_PLL_MAX_F       513	/* Max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define    STG4K3_PLL_MIN_OD      0	/* Min output divider (shift) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define    STG4K3_PLL_MAX_OD      2	/* Max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define    STG4K3_PLL_MIN_VCO_SC  (100000000 >> STG4K3_PLL_SCALER)	/* Min VCO rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define    STG4K3_PLL_MAX_VCO_SC  (500000000 >> STG4K3_PLL_SCALER)	/* Max VCO rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define    STG4K3_PLL_MINR_VCO_SC (100000000 >> STG4K3_PLL_SCALER)	/* Min VCO rate (restricted) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define    STG4K3_PLL_MAXR_VCO_SC (500000000 >> STG4K3_PLL_SCALER)	/* Max VCO rate (restricted) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define    STG4K3_PLL_MINR_VCO    100000000	/* Min VCO rate (restricted) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define    STG4K3_PLL_MAX_VCO     500000000	/* Max VCO rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define    STG4K3_PLL_MAXR_VCO    500000000	/* Max VCO rate (restricted) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define OS_DELAY(X) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) volatile u32 i,count=0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)     for(i=0;i<X;i++) count++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) static u32 InitSDRAMRegisters(volatile STG4000REG __iomem *pSTGReg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			      u32 dwSubSysID, u32 dwRevID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	u32 adwSDRAMArgCfg0[] = { 0xa0, 0x80, 0xa0, 0xa0, 0xa0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	u32 adwSDRAMCfg1[] = { 0x8732, 0x8732, 0xa732, 0xa732, 0x8732 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	u32 adwSDRAMCfg2[] = { 0x87d2, 0x87d2, 0xa7d2, 0x87d2, 0xa7d2 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	u32 adwSDRAMRsh[] = { 36, 39, 40 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	u32 adwChipSpeed[] = { 110, 120, 125 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	u32 dwMemTypeIdx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	u32 dwChipSpeedIdx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/* Get memory tpye and chip speed indexs from the SubSysDevID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	dwMemTypeIdx = (dwSubSysID & 0x70) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	dwChipSpeedIdx = (dwSubSysID & 0x180) >> 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (dwMemTypeIdx > 4 || dwChipSpeedIdx > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	/* Program SD-RAM interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	STG_WRITE_REG(SDRAMArbiterConf, adwSDRAMArgCfg0[dwMemTypeIdx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (dwRevID < 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		STG_WRITE_REG(SDRAMConf0, 0x49A1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg1[dwMemTypeIdx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		STG_WRITE_REG(SDRAMConf0, 0x4DF1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg2[dwMemTypeIdx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	STG_WRITE_REG(SDRAMConf2, 0x31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	STG_WRITE_REG(SDRAMRefresh, adwSDRAMRsh[dwChipSpeedIdx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	return adwChipSpeed[dwChipSpeedIdx] * 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) u32 ProgramClock(u32 refClock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		   u32 coreClock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		   u32 * FOut, u32 * ROut, u32 * POut)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	u32 R = 0, F = 0, OD = 0, ODIndex = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	u32 ulBestR = 0, ulBestF = 0, ulBestOD = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	u32 ulBestClk = 0, ulBestScore = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	u32 ulScore, ulPhaseScore, ulVcoScore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	u32 ulTmp = 0, ulVCO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	u32 ulScaleClockReq, ulMinClock, ulMaxClock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	u32 ODValues[] = { 1, 2, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/* Translate clock in Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	coreClock *= 100;	/* in Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	refClock *= 1000;	/* in Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	/* Work out acceptable clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 * The method calculates ~ +- 0.4% (1/256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	ulMinClock = coreClock - (coreClock >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	ulMaxClock = coreClock + (coreClock >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/* Scale clock required for use in calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	ulScaleClockReq = coreClock >> STG4K3_PLL_SCALER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	/* Iterate through post divider values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	for (ODIndex = 0; ODIndex < 3; ODIndex++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		OD = ODValues[ODIndex];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		R = STG4K3_PLL_MIN_R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		/* loop for pre-divider from min to max  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		while (R <= STG4K3_PLL_MAX_R) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			/* estimate required feedback multiplier */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			ulTmp = R * (ulScaleClockReq << OD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			/* F = ClkRequired * R * (2^OD) / Fref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			F = (u32)(ulTmp / (refClock >> STG4K3_PLL_SCALER));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			/* compensate for accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			if (F > STG4K3_PLL_MIN_F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 				F--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			 * We should be close to our target frequency (if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			 * achievable with current OD & R) let's iterate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			 * through F for best fit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			while ((F >= STG4K3_PLL_MIN_F) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			       (F <= STG4K3_PLL_MAX_F)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 				/* Calc VCO at full accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				ulVCO = refClock / R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 				ulVCO = F * ulVCO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 				 * Check it's within restricted VCO range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 				 * unless of course the desired frequency is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 				 * above the restricted range, then test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 				 * against VCO limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				if ((ulVCO >= STG4K3_PLL_MINR_VCO) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 				    ((ulVCO <= STG4K3_PLL_MAXR_VCO) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 				     ((coreClock > STG4K3_PLL_MAXR_VCO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 				      && (ulVCO <= STG4K3_PLL_MAX_VCO)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 					ulTmp = (ulVCO >> OD);	/* Clock = VCO / (2^OD) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 					/* Is this clock good enough? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 					if ((ulTmp >= ulMinClock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 					    && (ulTmp <= ulMaxClock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 						ulPhaseScore = (((refClock / R) - (refClock / STG4K3_PLL_MAX_R))) / ((refClock - (refClock / STG4K3_PLL_MAX_R)) >> 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 						ulVcoScore = ((ulVCO - STG4K3_PLL_MINR_VCO)) / ((STG4K3_PLL_MAXR_VCO - STG4K3_PLL_MINR_VCO) >> 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 						ulScore = ulPhaseScore + ulVcoScore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 						if (!ulBestScore) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 							ulBestOD = OD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 							ulBestF = F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 							ulBestR = R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 							ulBestClk = ulTmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 							ulBestScore =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 							    ulScore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 						}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 						/* is this better, ( aim for highest Score) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			/*--------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)                              Here we want to use a scoring system which will take account of both the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)                             value at the phase comparater and the VCO output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)                              to do this we will use a cumulative score between the two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)                           The way this ends up is that we choose the first value in the loop anyway
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)                           but we shall keep this code in case new restrictions come into play
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)                           --------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 						if ((ulScore >= ulBestScore) && (OD > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 							ulBestOD = OD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 							ulBestF = F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 							ulBestR = R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 							ulBestClk = ulTmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 							ulBestScore =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 							    ulScore;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 						}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 					}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 				F++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 			R++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	   did we find anything?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	   Then return RFOD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (ulBestScore) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		*ROut = ulBestR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		*FOut = ulBestF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		if ((ulBestOD == 2) || (ulBestOD == 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			*POut = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			*POut = ulBestOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	return (ulBestClk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) int SetCoreClockPLL(volatile STG4000REG __iomem *pSTGReg, struct pci_dev *pDev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	u32 F, R, P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	u16 core_pll = 0, sub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	u32 ulChipSpeed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	STG_WRITE_REG(IntMask, 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	/* Disable Primary Core Thread0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	tmp = STG_READ_REG(Thread0Enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	CLEAR_BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	STG_WRITE_REG(Thread0Enable, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	/* Disable Primary Core Thread1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	tmp = STG_READ_REG(Thread1Enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	CLEAR_BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	STG_WRITE_REG(Thread1Enable, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	STG_WRITE_REG(SoftwareReset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	STG_WRITE_REG(SoftwareReset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		      PMX2_SOFTRESET_ROM_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	/* Need to play around to reset TA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	STG_WRITE_REG(TAConfiguration, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	STG_WRITE_REG(SoftwareReset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	STG_WRITE_REG(SoftwareReset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		      PMX2_SOFTRESET_ROM_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	pci_read_config_word(pDev, PCI_CONFIG_SUBSYS_ID, &sub);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	ulChipSpeed = InitSDRAMRegisters(pSTGReg, (u32)sub,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		                         (u32)pDev->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (ulChipSpeed == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	ProgramClock(REF_FREQ, CORE_PLL_FREQ, &F, &R, &P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	core_pll |= ((P) | ((F - 2) << 2) | ((R - 2) << 11));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	/* Set Core PLL Control to Core PLL Mode  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	/* Send bits 0:7 of the Core PLL Mode register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	tmp = ((CORE_PLL_MODE_REG_0_7 << 8) | (core_pll & 0x00FF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	pci_write_config_word(pDev, CorePllControl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	/* Without some delay between the PCI config writes the clock does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	   not reliably set when the code is compiled -O3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	OS_DELAY(1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	tmp |= SET_BIT(14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	pci_write_config_word(pDev, CorePllControl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	OS_DELAY(1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	/* Send bits 8:15 of the Core PLL Mode register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	tmp =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	    ((CORE_PLL_MODE_REG_8_15 << 8) | ((core_pll & 0xFF00) >> 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	pci_write_config_word(pDev, CorePllControl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	OS_DELAY(1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	tmp |= SET_BIT(14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	pci_write_config_word(pDev, CorePllControl, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	OS_DELAY(1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	STG_WRITE_REG(SoftwareReset, PMX2_SOFTRESET_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	/* Enable Primary Core Thread0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	tmp = ((STG_READ_REG(Thread0Enable)) | SET_BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	STG_WRITE_REG(Thread0Enable, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	/* Enable Primary Core Thread1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	tmp = ((STG_READ_REG(Thread1Enable)) | SET_BIT(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	STG_WRITE_REG(Thread1Enable, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }