162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci *  linux/drivers/video/kyro/STG4000InitDevice.c
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *  Copyright (C) 2000 Imagination Technologies Ltd
562306a36Sopenharmony_ci *  Copyright (C) 2002 STMicroelectronics
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
862306a36Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
962306a36Sopenharmony_ci * for more details.
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/kernel.h>
1362306a36Sopenharmony_ci#include <linux/errno.h>
1462306a36Sopenharmony_ci#include <linux/types.h>
1562306a36Sopenharmony_ci#include <linux/pci.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include "STG4000Reg.h"
1862306a36Sopenharmony_ci#include "STG4000Interface.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* SDRAM fixed settings */
2162306a36Sopenharmony_ci#define SDRAM_CFG_0   0x49A1
2262306a36Sopenharmony_ci#define SDRAM_CFG_1   0xA732
2362306a36Sopenharmony_ci#define SDRAM_CFG_2   0x31
2462306a36Sopenharmony_ci#define SDRAM_ARB_CFG 0xA0
2562306a36Sopenharmony_ci#define SDRAM_REFRESH 0x20
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* Reset values */
2862306a36Sopenharmony_ci#define PMX2_SOFTRESET_DAC_RST		0x0001
2962306a36Sopenharmony_ci#define PMX2_SOFTRESET_C1_RST		0x0004
3062306a36Sopenharmony_ci#define PMX2_SOFTRESET_C2_RST		0x0008
3162306a36Sopenharmony_ci#define PMX2_SOFTRESET_3D_RST		0x0010
3262306a36Sopenharmony_ci#define PMX2_SOFTRESET_VIDIN_RST	0x0020
3362306a36Sopenharmony_ci#define PMX2_SOFTRESET_TLB_RST		0x0040
3462306a36Sopenharmony_ci#define PMX2_SOFTRESET_SD_RST		0x0080
3562306a36Sopenharmony_ci#define PMX2_SOFTRESET_VGA_RST		0x0100
3662306a36Sopenharmony_ci#define PMX2_SOFTRESET_ROM_RST		0x0200	/* reserved bit, do not reset */
3762306a36Sopenharmony_ci#define PMX2_SOFTRESET_TA_RST		0x0400
3862306a36Sopenharmony_ci#define PMX2_SOFTRESET_REG_RST		0x4000
3962306a36Sopenharmony_ci#define PMX2_SOFTRESET_ALL		0x7fff
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* Core clock freq */
4262306a36Sopenharmony_ci#define CORE_PLL_FREQ 1000000
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* Reference Clock freq */
4562306a36Sopenharmony_ci#define REF_FREQ 14318
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/* PCI Registers */
4862306a36Sopenharmony_cistatic u16 CorePllControl = 0x70;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define	PCI_CONFIG_SUBSYS_ID	0x2e
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/* Misc */
5362306a36Sopenharmony_ci#define CORE_PLL_MODE_REG_0_7      3
5462306a36Sopenharmony_ci#define CORE_PLL_MODE_REG_8_15     2
5562306a36Sopenharmony_ci#define CORE_PLL_MODE_CONFIG_REG   1
5662306a36Sopenharmony_ci#define DAC_PLL_CONFIG_REG         0
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#define STG_MAX_VCO 500000
5962306a36Sopenharmony_ci#define STG_MIN_VCO 100000
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/* PLL Clock */
6262306a36Sopenharmony_ci#define    STG4K3_PLL_SCALER      8	/* scale numbers by 2^8 for fixed point calc */
6362306a36Sopenharmony_ci#define    STG4K3_PLL_MIN_R       2	/* Minimum multiplier */
6462306a36Sopenharmony_ci#define    STG4K3_PLL_MAX_R       33	/* Max */
6562306a36Sopenharmony_ci#define    STG4K3_PLL_MIN_F       2	/* Minimum divisor */
6662306a36Sopenharmony_ci#define    STG4K3_PLL_MAX_F       513	/* Max */
6762306a36Sopenharmony_ci#define    STG4K3_PLL_MIN_OD      0	/* Min output divider (shift) */
6862306a36Sopenharmony_ci#define    STG4K3_PLL_MAX_OD      2	/* Max */
6962306a36Sopenharmony_ci#define    STG4K3_PLL_MIN_VCO_SC  (100000000 >> STG4K3_PLL_SCALER)	/* Min VCO rate */
7062306a36Sopenharmony_ci#define    STG4K3_PLL_MAX_VCO_SC  (500000000 >> STG4K3_PLL_SCALER)	/* Max VCO rate */
7162306a36Sopenharmony_ci#define    STG4K3_PLL_MINR_VCO_SC (100000000 >> STG4K3_PLL_SCALER)	/* Min VCO rate (restricted) */
7262306a36Sopenharmony_ci#define    STG4K3_PLL_MAXR_VCO_SC (500000000 >> STG4K3_PLL_SCALER)	/* Max VCO rate (restricted) */
7362306a36Sopenharmony_ci#define    STG4K3_PLL_MINR_VCO    100000000	/* Min VCO rate (restricted) */
7462306a36Sopenharmony_ci#define    STG4K3_PLL_MAX_VCO     500000000	/* Max VCO rate */
7562306a36Sopenharmony_ci#define    STG4K3_PLL_MAXR_VCO    500000000	/* Max VCO rate (restricted) */
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define OS_DELAY(X) \
7862306a36Sopenharmony_ci{ \
7962306a36Sopenharmony_civolatile u32 i,count=0; \
8062306a36Sopenharmony_ci    for(i=0;i<X;i++) count++; \
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistatic u32 InitSDRAMRegisters(volatile STG4000REG __iomem *pSTGReg,
8462306a36Sopenharmony_ci			      u32 dwSubSysID, u32 dwRevID)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	static const u8 adwSDRAMArgCfg0[] = { 0xa0, 0x80, 0xa0, 0xa0, 0xa0 };
8762306a36Sopenharmony_ci	static const u16 adwSDRAMCfg1[] = { 0x8732, 0x8732, 0xa732, 0xa732, 0x8732 };
8862306a36Sopenharmony_ci	static const u16 adwSDRAMCfg2[] = { 0x87d2, 0x87d2, 0xa7d2, 0x87d2, 0xa7d2 };
8962306a36Sopenharmony_ci	static const u8 adwSDRAMRsh[] = { 36, 39, 40 };
9062306a36Sopenharmony_ci	static const u8 adwChipSpeed[] = { 110, 120, 125 };
9162306a36Sopenharmony_ci	u32 dwMemTypeIdx;
9262306a36Sopenharmony_ci	u32 dwChipSpeedIdx;
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	/* Get memory tpye and chip speed indexs from the SubSysDevID */
9562306a36Sopenharmony_ci	dwMemTypeIdx = (dwSubSysID & 0x70) >> 4;
9662306a36Sopenharmony_ci	dwChipSpeedIdx = (dwSubSysID & 0x180) >> 7;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	if (dwMemTypeIdx > 4 || dwChipSpeedIdx > 2)
9962306a36Sopenharmony_ci		return 0;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	/* Program SD-RAM interface */
10262306a36Sopenharmony_ci	STG_WRITE_REG(SDRAMArbiterConf, adwSDRAMArgCfg0[dwMemTypeIdx]);
10362306a36Sopenharmony_ci	if (dwRevID < 5) {
10462306a36Sopenharmony_ci		STG_WRITE_REG(SDRAMConf0, 0x49A1);
10562306a36Sopenharmony_ci		STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg1[dwMemTypeIdx]);
10662306a36Sopenharmony_ci	} else {
10762306a36Sopenharmony_ci		STG_WRITE_REG(SDRAMConf0, 0x4DF1);
10862306a36Sopenharmony_ci		STG_WRITE_REG(SDRAMConf1, adwSDRAMCfg2[dwMemTypeIdx]);
10962306a36Sopenharmony_ci	}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	STG_WRITE_REG(SDRAMConf2, 0x31);
11262306a36Sopenharmony_ci	STG_WRITE_REG(SDRAMRefresh, adwSDRAMRsh[dwChipSpeedIdx]);
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	return adwChipSpeed[dwChipSpeedIdx] * 10000;
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ciu32 ProgramClock(u32 refClock,
11862306a36Sopenharmony_ci		   u32 coreClock,
11962306a36Sopenharmony_ci		   u32 * FOut, u32 * ROut, u32 * POut)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	u32 R = 0, F = 0, OD = 0, ODIndex = 0;
12262306a36Sopenharmony_ci	u32 ulBestR = 0, ulBestF = 0, ulBestOD = 0;
12362306a36Sopenharmony_ci	u32 ulBestClk = 0, ulBestScore = 0;
12462306a36Sopenharmony_ci	u32 ulScore, ulPhaseScore, ulVcoScore;
12562306a36Sopenharmony_ci	u32 ulTmp = 0, ulVCO;
12662306a36Sopenharmony_ci	u32 ulScaleClockReq, ulMinClock, ulMaxClock;
12762306a36Sopenharmony_ci	static const unsigned char ODValues[] = { 1, 2, 0 };
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	/* Translate clock in Hz */
13062306a36Sopenharmony_ci	coreClock *= 100;	/* in Hz */
13162306a36Sopenharmony_ci	refClock *= 1000;	/* in Hz */
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	/* Work out acceptable clock
13462306a36Sopenharmony_ci	 * The method calculates ~ +- 0.4% (1/256)
13562306a36Sopenharmony_ci	 */
13662306a36Sopenharmony_ci	ulMinClock = coreClock - (coreClock >> 8);
13762306a36Sopenharmony_ci	ulMaxClock = coreClock + (coreClock >> 8);
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	/* Scale clock required for use in calculations */
14062306a36Sopenharmony_ci	ulScaleClockReq = coreClock >> STG4K3_PLL_SCALER;
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	/* Iterate through post divider values */
14362306a36Sopenharmony_ci	for (ODIndex = 0; ODIndex < 3; ODIndex++) {
14462306a36Sopenharmony_ci		OD = ODValues[ODIndex];
14562306a36Sopenharmony_ci		R = STG4K3_PLL_MIN_R;
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci		/* loop for pre-divider from min to max  */
14862306a36Sopenharmony_ci		while (R <= STG4K3_PLL_MAX_R) {
14962306a36Sopenharmony_ci			/* estimate required feedback multiplier */
15062306a36Sopenharmony_ci			ulTmp = R * (ulScaleClockReq << OD);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci			/* F = ClkRequired * R * (2^OD) / Fref */
15362306a36Sopenharmony_ci			F = (u32)(ulTmp / (refClock >> STG4K3_PLL_SCALER));
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci			/* compensate for accuracy */
15662306a36Sopenharmony_ci			if (F > STG4K3_PLL_MIN_F)
15762306a36Sopenharmony_ci				F--;
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci			/*
16162306a36Sopenharmony_ci			 * We should be close to our target frequency (if it's
16262306a36Sopenharmony_ci			 * achievable with current OD & R) let's iterate
16362306a36Sopenharmony_ci			 * through F for best fit
16462306a36Sopenharmony_ci			 */
16562306a36Sopenharmony_ci			while ((F >= STG4K3_PLL_MIN_F) &&
16662306a36Sopenharmony_ci			       (F <= STG4K3_PLL_MAX_F)) {
16762306a36Sopenharmony_ci				/* Calc VCO at full accuracy */
16862306a36Sopenharmony_ci				ulVCO = refClock / R;
16962306a36Sopenharmony_ci				ulVCO = F * ulVCO;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci				/*
17262306a36Sopenharmony_ci				 * Check it's within restricted VCO range
17362306a36Sopenharmony_ci				 * unless of course the desired frequency is
17462306a36Sopenharmony_ci				 * above the restricted range, then test
17562306a36Sopenharmony_ci				 * against VCO limit
17662306a36Sopenharmony_ci				 */
17762306a36Sopenharmony_ci				if ((ulVCO >= STG4K3_PLL_MINR_VCO) &&
17862306a36Sopenharmony_ci				    ((ulVCO <= STG4K3_PLL_MAXR_VCO) ||
17962306a36Sopenharmony_ci				     ((coreClock > STG4K3_PLL_MAXR_VCO)
18062306a36Sopenharmony_ci				      && (ulVCO <= STG4K3_PLL_MAX_VCO)))) {
18162306a36Sopenharmony_ci					ulTmp = (ulVCO >> OD);	/* Clock = VCO / (2^OD) */
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci					/* Is this clock good enough? */
18462306a36Sopenharmony_ci					if ((ulTmp >= ulMinClock)
18562306a36Sopenharmony_ci					    && (ulTmp <= ulMaxClock)) {
18662306a36Sopenharmony_ci						ulPhaseScore = (((refClock / R) - (refClock / STG4K3_PLL_MAX_R))) / ((refClock - (refClock / STG4K3_PLL_MAX_R)) >> 10);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci						ulVcoScore = ((ulVCO - STG4K3_PLL_MINR_VCO)) / ((STG4K3_PLL_MAXR_VCO - STG4K3_PLL_MINR_VCO) >> 10);
18962306a36Sopenharmony_ci						ulScore = ulPhaseScore + ulVcoScore;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci						if (!ulBestScore) {
19262306a36Sopenharmony_ci							ulBestOD = OD;
19362306a36Sopenharmony_ci							ulBestF = F;
19462306a36Sopenharmony_ci							ulBestR = R;
19562306a36Sopenharmony_ci							ulBestClk = ulTmp;
19662306a36Sopenharmony_ci							ulBestScore =
19762306a36Sopenharmony_ci							    ulScore;
19862306a36Sopenharmony_ci						}
19962306a36Sopenharmony_ci						/* is this better, ( aim for highest Score) */
20062306a36Sopenharmony_ci			/*--------------------------------------------------------------------------
20162306a36Sopenharmony_ci                             Here we want to use a scoring system which will take account of both the
20262306a36Sopenharmony_ci                            value at the phase comparater and the VCO output
20362306a36Sopenharmony_ci                             to do this we will use a cumulative score between the two
20462306a36Sopenharmony_ci                          The way this ends up is that we choose the first value in the loop anyway
20562306a36Sopenharmony_ci                          but we shall keep this code in case new restrictions come into play
20662306a36Sopenharmony_ci                          --------------------------------------------------------------------------*/
20762306a36Sopenharmony_ci						if ((ulScore >= ulBestScore) && (OD > 0)) {
20862306a36Sopenharmony_ci							ulBestOD = OD;
20962306a36Sopenharmony_ci							ulBestF = F;
21062306a36Sopenharmony_ci							ulBestR = R;
21162306a36Sopenharmony_ci							ulBestClk = ulTmp;
21262306a36Sopenharmony_ci							ulBestScore =
21362306a36Sopenharmony_ci							    ulScore;
21462306a36Sopenharmony_ci						}
21562306a36Sopenharmony_ci					}
21662306a36Sopenharmony_ci				}
21762306a36Sopenharmony_ci				F++;
21862306a36Sopenharmony_ci			}
21962306a36Sopenharmony_ci			R++;
22062306a36Sopenharmony_ci		}
22162306a36Sopenharmony_ci	}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	/*
22462306a36Sopenharmony_ci	   did we find anything?
22562306a36Sopenharmony_ci	   Then return RFOD
22662306a36Sopenharmony_ci	 */
22762306a36Sopenharmony_ci	if (ulBestScore) {
22862306a36Sopenharmony_ci		*ROut = ulBestR;
22962306a36Sopenharmony_ci		*FOut = ulBestF;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci		if ((ulBestOD == 2) || (ulBestOD == 3)) {
23262306a36Sopenharmony_ci			*POut = 3;
23362306a36Sopenharmony_ci		} else
23462306a36Sopenharmony_ci			*POut = ulBestOD;
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	return (ulBestClk);
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ciint SetCoreClockPLL(volatile STG4000REG __iomem *pSTGReg, struct pci_dev *pDev)
24262306a36Sopenharmony_ci{
24362306a36Sopenharmony_ci	u32 F, R, P;
24462306a36Sopenharmony_ci	u16 core_pll = 0, sub;
24562306a36Sopenharmony_ci	u32 tmp;
24662306a36Sopenharmony_ci	u32 ulChipSpeed;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	STG_WRITE_REG(IntMask, 0xFFFF);
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	/* Disable Primary Core Thread0 */
25162306a36Sopenharmony_ci	tmp = STG_READ_REG(Thread0Enable);
25262306a36Sopenharmony_ci	CLEAR_BIT(0);
25362306a36Sopenharmony_ci	STG_WRITE_REG(Thread0Enable, tmp);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	/* Disable Primary Core Thread1 */
25662306a36Sopenharmony_ci	tmp = STG_READ_REG(Thread1Enable);
25762306a36Sopenharmony_ci	CLEAR_BIT(0);
25862306a36Sopenharmony_ci	STG_WRITE_REG(Thread1Enable, tmp);
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
26162306a36Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST);
26262306a36Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
26362306a36Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST |
26462306a36Sopenharmony_ci		      PMX2_SOFTRESET_ROM_RST);
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	/* Need to play around to reset TA */
26762306a36Sopenharmony_ci	STG_WRITE_REG(TAConfiguration, 0);
26862306a36Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
26962306a36Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_ROM_RST);
27062306a36Sopenharmony_ci	STG_WRITE_REG(SoftwareReset,
27162306a36Sopenharmony_ci		      PMX2_SOFTRESET_REG_RST | PMX2_SOFTRESET_TA_RST |
27262306a36Sopenharmony_ci		      PMX2_SOFTRESET_ROM_RST);
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	pci_read_config_word(pDev, PCI_CONFIG_SUBSYS_ID, &sub);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci	ulChipSpeed = InitSDRAMRegisters(pSTGReg, (u32)sub,
27762306a36Sopenharmony_ci		                         (u32)pDev->revision);
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	if (ulChipSpeed == 0)
28062306a36Sopenharmony_ci		return -EINVAL;
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	ProgramClock(REF_FREQ, CORE_PLL_FREQ, &F, &R, &P);
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	core_pll |= ((P) | ((F - 2) << 2) | ((R - 2) << 11));
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	/* Set Core PLL Control to Core PLL Mode  */
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	/* Send bits 0:7 of the Core PLL Mode register */
28962306a36Sopenharmony_ci	tmp = ((CORE_PLL_MODE_REG_0_7 << 8) | (core_pll & 0x00FF));
29062306a36Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
29162306a36Sopenharmony_ci	/* Without some delay between the PCI config writes the clock does
29262306a36Sopenharmony_ci	   not reliably set when the code is compiled -O3
29362306a36Sopenharmony_ci	 */
29462306a36Sopenharmony_ci	OS_DELAY(1000000);
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	tmp |= SET_BIT(14);
29762306a36Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
29862306a36Sopenharmony_ci	OS_DELAY(1000000);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	/* Send bits 8:15 of the Core PLL Mode register */
30162306a36Sopenharmony_ci	tmp =
30262306a36Sopenharmony_ci	    ((CORE_PLL_MODE_REG_8_15 << 8) | ((core_pll & 0xFF00) >> 8));
30362306a36Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
30462306a36Sopenharmony_ci	OS_DELAY(1000000);
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	tmp |= SET_BIT(14);
30762306a36Sopenharmony_ci	pci_write_config_word(pDev, CorePllControl, tmp);
30862306a36Sopenharmony_ci	OS_DELAY(1000000);
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	STG_WRITE_REG(SoftwareReset, PMX2_SOFTRESET_ALL);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci#if 0
31362306a36Sopenharmony_ci	/* Enable Primary Core Thread0 */
31462306a36Sopenharmony_ci	tmp = ((STG_READ_REG(Thread0Enable)) | SET_BIT(0));
31562306a36Sopenharmony_ci	STG_WRITE_REG(Thread0Enable, tmp);
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci	/* Enable Primary Core Thread1 */
31862306a36Sopenharmony_ci	tmp = ((STG_READ_REG(Thread1Enable)) | SET_BIT(0));
31962306a36Sopenharmony_ci	STG_WRITE_REG(Thread1Enable, tmp);
32062306a36Sopenharmony_ci#endif
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	return 0;
32362306a36Sopenharmony_ci}
324