Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.10 200 lines 5.0 kB view raw
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);