Author: wmb Date: 2009-11-10 08:08:15 +0000 (Tue, 10 Nov 2009) New Revision: 1468
Added: dev/intel/graphics/poulsbo.bth dev/intel/graphics/poulsbo.fth Log: Completed the previous checkin by adding the actual driver files; the previous one added only the directories.
Added: dev/intel/graphics/poulsbo.bth =================================================================== --- dev/intel/graphics/poulsbo.bth (rev 0) +++ dev/intel/graphics/poulsbo.bth 2009-11-10 08:08:15 UTC (rev 1468) @@ -0,0 +1,14 @@ +purpose: Load file for Poulsbo Frame Buffer FCode driver + +command: &tokenize &this +build-now + +silent on + +begin-tokenizing poulsbo.fc + +FCode-version2 +fload ${BP}/dev/intel/graphics/poulsbo.fth +end0 + +end-tokenizing
Added: dev/intel/graphics/poulsbo.fth =================================================================== --- dev/intel/graphics/poulsbo.fth (rev 0) +++ dev/intel/graphics/poulsbo.fth 2009-11-10 08:08:15 UTC (rev 1468) @@ -0,0 +1,444 @@ +\ See license at end of file +purpose: Display driver for Poulsbo using 800x600 LCD panel on LVDS + +\ The Poulsbo display engine is very similar to the i915 series, +\ so long as you ignore the acceleration. This driver in its +\ current state hardcodes a lot of assumptions about display +\ resolution and output device. + +\ 0 0 " 2,0" " /pci" begin-package + +" display" device-name + +\ Configuration space registers +my-address my-space encode-phys + 0 encode-int encode+ 0 encode-int encode+ + +\ MMIO register bank +0 0 my-space 0200.0010 + encode-phys encode+ + 0 encode-int encode+ h# 80000 encode-int encode+ + +\ I/O Space registers +0 0 my-space h# 0100.0014 + encode-phys encode+ + 0 encode-int encode+ 8 encode-int encode+ + +\ Aperture +0 0 my-space h# 0200.0018 + encode-phys encode+ + 0 encode-int encode+ h# 1000.0000 encode-int encode+ + +\ GATT +0 0 my-space h# 0200.001c + encode-phys encode+ + 0 encode-int encode+ h# 0004.0000 encode-int encode+ + + " reg" property + + + +: my-l@ ( offset -- l ) my-space + " config-l@" $call-parent ; +: my-l! ( l offset -- ) my-space + " config-l!" $call-parent ; +: my-w@ ( offset -- w ) my-space + " config-w@" $call-parent ; +: my-w! ( w offset -- ) my-space + " config-w!" $call-parent ; + +d# 32 value depth + +0 value msvdx +0 value vdc +0 value sgx +: page-bits ( n -- n' ) h# fff invert and ; + +: pci-len ( bar-offset -- len ) + >r + r@ my-l@ ( oldval ) + -1 r@ my-l! ( oldval ) + r@ my-l@ ( oldval writable-bits ) + swap r> my-l! ( writable-bits ) + h# f invert and ( top-bits ) + invert 1+ ( len ) +; + +0 value gtt +0 value gatt + +0 value gtt-phys +\ 0 value gatt-phys +0 value gtt-start +0 value /gtt +0 value /gatt +0 value stolen-base +0 value /stolen +0 value scratch-page +0 value scratch-page-pa + +h# 20.0000 value /fb \ Enough for 800x600x32bpp + +: mmio@ ( offset -- l ) vdc + rl@ ; +: mmio! ( l offset -- ) vdc + rl! ; + +: sgx@ ( offset -- l ) sgx + rl@ ; +: sgx! ( l offset -- ) sgx + rl! ; + +: adr>page# ( adr -- page# ) d# 12 rshift ; +: page#>adr ( page# -- adr ) d# 12 lshift ; +h# 1000 constant /page + +: map-bar ( phys.lo len bar# -- vadr ) + swap >r ( phys.lo bar# r: len ) + my-space + h# 200.0000 + ( phys.lo phys.hi r: len ) + 0 swap r> ( phys.lo,mid,hi len ) + " map-in" $call-parent +; + +: clockgating@ ( -- n ) 0 sgx@ ; +: clockgating! ( n -- ) 0 sgx! ; + +h# 2000.0000 constant dm_pixel +: use-code-base! ( value i -- ) h# a0c swap la+ sgx! ; +: init-use-base ( n len -- ) bounds ?do dm_pixel i use-code-base! loop ; + +: init-mmu ( -- ) + \ Clear any pending faults - psb_mmu.c : psb_mmu_driver_init + h# c00 sgx@ ( bif-ctrl ) + dup h# 10 or h# c00 sgx! ( bif-ctrl ) + h# 10 invert and h# c00 sgx! ( ) +; + +: init-gtt ( -- ) + h# 2020 dup mmio@ ( reg pge_ctl ) + tuck 1 or swap mmio! ( pge_ctl ) \ Enable + page-bits to gtt-phys ( ) + +\ h# 18 my-l@ page-bits to gatt-phys + h# 1c my-l@ page-bits to gtt-start + h# 1c pci-len to /gtt + h# 18 pci-len to /gatt + h# 5c my-l@ to stolen-base + + gtt-phys stolen-base - h# 1000 - to /stolen + + h# 0 /gtt h# 1c map-bar to gtt + + \ Insert the stolen pages into the GTT + stolen-base 1 + ( pte-template ) + /stolen 0 do ( pte-template ) + dup i + gtt i adr>page# la+ rl! ( pte-template ) + /page +loop ( pte-template ) + drop + + \ Fill the rest of the GTT with PTEs for a scratch page + /page " dma-alloc" $call-parent to scratch-page + scratch-page h# 1000 false " dma-map-in" $call-parent to scratch-page-pa + + /gatt /stolen ?do + scratch-page-pa 1+ gtt i adr>page# la+ rl! + /page +loop + + gtt /gtt + /page - rl@ drop \ Sync +; +: init-requestors ( -- ) + 0 h# c78 sgx! \ PSB_CR_BIF_BANK0 + 0 h# c7c sgx! \ PSB_CR_BIF_BANK1 + h# c7c sgx@ drop +; +: init-bases ( -- ) + h# 2000.0000 h# ab8 sgx! \ PSB_WSGX32(PSB_MEM_PDS_START, PSB_CR_PDS_EXEC_BASE); + h# 3000.0000 h# cac sgx! \ PSB_WSGX32(PSB_MEM_RASTGEOM_START, PSB_CR_BIF_3D_REQ_BASE); +; +: memory-setup ( -- ) + \ The manual says this bit is reserved, but the Linux driver defines and sets it + h# 52 my-w@ 4 or h# 52 my-w! \ Enable GMCH + h# 0 h# 80000 h# 10 map-bar to vdc + h# 50000 h# 08000 h# 10 map-bar to msvdx + h# 40000 h# 08000 h# 10 map-bar to sgx + 4 my-w@ 7 or 4 my-w! \ Enable bus mastering, memory and I/O access + + d# 3 d# 13 init-use-base \ psb_init_use_base(dev_priv, 3, 13); + + init-gtt + init-mmu + init-bases + + " address" get-my-property if + stolen-base encode-int " address" property +\ h# 0 /fb h# 18 map-bar to frame-buffer-adr +\ frame-buffer-adr + else +\ decode-int to frame-buffer-adr + 2drop + then +; + +\ Geometry for 800x600 LCD + +d# 800 constant hdisplay +d# 839 constant hsstart +d# 967 constant hsend +d# 1055 constant htotal + +d# 600 constant vdisplay +d# 600 constant vsstart +d# 604 constant vsend +d# 627 constant vtotal + +h# d804.0000 constant dpll-val \ VCO, high speed, VGA disable, LVDS, clock div 10, post div 4 +h# 0004.1108 constant fp-val \ N, M1, M2 divisors +\ h# d900.0000 constant dspcntr-val \ Enable, Gamma, 32bpp no alpha, pipe b +h# 9900.0000 constant dspcntr-val \ Enable, NoGamma, 32bpp no alpha, pipe b + +\ Empirically this has no effect. It is probably for CRT output +\ : dac-on ( -- ) +\ h# c000.0018 h# 61100 mmio! \ 80000000-DAC_ON 40000000-PIPEB 10-PVSYNC 8-PHSYNC +\ ; + +d# 3200 value bytes/line + +h# 0000 constant pipe-a +h# 1000 constant pipe-b +pipe-b value pipe + +: mmio!! ( value offset -- ) tuck mmio! mmio@ drop ; + +: pipe@ ( offset -- n ) pipe + mmio@ ; +: pipe! ( n offset -- ) pipe + mmio! ; +: pipe!! ( n offset -- ) pipe + mmio!! ; + +h# 70180 constant dspcntr-reg +h# 70184 constant dspbase-reg +h# 70008 constant pipeconf-reg +h# 61230 constant pfit-reg +h# 61180 constant lvds-reg + +\ Packs two 16-bit values into a 32-bit register, offsetting +\ each value by -1 +: crtconf! ( low high reg -- ) + >r swap 1- swap 1- wljoin r> pipe! +; + +\ A few of the pipe-dependent registers are at offsets of 4 +\ instead of h# 1000. + +: +pipe ( offset -- offset' ) pipe if 4 + then ; + +: fpreg! ( value -- ) h# 6040 +pipe mmio! ; + +: dpll! ( value -- ) + h# 6014 +pipe mmio!! + d# 150 " us" evaluate +; +: dpll@ ( -- value ) h# 6014 +pipe mmio@ ; +: wait-vblank ( -- ) d# 30 ms ; + +h# 8000.0000 constant enable-bit + +: load-lut ( -- ) + 100 0 do + i i i 0 bljoin h# a000 pipe 2/ + i la+ l! + loop +; + +: crtc-dpms-off ( -- ) \ CRTC prepare method + \ Disable display plane + dspcntr-reg pipe@ ( val ) + dup enable-bit and if ( val ) + enable-bit invert and dspcntr-reg pipe! + dspbase-reg pipe@ dspbase-reg pipe!! + else + drop + then + wait-vblank + + \ Disable display pipes + pipeconf-reg pipe@ ( val ) + dup enable-bit and if ( val ) + enable-bit invert and pipeconf-reg pipe!! + else + drop + then + wait-vblank + + dpll@ dup enable-bit and if + enable-bit invert and dpll! + else + drop + then +; + +: crtc-dpms-on ( -- ) \ CRTC commit method + dpll@ dup enable-bit and 0= if ( value ) + dup dpll! ( value ) + enable-bit or dup dpll! dpll! ( ) + else ( value ) + drop ( ) + then + + pipeconf-reg pipe@ dup enable-bit and 0= if + enable-bit or pipeconf-reg pipe! + else + drop + then + + dspcntr-reg pipe@ dup enable-bit and if + enable-bit or dspcntr-reg pipe! + dspbase-reg pipe@ dspbase-reg pipe! + else + drop + then + + load-lut +; + +: lvds-set-mode ( -- ) + \ When using LVDS, you have to do this little dance to turn on the PLL + + fp-val fpreg! + dpll-val enable-bit invert and dpll! \ VCO_ENABLE off for now + + lvds-reg mmio@ \ LVDS configuration + h# c000.0300 or \ LVDS_PORT_EN , LVDS_PIPEB_SELECT , LVDS_A0A2_CLKA_POWER_UP + h# 0000.003c invert and \ ! LVDS_CLKB_POWER_UP , ! LVDS_B0B3_POWER_UP + lvds-reg mmio!! + + fp-val fpreg! + dpll-val dpll! \ VCO_ENABLE on + + \ Double write because Linux driver does it because BIOS does it + dpll-val dpll! \ VCO_ENABLE on + + \ Now that the dance is over we can configure the geometry + + hdisplay htotal h# 60000 crtconf! \ H Display + hdisplay htotal h# 60004 crtconf! \ H Blanking + hsstart hsend h# 60008 crtconf! \ H Sync + vdisplay vtotal h# 6000c crtconf! \ V Display + vdisplay vtotal h# 60010 crtconf! \ V Blanking + vsstart vsend h# 60014 crtconf! \ V Sync + + bytes/line h# 70188 pipe! \ Pitch (stride) + hdisplay vdisplay h# 70190 crtconf! \ Size + 0 h# 7018c pipe! \ Position + vdisplay hdisplay h# 6001c crtconf! \ Pipe source + enable-bit pipeconf-reg pipe!! \ Pipe config + + wait-vblank + + dspcntr-val dspcntr-reg pipe! \ Display control + + 0 dspbase-reg pipe! \ PIPExBASE + + enable-bit h# 71400 mmio! \ Disable VGA plane + + wait-vblank +; + +false value backlight-inverse? +: set-backlight ( percentage -- ) + h# 61254 mmio@ lwsplit nip ( percent max ) + 1 invert and >r ( percent r: max' ) + d# 20 max ( percentage' r: max ) + r@ * d# 100 / ( duty-cycle r: max ) + backlight-inverse? if ( duty-cycle r: max ) + r@ swap - ( duty-cycle' ) + then ( duty-cycle r: max ) + 1 invert and ( duty-cycle r: max ) \ Low bit must be 0 + r> wljoin h# 61254 mmio! ( ) \ BLC_PWM_CTL +; + +d# 100 value backlight-val + +h# 61200 constant pp-status +h# 61204 constant pp-control +: lvds-on ( -- ) + pp-control mmio@ 1 or pp-control mmio! \ POWER_TARGET_ON + begin pp-status mmio@ enable-bit and until + backlight-val set-backlight +; +: lvds-off ( -- ) + 0 set-backlight + pp-control mmio@ 1 invert and pp-control mmio! + begin pp-status mmio@ enable-bit and 0= until +; + +: .ps pp-status mmio@ . ; +: pctl pp-control mmio! ; + +: lvds-scaling ( -- ) + 0 pfit-reg mmio! +\ pipe h# 1000 / d# 29 lshift pfit-reg mmio! +; +: setmode ( -- ) + memory-setup + lvds-off \ Output prepare method + crtc-dpms-off \ CRTC prepare method + lvds-set-mode \ CRTC mode_set method + lvds-scaling \ Output mode_set method + crtc-dpms-on \ CRTC commit method + lvds-on \ Output commit method +; + +: erase-frame-buffer ( -- ) + frame-buffer-adr /fb ( adr len ) + depth case + 8 of h# 0f fill endof + d# 16 of h# ffff " wfill" evaluate endof + d# 32 of h# ffff.ffff " lfill" evaluate endof + ( default ) nip nip + endcase + h# f to background-color +; +: map-frame-buffer ( -- ) +[ifdef] virtual-mode +.( XXX need to map frame buffer adr) cr +[then] + stolen-base to frame-buffer-adr +; + +: declare-props ( -- ) \ Instantiate screen properties + " width" get-my-property if + d# 800 encode-int " width" property + d# 600 encode-int " height" property + depth encode-int " depth" property + bytes/line encode-int " linebytes" property + else + 2drop + then +; + +defer gp-install ' noop to gp-install + +: set-terminal ( -- ) + d# 800 d# 600 ( width height ) + over char-width / over char-height / ( width height rows cols ) + bytes/line depth " fb-install" evaluate gp-install ( ) +; + + +0 value open-count + +: display-remove ( -- ) + open-count 1 = if + then + open-count 1- 0 max to open-count +; + +: display-install ( -- ) + open-count 0= if + setmode + declare-props \ Setup properites + map-frame-buffer + erase-frame-buffer + else + map-frame-buffer + then + default-font set-font + set-terminal + open-count 1+ to open-count +; + +: display-selftest ( -- failed? ) false ; + +' display-install is-install +' display-remove is-remove +' display-selftest is-selftest + +" display" device-type +" ISO8859-1" encode-string " character-set" property +0 0 encode-bytes " iso6429-1983-colors" property