soc.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. /*
  2. * (C) Copyright 2007
  3. * Sascha Hauer, Pengutronix
  4. *
  5. * (C) Copyright 2009 Freescale Semiconductor, Inc.
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <linux/errno.h>
  11. #include <asm/io.h>
  12. #include <asm/arch/imx-regs.h>
  13. #include <asm/arch/clock.h>
  14. #include <asm/arch/sys_proto.h>
  15. #include <asm/mach-imx/boot_mode.h>
  16. #include <asm/mach-imx/dma.h>
  17. #include <asm/mach-imx/hab.h>
  18. #include <stdbool.h>
  19. #include <asm/arch/mxc_hdmi.h>
  20. #include <asm/arch/crm_regs.h>
  21. #include <dm.h>
  22. #include <imx_thermal.h>
  23. #include <mmc.h>
  24. enum ldo_reg {
  25. LDO_ARM,
  26. LDO_SOC,
  27. LDO_PU,
  28. };
  29. struct scu_regs {
  30. u32 ctrl;
  31. u32 config;
  32. u32 status;
  33. u32 invalidate;
  34. u32 fpga_rev;
  35. };
  36. #if defined(CONFIG_IMX_THERMAL)
  37. static const struct imx_thermal_plat imx6_thermal_plat = {
  38. .regs = (void *)ANATOP_BASE_ADDR,
  39. .fuse_bank = 1,
  40. .fuse_word = 6,
  41. };
  42. U_BOOT_DEVICE(imx6_thermal) = {
  43. .name = "imx_thermal",
  44. .platdata = &imx6_thermal_plat,
  45. };
  46. #endif
  47. #if defined(CONFIG_SECURE_BOOT)
  48. struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
  49. .bank = 0,
  50. .word = 6,
  51. };
  52. #endif
  53. u32 get_nr_cpus(void)
  54. {
  55. struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
  56. return readl(&scu->config) & 3;
  57. }
  58. u32 get_cpu_rev(void)
  59. {
  60. struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  61. u32 reg = readl(&anatop->digprog_sololite);
  62. u32 type = ((reg >> 16) & 0xff);
  63. u32 major, cfg = 0;
  64. if (type != MXC_CPU_MX6SL) {
  65. reg = readl(&anatop->digprog);
  66. struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
  67. cfg = readl(&scu->config) & 3;
  68. type = ((reg >> 16) & 0xff);
  69. if (type == MXC_CPU_MX6DL) {
  70. if (!cfg)
  71. type = MXC_CPU_MX6SOLO;
  72. }
  73. if (type == MXC_CPU_MX6Q) {
  74. if (cfg == 1)
  75. type = MXC_CPU_MX6D;
  76. }
  77. }
  78. major = ((reg >> 8) & 0xff);
  79. if ((major >= 1) &&
  80. ((type == MXC_CPU_MX6Q) || (type == MXC_CPU_MX6D))) {
  81. major--;
  82. type = MXC_CPU_MX6QP;
  83. if (cfg == 1)
  84. type = MXC_CPU_MX6DP;
  85. }
  86. reg &= 0xff; /* mx6 silicon revision */
  87. return (type << 12) | (reg + (0x10 * (major + 1)));
  88. }
  89. /*
  90. * OCOTP_CFG3[17:16] (see Fusemap Description Table offset 0x440)
  91. * defines a 2-bit SPEED_GRADING
  92. */
  93. #define OCOTP_CFG3_SPEED_SHIFT 16
  94. #define OCOTP_CFG3_SPEED_800MHZ 0
  95. #define OCOTP_CFG3_SPEED_850MHZ 1
  96. #define OCOTP_CFG3_SPEED_1GHZ 2
  97. #define OCOTP_CFG3_SPEED_1P2GHZ 3
  98. /*
  99. * For i.MX6UL
  100. */
  101. #define OCOTP_CFG3_SPEED_528MHZ 1
  102. #define OCOTP_CFG3_SPEED_696MHZ 2
  103. /*
  104. * For i.MX6ULL
  105. */
  106. #define OCOTP_CFG3_SPEED_792MHZ 2
  107. #define OCOTP_CFG3_SPEED_900MHZ 3
  108. u32 get_cpu_speed_grade_hz(void)
  109. {
  110. struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  111. struct fuse_bank *bank = &ocotp->bank[0];
  112. struct fuse_bank0_regs *fuse =
  113. (struct fuse_bank0_regs *)bank->fuse_regs;
  114. uint32_t val;
  115. val = readl(&fuse->cfg3);
  116. val >>= OCOTP_CFG3_SPEED_SHIFT;
  117. val &= 0x3;
  118. if (is_mx6ul()) {
  119. if (val == OCOTP_CFG3_SPEED_528MHZ)
  120. return 528000000;
  121. else if (val == OCOTP_CFG3_SPEED_696MHZ)
  122. return 696000000;
  123. else
  124. return 0;
  125. }
  126. if (is_mx6ull()) {
  127. if (val == OCOTP_CFG3_SPEED_528MHZ)
  128. return 528000000;
  129. else if (val == OCOTP_CFG3_SPEED_792MHZ)
  130. return 792000000;
  131. else if (val == OCOTP_CFG3_SPEED_900MHZ)
  132. return 900000000;
  133. else
  134. return 0;
  135. }
  136. switch (val) {
  137. /* Valid for IMX6DQ */
  138. case OCOTP_CFG3_SPEED_1P2GHZ:
  139. if (is_mx6dq() || is_mx6dqp())
  140. return 1200000000;
  141. /* Valid for IMX6SX/IMX6SDL/IMX6DQ */
  142. case OCOTP_CFG3_SPEED_1GHZ:
  143. return 996000000;
  144. /* Valid for IMX6DQ */
  145. case OCOTP_CFG3_SPEED_850MHZ:
  146. if (is_mx6dq() || is_mx6dqp())
  147. return 852000000;
  148. /* Valid for IMX6SX/IMX6SDL/IMX6DQ */
  149. case OCOTP_CFG3_SPEED_800MHZ:
  150. return 792000000;
  151. }
  152. return 0;
  153. }
  154. /*
  155. * OCOTP_MEM0[7:6] (see Fusemap Description Table offset 0x480)
  156. * defines a 2-bit Temperature Grade
  157. *
  158. * return temperature grade and min/max temperature in Celsius
  159. */
  160. #define OCOTP_MEM0_TEMP_SHIFT 6
  161. u32 get_cpu_temp_grade(int *minc, int *maxc)
  162. {
  163. struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  164. struct fuse_bank *bank = &ocotp->bank[1];
  165. struct fuse_bank1_regs *fuse =
  166. (struct fuse_bank1_regs *)bank->fuse_regs;
  167. uint32_t val;
  168. val = readl(&fuse->mem0);
  169. val >>= OCOTP_MEM0_TEMP_SHIFT;
  170. val &= 0x3;
  171. if (minc && maxc) {
  172. if (val == TEMP_AUTOMOTIVE) {
  173. *minc = -40;
  174. *maxc = 125;
  175. } else if (val == TEMP_INDUSTRIAL) {
  176. *minc = -40;
  177. *maxc = 105;
  178. } else if (val == TEMP_EXTCOMMERCIAL) {
  179. *minc = -20;
  180. *maxc = 105;
  181. } else {
  182. *minc = 0;
  183. *maxc = 95;
  184. }
  185. }
  186. return val;
  187. }
  188. #ifdef CONFIG_REVISION_TAG
  189. u32 __weak get_board_rev(void)
  190. {
  191. u32 cpurev = get_cpu_rev();
  192. u32 type = ((cpurev >> 12) & 0xff);
  193. if (type == MXC_CPU_MX6SOLO)
  194. cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
  195. if (type == MXC_CPU_MX6D)
  196. cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF);
  197. return cpurev;
  198. }
  199. #endif
  200. static void clear_ldo_ramp(void)
  201. {
  202. struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  203. int reg;
  204. /* ROM may modify LDO ramp up time according to fuse setting, so in
  205. * order to be in the safe side we neeed to reset these settings to
  206. * match the reset value: 0'b00
  207. */
  208. reg = readl(&anatop->ana_misc2);
  209. reg &= ~(0x3f << 24);
  210. writel(reg, &anatop->ana_misc2);
  211. }
  212. /*
  213. * Set the PMU_REG_CORE register
  214. *
  215. * Set LDO_SOC/PU/ARM regulators to the specified millivolt level.
  216. * Possible values are from 0.725V to 1.450V in steps of
  217. * 0.025V (25mV).
  218. */
  219. static int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
  220. {
  221. struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  222. u32 val, step, old, reg = readl(&anatop->reg_core);
  223. u8 shift;
  224. /* No LDO_SOC/PU/ARM */
  225. if (is_mx6sll())
  226. return 0;
  227. if (mv < 725)
  228. val = 0x00; /* Power gated off */
  229. else if (mv > 1450)
  230. val = 0x1F; /* Power FET switched full on. No regulation */
  231. else
  232. val = (mv - 700) / 25;
  233. clear_ldo_ramp();
  234. switch (ldo) {
  235. case LDO_SOC:
  236. shift = 18;
  237. break;
  238. case LDO_PU:
  239. shift = 9;
  240. break;
  241. case LDO_ARM:
  242. shift = 0;
  243. break;
  244. default:
  245. return -EINVAL;
  246. }
  247. old = (reg & (0x1F << shift)) >> shift;
  248. step = abs(val - old);
  249. if (step == 0)
  250. return 0;
  251. reg = (reg & ~(0x1F << shift)) | (val << shift);
  252. writel(reg, &anatop->reg_core);
  253. /*
  254. * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per
  255. * step
  256. */
  257. udelay(3 * step);
  258. return 0;
  259. }
  260. static void set_ahb_rate(u32 val)
  261. {
  262. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  263. u32 reg, div;
  264. div = get_periph_clk() / val - 1;
  265. reg = readl(&mxc_ccm->cbcdr);
  266. writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) |
  267. (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr);
  268. }
  269. static void clear_mmdc_ch_mask(void)
  270. {
  271. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  272. u32 reg;
  273. reg = readl(&mxc_ccm->ccdr);
  274. /* Clear MMDC channel mask */
  275. if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sl() || is_mx6sll())
  276. reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK);
  277. else
  278. reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK | MXC_CCM_CCDR_MMDC_CH0_HS_MASK);
  279. writel(reg, &mxc_ccm->ccdr);
  280. }
  281. #define OCOTP_MEM0_REFTOP_TRIM_SHIFT 8
  282. static void init_bandgap(void)
  283. {
  284. struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  285. struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  286. struct fuse_bank *bank = &ocotp->bank[1];
  287. struct fuse_bank1_regs *fuse =
  288. (struct fuse_bank1_regs *)bank->fuse_regs;
  289. uint32_t val;
  290. /*
  291. * Ensure the bandgap has stabilized.
  292. */
  293. while (!(readl(&anatop->ana_misc0) & 0x80))
  294. ;
  295. /*
  296. * For best noise performance of the analog blocks using the
  297. * outputs of the bandgap, the reftop_selfbiasoff bit should
  298. * be set.
  299. */
  300. writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
  301. /*
  302. * On i.MX6ULL,we need to set VBGADJ bits according to the
  303. * REFTOP_TRIM[3:0] in fuse table
  304. * 000 - set REFTOP_VBGADJ[2:0] to 3b'110,
  305. * 110 - set REFTOP_VBGADJ[2:0] to 3b'000,
  306. * 001 - set REFTOP_VBGADJ[2:0] to 3b'001,
  307. * 010 - set REFTOP_VBGADJ[2:0] to 3b'010,
  308. * 011 - set REFTOP_VBGADJ[2:0] to 3b'011,
  309. * 100 - set REFTOP_VBGADJ[2:0] to 3b'100,
  310. * 101 - set REFTOP_VBGADJ[2:0] to 3b'101,
  311. * 111 - set REFTOP_VBGADJ[2:0] to 3b'111,
  312. */
  313. if (is_mx6ull()) {
  314. val = readl(&fuse->mem0);
  315. val >>= OCOTP_MEM0_REFTOP_TRIM_SHIFT;
  316. val &= 0x7;
  317. writel(val << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT,
  318. &anatop->ana_misc0_set);
  319. }
  320. }
  321. int arch_cpu_init(void)
  322. {
  323. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  324. init_aips();
  325. /* Need to clear MMDC_CHx_MASK to make warm reset work. */
  326. clear_mmdc_ch_mask();
  327. /*
  328. * Disable self-bias circuit in the analog bandap.
  329. * The self-bias circuit is used by the bandgap during startup.
  330. * This bit should be set after the bandgap has initialized.
  331. */
  332. init_bandgap();
  333. if (!is_mx6ul() && !is_mx6ull()) {
  334. /*
  335. * When low freq boot is enabled, ROM will not set AHB
  336. * freq, so we need to ensure AHB freq is 132MHz in such
  337. * scenario.
  338. *
  339. * To i.MX6UL, when power up, default ARM core and
  340. * AHB rate is 396M and 132M.
  341. */
  342. if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
  343. set_ahb_rate(132000000);
  344. }
  345. if (is_mx6ul()) {
  346. if (is_soc_rev(CHIP_REV_1_0) == 0) {
  347. /*
  348. * According to the design team's requirement on
  349. * i.MX6UL,the PMIC_STBY_REQ PAD should be configured
  350. * as open drain 100K (0x0000b8a0).
  351. * Only exists on TO1.0
  352. */
  353. writel(0x0000b8a0, IOMUXC_BASE_ADDR + 0x29c);
  354. } else {
  355. /*
  356. * From TO1.1, SNVS adds internal pull up control
  357. * for POR_B, the register filed is GPBIT[1:0],
  358. * after system boot up, it can be set to 2b'01
  359. * to disable internal pull up.It can save about
  360. * 30uA power in SNVS mode.
  361. */
  362. writel((readl(MX6UL_SNVS_LP_BASE_ADDR + 0x10) &
  363. (~0x1400)) | 0x400,
  364. MX6UL_SNVS_LP_BASE_ADDR + 0x10);
  365. }
  366. }
  367. if (is_mx6ull()) {
  368. /*
  369. * GPBIT[1:0] is suggested to set to 2'b11:
  370. * 2'b00 : always PUP100K
  371. * 2'b01 : PUP100K when PMIC_ON_REQ or SOC_NOT_FAIL
  372. * 2'b10 : always disable PUP100K
  373. * 2'b11 : PDN100K when SOC_FAIL, PUP100K when SOC_NOT_FAIL
  374. * register offset is different from i.MX6UL, since
  375. * i.MX6UL is fixed by ECO.
  376. */
  377. writel(readl(MX6UL_SNVS_LP_BASE_ADDR) |
  378. 0x3, MX6UL_SNVS_LP_BASE_ADDR);
  379. }
  380. /* Set perclk to source from OSC 24MHz */
  381. if (is_mx6sl())
  382. setbits_le32(&ccm->cscmr1, MXC_CCM_CSCMR1_PER_CLK_SEL_MASK);
  383. imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
  384. if (is_mx6sx())
  385. setbits_le32(&ccm->cscdr1, MXC_CCM_CSCDR1_UART_CLK_SEL);
  386. init_src();
  387. return 0;
  388. }
  389. #ifdef CONFIG_ENV_IS_IN_MMC
  390. __weak int board_mmc_get_env_dev(int devno)
  391. {
  392. return CONFIG_SYS_MMC_ENV_DEV;
  393. }
  394. static int mmc_get_boot_dev(void)
  395. {
  396. struct src *src_regs = (struct src *)SRC_BASE_ADDR;
  397. u32 soc_sbmr = readl(&src_regs->sbmr1);
  398. u32 bootsel;
  399. int devno;
  400. /*
  401. * Refer to
  402. * "i.MX 6Dual/6Quad Applications Processor Reference Manual"
  403. * Chapter "8.5.3.1 Expansion Device eFUSE Configuration"
  404. * i.MX6SL/SX/UL has same layout.
  405. */
  406. bootsel = (soc_sbmr & 0x000000FF) >> 6;
  407. /* No boot from sd/mmc */
  408. if (bootsel != 1)
  409. return -1;
  410. /* BOOT_CFG2[3] and BOOT_CFG2[4] */
  411. devno = (soc_sbmr & 0x00001800) >> 11;
  412. return devno;
  413. }
  414. int mmc_get_env_dev(void)
  415. {
  416. int devno = mmc_get_boot_dev();
  417. /* If not boot from sd/mmc, use default value */
  418. if (devno < 0)
  419. return CONFIG_SYS_MMC_ENV_DEV;
  420. return board_mmc_get_env_dev(devno);
  421. }
  422. #ifdef CONFIG_SYS_MMC_ENV_PART
  423. __weak int board_mmc_get_env_part(int devno)
  424. {
  425. return CONFIG_SYS_MMC_ENV_PART;
  426. }
  427. uint mmc_get_env_part(struct mmc *mmc)
  428. {
  429. int devno = mmc_get_boot_dev();
  430. /* If not boot from sd/mmc, use default value */
  431. if (devno < 0)
  432. return CONFIG_SYS_MMC_ENV_PART;
  433. return board_mmc_get_env_part(devno);
  434. }
  435. #endif
  436. #endif
  437. int board_postclk_init(void)
  438. {
  439. /* NO LDO SOC on i.MX6SLL */
  440. if (is_mx6sll())
  441. return 0;
  442. set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */
  443. return 0;
  444. }
  445. #if defined(CONFIG_FEC_MXC)
  446. void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
  447. {
  448. struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
  449. struct fuse_bank *bank = &ocotp->bank[4];
  450. struct fuse_bank4_regs *fuse =
  451. (struct fuse_bank4_regs *)bank->fuse_regs;
  452. if ((is_mx6sx() || is_mx6ul() || is_mx6ull()) && dev_id == 1) {
  453. u32 value = readl(&fuse->mac_addr2);
  454. mac[0] = value >> 24 ;
  455. mac[1] = value >> 16 ;
  456. mac[2] = value >> 8 ;
  457. mac[3] = value ;
  458. value = readl(&fuse->mac_addr1);
  459. mac[4] = value >> 24 ;
  460. mac[5] = value >> 16 ;
  461. } else {
  462. u32 value = readl(&fuse->mac_addr1);
  463. mac[0] = (value >> 8);
  464. mac[1] = value ;
  465. value = readl(&fuse->mac_addr0);
  466. mac[2] = value >> 24 ;
  467. mac[3] = value >> 16 ;
  468. mac[4] = value >> 8 ;
  469. mac[5] = value ;
  470. }
  471. }
  472. #endif
  473. /*
  474. * cfg_val will be used for
  475. * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0]
  476. * After reset, if GPR10[28] is 1, ROM will use GPR9[25:0]
  477. * instead of SBMR1 to determine the boot device.
  478. */
  479. const struct boot_mode soc_boot_modes[] = {
  480. {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)},
  481. /* reserved value should start rom usb */
  482. #if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL)
  483. {"usb", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
  484. #else
  485. {"usb", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)},
  486. #endif
  487. {"sata", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)},
  488. {"ecspi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)},
  489. {"ecspi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)},
  490. {"ecspi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)},
  491. {"ecspi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)},
  492. /* 4 bit bus width */
  493. {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)},
  494. {"esdhc2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
  495. {"esdhc3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
  496. {"esdhc4", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
  497. {NULL, 0},
  498. };
  499. void reset_misc(void)
  500. {
  501. #ifdef CONFIG_VIDEO_MXS
  502. lcdif_power_down();
  503. #endif
  504. }
  505. void s_init(void)
  506. {
  507. struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
  508. struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  509. u32 mask480;
  510. u32 mask528;
  511. u32 reg, periph1, periph2;
  512. if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sll())
  513. return;
  514. /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
  515. * to make sure PFD is working right, otherwise, PFDs may
  516. * not output clock after reset, MX6DL and MX6SL have added 396M pfd
  517. * workaround in ROM code, as bus clock need it
  518. */
  519. mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
  520. ANATOP_PFD_CLKGATE_MASK(1) |
  521. ANATOP_PFD_CLKGATE_MASK(2) |
  522. ANATOP_PFD_CLKGATE_MASK(3);
  523. mask528 = ANATOP_PFD_CLKGATE_MASK(1) |
  524. ANATOP_PFD_CLKGATE_MASK(3);
  525. reg = readl(&ccm->cbcmr);
  526. periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK)
  527. >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET);
  528. periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
  529. >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET);
  530. /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */
  531. if ((periph2 != 0x2) && (periph1 != 0x2))
  532. mask528 |= ANATOP_PFD_CLKGATE_MASK(0);
  533. if ((periph2 != 0x1) && (periph1 != 0x1) &&
  534. (periph2 != 0x3) && (periph1 != 0x3))
  535. mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
  536. writel(mask480, &anatop->pfd_480_set);
  537. writel(mask528, &anatop->pfd_528_set);
  538. writel(mask480, &anatop->pfd_480_clr);
  539. writel(mask528, &anatop->pfd_528_clr);
  540. }
  541. #ifdef CONFIG_IMX_HDMI
  542. void imx_enable_hdmi_phy(void)
  543. {
  544. struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
  545. u8 reg;
  546. reg = readb(&hdmi->phy_conf0);
  547. reg |= HDMI_PHY_CONF0_PDZ_MASK;
  548. writeb(reg, &hdmi->phy_conf0);
  549. udelay(3000);
  550. reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
  551. writeb(reg, &hdmi->phy_conf0);
  552. udelay(3000);
  553. reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
  554. writeb(reg, &hdmi->phy_conf0);
  555. writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
  556. }
  557. void imx_setup_hdmi(void)
  558. {
  559. struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  560. struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
  561. int reg, count;
  562. u8 val;
  563. /* Turn on HDMI PHY clock */
  564. reg = readl(&mxc_ccm->CCGR2);
  565. reg |= MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK|
  566. MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
  567. writel(reg, &mxc_ccm->CCGR2);
  568. writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
  569. reg = readl(&mxc_ccm->chsccdr);
  570. reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK|
  571. MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK|
  572. MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
  573. reg |= (CHSCCDR_PODF_DIVIDE_BY_3
  574. << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
  575. |(CHSCCDR_IPU_PRE_CLK_540M_PFD
  576. << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
  577. writel(reg, &mxc_ccm->chsccdr);
  578. /* Clear the overflow condition */
  579. if (readb(&hdmi->ih_fc_stat2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK) {
  580. /* TMDS software reset */
  581. writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &hdmi->mc_swrstz);
  582. val = readb(&hdmi->fc_invidconf);
  583. /* Need minimum 3 times to write to clear the register */
  584. for (count = 0 ; count < 5 ; count++)
  585. writeb(val, &hdmi->fc_invidconf);
  586. }
  587. }
  588. #endif
  589. #ifdef CONFIG_IMX_BOOTAUX
  590. int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data)
  591. {
  592. struct src *src_reg;
  593. u32 stack, pc;
  594. if (!boot_private_data)
  595. return -EINVAL;
  596. stack = *(u32 *)boot_private_data;
  597. pc = *(u32 *)(boot_private_data + 4);
  598. /* Set the stack and pc to M4 bootROM */
  599. writel(stack, M4_BOOTROM_BASE_ADDR);
  600. writel(pc, M4_BOOTROM_BASE_ADDR + 4);
  601. /* Enable M4 */
  602. src_reg = (struct src *)SRC_BASE_ADDR;
  603. clrsetbits_le32(&src_reg->scr, SRC_SCR_M4C_NON_SCLR_RST_MASK,
  604. SRC_SCR_M4_ENABLE_MASK);
  605. return 0;
  606. }
  607. int arch_auxiliary_core_check_up(u32 core_id)
  608. {
  609. struct src *src_reg = (struct src *)SRC_BASE_ADDR;
  610. unsigned val;
  611. val = readl(&src_reg->scr);
  612. if (val & SRC_SCR_M4C_NON_SCLR_RST_MASK)
  613. return 0; /* assert in reset */
  614. return 1;
  615. }
  616. #endif