Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / usb / ohci.fth
\ ========== Copyright Header Begin ==========================================
\
\ Hypervisor Software File: ohci.fth
\
\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
\
\ - Do no alter or remove copyright notices
\
\ - Redistribution and use of this software in source and binary forms, with
\ or without modification, are permitted provided that the following
\ conditions are met:
\
\ - Redistribution of source code must retain the above copyright notice,
\ this list of conditions and the following disclaimer.
\
\ - Redistribution in binary form must reproduce the above copyright notice,
\ this list of conditions and the following disclaimer in the
\ documentation and/or other materials provided with the distribution.
\
\ Neither the name of Sun Microsystems, Inc. or the names of contributors
\ may be used to endorse or promote products derived from this software
\ without specific prior written permission.
\
\ This software is provided "AS IS," without a warranty of any kind.
\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\
\ You acknowledge that this software is not designed, licensed or
\ intended for use in the design, construction, operation or maintenance of
\ any nuclear facility.
\
\ ========== Copyright Header End ============================================
id: @(#)ohci.fth 1.14 06/02/01
purpose:
copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
copyright: Use is subject to license terms.
\ stuff bits, leaving the rest alone, in the control reg.
: controlbit-on ( bit -- )
chip-base hc-control rl@ or
chip-base hc-control rl!
;
\ turn bit off, leaving the rest alone, in control reg.
: controlbit-off ( bit -- )
invert chip-base hc-control rl@ and
chip-base hc-control rl!
;
: periodic-on ( -- ) 4 controlbit-on ;
: periodic-off ( -- ) 4 controlbit-off ;
: isoc-on ( -- ) 8 controlbit-on ;
: isoc-off ( -- ) 8 controlbit-off ;
: control-on ( -- ) h# 10 controlbit-on ;
: control-off ( -- ) h# 10 controlbit-off ;
: bulk-on ( -- ) h# 20 controlbit-on ;
: bulk-off ( -- ) h# 20 controlbit-off ;
\ : q-on ( q-id -- )
\ h# 3e - 0 max
\ 4 swap lshift
\ controlbits-on
\ ;
\ : q-off ( q-id -- )
\ h# 3e - 0 max
\ 4 swap lshift
\ controlbits-off
\ ;
: >state ( n -- )
6 lshift
chip-base hc-control rl@
h# c0 invert and or
chip-base hc-control rl!
;
\ nominally 10 ms
\ usb1.1, 7.1.7.3 says at least 50 ms
: usb-reset ( -- ) 0 >state d# 100 ms ; \ power-on state
\ nominally 20 ms; USB 7.1.4.5; also usb1.1 7.1.7.5
: usb-resume ( -- ) 1 >state d# 40 ms ;
\ usb1.1 7.1.7.3 says wait 10 ms before talking to devices after usb-reset
\ usb1.1 7.1.7.5 says 10 ms delay after usb-resume
\ embed the delay here, since operational is the end of usb-reset
: usb-operational ( -- ) 2 >state d# 10 ms ;
\ XXX enough time? nominally 5 ms from where? how long does it take for
\ the controller to stop accessing memory? the time before we resume
\ the bus doesn't seem to be an issue?
\ The delay is to allow suspend to propagate down the bus. Devices need to
\ see no SOF for 3 ms to go to their own suspended state.
\ It is also to allow RIO to stop accessing memory.
: usb-suspend ( -- ) 3 >state 5 ms ;
\ stuff bit, leaving the rest alone, in the command/stat reg.
: bit>command ( bit -- )
chip-base hc-cmd-status rl@ or
chip-base hc-cmd-status rl!
;
: ohci-reset ( -- failed? ) \ reset controller only
1 bit>command
\ XXX can take up to 10 usecs before finishing reset
\ but if it takes longer than 1 ms to go to operational state, devices
\ on the bus can go into suspend state
\ 1 ms \ wait 10 usec
chip-base hc-cmd-status rl@ 1 and \ 0 means done resetting
;
: control-filled ( -- ) 2 bit>command ;
: bulk-filled ( -- ) 4 bit>command ;
\ stuff bit, leaving the rest alone, in the interrupt status reg.
: bit>int-status ( bit -- )
chip-base hc-int-status rl!
;
: clear-overrun ( -- ) 1 bit>int-status ;
: clear-done-head ( -- ) 2 bit>int-status ;
: clear-sof ( -- ) 4 bit>int-status ;
: clear-bad-error ( -- ) h# 10 bit>int-status ;
: clear-hub-change ( -- ) h# 40 bit>int-status ;
: clear-interrupts ( -- )
chip-base hc-int-status rl@
chip-base hc-int-status rl!
;
: new-done? ( -- new-done? ) 2 chip-base hc-int-status rl@ and ;
: new-sof? ( -- new-sof? ) 4 chip-base hc-int-status rl@ and ;
\ XXX RIO reset-port disables the port. not good. or does it toggle enable?
\ is it only lo-speed ports?
\ enable-port anyway, even if it says it's enabled per OS init code.
: clean-port ( port -- )
dup reset-port
dup enable-port
dup clear-connect-change
dup clear-port-reset
dup clear-port-suspend
clear-port-enable
clear-hub-change
;
0 value end-time \ used to sync wi. controller via next-frame
: timed-out? ( -- timed-out? )
get-msecs end-time u> \ XXX problem when going thru 0
;
\ If wait-for-sof times out, the chip is not copasetic
\ XXX throw from here; should publish some kind of error!
: wait-for-sof ( -- )
get-msecs d# 10 + is end-time \ really should be only 1 ms
begin
new-sof?
timed-out? or
until
;
: wait-for-first-sof ( -- sof? ) \ used during power on
clear-sof
false \ assumes failure
d# 300 0 do \ wait up to 3 seconds
new-sof? if
drop true leave
then
10 ms
loop
;
: next-frame ( -- ) clear-sof wait-for-sof ;
\ Stuff a new value into the fsmps field of fm-interval reg:
: fsmps! ( n -- )
d# 16 lshift
chip-base hc-fm-interval rl@
dup 8000 and 8000 xor >r \ toggle bit needed later
h# 3fff and or
r> or
chip-base hc-fm-interval rl!
;
\ XXX need to bang control reg. cmd-status reg
: start-controller ( -- ok? )
usb-reset
\ make sure frameremaining field is not large (SOF tokens start on next
\ transition)
usb-operational
\ want to see SOF within 3 seconds here or something is fatally wrong:
wait-for-first-sof ( sof? )
dup 0= if
." no usb SOF" cr
then
get-root-info
set-root-status
\ sequence triggers port status change in RIO. it's magic and shouldn't
\ be necessary, but it seems to get the chip more fully operational:
unpower-ports 2 ms \ 1 ms necessary; 2 to make sure
power-ports 4 ms \ 3 necessary
\ set-root-port-status
clear-interrupts
;
\ must keep resume disabled.
\ some control bits in the hub registers will keep specific ports from forcing
\ resume.
: stop-controller ( -- )
periodic-off isoc-off control-off bulk-off
next-frame
usb-suspend
;
\ set regs that have adjustable policy, that basically are touched only once
: set-policy ( -- )
\ h# 3e67 chip-base hc-period-start rl! \ XXX from manual; too long!
\ h# 2a30 chip-base hc-period-start rl!
\ give 20% to control/bulk, 80% to periodic:
h# 2580 chip-base hc-period-start rl!
\ h# 628 chip-base hc-ls-threshold rl! \ 628 is reset value
;
\ Sometimes the HcFmInterval register will not hold it's value
\ after the first write. This was seen primarily on the ULI 1575
\ controller, but also reported on the 1535+.
\ Loop on the write to ensure it has completed.
: hc-fm-interval! ( data -- error? )
chip-base hc-fm-interval
d# 10 0 do
2dup rl!
2dup rl@ = if
leave
then
d# 10 ms
loop
rl@ <> dup if
cmn-error[ " Unable to write to HcFmInterval Register" ]cmn-end
then
;
\ Leave controller off:
: set-regs ( -- error? )
0 chip-base hc-cmd-status rl!
h# c000.007f chip-base hc-int-disable rl! \ disable interrupts
clear-interrupts \ done later also; may not be needed here
dev-hcca chip-base hc-hcca rl!
dev-control-dummy dup \ empty control q
chip-base hc-control-head rl!
chip-base hc-control-current rl!
dev-bulk-dummy dup \ empty bulk q
chip-base hc-bulk-head rl!
chip-base hc-bulk-current rl!
0 chip-base hc-done-head rl! \ empty done q
h# a668.2edf hc-fm-interval! ( error? ) \ using 2668
\ OS uses 2668:
\ h# 2668 fsmps! \ XXX not here -- should calculate
set-root-hub
;
: toss-controller ( -- )
stop-controller dump-structs
unmap-regs
;
: init-controller ( -- ok? )
map-regs ohci-reset if \ reset failed error exit
." usb reset failed" cr
false exit \ XXX throw is better?
then
make-structs
chip-base hc-control rl@ drop \ read, then write, per OS driver.
0 chip-base hc-control rl! \ does usb-reset and clears reg.
d# 100 ms \ wait here; nominally 10 ms; see comment on usb-reset
set-policy
set-regs if
dump-structs unmap-regs
false exit
then
\ should start within 1 msec of ohci-reset?
start-controller
;