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