linux/drivers/usb/host/octeon2-common.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 2010, 2011 Cavium Networks
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/mutex.h>
  11#include <linux/delay.h>
  12
  13#include <asm/octeon/octeon.h>
  14#include <asm/octeon/cvmx-uctlx-defs.h>
  15
  16static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
  17
  18static int octeon2_usb_clock_start_cnt;
  19
  20void octeon2_usb_clocks_start(void)
  21{
  22        u64 div;
  23        union cvmx_uctlx_if_ena if_ena;
  24        union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
  25        union cvmx_uctlx_uphy_ctl_status uphy_ctl_status;
  26        union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
  27        int i;
  28        unsigned long io_clk_64_to_ns;
  29
  30
  31        mutex_lock(&octeon2_usb_clocks_mutex);
  32
  33        octeon2_usb_clock_start_cnt++;
  34        if (octeon2_usb_clock_start_cnt != 1)
  35                goto exit;
  36
  37        io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
  38
  39        /*
  40         * Step 1: Wait for voltages stable.  That surely happened
  41         * before starting the kernel.
  42         *
  43         * Step 2: Enable  SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
  44         */
  45        if_ena.u64 = 0;
  46        if_ena.s.en = 1;
  47        cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
  48
  49        /* Step 3: Configure the reference clock, PHY, and HCLK */
  50        clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
  51
  52        /*
  53         * If the UCTL looks like it has already been started, skip
  54         * the initialization, otherwise bus errors are obtained.
  55         */
  56        if (clk_rst_ctl.s.hrst)
  57                goto end_clock;
  58        /* 3a */
  59        clk_rst_ctl.s.p_por = 1;
  60        clk_rst_ctl.s.hrst = 0;
  61        clk_rst_ctl.s.p_prst = 0;
  62        clk_rst_ctl.s.h_clkdiv_rst = 0;
  63        clk_rst_ctl.s.o_clkdiv_rst = 0;
  64        clk_rst_ctl.s.h_clkdiv_en = 0;
  65        clk_rst_ctl.s.o_clkdiv_en = 0;
  66        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
  67
  68        /* 3b */
  69        /* 12MHz crystal. */
  70        clk_rst_ctl.s.p_refclk_sel = 0;
  71        clk_rst_ctl.s.p_refclk_div = 0;
  72        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
  73
  74        /* 3c */
  75        div = octeon_get_io_clock_rate() / 130000000ull;
  76
  77        switch (div) {
  78        case 0:
  79                div = 1;
  80                break;
  81        case 1:
  82        case 2:
  83        case 3:
  84        case 4:
  85                break;
  86        case 5:
  87                div = 4;
  88                break;
  89        case 6:
  90        case 7:
  91                div = 6;
  92                break;
  93        case 8:
  94        case 9:
  95        case 10:
  96        case 11:
  97                div = 8;
  98                break;
  99        default:
 100                div = 12;
 101                break;
 102        }
 103        clk_rst_ctl.s.h_div = div;
 104        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 105        /* Read it back, */
 106        clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
 107        clk_rst_ctl.s.h_clkdiv_en = 1;
 108        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 109        /* 3d */
 110        clk_rst_ctl.s.h_clkdiv_rst = 1;
 111        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 112
 113        /* 3e: delay 64 io clocks */
 114        ndelay(io_clk_64_to_ns);
 115
 116        /*
 117         * Step 4: Program the power-on reset field in the UCTL
 118         * clock-reset-control register.
 119         */
 120        clk_rst_ctl.s.p_por = 0;
 121        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 122
 123        /* Step 5:    Wait 1 ms for the PHY clock to start. */
 124        mdelay(1);
 125
 126        /*
 127         * Step 6: Program the reset input from automatic test
 128         * equipment field in the UPHY CSR
 129         */
 130        uphy_ctl_status.u64 = cvmx_read_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0));
 131        uphy_ctl_status.s.ate_reset = 1;
 132        cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
 133
 134        /* Step 7: Wait for at least 10ns. */
 135        ndelay(10);
 136
 137        /* Step 8: Clear the ATE_RESET field in the UPHY CSR. */
 138        uphy_ctl_status.s.ate_reset = 0;
 139        cvmx_write_csr(CVMX_UCTLX_UPHY_CTL_STATUS(0), uphy_ctl_status.u64);
 140
 141        /*
 142         * Step 9: Wait for at least 20ns for UPHY to output PHY clock
 143         * signals and OHCI_CLK48
 144         */
 145        ndelay(20);
 146
 147        /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
 148        /* 10a */
 149        clk_rst_ctl.s.o_clkdiv_rst = 1;
 150        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 151
 152        /* 10b */
 153        clk_rst_ctl.s.o_clkdiv_en = 1;
 154        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 155
 156        /* 10c */
 157        ndelay(io_clk_64_to_ns);
 158
 159        /*
 160         * Step 11: Program the PHY reset field:
 161         * UCTL0_CLK_RST_CTL[P_PRST] = 1
 162         */
 163        clk_rst_ctl.s.p_prst = 1;
 164        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 165
 166        /* Step 12: Wait 1 uS. */
 167        udelay(1);
 168
 169        /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
 170        clk_rst_ctl.s.hrst = 1;
 171        cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
 172
 173end_clock:
 174        /* Now we can set some other registers.  */
 175
 176        for (i = 0; i <= 1; i++) {
 177                port_ctl_status.u64 =
 178                        cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
 179                /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */
 180                port_ctl_status.s.txvreftune = 15;
 181                port_ctl_status.s.txrisetune = 1;
 182                port_ctl_status.s.txpreemphasistune = 1;
 183                cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
 184                               port_ctl_status.u64);
 185        }
 186
 187        /* Set uSOF cycle period to 60,000 bits. */
 188        cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull);
 189exit:
 190        mutex_unlock(&octeon2_usb_clocks_mutex);
 191}
 192EXPORT_SYMBOL(octeon2_usb_clocks_start);
 193
 194void octeon2_usb_clocks_stop(void)
 195{
 196        mutex_lock(&octeon2_usb_clocks_mutex);
 197        octeon2_usb_clock_start_cnt--;
 198        mutex_unlock(&octeon2_usb_clocks_mutex);
 199}
 200EXPORT_SYMBOL(octeon2_usb_clocks_stop);
 201