Ignore:
Timestamp:
2012-11-25T21:34:07Z (12 years ago)
Author:
Maurizio Lombardi <m.lombardi85@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e1a27be
Parents:
150a271 (diff), 7462674 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c

    r150a271 r8f88beb  
    3535/** @file
    3636 */
    37 #define _DDF_DATA_IMPLANT
    38 
    39 #define DEBUG_CM
    40 
    41 #include <ddf/driver.h>
     37
     38#define DEBUG_CM 0
     39
    4240#include <ddf/log.h>
    4341#include <errno.h>
    4442#include <ops/hw_res.h>
    4543#include <stdio.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"
     44
     45#include "amdm37x.h"
    5346
    5447#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 }
    22148
    22249typedef struct {
     
    22451} rootamdm37x_fun_t;
    22552
     53/* See amdm37x TRM page. 3316 for these values */
    22654#define OHCI_BASE_ADDRESS  0x48064400
    22755#define OHCI_SIZE  1024
     
    23260        {
    23361                .type = MEM_RANGE,
    234                 /* See amdm37x TRM page. 3316 for these values */
    23562                .res.io_range = {
    23663                        .address = OHCI_BASE_ADDRESS,
     
    24370                .res.interrupt = { .irq = 76 },
    24471        },
    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         }
    25272};
    25373
     
    26888};
    26989
     90static const rootamdm37x_fun_t ohci = {
     91        .hw_resources = {
     92            .resources = ohci_res,
     93            .count = sizeof(ohci_res)/sizeof(ohci_res[0]),
     94        }
     95};
     96
    27097static const rootamdm37x_fun_t ehci = {
    27198        .hw_resources = {
     
    283110};
    284111
    285 static ddf_dev_ops_t rootamdm37x_fun_ops =
    286 {
     112static ddf_dev_ops_t rootamdm37x_fun_ops = {
    287113        .interfaces[HW_RES_DEV_IFACE] = &fun_hw_res_ops
    288114};
    289115
    290 static bool rootamdm37x_add_fun(ddf_dev_t *dev, const char *name,
     116static int rootamdm37x_add_fun(ddf_dev_t *dev, const char *name,
    291117    const char *str_match_id, const rootamdm37x_fun_t *fun)
    292118{
     
    298124                return ENOMEM;
    299125       
    300        
    301126        /* Add match id */
    302         if (ddf_fun_add_match_id(fnode, str_match_id, 100) != EOK) {
     127        int ret = ddf_fun_add_match_id(fnode, str_match_id, 100);
     128        if (ret != EOK) {
    303129                ddf_fun_destroy(fnode);
    304                 return false;
    305         }
    306        
     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) {
     137                ddf_fun_destroy(fnode);
     138                return ENOMEM;
     139        }
     140        *rf = *fun;
     141
    307142        /* Set provided operations to the device. */
    308         ddf_fun_data_implant(fnode, (void*)fun);
    309143        ddf_fun_set_ops(fnode, &rootamdm37x_fun_ops);
    310144       
    311145        /* Register function. */
    312         if (ddf_fun_bind(fnode) != EOK) {
     146        ret = ddf_fun_bind(fnode);
     147        if (ret != EOK) {
    313148                ddf_msg(LVL_ERROR, "Failed binding function %s.", name);
    314                 // TODO This will try to free our data!
    315149                ddf_fun_destroy(fnode);
    316                 return false;
    317         }
    318        
    319         return true;
     150                return ret;
     151        }
     152       
     153        return EOK;
    320154}
    321155
     
    334168        if (!device)
    335169                return ENOMEM;
    336         int ret = amdm37x_hw_access_init(device);
     170        int ret = amdm37x_init(device, DEBUG_CM);
    337171        if (ret != EOK) {
    338172                ddf_msg(LVL_FATAL, "Failed to setup hw access!.\n");
     
    340174        }
    341175
    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);
     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);
    349184        if (ret != EOK) {
    350185                ddf_msg(LVL_FATAL, "Failed to init USB TLL!.\n");
    351                 usb_clocks(device, false);
     186                amdm37x_usb_clocks_set(device, false);
    352187                return ret;
    353188        }
    354189
    355190        /* Register functions */
    356         if (!rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci))
     191        if (rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci) != EOK)
    357192                ddf_msg(LVL_ERROR, "Failed to add OHCI function for "
    358193                    "BeagleBoard-xM platform.");
    359         if (!rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci))
     194        if (rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci) != EOK)
    360195                ddf_msg(LVL_ERROR, "Failed to add EHCI function for "
    361196                    "BeagleBoard-xM platform.");
     
    375210};
    376211
    377 static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode)
     212static hw_resource_list_t * rootamdm37x_get_resources(ddf_fun_t *fnode)
    378213{
    379214        rootamdm37x_fun_t *fun = ddf_fun_data_get(fnode);
     
    384219static bool rootamdm37x_enable_interrupt(ddf_fun_t *fun)
    385220{
    386         /* TODO */
     221        //TODO: Implement
    387222        return false;
    388223}
Note: See TracChangeset for help on using the changeset viewer.