18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci *  linux/drivers/video/kyro/STG4000InitDevice.c
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *  Copyright (C) 2000 Imagination Technologies Ltd
58c2ecf20Sopenharmony_ci *  Copyright (C) 2002 STMicroelectronics
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
88c2ecf20Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
98c2ecf20Sopenharmony_ci * for more details.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci#include <linux/errno.h>
148c2ecf20Sopenharmony_ci#include <linux/types.h>
158c2ecf20Sopenharmony_ci#include <linux/pci.h>
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include "STG4000Reg.h"
188c2ecf20Sopenharmony_ci#include "STG4000Interface.h"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/* SDRAM fixed settings */
218c2ecf20Sopenharmony_ci#define SDRAM_CFG_0   0x49A1
228c2ecf20Sopenharmony_ci#define SDRAM_CFG_1   0xA732
238c2ecf20Sopenharmony_ci#define SDRAM_CFG_2   0x31
248c2ecf20Sopenharmony_ci#define SDRAM_ARB_CFG 0xA0
258c2ecf20Sopenharmony_ci#define SDRAM_REFRESH 0x20
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/* Reset values */
288c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_DAC_RST		0x0001
298c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_C1_RST		0x0004
308c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_C2_RST		0x0008
318c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_3D_RST		0x0010
328c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_VIDIN_RST	0x0020
338c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_TLB_RST		0x0040
348c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_SD_RST		0x0080
358c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_VGA_RST		0x0100
368c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_ROM_RST		0x0200	/* reserved bit, do not reset */
378c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_TA_RST		0x0400
388c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_REG_RST		0x4000
398c2ecf20Sopenharmony_ci#define PMX2_SOFTRESET_ALL		0x7fff
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/* Core clock freq */
428c2ecf20Sopenharmony_ci#define CORE_PLL_FREQ 1000000
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci/* Reference Clock freq */
458c2ecf20Sopenharmony_ci#define REF_FREQ 14318
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/* PCI Registers */
488c2ecf20Sopenharmony_cistatic u16 CorePllControl = 0x70;
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci#define	PCI_CONFIG_SUBSYS_ID	0x2e
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci/* Misc */
538c2ecf20Sopenharmony_ci#define CORE_PLL_MODE_REG_0_7      3
548c2ecf20Sopenharmony_ci#define CORE_PLL_MODE_REG_8_15     2
558c2ecf20Sopenharmony_ci#define CORE_PLL_MODE_CONFIG_REG   1
568c2ecf20Sopenharmony_ci#define DAC_PLL_CONFIG_REG         0
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#define STG_MAX_VCO 500000
598c2ecf20Sopenharmony_ci#define STG_MIN_VCO 100000
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci/* PLL Clock */
628c2ecf20Sopenharmony_ci#define    STG4K3_PLL_SCALER      8	/* scale numbers by 2^8 for fixed point calc */
638c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MIN_R       2	/* Minimum multiplier */
648c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MAX_R       33	/* Max */
658c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MIN_F       2	/* Minimum divisor */
668c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MAX_F       513	/* Max */
678c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MIN_OD      0	/* Min output divider (shift) */
688c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MAX_OD      2	/* Max */
698c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MIN_VCO_SC  (100000000 >> STG4K3_PLL_SCALER)	/* Min VCO rate */
708c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MAX_VCO_SC  (500000000 >> STG4K3_PLL_SCALER)	/* Max VCO rate */
718c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MINR_VCO_SC (100000000 >> STG4K3_PLL_SCALER)	/* Min VCO rate (restricted) */
728c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MAXR_VCO_SC (500000000 >> STG4K3_PLL_SCALER)	/* Max VCO rate (restricted) */
738c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MINR_VCO    100000000	/* Min VCO rate (restricted) */
748c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MAX_VCO     500000000	/* Max VCO rate */
758c2ecf20Sopenharmony_ci#define    STG4K3_PLL_MAXR_VCO    500000000	/* Max VCO rate (restricted) */
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci#define OS_DELAY(X) \
788c2ecf20Sopenharmony_ci{ \
798c2ecf20Sopenharmony_civolatile u32 i,count=0; \
808c2ecf20Sopenharmony_ci    for(i=0;i<X;i++) count++; \
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistatic u32 InitSDRAMRegisters(volatile STG4000REG __iomem *pSTGReg,
848c2ecf20Sopenharmony_ci			      u32 dwSubSysID, u32 dwRevID)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	u32 adwSDRAMArgCfg0[] = { 0xa0, 0x80, 0xa0, 0xa0, 0xa0 };
878c2ecf20Sopenharmony_ci	u32 adwSDRAMCfg1[] = { 0x8732, 0x8732, 0xa732, 0xa732, 0x8732 };
888c2ecf20Sopenharmony_ci	u32 adwSDRAMCfg2[] = { 0x87d2, 0x87d2, 0xa7d2, 0x87d2, 0xa7d2 };
898c2ecf20Sopenharmony_ci	u32 adwSDRAMRsh[] = { 36, 39, 40 };
908c2ecf20Sopenharmony_ci	u32 adwChipSpeed[] = { 110, 120, 125 };
918c2ecf20Sopenharmony_ci	u32 dwMemTypeIdx;
928c2ecf20Sopenharmony_ci	u32 dwChipSpeedIdx;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/* Get memory tpye and chip speed indexs from the SubSysDevID */
958c2ecf20Sopenharmony_ci	dwMemTypeIdx = (dwSubSysID & 0x70) >> 4;
968c2ecf20Sopenharmony_ci	dwChipSpeedIdx = (dwSubSysID & 0x180) >> 7;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	if (dwMemTypeIdx > 4 || dwChipSpeedIdx > 2)
998c2ecf20Sopenharmony_ci		return 0;
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci	/* Program SD-RAM interface */
1028c2ecf20Sopenharmony_ci	STG_WRITE_REG(SDRAMArbiterConf, adwSDRAMArgCfg0[dwMemTypeIdx]);
1038c2ecf20Sopenharmony_ci	if (dwRevID < 5) {
1048c2ecf20Sopenharmony_ci		STG_WRITE_REG(SDRAMConf0, 0x49A1);
1058c2ecf20Sopenharmony_ci		STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg1[dwMemTypeIdx]);
1068c2ecf20Sopenharmony_ci	} else {
1078c2ecf20Sopenharmony_ci		STG_WRITE_REG(SDRAMConf0, 0x4DF1);
1088c2ecf20Sopenharmony_ci		STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg2[dwMemTypeIdx]);
1098c2ecf20Sopenharmony_ci	}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	STG_WRITE_REG(SDRAMConf2, 0x31);
1128c2ecf20Sopenharmony_ci	STG_WRITE_REG(SDRAMRefresh, adwSDRAMRsh[dwChipSpeedIdx]);
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	return adwChipSpeed[dwChipSpeedIdx] * 10000;
1158c2ecf20Sopenharmony_ci}
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ciu32 ProgramClock(u32 refClock,
1188c2ecf20Sopenharmony_ci		   u32 coreClock,
1198c2ecf20Sopenharmony_ci		   u32 * FOut, u32 * ROut, u32 * POut)
1208c2ecf20Sopenharmony_ci{
1218c2ecf20Sopenharmony_ci	u32 R = 0, F = 0, OD = 0, ODIndex = 0;
1228c2ecf20Sopenharmony_ci	u32 ulBestR = 0, ulBestF = 0, ulBestOD = 0;
1238c2ecf20Sopenharmony_ci	u32 ulBestClk = 0, ulBestScore = 0;
1248c2ecf20Sopenharmony_ci	u32 ulScore, ulPhaseScore, ulVcoScore;
1258c2ecf20Sopenharmony_ci	u32 ulTmp = 0, ulVCO;
1268c2ecf20Sopenharmony_ci	u32 ulScaleClockReq, ulMinClock, ulMaxClock;
1278c2ecf20Sopenharmony_ci	u32 ODValues[] = { 1, 2, 0 };
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	/* Translate clock in Hz */
1308c2ecf20Sopenharmony_ci	coreClock *= 100;	/* in Hz */
1318c2ecf20Sopenharmony_ci	refClock *= 1000;	/* in Hz */
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	/* Work out acceptable clock
1348c2ecf20Sopenharmony_ci	 * The method calculates ~ +- 0.4% (1/256)
1358c2ecf20Sopenharmony_ci	 */
1368c2ecf20Sopenharmony_ci	ulMinClock = coreClock - (coreClock >> 8);
1378c2ecf20Sopenharmony_ci	ulMaxClock = coreClock + (coreClock >> 8);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	/* Scale clock required for use in calculations */
1408c2ecf20Sopenharmony_ci	ulScaleClockReq = coreClock >> STG4K3_PLL_SCALER;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	/* Iterate through post divider values */
1438c2ecf20Sopenharmony_ci	for (ODIndex = 0; ODIndex < 3; ODIndex++) {
1448c2ecf20Sopenharmony_ci		OD = ODValues[ODIndex];
1458c2ecf20Sopenharmony_ci		R = STG4K3_PLL_MIN_R;
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci		/* loop for pre-divider from min to max  */
1488c2ecf20Sopenharmony_ci		while (R <= STG4K3_PLL_MAX_R) {
1498c2ecf20Sopenharmony_ci			/* estimate required feedback multiplier */
1508c2ecf20Sopenharmony_ci			ulTmp = R * (ulScaleClockReq << OD);
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci			/* F = ClkRequired * R * (2^OD) / Fref */
1538c2ecf20Sopenharmony_ci			F = (u32)(ulTmp / (refClock >> STG4K3_PLL_SCALER));
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci			/* compensate for accuracy */
1568c2ecf20Sopenharmony_ci			if (F > STG4K3_PLL_MIN_F)
1578c2ecf20Sopenharmony_ci				F--;
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci			/*
1618c2ecf20Sopenharmony_ci			 * We should be close to our target frequency (if it's
1628c2ecf20Sopenharmony_ci			 * achievable with current OD & R) let's iterate
1638c2ecf20Sopenharmony_ci			 * through F for best fit
1648c2ecf20Sopenharmony_ci			 */
1658c2ecf20Sopenharmony_ci			while ((F >= STG4K3_PLL_MIN_F) &&
1668c2ecf20Sopenharmony_ci			       (F <= STG4K3_PLL_MAX_F)) {
1678c2ecf20Sopenharmony_ci				/* Calc VCO at full accuracy */
1688c2ecf20Sopenharmony_ci				ulVCO = refClock / R;
1698c2ecf20Sopenharmony_ci				ulVCO = F * ulVCO;
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci				/*
1728c2ecf20Sopenharmony_ci				 * Check it's within restricted VCO range
1738c2ecf20Sopenharmony_ci				 * unless of course the desired frequency is
1748c2ecf20Sopenharmony_ci				 * above the restricted range, then test
1758c2ecf20Sopenharmony_ci				 * against VCO limit
1768c2ecf20Sopenharmony_ci				 */
1778c2ecf20Sopenharmony_ci				if ((ulVCO >= STG4K3_PLL_MINR_VCO) &&
1788c2ecf20Sopenharmony_ci				    ((ulVCO <= STG4K3_PLL_MAXR_VCO) ||
1798c2ecf20Sopenharmony_ci				     ((coreClock > STG4K3_PLL_MAXR_VCO)
1808c2ecf20Sopenharmony_ci				      && (ulVCO <= STG4K3_PLL_MAX_VCO)))) {
1818c2ecf20Sopenharmony_ci					ulTmp = (ulVCO >> OD);	/* Clock = VCO / (2^OD) */
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci					/* Is this clock good enough? */
1848c2ecf20Sopenharmony_ci					if ((ulTmp >= ulMinClock)
1858c2ecf20Sopenharmony_ci					    && (ulTmp <= ulMaxClock)) {
1868c2ecf20Sopenharmony_ci						ulPhaseScore = (((refClock / R) - (refClock / STG4K3_PLL_MAX_R))) / ((refClock - (refClock / STG4K3_PLL_MAX_R)) >> 10);
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci						ulVcoScore = ((ulVCO - STG4K3_PLL_MINR_VCO)) / ((STG4K3_PLL_MAXR_VCO - STG4K3_PLL_MINR_VCO) >> 10);
1898c2ecf20Sopenharmony_ci						ulScore = ulPhaseScore + ulVcoScore;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci						if (!ulBestScore) {
1928c2ecf20Sopenharmony_ci							ulBestOD = OD;
1938c2ecf20Sopenharmony_ci							ulBestF = F;
1948c2ecf20Sopenharmony_ci							ulBestR = R;
1958c2ecf20Sopenharmony_ci							ulBestClk = ulTmp;
1968c2ecf20Sopenharmony_ci							ulBestScore =
1978c2ecf20Sopenharmony_ci							    ulScore;
1988c2ecf20Sopenharmony_ci						}
1998c2ecf20Sopenharmony_ci						/* is this better, ( aim for highest Score) */
2008c2ecf20Sopenharmony_ci			/*--------------------------------------------------------------------------
2018c2ecf20Sopenharmony_ci                             Here we want to use a scoring system which will take account of both the
2028c2ecf20Sopenharmony_ci                            value at the phase comparater and the VCO output
2038c2ecf20Sopenharmony_ci                             to do this we will use a cumulative score between the two
2048c2ecf20Sopenharmony_ci                          The way this ends up is that we choose the first value in the loop anyway
2058c2ecf20Sopenharmony_ci                          but we shall keep this code in case new restrictions come into play
2068c2ecf20Sopenharmony_ci                          --------------------------------------------------------------------------*/
2078c2ecf20Sopenharmony_ci						if ((ulScore >= ulBestScore) && (OD > 0)) {
2088c2ecf20Sopenharmony_ci							ulBestOD = OD;
2098c2ecf20Sopenharmony_ci							ulBestF = F;
2108c2ecf20Sopenharmony_ci							ulBestR = R;
2118c2ecf20Sopenharmony_ci							ulBestClk = ulTmp;
2128c2ecf20Sopenharmony_ci							ulBestScore =
2138c2ecf20Sopenharmony_ci							    ulScore;
2148c2ecf20Sopenharmony_ci						}
2158c2ecf20Sopenharmony_ci					}
2168c2ecf20Sopenharmony_ci				}
2178c2ecf20Sopenharmony_ci				F++;
2188c2ecf20Sopenharmony_ci			}
2198c2ecf20Sopenharmony_ci			R++;
2208c2ecf20Sopenharmony_ci		}
2218c2ecf20Sopenharmony_ci	}
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	/*
2248c2ecf20Sopenharmony_ci	   did we find anything?
2258c2ecf20Sopenharmony_ci	   Then return RFOD
2268c2ecf20Sopenharmony_ci	 */
2278c2ecf20Sopenharmony_ci	if (ulBestScore) {
2288c2ecf20Sopenharmony_ci		*ROut = ulBestR;
2298c2ecf20Sopenharmony_ci		*FOut = ulBestF;
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci		if ((ulBestOD == 2) || (ulBestOD == 3)) {
2328c2ecf20Sopenharmony_ci			*POut = 3;
2338c2ecf20Sopenharmony_ci		} else
2348c2ecf20Sopenharmony_ci			*POut = ulBestOD;
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	return (ulBestClk);
2398c2ecf20Sopenharmony_ci}
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ciint SetCoreClockPLL(volatile STG4000REG __iomem *pSTGReg, struct pci_dev *pDev)
2428c2ecf20Sopenharmony_ci{
2438c2ecf20Sopenharmony_ci	u32 F, R, P;
2448c2ecf20Sopenharmony_ci	u16 core_pll = 0, sub;
2458c2ecf20Sopenharmony_ci	u32 tmp;
2468c2ecf20Sopenharmony_ci	u32 ulChipSpeed;
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	STG_WRITE_REG(IntMask, 0xFFFF);
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci	/* Disable Primary Core Thread0 */
2518c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(Thread0Enable);
2528c2ecf20Sopenharmony_ci	CLEAR_BIT(0);
2538c2ecf20Sopenharmony_ci	STG_WRITE_REG(Thread0Enable, tmp);
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	/* Disable Primary Core Thread1 */
2568c2ecf20Sopenharmony_ci	tmp = STG_READ_REG(Thread1Enable);
2578c2ecf20Sopenharmony_ci	CLEAR_BIT(0);
2588c2ecf20Sopenharmony_ci	STG_WRITE_REG(Thread1Enable, tmp);
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
2618c2ecf20Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST);
2628c2ecf20Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
2638c2ecf20Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST |
2648c2ecf20Sopenharmony_ci		      PMX2_SOFTRESET_ROM_RST);
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	/* Need to play around to reset TA */
2678c2ecf20Sopenharmony_ci	STG_WRITE_REG(TAConfiguration, 0);
2688c2ecf20Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
2698c2ecf20Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST);
2708c2ecf20Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
2718c2ecf20Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST |
2728c2ecf20Sopenharmony_ci		      PMX2_SOFTRESET_ROM_RST);
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	pci_read_config_word(pDev, PCI_CONFIG_SUBSYS_ID, &sub);
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	ulChipSpeed = InitSDRAMRegisters(pSTGReg, (u32)sub,
2778c2ecf20Sopenharmony_ci		                         (u32)pDev->revision);
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	if (ulChipSpeed == 0)
2808c2ecf20Sopenharmony_ci		return -EINVAL;
2818c2ecf20Sopenharmony_ci
2828c2ecf20Sopenharmony_ci	ProgramClock(REF_FREQ, CORE_PLL_FREQ, &F, &R, &P);
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	core_pll |= ((P) | ((F - 2) << 2) | ((R - 2) << 11));
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	/* Set Core PLL Control to Core PLL Mode  */
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ci	/* Send bits 0:7 of the Core PLL Mode register */
2898c2ecf20Sopenharmony_ci	tmp = ((CORE_PLL_MODE_REG_0_7 << 8) | (core_pll & 0x00FF));
2908c2ecf20Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
2918c2ecf20Sopenharmony_ci	/* Without some delay between the PCI config writes the clock does
2928c2ecf20Sopenharmony_ci	   not reliably set when the code is compiled -O3
2938c2ecf20Sopenharmony_ci	 */
2948c2ecf20Sopenharmony_ci	OS_DELAY(1000000);
2958c2ecf20Sopenharmony_ci
2968c2ecf20Sopenharmony_ci	tmp |= SET_BIT(14);
2978c2ecf20Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
2988c2ecf20Sopenharmony_ci	OS_DELAY(1000000);
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	/* Send bits 8:15 of the Core PLL Mode register */
3018c2ecf20Sopenharmony_ci	tmp =
3028c2ecf20Sopenharmony_ci	    ((CORE_PLL_MODE_REG_8_15 << 8) | ((core_pll & 0xFF00) >> 8));
3038c2ecf20Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
3048c2ecf20Sopenharmony_ci	OS_DELAY(1000000);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	tmp |= SET_BIT(14);
3078c2ecf20Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
3088c2ecf20Sopenharmony_ci	OS_DELAY(1000000);
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	STG_WRITE_REG(SoftwareReset, PMX2_SOFTRESET_ALL);
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci#if 0
3138c2ecf20Sopenharmony_ci	/* Enable Primary Core Thread0 */
3148c2ecf20Sopenharmony_ci	tmp = ((STG_READ_REG(Thread0Enable)) | SET_BIT(0));
3158c2ecf20Sopenharmony_ci	STG_WRITE_REG(Thread0Enable, tmp);
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci	/* Enable Primary Core Thread1 */
3188c2ecf20Sopenharmony_ci	tmp = ((STG_READ_REG(Thread1Enable)) | SET_BIT(0));
3198c2ecf20Sopenharmony_ci	STG_WRITE_REG(Thread1Enable, tmp);
3208c2ecf20Sopenharmony_ci#endif
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci	return 0;
3238c2ecf20Sopenharmony_ci}
324