board.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net>
  4. * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
  5. *
  6. * (C) Copyright 2007-2011
  7. * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
  8. * Tom Cubie <tangliang@allwinnertech.com>
  9. *
  10. * Some board init for the Allwinner A10-evb board.
  11. */
  12. #include <common.h>
  13. #include <dm.h>
  14. #include <env.h>
  15. #include <hang.h>
  16. #include <image.h>
  17. #include <init.h>
  18. #include <log.h>
  19. #include <mmc.h>
  20. #include <axp_pmic.h>
  21. #include <generic-phy.h>
  22. #include <phy-sun4i-usb.h>
  23. #include <asm/arch/clock.h>
  24. #include <asm/arch/cpu.h>
  25. #include <asm/arch/display.h>
  26. #include <asm/arch/dram.h>
  27. #include <asm/arch/gpio.h>
  28. #include <asm/arch/mmc.h>
  29. #include <asm/arch/prcm.h>
  30. #include <asm/arch/spl.h>
  31. #include <asm/global_data.h>
  32. #include <linux/delay.h>
  33. #include <u-boot/crc.h>
  34. #ifndef CONFIG_ARM64
  35. #include <asm/armv7.h>
  36. #endif
  37. #include <asm/gpio.h>
  38. #include <asm/io.h>
  39. #include <u-boot/crc.h>
  40. #include <env_internal.h>
  41. #include <linux/libfdt.h>
  42. #include <fdt_support.h>
  43. #include <nand.h>
  44. #include <net.h>
  45. #include <spl.h>
  46. #include <sy8106a.h>
  47. #include <asm/setup.h>
  48. #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
  49. /* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */
  50. int soft_i2c_gpio_sda;
  51. int soft_i2c_gpio_scl;
  52. static int soft_i2c_board_init(void)
  53. {
  54. int ret;
  55. soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA);
  56. if (soft_i2c_gpio_sda < 0) {
  57. printf("Error invalid soft i2c sda pin: '%s', err %d\n",
  58. CONFIG_VIDEO_LCD_PANEL_I2C_SDA, soft_i2c_gpio_sda);
  59. return soft_i2c_gpio_sda;
  60. }
  61. ret = gpio_request(soft_i2c_gpio_sda, "soft-i2c-sda");
  62. if (ret) {
  63. printf("Error requesting soft i2c sda pin: '%s', err %d\n",
  64. CONFIG_VIDEO_LCD_PANEL_I2C_SDA, ret);
  65. return ret;
  66. }
  67. soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL);
  68. if (soft_i2c_gpio_scl < 0) {
  69. printf("Error invalid soft i2c scl pin: '%s', err %d\n",
  70. CONFIG_VIDEO_LCD_PANEL_I2C_SCL, soft_i2c_gpio_scl);
  71. return soft_i2c_gpio_scl;
  72. }
  73. ret = gpio_request(soft_i2c_gpio_scl, "soft-i2c-scl");
  74. if (ret) {
  75. printf("Error requesting soft i2c scl pin: '%s', err %d\n",
  76. CONFIG_VIDEO_LCD_PANEL_I2C_SCL, ret);
  77. return ret;
  78. }
  79. return 0;
  80. }
  81. #else
  82. static int soft_i2c_board_init(void) { return 0; }
  83. #endif
  84. DECLARE_GLOBAL_DATA_PTR;
  85. void i2c_init_board(void)
  86. {
  87. #ifdef CONFIG_I2C0_ENABLE
  88. #if defined(CONFIG_MACH_SUN4I) || \
  89. defined(CONFIG_MACH_SUN5I) || \
  90. defined(CONFIG_MACH_SUN7I) || \
  91. defined(CONFIG_MACH_SUN8I_R40)
  92. sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0);
  93. sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0);
  94. clock_twi_onoff(0, 1);
  95. #elif defined(CONFIG_MACH_SUN6I)
  96. sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
  97. sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
  98. clock_twi_onoff(0, 1);
  99. #elif defined(CONFIG_MACH_SUN8I_V3S)
  100. sunxi_gpio_set_cfgpin(SUNXI_GPB(6), SUN8I_V3S_GPB_TWI0);
  101. sunxi_gpio_set_cfgpin(SUNXI_GPB(7), SUN8I_V3S_GPB_TWI0);
  102. clock_twi_onoff(0, 1);
  103. #elif defined(CONFIG_MACH_SUN8I)
  104. sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
  105. sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
  106. clock_twi_onoff(0, 1);
  107. #elif defined(CONFIG_MACH_SUN50I)
  108. sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_GPH_TWI0);
  109. sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_GPH_TWI0);
  110. clock_twi_onoff(0, 1);
  111. #endif
  112. #endif
  113. #ifdef CONFIG_I2C1_ENABLE
  114. #if defined(CONFIG_MACH_SUN4I) || \
  115. defined(CONFIG_MACH_SUN7I) || \
  116. defined(CONFIG_MACH_SUN8I_R40)
  117. sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1);
  118. sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1);
  119. clock_twi_onoff(1, 1);
  120. #elif defined(CONFIG_MACH_SUN5I)
  121. sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1);
  122. sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1);
  123. clock_twi_onoff(1, 1);
  124. #elif defined(CONFIG_MACH_SUN6I)
  125. sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1);
  126. sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1);
  127. clock_twi_onoff(1, 1);
  128. #elif defined(CONFIG_MACH_SUN8I)
  129. sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
  130. sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
  131. clock_twi_onoff(1, 1);
  132. #elif defined(CONFIG_MACH_SUN50I)
  133. sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN50I_GPH_TWI1);
  134. sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1);
  135. clock_twi_onoff(1, 1);
  136. #endif
  137. #endif
  138. #ifdef CONFIG_I2C2_ENABLE
  139. #if defined(CONFIG_MACH_SUN4I) || \
  140. defined(CONFIG_MACH_SUN7I) || \
  141. defined(CONFIG_MACH_SUN8I_R40)
  142. sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2);
  143. sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2);
  144. clock_twi_onoff(2, 1);
  145. #elif defined(CONFIG_MACH_SUN5I)
  146. sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2);
  147. sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2);
  148. clock_twi_onoff(2, 1);
  149. #elif defined(CONFIG_MACH_SUN6I)
  150. sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2);
  151. sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2);
  152. clock_twi_onoff(2, 1);
  153. #elif defined(CONFIG_MACH_SUN8I)
  154. sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
  155. sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
  156. clock_twi_onoff(2, 1);
  157. #elif defined(CONFIG_MACH_SUN50I)
  158. sunxi_gpio_set_cfgpin(SUNXI_GPE(14), SUN50I_GPE_TWI2);
  159. sunxi_gpio_set_cfgpin(SUNXI_GPE(15), SUN50I_GPE_TWI2);
  160. clock_twi_onoff(2, 1);
  161. #endif
  162. #endif
  163. #ifdef CONFIG_I2C3_ENABLE
  164. #if defined(CONFIG_MACH_SUN6I)
  165. sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3);
  166. sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3);
  167. clock_twi_onoff(3, 1);
  168. #elif defined(CONFIG_MACH_SUN7I) || \
  169. defined(CONFIG_MACH_SUN8I_R40)
  170. sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3);
  171. sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3);
  172. clock_twi_onoff(3, 1);
  173. #endif
  174. #endif
  175. #ifdef CONFIG_I2C4_ENABLE
  176. #if defined(CONFIG_MACH_SUN7I) || \
  177. defined(CONFIG_MACH_SUN8I_R40)
  178. sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4);
  179. sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4);
  180. clock_twi_onoff(4, 1);
  181. #endif
  182. #endif
  183. #ifdef CONFIG_R_I2C_ENABLE
  184. #ifdef CONFIG_MACH_SUN50I
  185. clock_twi_onoff(5, 1);
  186. sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI);
  187. sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI);
  188. #elif CONFIG_MACH_SUN50I_H616
  189. clock_twi_onoff(5, 1);
  190. sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN50I_H616_GPL_R_TWI);
  191. sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN50I_H616_GPL_R_TWI);
  192. #else
  193. clock_twi_onoff(5, 1);
  194. sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
  195. sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
  196. #endif
  197. #endif
  198. }
  199. #if defined(CONFIG_ENV_IS_IN_MMC) && defined(CONFIG_ENV_IS_IN_FAT)
  200. enum env_location env_get_location(enum env_operation op, int prio)
  201. {
  202. switch (prio) {
  203. case 0:
  204. return ENVL_FAT;
  205. case 1:
  206. return ENVL_MMC;
  207. default:
  208. return ENVL_UNKNOWN;
  209. }
  210. }
  211. #endif
  212. #ifdef CONFIG_DM_MMC
  213. static void mmc_pinmux_setup(int sdc);
  214. #endif
  215. /* add board specific code here */
  216. int board_init(void)
  217. {
  218. __maybe_unused int id_pfr1, ret, satapwr_pin, macpwr_pin;
  219. gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
  220. #ifndef CONFIG_ARM64
  221. asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
  222. debug("id_pfr1: 0x%08x\n", id_pfr1);
  223. /* Generic Timer Extension available? */
  224. if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) {
  225. uint32_t freq;
  226. debug("Setting CNTFRQ\n");
  227. /*
  228. * CNTFRQ is a secure register, so we will crash if we try to
  229. * write this from the non-secure world (read is OK, though).
  230. * In case some bootcode has already set the correct value,
  231. * we avoid the risk of writing to it.
  232. */
  233. asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq));
  234. if (freq != COUNTER_FREQUENCY) {
  235. debug("arch timer frequency is %d Hz, should be %d, fixing ...\n",
  236. freq, COUNTER_FREQUENCY);
  237. #ifdef CONFIG_NON_SECURE
  238. printf("arch timer frequency is wrong, but cannot adjust it\n");
  239. #else
  240. asm volatile("mcr p15, 0, %0, c14, c0, 0"
  241. : : "r"(COUNTER_FREQUENCY));
  242. #endif
  243. }
  244. }
  245. #endif /* !CONFIG_ARM64 */
  246. ret = axp_gpio_init();
  247. if (ret)
  248. return ret;
  249. /* strcmp() would look better, but doesn't get optimised away. */
  250. if (CONFIG_SATAPWR[0]) {
  251. satapwr_pin = sunxi_name_to_gpio(CONFIG_SATAPWR);
  252. if (satapwr_pin >= 0) {
  253. gpio_request(satapwr_pin, "satapwr");
  254. gpio_direction_output(satapwr_pin, 1);
  255. /*
  256. * Give the attached SATA device time to power-up
  257. * to avoid link timeouts
  258. */
  259. mdelay(500);
  260. }
  261. }
  262. if (CONFIG_MACPWR[0]) {
  263. macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
  264. if (macpwr_pin >= 0) {
  265. gpio_request(macpwr_pin, "macpwr");
  266. gpio_direction_output(macpwr_pin, 1);
  267. }
  268. }
  269. #if CONFIG_IS_ENABLED(DM_I2C)
  270. /*
  271. * Temporary workaround for enabling I2C clocks until proper sunxi DM
  272. * clk, reset and pinctrl drivers land.
  273. */
  274. i2c_init_board();
  275. #endif
  276. #ifdef CONFIG_DM_MMC
  277. /*
  278. * Temporary workaround for enabling MMC clocks until a sunxi DM
  279. * pinctrl driver lands.
  280. */
  281. mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
  282. #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
  283. mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
  284. #endif
  285. #endif /* CONFIG_DM_MMC */
  286. /* Uses dm gpio code so do this here and not in i2c_init_board() */
  287. return soft_i2c_board_init();
  288. }
  289. /*
  290. * On older SoCs the SPL is actually at address zero, so using NULL as
  291. * an error value does not work.
  292. */
  293. #define INVALID_SPL_HEADER ((void *)~0UL)
  294. static struct boot_file_head * get_spl_header(uint8_t req_version)
  295. {
  296. struct boot_file_head *spl = (void *)(ulong)SPL_ADDR;
  297. uint8_t spl_header_version = spl->spl_signature[3];
  298. /* Is there really the SPL header (still) there? */
  299. if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
  300. return INVALID_SPL_HEADER;
  301. if (spl_header_version < req_version) {
  302. printf("sunxi SPL version mismatch: expected %u, got %u\n",
  303. req_version, spl_header_version);
  304. return INVALID_SPL_HEADER;
  305. }
  306. return spl;
  307. }
  308. static const char *get_spl_dt_name(void)
  309. {
  310. struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
  311. /* Check if there is a DT name stored in the SPL header. */
  312. if (spl != INVALID_SPL_HEADER && spl->dt_name_offset)
  313. return (char *)spl + spl->dt_name_offset;
  314. return NULL;
  315. }
  316. int dram_init(void)
  317. {
  318. struct boot_file_head *spl = get_spl_header(SPL_DRAM_HEADER_VERSION);
  319. if (spl == INVALID_SPL_HEADER)
  320. gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0,
  321. PHYS_SDRAM_0_SIZE);
  322. else
  323. gd->ram_size = (phys_addr_t)spl->dram_size << 20;
  324. if (gd->ram_size > CONFIG_SUNXI_DRAM_MAX_SIZE)
  325. gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE;
  326. return 0;
  327. }
  328. #if defined(CONFIG_NAND_SUNXI)
  329. static void nand_pinmux_setup(void)
  330. {
  331. unsigned int pin;
  332. for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++)
  333. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
  334. #if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I
  335. for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++)
  336. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
  337. #endif
  338. /* sun4i / sun7i do have a PC23, but it is not used for nand,
  339. * only sun7i has a PC24 */
  340. #ifdef CONFIG_MACH_SUN7I
  341. sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
  342. #endif
  343. }
  344. static void nand_clock_setup(void)
  345. {
  346. struct sunxi_ccm_reg *const ccm =
  347. (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
  348. setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
  349. #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I || \
  350. defined CONFIG_MACH_SUN9I || defined CONFIG_MACH_SUN50I
  351. setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_NAND0));
  352. #endif
  353. setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
  354. }
  355. void board_nand_init(void)
  356. {
  357. nand_pinmux_setup();
  358. nand_clock_setup();
  359. #ifndef CONFIG_SPL_BUILD
  360. sunxi_nand_init();
  361. #endif
  362. }
  363. #endif
  364. #ifdef CONFIG_MMC
  365. static void mmc_pinmux_setup(int sdc)
  366. {
  367. unsigned int pin;
  368. __maybe_unused int pins;
  369. switch (sdc) {
  370. case 0:
  371. /* SDC0: PF0-PF5 */
  372. for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) {
  373. sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0);
  374. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  375. sunxi_gpio_set_drv(pin, 2);
  376. }
  377. break;
  378. case 1:
  379. pins = sunxi_name_to_gpio_bank(CONFIG_MMC1_PINS);
  380. #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
  381. defined(CONFIG_MACH_SUN8I_R40)
  382. if (pins == SUNXI_GPIO_H) {
  383. /* SDC1: PH22-PH-27 */
  384. for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) {
  385. sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1);
  386. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  387. sunxi_gpio_set_drv(pin, 2);
  388. }
  389. } else {
  390. /* SDC1: PG0-PG5 */
  391. for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
  392. sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1);
  393. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  394. sunxi_gpio_set_drv(pin, 2);
  395. }
  396. }
  397. #elif defined(CONFIG_MACH_SUN5I)
  398. /* SDC1: PG3-PG8 */
  399. for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) {
  400. sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1);
  401. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  402. sunxi_gpio_set_drv(pin, 2);
  403. }
  404. #elif defined(CONFIG_MACH_SUN6I)
  405. /* SDC1: PG0-PG5 */
  406. for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
  407. sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1);
  408. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  409. sunxi_gpio_set_drv(pin, 2);
  410. }
  411. #elif defined(CONFIG_MACH_SUN8I)
  412. if (pins == SUNXI_GPIO_D) {
  413. /* SDC1: PD2-PD7 */
  414. for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) {
  415. sunxi_gpio_set_cfgpin(pin, SUN8I_GPD_SDC1);
  416. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  417. sunxi_gpio_set_drv(pin, 2);
  418. }
  419. } else {
  420. /* SDC1: PG0-PG5 */
  421. for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
  422. sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1);
  423. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  424. sunxi_gpio_set_drv(pin, 2);
  425. }
  426. }
  427. #endif
  428. break;
  429. case 2:
  430. pins = sunxi_name_to_gpio_bank(CONFIG_MMC2_PINS);
  431. #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
  432. /* SDC2: PC6-PC11 */
  433. for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) {
  434. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  435. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  436. sunxi_gpio_set_drv(pin, 2);
  437. }
  438. #elif defined(CONFIG_MACH_SUN5I)
  439. if (pins == SUNXI_GPIO_E) {
  440. /* SDC2: PE4-PE9 */
  441. for (pin = SUNXI_GPE(4); pin <= SUNXI_GPD(9); pin++) {
  442. sunxi_gpio_set_cfgpin(pin, SUN5I_GPE_SDC2);
  443. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  444. sunxi_gpio_set_drv(pin, 2);
  445. }
  446. } else {
  447. /* SDC2: PC6-PC15 */
  448. for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
  449. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  450. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  451. sunxi_gpio_set_drv(pin, 2);
  452. }
  453. }
  454. #elif defined(CONFIG_MACH_SUN6I)
  455. if (pins == SUNXI_GPIO_A) {
  456. /* SDC2: PA9-PA14 */
  457. for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
  458. sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC2);
  459. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  460. sunxi_gpio_set_drv(pin, 2);
  461. }
  462. } else {
  463. /* SDC2: PC6-PC15, PC24 */
  464. for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
  465. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  466. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  467. sunxi_gpio_set_drv(pin, 2);
  468. }
  469. sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
  470. sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
  471. sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
  472. }
  473. #elif defined(CONFIG_MACH_SUN8I_R40)
  474. /* SDC2: PC6-PC15, PC24 */
  475. for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
  476. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  477. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  478. sunxi_gpio_set_drv(pin, 2);
  479. }
  480. sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
  481. sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
  482. sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
  483. #elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I)
  484. /* SDC2: PC5-PC6, PC8-PC16 */
  485. for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
  486. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  487. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  488. sunxi_gpio_set_drv(pin, 2);
  489. }
  490. for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) {
  491. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  492. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  493. sunxi_gpio_set_drv(pin, 2);
  494. }
  495. #elif defined(CONFIG_MACH_SUN50I_H6)
  496. /* SDC2: PC4-PC14 */
  497. for (pin = SUNXI_GPC(4); pin <= SUNXI_GPC(14); pin++) {
  498. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  499. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  500. sunxi_gpio_set_drv(pin, 2);
  501. }
  502. #elif defined(CONFIG_MACH_SUN50I_H616)
  503. /* SDC2: PC0-PC1, PC5-PC6, PC8-PC11, PC13-PC16 */
  504. for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(16); pin++) {
  505. if (pin > SUNXI_GPC(1) && pin < SUNXI_GPC(5))
  506. continue;
  507. if (pin == SUNXI_GPC(7) || pin == SUNXI_GPC(12))
  508. continue;
  509. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  510. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  511. sunxi_gpio_set_drv(pin, 3);
  512. }
  513. #elif defined(CONFIG_MACH_SUN9I)
  514. /* SDC2: PC6-PC16 */
  515. for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(16); pin++) {
  516. sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
  517. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  518. sunxi_gpio_set_drv(pin, 2);
  519. }
  520. #else
  521. puts("ERROR: No pinmux setup defined for MMC2!\n");
  522. #endif
  523. break;
  524. case 3:
  525. pins = sunxi_name_to_gpio_bank(CONFIG_MMC3_PINS);
  526. #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
  527. defined(CONFIG_MACH_SUN8I_R40)
  528. /* SDC3: PI4-PI9 */
  529. for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) {
  530. sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3);
  531. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  532. sunxi_gpio_set_drv(pin, 2);
  533. }
  534. #elif defined(CONFIG_MACH_SUN6I)
  535. if (pins == SUNXI_GPIO_A) {
  536. /* SDC3: PA9-PA14 */
  537. for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
  538. sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC3);
  539. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  540. sunxi_gpio_set_drv(pin, 2);
  541. }
  542. } else {
  543. /* SDC3: PC6-PC15, PC24 */
  544. for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
  545. sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3);
  546. sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
  547. sunxi_gpio_set_drv(pin, 2);
  548. }
  549. sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3);
  550. sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
  551. sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
  552. }
  553. #endif
  554. break;
  555. default:
  556. printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc);
  557. break;
  558. }
  559. }
  560. int board_mmc_init(struct bd_info *bis)
  561. {
  562. __maybe_unused struct mmc *mmc0, *mmc1;
  563. mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
  564. mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
  565. if (!mmc0)
  566. return -1;
  567. #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
  568. mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
  569. mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
  570. if (!mmc1)
  571. return -1;
  572. #endif
  573. return 0;
  574. }
  575. #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
  576. int mmc_get_env_dev(void)
  577. {
  578. switch (sunxi_get_boot_device()) {
  579. case BOOT_DEVICE_MMC1:
  580. return 0;
  581. case BOOT_DEVICE_MMC2:
  582. return 1;
  583. default:
  584. return CONFIG_SYS_MMC_ENV_DEV;
  585. }
  586. }
  587. #endif
  588. #endif
  589. #ifdef CONFIG_SPL_BUILD
  590. static void sunxi_spl_store_dram_size(phys_addr_t dram_size)
  591. {
  592. struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
  593. if (spl == INVALID_SPL_HEADER)
  594. return;
  595. /* Promote the header version for U-Boot proper, if needed. */
  596. if (spl->spl_signature[3] < SPL_DRAM_HEADER_VERSION)
  597. spl->spl_signature[3] = SPL_DRAM_HEADER_VERSION;
  598. spl->dram_size = dram_size >> 20;
  599. }
  600. void sunxi_board_init(void)
  601. {
  602. int power_failed = 0;
  603. #ifdef CONFIG_SY8106A_POWER
  604. power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT);
  605. #endif
  606. #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
  607. defined CONFIG_AXP221_POWER || defined CONFIG_AXP305_POWER || \
  608. defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
  609. power_failed = axp_init();
  610. #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
  611. defined CONFIG_AXP818_POWER
  612. power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT);
  613. #endif
  614. #if !defined(CONFIG_AXP305_POWER)
  615. power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT);
  616. power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT);
  617. #endif
  618. #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER)
  619. power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT);
  620. #endif
  621. #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
  622. defined CONFIG_AXP818_POWER
  623. power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT);
  624. #endif
  625. #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
  626. defined CONFIG_AXP818_POWER
  627. power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT);
  628. #endif
  629. #if !defined(CONFIG_AXP305_POWER)
  630. power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT);
  631. #endif
  632. #if !defined(CONFIG_AXP152_POWER) && !defined(CONFIG_AXP305_POWER)
  633. power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT);
  634. #endif
  635. #ifdef CONFIG_AXP209_POWER
  636. power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT);
  637. #endif
  638. #if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP809_POWER) || \
  639. defined(CONFIG_AXP818_POWER)
  640. power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT);
  641. power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT);
  642. #if !defined CONFIG_AXP809_POWER
  643. power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT);
  644. power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT);
  645. #endif
  646. power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT);
  647. power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT);
  648. power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT);
  649. #endif
  650. #ifdef CONFIG_AXP818_POWER
  651. power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT);
  652. power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT);
  653. power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT);
  654. #endif
  655. #if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
  656. power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON));
  657. #endif
  658. #endif
  659. printf("DRAM:");
  660. gd->ram_size = sunxi_dram_init();
  661. printf(" %d MiB\n", (int)(gd->ram_size >> 20));
  662. if (!gd->ram_size)
  663. hang();
  664. sunxi_spl_store_dram_size(gd->ram_size);
  665. /*
  666. * Only clock up the CPU to full speed if we are reasonably
  667. * assured it's being powered with suitable core voltage
  668. */
  669. if (!power_failed)
  670. clock_set_pll1(CONFIG_SYS_CLK_FREQ);
  671. else
  672. printf("Failed to set core voltage! Can't set CPU frequency\n");
  673. }
  674. #endif
  675. #ifdef CONFIG_USB_GADGET
  676. int g_dnl_board_usb_cable_connected(void)
  677. {
  678. struct udevice *dev;
  679. struct phy phy;
  680. int ret;
  681. ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
  682. if (ret) {
  683. pr_err("%s: Cannot find USB device\n", __func__);
  684. return ret;
  685. }
  686. ret = generic_phy_get_by_name(dev, "usb", &phy);
  687. if (ret) {
  688. pr_err("failed to get %s USB PHY\n", dev->name);
  689. return ret;
  690. }
  691. ret = generic_phy_init(&phy);
  692. if (ret) {
  693. pr_debug("failed to init %s USB PHY\n", dev->name);
  694. return ret;
  695. }
  696. ret = sun4i_usb_phy_vbus_detect(&phy);
  697. if (ret == 1) {
  698. pr_err("A charger is plugged into the OTG\n");
  699. return -ENODEV;
  700. }
  701. return ret;
  702. }
  703. #endif
  704. #ifdef CONFIG_SERIAL_TAG
  705. void get_board_serial(struct tag_serialnr *serialnr)
  706. {
  707. char *serial_string;
  708. unsigned long long serial;
  709. serial_string = env_get("serial#");
  710. if (serial_string) {
  711. serial = simple_strtoull(serial_string, NULL, 16);
  712. serialnr->high = (unsigned int) (serial >> 32);
  713. serialnr->low = (unsigned int) (serial & 0xffffffff);
  714. } else {
  715. serialnr->high = 0;
  716. serialnr->low = 0;
  717. }
  718. }
  719. #endif
  720. /*
  721. * Check the SPL header for the "sunxi" variant. If found: parse values
  722. * that might have been passed by the loader ("fel" utility), and update
  723. * the environment accordingly.
  724. */
  725. static void parse_spl_header(const uint32_t spl_addr)
  726. {
  727. struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);
  728. if (spl == INVALID_SPL_HEADER)
  729. return;
  730. if (!spl->fel_script_address)
  731. return;
  732. if (spl->fel_uEnv_length != 0) {
  733. /*
  734. * data is expected in uEnv.txt compatible format, so "env
  735. * import -t" the string(s) at fel_script_address right away.
  736. */
  737. himport_r(&env_htab, (char *)(uintptr_t)spl->fel_script_address,
  738. spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
  739. return;
  740. }
  741. /* otherwise assume .scr format (mkimage-type script) */
  742. env_set_hex("fel_scriptaddr", spl->fel_script_address);
  743. }
  744. static bool get_unique_sid(unsigned int *sid)
  745. {
  746. if (sunxi_get_sid(sid) != 0)
  747. return false;
  748. if (!sid[0])
  749. return false;
  750. /*
  751. * The single words 1 - 3 of the SID have quite a few bits
  752. * which are the same on many models, so we take a crc32
  753. * of all 3 words, to get a more unique value.
  754. *
  755. * Note we only do this on newer SoCs as we cannot change
  756. * the algorithm on older SoCs since those have been using
  757. * fixed mac-addresses based on only using word 3 for a
  758. * long time and changing a fixed mac-address with an
  759. * u-boot update is not good.
  760. */
  761. #if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \
  762. !defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \
  763. !defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33)
  764. sid[3] = crc32(0, (unsigned char *)&sid[1], 12);
  765. #endif
  766. /* Ensure the NIC specific bytes of the mac are not all 0 */
  767. if ((sid[3] & 0xffffff) == 0)
  768. sid[3] |= 0x800000;
  769. return true;
  770. }
  771. /*
  772. * Note this function gets called multiple times.
  773. * It must not make any changes to env variables which already exist.
  774. */
  775. static void setup_environment(const void *fdt)
  776. {
  777. char serial_string[17] = { 0 };
  778. unsigned int sid[4];
  779. uint8_t mac_addr[6];
  780. char ethaddr[16];
  781. int i;
  782. if (!get_unique_sid(sid))
  783. return;
  784. for (i = 0; i < 4; i++) {
  785. sprintf(ethaddr, "ethernet%d", i);
  786. if (!fdt_get_alias(fdt, ethaddr))
  787. continue;
  788. if (i == 0)
  789. strcpy(ethaddr, "ethaddr");
  790. else
  791. sprintf(ethaddr, "eth%daddr", i);
  792. if (env_get(ethaddr))
  793. continue;
  794. /* Non OUI / registered MAC address */
  795. mac_addr[0] = (i << 4) | 0x02;
  796. mac_addr[1] = (sid[0] >> 0) & 0xff;
  797. mac_addr[2] = (sid[3] >> 24) & 0xff;
  798. mac_addr[3] = (sid[3] >> 16) & 0xff;
  799. mac_addr[4] = (sid[3] >> 8) & 0xff;
  800. mac_addr[5] = (sid[3] >> 0) & 0xff;
  801. eth_env_set_enetaddr(ethaddr, mac_addr);
  802. }
  803. if (!env_get("serial#")) {
  804. snprintf(serial_string, sizeof(serial_string),
  805. "%08x%08x", sid[0], sid[3]);
  806. env_set("serial#", serial_string);
  807. }
  808. }
  809. int misc_init_r(void)
  810. {
  811. const char *spl_dt_name;
  812. uint boot;
  813. env_set("fel_booted", NULL);
  814. env_set("fel_scriptaddr", NULL);
  815. env_set("mmc_bootdev", NULL);
  816. boot = sunxi_get_boot_device();
  817. /* determine if we are running in FEL mode */
  818. if (boot == BOOT_DEVICE_BOARD) {
  819. env_set("fel_booted", "1");
  820. parse_spl_header(SPL_ADDR);
  821. /* or if we booted from MMC, and which one */
  822. } else if (boot == BOOT_DEVICE_MMC1) {
  823. env_set("mmc_bootdev", "0");
  824. } else if (boot == BOOT_DEVICE_MMC2) {
  825. env_set("mmc_bootdev", "1");
  826. }
  827. /* Set fdtfile to match the FIT configuration chosen in SPL. */
  828. spl_dt_name = get_spl_dt_name();
  829. if (spl_dt_name) {
  830. char *prefix = IS_ENABLED(CONFIG_ARM64) ? "allwinner/" : "";
  831. char str[64];
  832. snprintf(str, sizeof(str), "%s%s.dtb", prefix, spl_dt_name);
  833. env_set("fdtfile", str);
  834. }
  835. setup_environment(gd->fdt_blob);
  836. return 0;
  837. }
  838. int board_late_init(void)
  839. {
  840. #ifdef CONFIG_USB_ETHER
  841. usb_ether_init();
  842. #endif
  843. return 0;
  844. }
  845. static void bluetooth_dt_fixup(void *blob)
  846. {
  847. /* Some devices ship with a Bluetooth controller default address.
  848. * Set a valid address through the device tree.
  849. */
  850. uchar tmp[ETH_ALEN], bdaddr[ETH_ALEN];
  851. unsigned int sid[4];
  852. int i;
  853. if (!CONFIG_BLUETOOTH_DT_DEVICE_FIXUP[0])
  854. return;
  855. if (eth_env_get_enetaddr("bdaddr", tmp)) {
  856. /* Convert between the binary formats of the corresponding stacks */
  857. for (i = 0; i < ETH_ALEN; ++i)
  858. bdaddr[i] = tmp[ETH_ALEN - i - 1];
  859. } else {
  860. if (!get_unique_sid(sid))
  861. return;
  862. bdaddr[0] = ((sid[3] >> 0) & 0xff) ^ 1;
  863. bdaddr[1] = (sid[3] >> 8) & 0xff;
  864. bdaddr[2] = (sid[3] >> 16) & 0xff;
  865. bdaddr[3] = (sid[3] >> 24) & 0xff;
  866. bdaddr[4] = (sid[0] >> 0) & 0xff;
  867. bdaddr[5] = 0x02;
  868. }
  869. do_fixup_by_compat(blob, CONFIG_BLUETOOTH_DT_DEVICE_FIXUP,
  870. "local-bd-address", bdaddr, ETH_ALEN, 1);
  871. }
  872. int ft_board_setup(void *blob, struct bd_info *bd)
  873. {
  874. int __maybe_unused r;
  875. /*
  876. * Call setup_environment again in case the boot fdt has
  877. * ethernet aliases the u-boot copy does not have.
  878. */
  879. setup_environment(blob);
  880. bluetooth_dt_fixup(blob);
  881. #ifdef CONFIG_VIDEO_DT_SIMPLEFB
  882. r = sunxi_simplefb_setup(blob);
  883. if (r)
  884. return r;
  885. #endif
  886. return 0;
  887. }
  888. #ifdef CONFIG_SPL_LOAD_FIT
  889. static void set_spl_dt_name(const char *name)
  890. {
  891. struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);
  892. if (spl == INVALID_SPL_HEADER)
  893. return;
  894. /* Promote the header version for U-Boot proper, if needed. */
  895. if (spl->spl_signature[3] < SPL_DT_HEADER_VERSION)
  896. spl->spl_signature[3] = SPL_DT_HEADER_VERSION;
  897. strcpy((char *)&spl->string_pool, name);
  898. spl->dt_name_offset = offsetof(struct boot_file_head, string_pool);
  899. }
  900. int board_fit_config_name_match(const char *name)
  901. {
  902. const char *best_dt_name = get_spl_dt_name();
  903. int ret;
  904. #ifdef CONFIG_DEFAULT_DEVICE_TREE
  905. if (best_dt_name == NULL)
  906. best_dt_name = CONFIG_DEFAULT_DEVICE_TREE;
  907. #endif
  908. if (best_dt_name == NULL) {
  909. /* No DT name was provided, so accept the first config. */
  910. return 0;
  911. }
  912. #ifdef CONFIG_PINE64_DT_SELECTION
  913. if (strstr(best_dt_name, "-pine64-plus")) {
  914. /* Differentiate the Pine A64 boards by their DRAM size. */
  915. if ((gd->ram_size == 512 * 1024 * 1024))
  916. best_dt_name = "sun50i-a64-pine64";
  917. }
  918. #endif
  919. #ifdef CONFIG_PINEPHONE_DT_SELECTION
  920. if (strstr(best_dt_name, "-pinephone")) {
  921. /* Differentiate the PinePhone revisions by GPIO inputs. */
  922. prcm_apb0_enable(PRCM_APB0_GATE_PIO);
  923. sunxi_gpio_set_pull(SUNXI_GPL(6), SUNXI_GPIO_PULL_UP);
  924. sunxi_gpio_set_cfgpin(SUNXI_GPL(6), SUNXI_GPIO_INPUT);
  925. udelay(100);
  926. /* PL6 is pulled low by the modem on v1.2. */
  927. if (gpio_get_value(SUNXI_GPL(6)) == 0)
  928. best_dt_name = "sun50i-a64-pinephone-1.2";
  929. else
  930. best_dt_name = "sun50i-a64-pinephone-1.1";
  931. sunxi_gpio_set_cfgpin(SUNXI_GPL(6), SUNXI_GPIO_DISABLE);
  932. sunxi_gpio_set_pull(SUNXI_GPL(6), SUNXI_GPIO_PULL_DISABLE);
  933. prcm_apb0_disable(PRCM_APB0_GATE_PIO);
  934. }
  935. #endif
  936. ret = strcmp(name, best_dt_name);
  937. /*
  938. * If one of the FIT configurations matches the most accurate DT name,
  939. * update the SPL header to provide that DT name to U-Boot proper.
  940. */
  941. if (ret == 0)
  942. set_spl_dt_name(best_dt_name);
  943. return ret;
  944. }
  945. #endif