1/* 2 * ========================================================================= 3 * ARM and PandaBoard specific functions 4 * ========================================================================= 5 */ 6 7#include <barrelfish/barrelfish.h> 8 9#include <usb/usb.h> 10 11#include <arch/arm/omap44xx/device_registers.h> 12#include <maps/omap44xx_map.h> 13 14#include <dev/omap/ehci_dev.h> 15#include <dev/omap/omap44xx_hsusbhost_dev.h> 16#include <dev/omap/omap44xx_usbtllhs_config_dev.h> 17#include <dev/omap/omap44xx_scrm_dev.h> 18#include <dev/omap/omap44xx_sysctrl_padconf_core_dev.h> 19#include <dev/omap/omap44xx_sysctrl_padconf_wkup_dev.h> 20#include <dev/omap/omap44xx_gpio_dev.h> 21#include <dev/omap/omap44xx_ehci_dev.h> 22#include <dev/omap/omap44xx_l3init_cm2_dev.h> 23#include <dev/omap/omap44xx_l4per_cm2_dev.h> 24#include <dev/omap/omap44xx_ckgen_prm_dev.h> 25 26#include <driverkit/driverkit.h> 27 28/* mackerel bases for USB initialization */ 29static omap44xx_hsusbhost_t hsusbhost_base; 30static omap44xx_usbtllhs_config_t usbtllhs_config_base; 31static omap44xx_scrm_t srcm_base; 32static omap44xx_sysctrl_padconf_wkup_t sysctrl_padconf_wkup_base; 33static omap44xx_sysctrl_padconf_core_t sysctrl_padconf_core_base; 34static omap44xx_gpio_t gpio_1_base; 35static omap44xx_gpio_t gpio_2_base; 36static omap44xx_ehci_t ehci_base; 37static omap44xx_ckgen_prm_t ckgen_base; 38static omap44xx_l4per_cm2_t l4per_base; 39static omap44xx_l3init_cm2_t l3init_base; 40 41#include "platform.h" 42// the offset into the supplied capability 43#define USB_CAPABILITY_OFFSET (0x00000C00) 44 45// the EHCI interrupt number on the pandaboard 46#define USB_ARM_EHCI_IRQ 109 47 48 49 50/* 51 * initialize the USB functionality of the pandaboard 52 */ 53static void hsusb_init(void) 54{ 55 56 printf(" > hsusb_init()...\n"); 57 58 /* 59 * Global Initialization of the OMAPP44xx USB Sub System 60 */ 61 printf(" > > USB TTL reset..."); 62 63 /* 64 * Reset USBTTL 65 * USBTLL_SYSCONFIG = 0x2 66 */ 67 omap44xx_usbtllhs_config_usbtll_sysconfig_softreset_wrf( 68 &usbtllhs_config_base, 0x1); 69 70 /* 71 * wait till reset is done 72 */ 73 while (!omap44xx_usbtllhs_config_usbtll_sysstatus_resetdone_rdf( 74 &usbtllhs_config_base)) 75 ; 76 77 /* 78 * USBTLL_SYSCONFIG 79 * - Setting ENAWAKEUP 80 * - Setting SIDLEMODE 81 * - Setting CLOCKACTIVITY 82 */ 83 omap44xx_usbtllhs_config_usbtll_sysconfig_t sysconf = 0x0; 84 sysconf = omap44xx_usbtllhs_config_usbtll_sysconfig_clockactivity_insert( 85 sysconf, 0x1); 86 sysconf = omap44xx_usbtllhs_config_usbtll_sysconfig_enawakeup_insert( 87 sysconf, 0x1); 88 sysconf = omap44xx_usbtllhs_config_usbtll_sysconfig_sidlemode_insert( 89 sysconf, 0x1); 90 omap44xx_usbtllhs_config_usbtll_sysconfig_wr(&usbtllhs_config_base, 91 sysconf); 92 93 printf("OK\n"); 94 95 /* 96 * USBTLL_IRQENABLE: 97 * - all interrupts 98 */ 99 omap44xx_usbtllhs_config_usbtll_irqenable_t irqena = omap44xx_usbtllhs_config_usbtll_irqenable_default; 100 irqena = omap44xx_usbtllhs_config_usbtll_irqenable_fclk_start_en_insert( 101 irqena, 0x1); 102 irqena = omap44xx_usbtllhs_config_usbtll_irqenable_fclk_end_en_insert( 103 irqena, 0x1); 104 irqena = omap44xx_usbtllhs_config_usbtll_irqenable_access_error_en_insert( 105 irqena, 0x1); 106 omap44xx_usbtllhs_config_usbtll_irqenable_wr(&usbtllhs_config_base, irqena); 107 108 printf(" > > USB host controller reset..."); 109 110 /* 111 * per form a reset on the USB host controller module 112 * this resets both EHCI and OCHI controllers 113 * 114 * UHH_SYSCONFIG = 0x1 115 */ 116 omap44xx_hsusbhost_uhh_sysconfig_softreset_wrf(&hsusbhost_base, 0x1); 117 118 /* 119 * wait till reset is done 120 * UHH_SYSSTATUS = 0x6 121 */ 122 omap44xx_hsusbhost_uhh_sysstatus_t uhh_sysstat; 123 uint8_t ehci_done; 124 uint8_t ohci_done; 125 do { 126 uhh_sysstat = omap44xx_hsusbhost_uhh_sysstatus_rd(&hsusbhost_base); 127 ehci_done = omap44xx_hsusbhost_uhh_sysstatus_ehci_resetdone_extract( 128 uhh_sysstat); 129 ohci_done = omap44xx_hsusbhost_uhh_sysstatus_ohci_resetdone_extract( 130 uhh_sysstat); 131 } while (!(ehci_done & ohci_done)); 132 133 /* enable some USB host features 134 * UHH_SYSCONFIG 135 * - STANDBYMODE 136 * - IDLEMODE 137 */ 138 omap44xx_hsusbhost_uhh_sysconfig_standbymode_wrf(&hsusbhost_base, 0x1); 139 omap44xx_hsusbhost_uhh_sysconfig_idlemode_wrf(&hsusbhost_base, 0x1); 140 141 printf("OK\n"); 142 143 printf(" > > Setting USB host configuration values..."); 144 145 /* 146 * setting the host configuration to external PHY and enable 147 * the burst types, app start clk 148 * 149 * UHH_HOSTCONFIG 150 * - APP_START_CLK 151 * - ENAINCR_x 152 */ 153 // *((volatile uint32_t*) (0x4A064040)) = 154 // (uint32_t) ((0x7 << 2) | (0x1 << 31)); 155 omap44xx_hsusbhost_uhh_hostconfig_t hcfg = omap44xx_hsusbhost_uhh_hostconfig_default; 156 hcfg = omap44xx_hsusbhost_uhh_hostconfig_app_start_clk_insert(hcfg, 0x1); 157 hcfg = omap44xx_hsusbhost_uhh_hostconfig_ena_incr4_insert(hcfg, 0x1); 158 hcfg = omap44xx_hsusbhost_uhh_hostconfig_ena_incr8_insert(hcfg, 0x1); 159 hcfg = omap44xx_hsusbhost_uhh_hostconfig_ena_incr16_insert(hcfg, 0x1); 160 omap44xx_hsusbhost_uhh_hostconfig_wr(&hsusbhost_base, hcfg); 161 162 printf("OK\n"); 163 164 printf(" > done.\n"); 165} 166 167// GPIO numbers for enabling the USB hub on the pandaboard 168#define HSUSB_HUB_POWER 1 169#define HSUSB_HUB_RESET 30 170 171 172/* 173 * Initialize the high speed usb hub on the pandaboard 174 */ 175static void usb_power_on(void) 176{ 177 printf("usb_power_on()... \n"); 178 179 printf(" > forward the AUXCLK3 to GPIO_WK31\n"); 180 /* 181 * the USB hub needs the FREF_CLK3_OUT to be 19.2 MHz and that this 182 * clock goes to the GPIO_WK31 out. 183 * Assume that the sys clock is 38.4 MHz so we use a divider of 2 184 * 185 * Bit 8: is the enable bit 186 * Bit 16: is the divider bit (here for two) 187 */ 188 189 omap44xx_scrm_auxclk3_t auxclk3 = omap44xx_scrm_auxclk3_default; 190 auxclk3 = omap44xx_scrm_auxclk3_enable_insert(auxclk3, 191 omap44xx_scrm_ENABLE_EXT_1); 192 auxclk3 = omap44xx_scrm_auxclk3_clkdiv_insert(auxclk3, 193 omap44xx_scrm_MODE_1); 194 omap44xx_scrm_auxclk3_wr(&srcm_base, auxclk3); 195 196 /* 197 * Forward the clock to the GPIO_WK31 pin 198 * - muxmode = fref_clk3_out (0x0) 199 * - no pullup/down (0x0) 200 * - no input buffer (0x0) 201 * - no wake up (0x0) 202 */ 203 omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_t clk3_out; 204 clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_rd( 205 &sysctrl_padconf_wkup_base); 206 clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_muxmode_insert( 207 clk3_out, 0x0); 208 clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_pulludenable_insert( 209 clk3_out, 0x0); 210 clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_pulltypeselect_insert( 211 clk3_out, 0x0); 212 clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_inputenable_insert( 213 clk3_out, 0x0); 214 clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_wakeupenable_insert( 215 clk3_out, 0x0); 216 clk3_out = omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_fref_clk3_out_wakeupevent_insert( 217 clk3_out, 0x0); 218 omap44xx_sysctrl_padconf_wkup_control_wkup_pad0_fref_clk3_out_pad1_fref_clk4_req_wr( 219 &sysctrl_padconf_wkup_base, clk3_out); 220 221 printf(" > reset external USB hub and PHY\n"); 222 223 /* 224 * Perform a reset on the USB hub i.e. drive the GPIO_1 pin to low 225 * and enable the dataout for the this pin in GPIO 226 */ 227 228 uint32_t gpoi_1_oe = omap44xx_gpio_oe_rd(&gpio_1_base) 229 & (~(1UL << HSUSB_HUB_POWER)); 230 omap44xx_gpio_oe_wr(&gpio_1_base, gpoi_1_oe); 231 232 omap44xx_gpio_cleardataout_wr(&gpio_1_base, (1UL << HSUSB_HUB_POWER)); 233 234 /* 235 * forward the data outline to the USB hub by muxing the 236 * CONTROL_CORE_PAD0_KPD_COL1_PAD1_KPD_COL2 into mode 3 (gpio_1) 237 */ 238 239 omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_t gpio1_mux; 240 gpio1_mux = omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_rd( 241 &sysctrl_padconf_core_base) & 0x0000FFFF; 242 gpio1_mux = omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_kpd_col2_muxmode_insert( 243 gpio1_mux, 0x3); 244 omap44xx_sysctrl_padconf_core_control_core_pad0_kpd_col1_pad1_kpd_col2_wr( 245 &sysctrl_padconf_core_base, gpio1_mux); 246 247 /* 248 * Perform a reset on the USB phy i.e. drive GPIO_62 to low 249 * 250 * HSUSB_HUB_RESET: 0 = Hub & Phy held in reset 1 = Normal operation. 251 */ 252 253 uint32_t gpoi_2_oe = omap44xx_gpio_oe_rd(&gpio_2_base) 254 & (~(1UL << HSUSB_HUB_RESET)); 255 omap44xx_gpio_oe_wr(&gpio_2_base, gpoi_2_oe); 256 257 omap44xx_gpio_cleardataout_wr(&gpio_2_base, (1UL << HSUSB_HUB_RESET)); 258 259 /* 260 * forward the data on gpio_62 pin to the output by muxing 261 * CONTROL_CORE_PAD0_GPMC_WAIT1_PAD1_GPMC_WAIT2 to mode 0x3 262 */ 263 264 omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_t gpio62_mux; 265 gpio62_mux = (omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_rd( 266 &sysctrl_padconf_core_base) & 0xFFFF0000); 267 gpio62_mux = omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_gpmc_wait1_muxmode_insert( 268 gpio62_mux, 0x3); 269 omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_wr( 270 &sysctrl_padconf_core_base, gpio62_mux); 271 omap44xx_sysctrl_padconf_core_control_core_pad0_gpmc_wait1_pad1_gpmc_wait2_wr( 272 &sysctrl_padconf_core_base, gpio62_mux); 273 274 /* delay to give the hardware time to reset */ 275 barrelfish_usleep(1000000); 276 277 hsusb_init(); 278 279 printf(" > enable the external USB hub and PHY\n"); 280 281 /* power on the USB subsystem */ 282 omap44xx_gpio_setdataout_wr(&gpio_1_base, (1UL << HSUSB_HUB_POWER)); 283 284 /* enable the USB HUB */ 285 omap44xx_gpio_setdataout_wr(&gpio_2_base, (1UL << HSUSB_HUB_RESET)); 286 287 barrelfish_usleep(1000000); 288 289 printf(" > performing softreset on the USB PHY\n"); 290 291 omap44xx_ehci_insnreg05_ulpi_t ulpi = omap44xx_ehci_insnreg05_ulpi_default; 292 ulpi = omap44xx_ehci_insnreg05_ulpi_control_insert(ulpi, 293 omap44xx_ehci_CONTROL_1); 294 ulpi = omap44xx_ehci_insnreg05_ulpi_portsel_insert(ulpi, 295 omap44xx_ehci_PORTSEL_1); 296 ulpi = omap44xx_ehci_insnreg05_ulpi_opsel_insert(ulpi, 297 omap44xx_ehci_OPSEL_2); 298 ulpi = omap44xx_ehci_insnreg05_ulpi_regadd_insert(ulpi, 0x5); //ctrl reg 299 ulpi = omap44xx_ehci_insnreg05_ulpi_rdwrdata_insert(ulpi, (0x1 << 5)); 300 301 omap44xx_ehci_insnreg05_ulpi_wr(&ehci_base, ulpi); 302 303 while (omap44xx_ehci_insnreg05_ulpi_control_rdf(&ehci_base)) { 304 barrelfish_usleep(10000); 305 } 306 307 try_again: 308 /* wait till reset is done */ 309 ulpi = omap44xx_ehci_insnreg05_ulpi_opsel_insert(ulpi, 310 omap44xx_ehci_OPSEL_3); 311 ulpi = omap44xx_ehci_insnreg05_ulpi_rdwrdata_insert(ulpi, 0x0); 312 omap44xx_ehci_insnreg05_ulpi_wr(&ehci_base, ulpi); 313 314 while (omap44xx_ehci_insnreg05_ulpi_control_rdf(&ehci_base)) { 315 barrelfish_usleep(10000); 316 } 317 if (omap44xx_ehci_insnreg05_ulpi_rdwrdata_rdf(&ehci_base) & (0x1 << 5)) { 318 goto try_again; 319 } 320 321 /* read the debug register */ 322 ulpi = omap44xx_ehci_insnreg05_ulpi_regadd_insert(ulpi, 0x15); 323 omap44xx_ehci_insnreg05_ulpi_wr(&ehci_base, ulpi); 324 325 while (omap44xx_ehci_insnreg05_ulpi_control_rdf(&ehci_base)) { 326 barrelfish_usleep(10000); 327 } 328 329 uint8_t line_state = omap44xx_ehci_insnreg05_ulpi_rdwrdata_rdf(&ehci_base) & 0x1; 330 printf(" > ULPI line state = %s\n", 331 line_state ? "Connected" : "Disconnected"); 332 assert(line_state); 333 334 printf("done.\n"); 335} 336 337static void prcm_init(void) 338{ 339 printf("prcm_init()...\n"); 340 341 printf(" > CM_SYS_CLKSEL=38.4MHz \n"); 342 /* 343 * Set the system clock to 38.4 MHz 344 * CM_SYS_CLKSEL = 0x7 345 */ 346 347 omap44xx_ckgen_prm_cm_sys_clksel_wr(&ckgen_base, 348 omap44xx_ckgen_prm_SYS_CLKSEL_7); 349 350 if (!omap44xx_ckgen_prm_cm_sys_clksel_rd(&ckgen_base)) { 351 printf("WARNING: Could not set SYS_CLK\n"); 352 return; 353 } 354 355 /* ALTCLKSRC in SRCM*/ 356 omap44xx_scrm_altclksrc_t altclk = omap44xx_scrm_altclksrc_default; 357 altclk = omap44xx_scrm_altclksrc_mode_insert(altclk, omap44xx_scrm_MODE_1); 358 altclk = omap44xx_scrm_altclksrc_enable_int_insert(altclk, 0x1); 359 altclk = omap44xx_scrm_altclksrc_enable_ext_insert(altclk, 0x1); 360 omap44xx_scrm_altclksrc_wr(&srcm_base, altclk); 361 362 printf(" > Enabling L4PER interconnect clock\n"); 363 /* CM_L4PER_CLKSTCTRL */ 364 omap44xx_l4per_cm2_cm_l4per_clkstctrl_clktrctrl_wrf(&l4per_base, 0x2); 365 366 printf(" > Enabling GPIOi clocks\n"); 367 /* CM_L4PER_GPIO2_CLKCTRL */ 368 omap44xx_l4per_cm2_cm_l4per_gpio2_clkctrl_modulemode_wrf(&l4per_base, 0x1); 369 /* CM_L4PER_GPIO3_CLKCTRL */ 370 omap44xx_l4per_cm2_cm_l4per_gpio3_clkctrl_modulemode_wrf(&l4per_base, 0x1); 371 /* CM_L4PER_GPIO4_CLKCTRL */ 372 omap44xx_l4per_cm2_cm_l4per_gpio4_clkctrl_modulemode_wrf(&l4per_base, 0x1); 373 /* CM_L4PER_GPIO5_CLKCTRL */ 374 omap44xx_l4per_cm2_cm_l4per_gpio5_clkctrl_modulemode_wrf(&l4per_base, 0x1); 375 /* CM_L4PER_GPIO6_CLKCTRL */ 376 omap44xx_l4per_cm2_cm_l4per_gpio6_clkctrl_modulemode_wrf(&l4per_base, 0x1); 377 /* CM_L4PER_HDQ1W_CLKCTRL */ 378 omap44xx_l4per_cm2_cm_l4per_hdq1w_clkctrl_modulemode_wrf(&l4per_base, 0x2); 379 380 printf(" > Enabling L3INIT USB clocks\n"); 381 /* CM_L3INIT_HSI_CLKCTRL */ 382 omap44xx_l3init_cm2_cm_l3init_hsi_clkctrl_modulemode_wrf(&l3init_base, 0x1); 383 384 /* CM_L3INIT_HSUSBHOST_CLKCTRL */ 385 omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_t hsusb_cm = 0x0; 386 hsusb_cm = omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_clksel_utmi_p1_insert( 387 hsusb_cm, 0x3); 388 hsusb_cm = omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_modulemode_insert( 389 hsusb_cm, 0x2); 390 hsusb_cm |= 0xFF00; // all clocks 391 omap44xx_l3init_cm2_cm_l3init_hsusbhost_clkctrl_wr(&l3init_base, hsusb_cm); 392 393 /* CM_L3INIT_HSUSBOTG_CLKCTRL */ 394 omap44xx_l3init_cm2_cm_l3init_hsusbotg_clkctrl_modulemode_wrf(&l3init_base, 395 0x1); 396 397 /* CM_L3INIT_HSUSBTLL_CLKCTRL */ 398 omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_t usbtll_cm = 0x0; 399 usbtll_cm = omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_modulemode_insert( 400 usbtll_cm, 0x1); 401 usbtll_cm = omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_optfclken_usb_ch0_clk_insert( 402 usbtll_cm, 0x1); 403 usbtll_cm = omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_optfclken_usb_ch1_clk_insert( 404 usbtll_cm, 0x1); 405 omap44xx_l3init_cm2_cm_l3init_hsusbtll_clkctrl_wr(&l3init_base, usbtll_cm); 406 407 /* CM_L3INIT_FSUSB_CLKCTRL */ 408 omap44xx_l3init_cm2_cm_l3init_fsusb_clkctrl_modulemode_wrf(&l3init_base, 409 0x2); 410 /* CM_L3INIT_USBPHY_CLKCTRL */ 411 omap44xx_l3init_cm2_cm_l3init_usbphy_clkctrl_wr(&l3init_base, 0x301); 412 413 printf("done.\n"); 414} 415 416static void set_muxconf_regs(void) 417{ 418 printf("set_muxconf_regs()..."); 419 420 /* CONTROL_PADCONF_CORE_SYSCONFIG */ 421 omap44xx_sysctrl_padconf_core_control_padconf_core_sysconfig_ip_sysconfig_idlemode_wrf( 422 &sysctrl_padconf_core_base, 0x1); 423 424 /* CONTROL_PADCONF_WKUP_SYSCONFIG */ 425 omap44xx_sysctrl_padconf_wkup_control_padconf_wkup_sysconfig_ip_sysconfig_idlemode_wrf( 426 &sysctrl_padconf_wkup_base, 0x1); 427 428 /* USBB1_CLK */ 429 omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_t ulpitll; 430 ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_rd( 431 &sysctrl_padconf_core_base) & 0x0000FFFF; 432 ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_usbb1_ulpitll_clk_inputenable_insert( 433 ulpitll, 0x1); 434 ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_usbb1_ulpitll_clk_pulludenable_insert( 435 ulpitll, 0x1); 436 ulpitll = omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_usbb1_ulpitll_clk_muxmode_insert( 437 ulpitll, 0x4); 438 omap44xx_sysctrl_padconf_core_control_core_pad0_cam_globalreset_pad1_usbb1_ulpitll_clk_wr( 439 &sysctrl_padconf_core_base, ulpitll); 440 441 /* USBB1_STP / USBB1_DIR */ 442 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_t usb_dir = 0x0; 443 usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_stp_muxmode_insert( 444 usb_dir, 0x4); 445 usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_dir_muxmode_insert( 446 usb_dir, 0x4); 447 usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_dir_inputenable_insert( 448 usb_dir, 0x1); 449 usb_dir = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_usbb1_ulpitll_dir_pulludenable_insert( 450 usb_dir, 0x1); 451 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_stp_pad1_usbb1_ulpitll_dir_wr( 452 &sysctrl_padconf_core_base, usb_dir); 453 454 /* this values are used for all the 8 data lines */ 455 uint32_t usb_dat = 0x0; 456 usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_dat0_muxmode_insert( 457 usb_dat, 0x4); 458 usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_nxt_muxmode_insert( 459 usb_dat, 0x4); 460 usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_dat0_inputenable_insert( 461 usb_dat, 0x1); 462 usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_nxt_inputenable_insert( 463 usb_dat, 0x1); 464 usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_dat0_pulludenable_insert( 465 usb_dat, 0x1); 466 usb_dat = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_usbb1_ulpitll_nxt_pulludenable_insert( 467 usb_dat, 0x1); 468 469 /* USBB1_DAT0 / USBB1_NXT */ 470 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_nxt_pad1_usbb1_ulpitll_dat0_wr( 471 &sysctrl_padconf_core_base, usb_dat); 472 473 /* USBB1_DAT1 / USBB1_DAT2 */ 474 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat1_pad1_usbb1_ulpitll_dat2_wr( 475 &sysctrl_padconf_core_base, usb_dat); 476 477 /* USBB1_DAT3 / USBB1_DAT4 */ 478 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat3_pad1_usbb1_ulpitll_dat4_wr( 479 &sysctrl_padconf_core_base, usb_dat); 480 481 /* USBB1_DAT5 / USBB1_DAT6 */ 482 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat5_pad1_usbb1_ulpitll_dat6_wr( 483 &sysctrl_padconf_core_base, usb_dat); 484 485 /* USBB1_DAT7 */ 486 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_t usb_dat7; 487 usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_rd( 488 &sysctrl_padconf_core_base) & 0xFFFF0000; 489 usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_usbb1_ulpitll_dat7_muxmode_insert( 490 usb_dat7, 0x4); 491 usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_usbb1_ulpitll_dat7_pulludenable_insert( 492 usb_dat7, 0x1); 493 usb_dat7 = omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_usbb1_ulpitll_dat7_inputenable_insert( 494 usb_dat7, 0x1); 495 omap44xx_sysctrl_padconf_core_control_core_pad0_usbb1_ulpitll_dat7_pad1_usbb1_hsic_data_wr( 496 &sysctrl_padconf_core_base, usb_dat7); 497 498 printf("done\n"); 499} 500 501/** 502 * Entry point called from boot.S for bootstrap processor. 503 * if is_bsp == true, then pointer points to multiboot_info 504 * else pointer points to a global struct 505 */ 506static errval_t usb_init(void) 507{ 508 errval_t err; 509 printf("-------------------------\nUSB Host initialization\n"); 510 lvaddr_t base; 511 err = map_device_register(OMAP44XX_MAP_L4_CFG_HSUSBHOST, OMAP44XX_MAP_L4_CFG_HSUSBHOST_SIZE, &base); 512 if (err_is_fail(err)) { 513 return err; 514 } 515 omap44xx_hsusbhost_initialize(&hsusbhost_base, (mackerel_addr_t) base); 516 omap44xx_ehci_initialize(&ehci_base, (mackerel_addr_t) base + 0xC00); 517 518 err = map_device_register(OMAP44XX_MAP_L4_CFG_HSUSBTLL, OMAP44XX_MAP_L4_CFG_HSUSBTLL_SIZE, &base); 519 if (err_is_fail(err)) { 520 return err; 521 } 522 omap44xx_usbtllhs_config_initialize(&usbtllhs_config_base, (mackerel_addr_t) base); 523 524 525 err = map_device_register(OMAP44XX_MAP_L4_WKUP_SRCM, OMAP44XX_MAP_L4_WKUP_SRCM_SIZE, &base); 526 if (err_is_fail(err)) { 527 return err; 528 } 529 omap44xx_scrm_initialize(&srcm_base, (mackerel_addr_t) base); 530 531 err = map_device_register(OMAP44XX_MAP_L4_WKUP_SYSCTRL_PADCONF_WKUP, OMAP44XX_MAP_L4_WKUP_SYSCTRL_PADCONF_WKUP_SIZE, &base); 532 if (err_is_fail(err)) { 533 return err; 534 } 535 omap44xx_sysctrl_padconf_wkup_initialize(&sysctrl_padconf_wkup_base, (mackerel_addr_t) base); 536 537 err = map_device_register(OMAP44XX_MAP_L4_CFG_SYSCTRL_PADCONF_CORE, OMAP44XX_MAP_L4_CFG_SYSCTRL_PADCONF_CORE_SIZE, &base); 538 if (err_is_fail(err)) { 539 return err; 540 } 541 omap44xx_sysctrl_padconf_core_initialize(&sysctrl_padconf_core_base, (mackerel_addr_t) base); 542 543 err = map_device_register(OMAP44XX_MAP_L4_WKUP_GPIO1, OMAP44XX_MAP_L4_WKUP_GPIO1_SIZE, &base); 544 if (err_is_fail(err)) { 545 return err; 546 } 547 omap44xx_gpio_initialize(&gpio_1_base, (mackerel_addr_t) base); 548 549 err = map_device_register(OMAP44XX_MAP_L4_PER_GPIO2, OMAP44XX_MAP_L4_PER_GPIO2_SIZE, &base); 550 if (err_is_fail(err)) { 551 return err; 552 } 553 omap44xx_gpio_initialize(&gpio_2_base, (mackerel_addr_t) base); 554 555 err = map_device_register(OMAP44XX_MAP_L4_WKUP_PRM, OMAP44XX_MAP_L4_WKUP_PRM_SIZE, &base); 556 if (err_is_fail(err)) { 557 return err; 558 } 559 omap44xx_ckgen_prm_initialize(&ckgen_base, (mackerel_addr_t) base + 0x100); 560 561 err = map_device_register(OMAP44XX_MAP_L4_CFG_CM2, OMAP44XX_MAP_L4_CFG_CM2_SIZE, &base); 562 if (err_is_fail(err)) { 563 return err; 564 } 565 omap44xx_l4per_cm2_initialize(&l4per_base, (mackerel_addr_t) base + 0x1400); 566 omap44xx_l3init_cm2_initialize(&l3init_base, (mackerel_addr_t) base + 0x1300); 567 568 prcm_init(); 569 set_muxconf_regs(); 570 usb_power_on(); 571 printf("-------------------------\n"); 572 573 return SYS_ERR_OK; 574} 575 576/** 577 * \brief this is a quick check function if everything is all right 578 * 579 * NOTE: there is just one specific setting possible on the PandaBoard 580 * EHCI controller, with the specific capability and the specific offset 581 * This function checks if these values match to ensure functionality 582 * If you change something with the startup of the USB manager domain 583 * you may need to change the values in this function! 584 */ 585usb_error_t platform_checkup(uintptr_t base, int argc, char *argv[]) 586{ 587 USB_DEBUG("performing pandaboard integrity check.\n"); 588 589 errval_t err = usb_init(); 590 if (err_is_fail(err)) { 591 USER_PANIC_ERR(err, "USB initialization failed\n"); 592 } 593 594 /* checking the host controller type */ 595 if (strcmp(argv[0], "ehci")) { 596 debug_printf("wrong host controller type: %s\n", argv[0]); 597 return (USB_ERR_INVAL); 598 } 599 600 /* checking the memory offset */ 601 if (strtoul(argv[1], NULL, 10) != ((uint32_t) USB_CAPABILITY_OFFSET)) { 602 debug_printf("wrong offset!: %x (%s)\n", strtoul(argv[1], NULL, 10), 603 argv[1]); 604 return (USB_ERR_INVAL); 605 } 606 607 /* checking the IRQ number */ 608 if (strtoul(argv[2], NULL, 10) != USB_ARM_EHCI_IRQ) { 609 debug_printf("wrong interrupt number: %s, %x", argv[2], 610 strtoul(argv[2], NULL, 10)); 611 return (USB_ERR_INVAL); 612 } 613 614 /* 615 * here we read some values from the ULPI register of the PandaBoards 616 * additional ULPI interface on the EHCI controller. 617 * 618 * The request are forwarded to the external ULPI receiver on the 619 * PandaBoard. 620 * 621 * NOTE: Not every EHCI controller has those register! 622 */ 623 624 uintptr_t tmp = USB_CAPABILITY_OFFSET + (uintptr_t) base; 625 volatile uint32_t *ulpi_debug_reg = (volatile uint32_t*) (tmp + 0x00A4); 626 debug_printf("address of ehci base = %p\n", (void *)tmp); 627 debug_printf("address of ulpi debug reg = %p\n", ulpi_debug_reg); 628 /* 629 * This request reads the debug register of the ULPI receiver. The values 630 * returned are the line state. If the returned value is 0x1 this means 631 * there is connection i.e. the USB hub on the PandaBoard is reachable. 632 */ 633 634 printf("check whether USB hub is reachable... "); 635 *ulpi_debug_reg = (uint32_t) ((0x15 << 16) 636 | (0x3 << 22) | (0x1 << 24) | (0x1 << 31)); 637 638 /* wait till the request is done */ 639 while ((*ulpi_debug_reg) & (1UL << 31)) { 640 thread_yield(); 641 } 642 643 // XXX: reset register here? 644 ulpi_debug_reg = (volatile uint32_t*) (tmp + 0x00A4); 645 /* compare the result */ 646 if (!((*ulpi_debug_reg) & 0x1)) { 647 return (USB_ERR_INVAL); 648 } 649 650 printf("ok\nCheck vendor ID of ULPI receiver... "); 651 /* 652 * This request reads out the low part of the vendor id from the ULPI 653 * receiver on the PandaBoard. This should be 0x24. 654 * 655 * XXX: Assuming that all the Pandaboards have the same ULPI receiver 656 */ 657 *ulpi_debug_reg = (uint32_t) ((0x00 << 16) 658 | (0x3 << 22) | (0x1 << 24) | (0x1 << 31)); 659 660 /* wait till request is done */ 661 while ((*ulpi_debug_reg) & (1 << 31)) { 662 } 663 664 /* compare the values */ 665 if (0x24 != ((*ulpi_debug_reg) & 0xFF)) { 666 return (USB_ERR_INVAL); 667 } 668 printf("ok\n"); 669 670 return (USB_ERR_OK); 671} 672