Beagleboard-xMのブートローダ(x-loader, u-boot)がrev.Bとrev.Cで処理を分岐しているところを眺めてみる
ネタは古めなんだけどちゃんと調べてなかったので掘り返してみた。
iseroidさんのblog
http://iseroid.blogspot.com/2012/02/beagleboard-xmicsandroid40revb.html
を読んでいると
Beagleboard-xMのrev.A/Bとrev.Cの違いは
Beagleboard-xMの電源を入れた時にUSBハブチップの出力電源がハードウェア的に
ONになっているのがrev.A/B
OFFになっているのがrev.C
ということらしい。
つまりrev.CではUSBハブの電源をONにしてやる処理が必要になる。
このあたりどこで処理を分岐しているのか、ソースコードを眺めてみた。
結論から言うとrev.A/Bとrev.Cの間で処理を分岐させているというよりも、
rev.Cで変更のあった箇所の処理をrev.A/Bでも(問題ないから)かぶせて実行しているようだ。
眺めたソースコードは
TI DevKit 2.1の
TI_Android_GingerBread_2_3_4Sources
http://software-dl.ti.com/dsps/dsps_public_sw/sdo_tii/TI_Android_DevKit/TI_Android_GingerBread_2_3_4_DevKit_2_1/index_FDS.html
1.x-loaderのソースコード
x-loaderのソースコードを眺めてみると
Beagleboard-xMのrev.A/Bかrev.Cの判定はGPIOの171,172,173でやっているらしい。
rev.A/Bとrev.C間で分岐させている処理はリビジョンのprintfくらい。
GPIO173 | GPIO172 | GPIO171 | |
XM rev.A/B | 0 | 0 | 0 |
XM rev.C | 0 | 1 | 0 |
x-loader/board/omap3beagle/omap3beagle.c
/* BeagleBoard revisions */ #define REVISION_AXBX 0x7 #define REVISION_CX 0x6 #define REVISION_C4 0x5 #define REVISION_XM 0x0 #define REVISION_XMC 0x2 ...(中略)... /****************************************** * beagle_identify * Description: Detect if we are running on a Beagle revision Ax/Bx, * C1/2/3, C4 or D. This can be done by reading * the level of GPIO173, GPIO172 and GPIO171. This should * result in * GPIO173, GPIO172, GPIO171: 1 1 1 => Ax/Bx * GPIO173, GPIO172, GPIO171: 1 1 0 => C1/2/3 * GPIO173, GPIO172, GPIO171: 1 0 1 => C4 * GPIO173, GPIO172, GPIO171: 0 0 0 => XM ******************************************/ int beagle_revision(void) { ...(中略)... /********************************************************************* * config_3430sdram_ddr() - Init DDR on 3430SDP dev board. *********************************************************************/ void config_3430sdram_ddr(void) { /* reset sdrc controller */ __raw_writel(SOFTRESET, SDRC_SYSCONFIG); wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000); __raw_writel(0, SDRC_SYSCONFIG); /* setup sdrc to ball mux */ __raw_writel(SDP_SDRC_SHARING, SDRC_SHARING); if ((beagle_revision() == REVISION_XM) || (beagle_revision() == REVISION_XMC)) { __raw_writel(0x2, SDRC_CS_CFG); /* 256MB/bank */ __raw_writel(SDP_SDRC_MDCFG_0_DDR_XM, SDRC_MCFG_0); __raw_writel(SDP_SDRC_MDCFG_0_DDR_XM, SDRC_MCFG_1); __raw_writel(MICRON_V_ACTIMA_200, SDRC_ACTIM_CTRLA_0); __raw_writel(MICRON_V_ACTIMB_200, SDRC_ACTIM_CTRLB_0); __raw_writel(MICRON_V_ACTIMA_200, SDRC_ACTIM_CTRLA_1); __raw_writel(MICRON_V_ACTIMB_200, SDRC_ACTIM_CTRLB_1); __raw_writel(SDP_3430_SDRC_RFR_CTRL_200MHz, SDRC_RFR_CTRL_0); __raw_writel(SDP_3430_SDRC_RFR_CTRL_200MHz, SDRC_RFR_CTRL_1); } else { __raw_writel(0x1, SDRC_CS_CFG); /* 128MB/bank */ __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_1); __raw_writel(MICRON_V_ACTIMA_165, SDRC_ACTIM_CTRLA_0); __raw_writel(MICRON_V_ACTIMB_165, SDRC_ACTIM_CTRLB_0); __raw_writel(MICRON_V_ACTIMA_165, SDRC_ACTIM_CTRLA_1); __raw_writel(MICRON_V_ACTIMB_165, SDRC_ACTIM_CTRLB_1); __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_0); __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_1); } ... /******************************************************* * Routine: misc_init_r * Description: Init ethernet (done here so udelay works) ********************************************************/ int misc_init_r(void) { int rev; rev = beagle_revision(); switch (rev) { case REVISION_AXBX: printf("Beagle Rev Ax/Bx\n"); break; case REVISION_CX: printf("Beagle Rev C1/C2/C3\n"); break; case REVISION_C4: printf("Beagle Rev C4\n"); break; case REVISION_XM: printf("Beagle xM Rev A\n"); break; case REVISION_XMC: printf("Beagle xM Rev C\n"); break; default: printf("Beagle unknown 0x%02x\n", rev); } return 0; }
2.u-bootのソースコード
リビジョンの判定はx-loaderと同じ。
rev.A/Bもrev.CもUSB HUBの電源をONにしているようだ。
u-boot/board/ti/beagle/beagle.h
... /* BeagleBoard revisions */ #define REVISION_AXBX 0x7 #define REVISION_CX 0x6 #define REVISION_C4 0x5 #define REVISION_XM 0x0 #define REVISION_XMC 0x2 ...
u-boot/board/ti/beagle/beagle.c
/* * Routine: misc_init_r * Description: Configure board specific parts */ int misc_init_r(void) { struct gpio *gpio5_base = (struct gpio *)OMAP34XX_GPIO5_BASE; struct gpio *gpio6_base = (struct gpio *)OMAP34XX_GPIO6_BASE; /* * Configure drive strength for IO cells */ *(ulong *)(CONTROL_PROG_IO1) &= ~(PRG_I2C2_PULLUPRESX); beagle_identify(); twl4030_power_init(); twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON); switch (beagle_revision) { case REVISION_AXBX: printf("Beagle Rev Ax/Bx\n"); setenv("mpurate", "600"); break; case REVISION_CX: printf("Beagle Rev C1/C2/C3\n"); MUX_BEAGLE_C(); setenv("mpurate", "600"); break; case REVISION_C4: printf("Beagle Rev C4\n"); MUX_BEAGLE_C(); /* Set VAUX2 to 1.8V for EHCI PHY */ twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED, TWL4030_PM_RECEIVER_VAUX2_VSEL_18, TWL4030_PM_RECEIVER_VAUX2_DEV_GRP, TWL4030_PM_RECEIVER_DEV_GRP_P1); setenv("mpurate", "720"); break; case REVISION_XM: case REVISION_XMC: printf("Beagle xM Rev A/C\n"); MUX_BEAGLE_XM(); /* Set VAUX2 to 1.8V for EHCI PHY */ twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED, TWL4030_PM_RECEIVER_VAUX2_VSEL_18, TWL4030_PM_RECEIVER_VAUX2_DEV_GRP, TWL4030_PM_RECEIVER_DEV_GRP_P1); setenv("mpurate", "1000"); break; default: printf("Beagle unknown 0x%02x\n", beagle_revision); } /* Configure GPIOs to output */ writel(~(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe); writel(~(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 | GPIO15 | GPIO14 | GPIO13 | GPIO12), &gpio5_base->oe); /* Set GPIOs */ writel(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1, &gpio6_base->setdataout); writel(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 | GPIO15 | GPIO14 | GPIO13 | GPIO12, &gpio5_base->setdataout); dieid_num_r(); return 0; }