Changes in uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c [bebf97d:57912af3] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c
rbebf97d r57912af3 35 35 /** @file 36 36 */ 37 38 #define DEBUG_CM 0 39 37 #define _DDF_DATA_IMPLANT 38 39 #define DEBUG_CM 40 41 #include <ddf/driver.h> 40 42 #include <ddf/log.h> 41 43 #include <errno.h> 42 44 #include <ops/hw_res.h> 43 45 #include <stdio.h> 44 45 #include "amdm37x.h" 46 #include <ddi.h> 47 48 #include "uhh.h" 49 #include "usbtll.h" 50 #include "cm/core.h" 51 #include "cm/clock_control.h" 52 #include "cm/usbhost.h" 46 53 47 54 #define NAME "rootamdm37x" 55 56 typedef struct { 57 uhh_regs_t *uhh; 58 tll_regs_t *tll; 59 struct { 60 core_cm_regs_t *core; 61 clock_control_cm_regs_t *clocks; 62 usbhost_cm_regs_t *usbhost; 63 } cm; 64 } amdm37x_t; 65 66 #ifdef DEBUG_CM 67 static void log(volatile void *place, uint32_t val, volatile void* base, size_t size, void *data, bool write) 68 { 69 printf("PIO %s: %p(%p) %#"PRIx32"\n", write ? "WRITE" : "READ", 70 (place - base) + data, place, val); 71 } 72 #endif 73 74 static int amdm37x_hw_access_init(amdm37x_t *device) 75 { 76 assert(device); 77 int ret = EOK; 78 79 ret = pio_enable((void*)USBHOST_CM_BASE_ADDRESS, USBHOST_CM_SIZE, 80 (void**)&device->cm.usbhost); 81 if (ret != EOK) 82 return ret; 83 84 ret = pio_enable((void*)CORE_CM_BASE_ADDRESS, CORE_CM_SIZE, 85 (void**)&device->cm.core); 86 if (ret != EOK) 87 return ret; 88 89 ret = pio_enable((void*)CLOCK_CONTROL_CM_BASE_ADDRESS, 90 CLOCK_CONTROL_CM_SIZE, (void**)&device->cm.clocks); 91 if (ret != EOK) 92 return ret; 93 94 ret = pio_enable((void*)AMDM37x_USBTLL_BASE_ADDRESS, 95 AMDM37x_USBTLL_SIZE, (void**)&device->tll); 96 if (ret != EOK) 97 return ret; 98 99 ret = pio_enable((void*)AMDM37x_UHH_BASE_ADDRESS, 100 AMDM37x_UHH_SIZE, (void**)&device->uhh); 101 if (ret != EOK) 102 return ret; 103 104 #ifdef DEBUG_CM 105 pio_trace_enable(device->tll, AMDM37x_USBTLL_SIZE, log, (void*)AMDM37x_USBTLL_BASE_ADDRESS); 106 pio_trace_enable(device->cm.clocks, CLOCK_CONTROL_CM_SIZE, log, (void*)CLOCK_CONTROL_CM_BASE_ADDRESS); 107 pio_trace_enable(device->cm.core, CORE_CM_SIZE, log, (void*)CORE_CM_BASE_ADDRESS); 108 pio_trace_enable(device->cm.usbhost, USBHOST_CM_SIZE, log, (void*)USBHOST_CM_BASE_ADDRESS); 109 pio_trace_enable(device->uhh, AMDM37x_UHH_SIZE, log, (void*)AMDM37x_UHH_BASE_ADDRESS); 110 #endif 111 return EOK; 112 } 113 114 static int usb_clocks(amdm37x_t *device, bool on) 115 { 116 /* Set DPLL3 to automatic */ 117 pio_change_32(&device->cm.clocks->autoidle_pll, 118 CLOCK_CONTROL_CM_AUTOIDLE_PLL_AUTO_CORE_DPLL_AUTOMATIC, 119 CLOCK_CONTROL_CM_AUTOIDLE_PLL_AUTO_CORE_DPLL_MASK, 5); 120 121 /* Set DPLL4 to automatic */ 122 pio_change_32(&device->cm.clocks->autoidle_pll, 123 CLOCK_CONTROL_CM_AUTOIDLE_PLL_AUTO_PERIPH_DPLL_AUTOMATIC, 124 CLOCK_CONTROL_CM_AUTOIDLE_PLL_AUTO_PERIPH_DPLL_MASK, 5); 125 126 /* Set DPLL5 to automatic */ 127 pio_change_32(&device->cm.clocks->autoidle2_pll, 128 CLOCK_CONTROL_CM_AUTOIDLE2_PLL_AUTO_PERIPH2_DPLL_AUTOMATIC, 129 CLOCK_CONTROL_CM_AUTOIDLE2_PLL_AUTO_PERIPH2_DPLL_MASK, 5); 130 131 132 #ifdef DEBUG_CM 133 printf("DPLL5 could be on: %"PRIx32" %"PRIx32".\n", 134 pio_read_32((ioport32_t*)&device->cm.clocks->idlest_ckgen), 135 pio_read_32((ioport32_t*)&device->cm.clocks->idlest2_ckgen)); 136 #endif 137 138 if (on) { 139 /* Enable interface and function clock for USB TLL */ 140 pio_set_32(&device->cm.core->fclken3, 141 CORE_CM_FCLKEN3_EN_USBTLL_FLAG, 5); 142 pio_set_32(&device->cm.core->iclken3, 143 CORE_CM_ICLKEN3_EN_USBTLL_FLAG, 5); 144 145 /* Enable interface and function clock for USB hosts */ 146 pio_set_32(&device->cm.usbhost->fclken, 147 USBHOST_CM_FCLKEN_EN_USBHOST1_FLAG | 148 USBHOST_CM_FCLKEN_EN_USBHOST2_FLAG, 5); 149 pio_set_32(&device->cm.usbhost->iclken, 150 USBHOST_CM_ICLKEN_EN_USBHOST, 5); 151 #ifdef DEBUG_CM 152 printf("DPLL5 (and everything else) should be on: %"PRIx32" %"PRIx32".\n", 153 pio_read_32((ioport32_t*)&device->cm.clocks->idlest_ckgen), 154 pio_read_32((ioport32_t*)&device->cm.clocks->idlest2_ckgen)); 155 #endif 156 } else { 157 /* Disable interface and function clock for USB hosts */ 158 pio_clear_32(&device->cm.usbhost->iclken, 159 USBHOST_CM_ICLKEN_EN_USBHOST, 5); 160 pio_clear_32(&device->cm.usbhost->fclken, 161 USBHOST_CM_FCLKEN_EN_USBHOST1_FLAG | 162 USBHOST_CM_FCLKEN_EN_USBHOST2_FLAG, 5); 163 164 /* Disable interface and function clock for USB TLL */ 165 pio_clear_32(&device->cm.core->iclken3, 166 CORE_CM_ICLKEN3_EN_USBTLL_FLAG, 5); 167 pio_clear_32(&device->cm.core->fclken3, 168 CORE_CM_FCLKEN3_EN_USBTLL_FLAG, 5); 169 } 170 171 return EOK; 172 } 173 174 /** Initialize USB TLL port connections. 175 * 176 * Different modes are on page 3312 of the Manual Figure 22-34. 177 * Select mode than can operate in FS/LS. 178 */ 179 static int usb_tll_init(amdm37x_t *device) 180 { 181 182 /* Reset USB TLL */ 183 pio_set_32(&device->tll->sysconfig, TLL_SYSCONFIG_SOFTRESET_FLAG, 5); 184 ddf_msg(LVL_DEBUG2, "Waiting for USB TLL reset"); 185 while (!(pio_read_32(&device->tll->sysstatus) & TLL_SYSSTATUS_RESET_DONE_FLAG)); 186 ddf_msg(LVL_DEBUG, "USB TLL Reset done."); 187 188 /* Setup idle mode (smart idle) */ 189 pio_change_32(&device->tll->sysconfig, 190 TLL_SYSCONFIG_CLOCKACTIVITY_FLAG | TLL_SYSCONFIG_AUTOIDLE_FLAG | 191 TLL_SYSCONFIG_SIDLE_MODE_SMART, TLL_SYSCONFIG_SIDLE_MODE_MASK, 5); 192 193 /* Smart idle for UHH */ 194 pio_change_32(&device->uhh->sysconfig, 195 UHH_SYSCONFIG_CLOCKACTIVITY_FLAG | UHH_SYSCONFIG_AUTOIDLE_FLAG | 196 UHH_SYSCONFIG_SIDLE_MODE_SMART, UHH_SYSCONFIG_SIDLE_MODE_MASK, 5); 197 198 /* Set all ports to go through TLL(UTMI) 199 * Direct connection can only work in HS mode */ 200 pio_set_32(&device->uhh->hostconfig, 201 UHH_HOSTCONFIG_P1_ULPI_BYPASS_FLAG | 202 UHH_HOSTCONFIG_P2_ULPI_BYPASS_FLAG | 203 UHH_HOSTCONFIG_P3_ULPI_BYPASS_FLAG, 5); 204 205 /* What is this? */ 206 pio_set_32(&device->tll->shared_conf, TLL_SHARED_CONF_FCLK_IS_ON_FLAG, 5); 207 208 for (unsigned i = 0; i < 3; ++i) { 209 /* Serial mode is the only one capable of FS/LS operation. 210 * Select FS/LS mode, no idea what the difference is 211 * one of bidirectional modes might be good choice 212 * 2 = 3pin bidi phy. */ 213 pio_change_32(&device->tll->channel_conf[i], 214 TLL_CHANNEL_CONF_CHANMODE_UTMI_SERIAL_MODE | 215 TLL_CHANNEL_CONF_FSLSMODE_3PIN_BIDI_PHY, 216 TLL_CHANNEL_CONF_CHANMODE_MASK | 217 TLL_CHANNEL_CONF_FSLSMODE_MASK, 5); 218 } 219 return EOK; 220 } 48 221 49 222 typedef struct { … … 51 224 } rootamdm37x_fun_t; 52 225 53 /* See amdm37x TRM page. 3316 for these values */54 226 #define OHCI_BASE_ADDRESS 0x48064400 55 227 #define OHCI_SIZE 1024 … … 60 232 { 61 233 .type = MEM_RANGE, 234 /* See amdm37x TRM page. 3316 for these values */ 62 235 .res.io_range = { 63 236 .address = OHCI_BASE_ADDRESS, … … 70 243 .res.interrupt = { .irq = 76 }, 71 244 }, 245 }; 246 247 static const rootamdm37x_fun_t ohci = { 248 .hw_resources = { 249 .resources = ohci_res, 250 .count = sizeof(ohci_res)/sizeof(ohci_res[0]), 251 } 72 252 }; 73 253 … … 88 268 }; 89 269 90 static const rootamdm37x_fun_t ohci = {91 .hw_resources = {92 .resources = ohci_res,93 .count = sizeof(ohci_res)/sizeof(ohci_res[0]),94 }95 };96 97 270 static const rootamdm37x_fun_t ehci = { 98 271 .hw_resources = { … … 110 283 }; 111 284 112 static ddf_dev_ops_t rootamdm37x_fun_ops = { 285 static ddf_dev_ops_t rootamdm37x_fun_ops = 286 { 113 287 .interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops 114 288 }; 115 289 116 static introotamdm37x_add_fun(ddf_dev_t *dev, const char *name,290 static bool rootamdm37x_add_fun(ddf_dev_t *dev, const char *name, 117 291 const char *str_match_id, const rootamdm37x_fun_t *fun) 118 292 { … … 124 298 return ENOMEM; 125 299 300 126 301 /* Add match id */ 127 int ret = ddf_fun_add_match_id(fnode, str_match_id, 100); 128 if (ret != EOK) { 302 if (ddf_fun_add_match_id(fnode, str_match_id, 100) != EOK) { 129 303 ddf_fun_destroy(fnode); 130 return ret; 131 } 132 133 /* Alloc needed data */ 134 rootamdm37x_fun_t *rf = 135 ddf_fun_data_alloc(fnode, sizeof(rootamdm37x_fun_t)); 136 if (!rf) { 304 return false; 305 } 306 307 /* Set provided operations to the device. */ 308 ddf_fun_data_implant(fnode, (void*)fun); 309 ddf_fun_set_ops(fnode, &rootamdm37x_fun_ops); 310 311 /* Register function. */ 312 if (ddf_fun_bind(fnode) != EOK) { 313 ddf_msg(LVL_ERROR, "Failed binding function %s.", name); 314 // TODO This will try to free our data! 137 315 ddf_fun_destroy(fnode); 138 return ENOMEM; 139 } 140 *rf = *fun; 141 142 /* Set provided operations to the device. */ 143 ddf_fun_set_ops(fnode, &rootamdm37x_fun_ops); 144 145 /* Register function. */ 146 ret = ddf_fun_bind(fnode); 147 if (ret != EOK) { 148 ddf_msg(LVL_ERROR, "Failed binding function %s.", name); 149 ddf_fun_destroy(fnode); 150 return ret; 151 } 152 153 return EOK; 316 return false; 317 } 318 319 return true; 154 320 } 155 321 … … 168 334 if (!device) 169 335 return ENOMEM; 170 int ret = amdm37x_ init(device, DEBUG_CM);336 int ret = amdm37x_hw_access_init(device); 171 337 if (ret != EOK) { 172 338 ddf_msg(LVL_FATAL, "Failed to setup hw access!.\n"); … … 174 340 } 175 341 176 /* Set dplls to ON and automatic */ 177 amdm37x_setup_dpll_on_autoidle(device); 178 179 /* Enable function and interface clocks */ 180 amdm37x_usb_clocks_set(device, true); 181 182 /* Init TLL */ 183 ret = amdm37x_usb_tll_init(device); 342 ret = usb_clocks(device, true); 343 if (ret != EOK) { 344 ddf_msg(LVL_FATAL, "Failed to enable USB HC clocks!.\n"); 345 return ret; 346 } 347 348 ret = usb_tll_init(device); 184 349 if (ret != EOK) { 185 350 ddf_msg(LVL_FATAL, "Failed to init USB TLL!.\n"); 186 amdm37x_usb_clocks_set(device, false);351 usb_clocks(device, false); 187 352 return ret; 188 353 } 189 354 190 355 /* Register functions */ 191 if ( rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci) != EOK)356 if (!rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci)) 192 357 ddf_msg(LVL_ERROR, "Failed to add OHCI function for " 193 358 "BeagleBoard-xM platform."); 194 if ( rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci) != EOK)359 if (!rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci)) 195 360 ddf_msg(LVL_ERROR, "Failed to add EHCI function for " 196 361 "BeagleBoard-xM platform."); … … 210 375 }; 211 376 212 static hw_resource_list_t * 377 static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode) 213 378 { 214 379 rootamdm37x_fun_t *fun = ddf_fun_data_get(fnode); … … 219 384 static bool rootamdm37x_enable_interrupt(ddf_fun_t *fun) 220 385 { 221 / /TODO: Implement386 /* TODO */ 222 387 return false; 223 388 }
Note:
See TracChangeset
for help on using the changeset viewer.