source: cpu/arm/mmp3/hdmi.fth

Last change on this file was 3492, checked in by wmb, 5 months ago

OLPC XO-4 - Added model property to hdmi device node.

File size: 15.5 KB
Line 
1\ See license at end of file
2purpose: MMP3 HDMI driver
3
4   new-device
5      " hdmi" device-name
6
7      " mrvl,pxa688-hdmi" +compatible
8      0 0 encode-bytes
9         hdmi-hp-det-gpio# 0 encode-gpio
10      " gpios" property
11      " /hdmi-i2c" encode-phandle " ddc-i2c-bus" property
12
13      " HDMI" model
14
15      : +i  encode-int encode+  ;
16      h# 60010005 " clock-divider-regval" integer-property
17      decimal
18      0 0 encode-bytes
19      \ xres,  yres, refresh,       clockhz,  left, right,  top, bottom, hsync, vsync, flags, widthmm, heightmm
20      1280 +i 720 +i    60 +i  74,250,000 +i  110 +i  220 +i  5 +i    20 +i  40 +i    5 +i   1 +i   0 +i   0 +i
21      hex
22      " linux,timing-modes" property
23      " 1280x720@60"  " linux,mode-names" string-property
24   finish-device
25
26: hdmi-present?  ( -- flag )   hdmi-hp-det-gpio# gpio-pin@ 0=  ;
27
28: +hdmi  h# 20bc00 +  ;
29: hdmi!  +hdmi io!  ;
30: hdmi@  +hdmi io@  ;
31
32: hdmi-i!  ( b reg# -- )  swap  0 hdmi!  h# 8000.0000 or 4 hdmi!  ;
33: hdmi-i@  ( reg# -- b )  h# 4000.0000 or 4 hdmi!  0 hdmi@  ;
34
35: phy-cfg0@  ( -- n )  h# 08 hdmi@  ;  : phy-cfg0!  ( n -- )  h# 08 hdmi!  ;
36: phy-cfg1@  ( -- n )  h# 0c hdmi@  ;  : phy-cfg1!  ( n -- )  h# 0c hdmi!  ;
37: phy-cfg2@  ( -- n )  h# 10 hdmi@  ;  : phy-cfg2!  ( n -- )  h# 10 hdmi!  ;
38: phy-cfg3@  ( -- n )  h# 14 hdmi@  ;  : phy-cfg3!  ( n -- )  h# 14 hdmi!  ;
39
40: audio-cfg@ ( -- n )  h# 18 hdmi@  ;  : audio-cfg! ( n -- )  h# 18 hdmi!  ;
41: clock-cfg@ ( -- n )  h# 1c hdmi@  ;  : clock-cfg! ( n -- )  h# 1c hdmi!  ;
42
43: pll-cfg0@  ( -- n )  h# 20 hdmi@  ;  : pll-cfg0!  ( n -- )  h# 20 hdmi!  ;
44: pll-cfg1@  ( -- n )  h# 24 hdmi@  ;  : pll-cfg1!  ( n -- )  h# 24 hdmi!  ;
45: pll-cfg2@  ( -- n )  h# 28 hdmi@  ;  : pll-cfg2!  ( n -- )  h# 28 hdmi!  ;
46: pll-cfg3@  ( -- n )  h# 2c hdmi@  ;  : pll-cfg3!  ( n -- )  h# 2c hdmi!  ;
47
48: -bits  ( n value bit# -- n' )  lshift invert and  ;
49: +bits  ( n value bit# -- n' )  lshift or  ;
50
51[ifdef] debug-words
52h# f090099 value pll3-ctrl1
53h#      9b value pll3-fbdiv
54h#       3 value pll3-refdiv
55: pll3-on
56   h# 20000000  h# 58 mpmu-clr      \ Reset PLL3 reset
57   h#      100  h# 50 mpmu-clr      \ Ensure PLL3 off
58   1 h# 60 mpmu-set                \ set SEL_VCO_CLK_SE in PMUM_PLL3_CTRL2
59   0  pll3-refdiv  d# 19 +bits  pll3-fbdiv d# 10 +bits  1 d# 9 +bits  h# 50 mpmu!
60   pll3-ctrl1   h# 58 mpmu!
61   h#      100  h# 50 mpmu-set      \ Power up PLL3
62   d# 50 us
63   h# 20000000  h# 58 mpmu-set      \ Release PLL3 reset
64;
65
66create pll-table-mmp2
67  decimal
68\  f   div     offset    fb   ref    kvco
69  25 ,   4 ,  h# 4ec5 ,  38 ,  16 ,  h# c ,
70  27 ,   4 ,  h# 35cb ,  41 ,  16 ,  h# b ,
71  54 ,   2 ,  h# 35cb ,  41 ,  16 ,  h# b ,
72  74 ,   2 ,  h#  84b ,  57 ,  16 ,  h# 3 ,
73 108 ,   1 ,  h# 35cb ,  41 ,  16 ,  h# b ,
74 148 ,   1 ,  h#  84b ,  57 ,  16 ,  h# 3 ,
75  -1 ,
76hex
77[then]
78
79create pll-table
80  decimal
81\  0     1           2     3    4       5
82\  f  post      offset    fb  ref    kvco
83  25 ,   3 ,  h# 11c47 ,  39 ,  0 ,  h# 4 ,
84  27 ,   3 ,  h# 12d03 ,  42 ,  0 ,  h# 4 ,
85  54 ,   2 ,  h# 12d02 ,  42 ,  0 ,  h# 4 ,
86  74 ,   2 ,  h# 0084b ,  57 ,  0 ,  h# 4 ,
87 108 ,   1 ,  h# 12d03 ,  42 ,  0 ,  h# 4 ,
88 148 ,   1 ,  h# 0084b ,  57 ,  0 ,  h# 4 ,
89  -1 ,
90hex
91
92: find-pll  ( freq -- adr )
93   pll-table  begin  dup @  -1 <>  while  ( freq adr )
94      2dup @ =  if  nip exit  then        ( freq adr )
95      6 na+                               ( freq adr' )
96   repeat                                 ( freq adr )
97   -6 na+
98;
99
1001 value vpll-calclk-div
1011 value vddm
1029 value vddl
1039 value icp
1042 value vreg-ivref
1050 value reset-offset
1061 value clk-det-en
1075 value intpi
1080 value reset-intp-ext
1091 value pll-mode
1102 value vth-vpll-ca
111
112: pll-cfg  ( freq -- )
113   find-pll  >r     ( table-adr )
114
115   pll-cfg3@  3 invert and  pll-cfg3!  \ Power off and reset
116
117   0
118   intpi           d# 27 +bits
119   clk-det-en      d# 26 +bits
120   r@ 5 na+ @      d# 20 +bits   \ KVCO
121   vreg-ivref      d# 17 +bits
122   r@ 1 na+ @      d# 14 +bits   \ POSTDIV
123   icp             d# 10 +bits
124   vddl            d#  6 +bits
125   vddm            d#  4 +bits
126   vpll-calclk-div d#  1 +bits
127   1               d#  0 +bits   \ "Chicken bit" to enable PHY register access
128   pll-cfg0!
129
130   0
131   vth-vpll-ca   d# 29 +bits
132   1             d# 24 +bits   \ EN_PANEL
133   1             d# 23 +bits   \ EN_HDMI
134   r@ 2 na+ @    d#  4 +bits   \ FREQ_OFFSET_INNER
135   pll-mode      d#  3 +bits   \ MODE
136   pll-cfg1!
137
138   0                           \ FREQ_OFFSET_ADJ
139   pll-cfg2!
140
141   pll-cfg3@
142   h# fffc invert and          \ Clear FBDIV and REFDIV fields
143   r@ 3 na+ @    d#  7 +bits
144   r@ 4 na+ @    d#  2 +bits
145   dup       pll-cfg3!         \ Set divisors
146   1 or  dup pll-cfg3!  1 ms   \ Power up
147   2 or      pll-cfg3!         \ Release reset
148
149   d# 100 0  do
150      pll-cfg3@ h# 400000 and  ?leave
151      1 ms
152      i 9 =  if  ." HDMI PLL failed to lock"  cr  then
153   loop
154
155   r> drop
156;
157
158: send-packet  ( adr len packet# -- )
159   >r                               ( adr len  r: packet# )
160   r@ d# 32 * h# 60 +               ( adr len index )
161
162   \ Clear trailing bytes
163   over  d# 31 swap  ?do            ( adr len index )
164      0 i hdmi-i!                   ( adr len index )
165   loop
166
167   0 swap  2swap                    ( sum  index adr  len )
168   0  ?do                           ( sum  index adr  )
169      2dup i + c@                   ( sum  index adr  index byte )
170      tuck swap c!                  ( sum  index adr  byte )
171      3 roll +  -rot                ( sum' index adr  )
172   loop                             ( sum  index adr  )
173   drop                             ( sum  index )
174   swap negate h# ff and            ( index  sum' )
175   over 3 + hdmi-i!                 ( index )
176
177   \ I'm not sure what this is for; one of the drivers did it
178   1 over d# 31 + hdmi-i!           ( index )
179   drop                             ( )
180
181   1 r> lshift  dup h# 5f hdmi-i!  h# 5e hdmi-i!  \ HDTX_HOST_PKT_CTRL1/0
182;
183
184create avi-packet
185   h# 82 c,  h#  2 c,  h# 0d c,  0 c,  \ 0-3: header
186   h# 10 c,  \ 4: 10 is active format, validates bits 3:0 of next byte
187   h# a8 c,  \ 5: 80 is ITU709 colors, 20 is 16:9, 8 is same aspect ratio
188   h# 00 c,  \ 6: 80 bit means computer display ...
189   h# 00 c,  \ 7: panel type
190       0 c,  \ 8: pixel repetition factor
191   \ The rest would be top, bottom, left, right bars
192here avi-packet - constant /avi-packet
193
194\ The columns up to "Code" are from CEA-861-D (the DVI spec)
195\ The remaining columns (sync parameters) are from Marvell bringup code - lcd0_tv.c
196
197create hdmi-resolutions
198decimal
199\    0      1    2      3     4      5     6     7    8     9    10    11   12   13   14
200\  Hact   Vact Refr   Htot Hblnk Vtotal Vblnk PxMHz Code Hsync  Hfp   Hbp Vsync Vfp  Vbp
201   640 ,  480 , 60 ,  800 , 160 ,  525 ,  45 ,  25 ,  1 ,  96 ,  48 ,  16 ,  2 , 33 , 10 ,
202   720 ,  480 , 60 ,  858 , 138 ,  525 ,  45 ,  27 ,  3 ,  62 ,  60 ,  16 ,  6 , 30 ,  9 ,
203  1280 ,  720 , 60 , 1650 , 370 ,  750 ,  30 ,  74 ,  4 ,  40 , 220 , 110 ,  5 , 20 ,  5 ,
204  1440 ,  240 , 60 , 1716 , 276 ,  262 ,  22 ,  27 ,  9 , 124 , 114 ,  38 ,  3 , 15 ,  4 ,
205\ 2880 ,  240 , 60 , 3432 , 552 ,  262 ,  22 ,  54 , 13 , ???  \ Sync values unknown ...
206\ 1440 ,  480 , 60 , 1716 , 276 ,  525 ,  45 ,  54 , 15 , ???
207  1920 , 1080 , 60 , 2200 , 280 , 1125 ,  45 , 148 , 16 ,  44 , 148 ,  88 ,  5 , 36  , 4 ,
208   720 ,  576 , 50 ,  864 , 144 ,  625 ,  49 ,  27 , 18 ,  64 ,  68 ,  12 ,  5 , 39  , 5 ,
209  1440 ,  288 , 50 , 1728 , 288 ,  312 ,  24 ,  27 , 24 , 126 , 138 ,  24 ,  3 , 18  , 3 ,
210\ 2880 ,  288 , 50 , 3456 , 576 ,  312 ,  24 ,  54 , 28 , ???
211\ 2880 ,  480 , 60 , 3432 , 552 ,  525 ,  45 , 108 , 36 , ???
212\ 2880 ,  576 , 50 , 3456 , 576 ,  625 ,  49 , 108 , 38 , ???
213-1 ,
214hex
215
2160 value res-adr
217: res@  ( index -- value ) res-adr swap na+ @  ;
218
219: find-resolution  ( h v -- error? )
220   hdmi-resolutions  begin      ( h v adr )
221      dup @ -1 <>               ( h v adr flag )
222   while                        ( h v adr )
223      3dup 2@ swap  d=  if      ( h v adr )
224         to res-adr  2drop      ( )
225         false exit             ( -- adr false )
226      then                      ( h v adr )
227      d# 15 na+                 ( h v adr' )
228   repeat                       ( h v adr )
229   3drop true
230;
231
232: set-hdmi-clock-cfg  ( -- )
233\  3         \ The docs say to write 0 to bits 0:3 but the code writes 3
234             \ On MMP2 this is the the FIFO read and write timing
235   0
236   1     4 +bits \ HDMI_ENABLE
237   6     5 +bits \ MCLK_DIV
238   5     9 +bits \ TCLK_DIV
239   5 d# 13 +bits \ PRCLK_DIV
240   clock-cfg!
241;
242: hdmi-set-detection  ( on/off -- )
243   h# 14 hdmi@  h# 400                  ( on/off value bitmask )
244   rot  if  or  else  invert and  then  ( value' )
245   h# 14 hdmi!
246;
247
248: select-phy  ( -- )  pll-cfg0@ 1 or pll-cfg0!  ;   \ alias phy select-phy
249: select-3d   ( -- )  pll-cfg0@ 1 invert and pll-cfg0!  ;
250
251\ Tune these for best eye diagram
2526 value damp  2 value eamp  0 value cp
2530 value ajd   1 value svtx  8 value idrv 
254
255: setup-phy  ( freq -- )
256   d# 148 =  if  9  else  8  then  to idrv
257
258   select-phy
259
260   damp o# 1111 *
261   eamp o# 11110000 * or
262   cp h# 55000000 * or
263   phy-cfg0!
264
265   ajd  h# f0000000 *
266   svtx o# 1111 * d# 16 +bits
267   idrv h# 1111 *     0 +bits
268   phy-cfg1!
269;
270: setup-fifo  ( -- )
271   1     h#  3a hdmi-i!     \ HDMI, not DCI, Mode.  No pixel repetition
272   1     h#  48 hdmi-i!     \ DC_FIFO_WR_PTR  \ Alt value:  0
273   h# 1a h#  49 hdmi-i!     \ DC_FIFO_RD_PTR  \ Alt value: 1f
274
275   1     h#  47 hdmi-i!     \ DC_FIFO_SFT_RST
276   0     h#  47 hdmi-i!     \ DC_FIFO_SFT_RST
277
278   8     h# 131 hdmi-i!     \ PHY_FIFO_PTRS \ Alt value: 80
279
280   1     h# 130 hdmi-i!     \ PHY_FIFO_SOFT_RST
281   0     h# 130 hdmi-i!     \ PHY_FIFO_SOFT_RST
282
283   0     h#  39 hdmi-i!     \ VIDEO_CTRL
284   h# 40 h#  39 hdmi-i!     \ VIDEO_CTRL (set INT_FRM_SEL) \ Alt value: 58
285;
286
287: hdmi-video-cfg  ( -- )
288   true hdmi-set-detection
289
290   7 res@ pll-cfg
291
292   set-hdmi-clock-cfg
293
294   0 phy-cfg2!                \ Unreset TX
295   h# 0001.0000 phy-cfg2!     \ RESET_TX
296   h#        10 phy-cfg2!     \ Termination
297
298   8 res@ avi-packet 7 + c!
299   avi-packet /avi-packet  1  send-packet
300
301   h# e0  h# 58 hdmi-i!     \ HDTX_TDATA3_0
302   h# 83  h# 59 hdmi-i!     \ HDTX_TDATA3_1
303   h# 0f  h# 5a hdmi-i!     \ HDTX_TDATA3_2
304
305   7 res@ setup-phy
306   setup-fifo
307;
308
309: init-tv-clock  ( -- )
310   h# 4c pmua@ dup  h# 10 and  0=  if  ( val )
311\     h# f8fc0 invert and   \ Clear prescaler and divisor fields
312\     h# d0280 or           \ DSI PHY Prescaler to default value 1a, /2, PLL2
313\     dup h# 4c pmua!       ( val )
314\     h# 103f or            ( val' )
315\     dup h# 4c pmua!       ( val )
316   then                     ( val )
317   h# 2000 or  h# 4c pmua!  ( )     \ Enable HDMI ref clock
318
319   \ Integer divisor (5), reserved (1<<16), select HDMI CLK (3<<29)
320\  5  1 d# 16 +bits  3 d# 29 +bits  h# 9c lcd!  \ LCD_TCLK_DIV
321   5  3 d# 29 +bits  h# 9c lcd!  \ LCD_TCLK_DIV
322;
323
324: lcd-xy!  ( hor vert reg# -- )  >r  wljoin  r> lcd!  ;
325\ : tv-video-src-res!  ( hor vert -- )  wljoin h# 2c lcd!  ;
326\ : tv-video-dst-res!  ( hor vert -- )  wljoin h# 30 lcd!  ;
327: tv-gfx-base!  ( adr -- )  h# 34 lcd!  ;
328: tv-gfx-pitch!  ( pitch -- )  h# 3c lcd!  ;
329: tv-gfx-offset!  ( hor vert -- )  h# 40 lcd-xy!  ;
330: tv-gfx-src-res!  ( hor vert -- )  h# 44 lcd-xy!  ;
331: tv-gfx-dst-res!  ( hor vert -- )  h# 48 lcd-xy!  ;
332: tv-cursor-pos!  ( hor vert -- )  h# 4c lcd-xy!  ;
333: tv-cursor-size!  ( hor vert -- )  h# 50 lcd-xy!  ;
334: tv-size!  ( hor vert -- )  h# 54 lcd-xy!  ;
335: tv-active!  ( hor vert -- )  h# 58 lcd-xy!  ;
336: tv-porch!  ( hfront hback vfront vback -- )  h# 60 lcd-xy!  h# 5c lcd-xy!  ;
337: tv-blank-color!  ( color -- )  h# 64 lcd!  ;
338: tv-vsync!  ( rising falling -- )  h# 7c lcd-xy!  ;
339: tv-dma-ctrl0!  ( n -- )  h# 80 lcd!  ;  : tv-dma-ctrl0@  ( -- n )  h# 80 lcd@  ;
340: tv-dma-ctrl1!  ( n -- )  h# 84 lcd!  ;
341: tv-contrast!  ( contrast brightness -- )  h# 88 lcd-xy!  ;
342: tv-saturation!  ( saturation mult -- )  h# 8c lcd-xy!  ;
343: tv-hue!  ( cos sin -- )  h# 90 lcd-xy!  ;
344: tv-tvif!  ( n -- )  h# 94 lcd!  ;  : tv-tvif@  ( -- n )  h# 94 lcd@  ;
345: tv-divider!  ( n -- )  h# 9c lcd!  ;
346
347\ : dither!  ( n -- )  h# a0 lcd!  ;
348\ : dither-table!  ( n -- )  h# a4 lcd!  ;
349
350d# 16 value tv-bpp
351: init-tv-graphics  ( -- )
352   init-tv-clock
353
354   0 tv-dma-ctrl0!    \ Start with graphics DMA off
355
356   0 res@  1 res@  tv-active!
357   
358   tv-dma-ctrl0@ 
359   1    d#  8 +bits  \ DMA enable
360
361   h# f d# 16 -bits
362   0    d# 16 +bits  \ Pixel format RGB565
363
364   7    d#  9 -bits  \ Turn off YUV422PACK, YVYU422P, UYVY422P
365
366   1    d# 12 +bits  \ RGBswap (RGB, not BGR)
367               
368   1    d# 27 +bits  \ DMA AXI arbiter enable
369   tv-dma-ctrl0!
370
371\  tv-dma-ctrl1@  h# a00eff00 or tv-dma-ctrl1!  \ or h# 2000FF04;
372\  h# 283eff00 tv-dma-ctrl1!
373   h# 2803ff00 tv-dma-ctrl1!
374
375   h# f4 lcd@  tv-gfx-base!     \ Same base address as DCON panel
376   hdisp vdisp tv-gfx-src-res!  \ Same source res as DCON panel
377       
378   hdisp  bytes/pixel *  tv-gfx-pitch!
379       
380   0 res@  1 res@  tv-gfx-dst-res!
381
382   h# 00ff1000 tv-tvif!  \ XXX check this
383       
384   \  hbp        hres+hbp
385   d# 11 res@   dup 0 res@ +  tv-vsync!
386
387   \ htotal  vtotal     
388   3 res@    5 res@  tv-size!
389
390   \ hfp       hbp         vfp         vbp
391   d# 10 res@  d# 11 res@  d# 13 res@  d# 14 res@  tv-porch!
392
393\       /* deafult registers */
394\       BU_REG_WRITE( LCD_SRAM_CTRL, 0 );
395\       BU_REG_WRITE( LCD_SRAM_WRDAT, 0 );
396\       BU_REG_WRITE( LCD_SRAM_PARA0, 0 );
397\       BU_REG_WRITE( LCD_SRAM_PARA1, 0x0 );
398
399   h# 4000 0  tv-contrast!
400   h# 4000 h# 2000  tv-saturation!
401   h# 4000 0  tv-hue!
402
403   h# 1bc lcd@  h# 30 or  h# 1bc lcd!  \ PN_IOPAD_CONTROL - 1K boundary, burst 16
404
405   h# 1dc lcd@  h# fff0 or  h# 1dc lcd!  \ LCD_TOP_CTRL - burst lengths
406
407   tv-tvif@  1 or  tv-tvif!    \ Enable
408;
409
410: start-hdmi  ( h v -- )
411   \ XXX need to do monitor detection and use EDID to find its resolutions
412   find-resolution  abort" Unsupported resolution"  ( )
413   init-tv-graphics
414   hdmi-video-cfg
415;       
416
417: 720p  d# 1280 d# 720 start-hdmi  ;
418: 1080p  d# 1920 d# 1080 start-hdmi  ;
419
420also forth definitions
421: 1080p  ( -- )  " 1080p" $call-screen  ;
422: 720p  ( -- )  " 720p" $call-screen  ;
423previous definitions
424
425\ /* A:B means that g_res_support[B] = 1 if videoID == A */
426\ /* 1:3 2:0 3:0 4:1 8:4 9:4 12:7 13:7 14:8 15:8 16:2 17:2 18:2 */
427\ /* 21:10 22:10 23:6 24:6 27:9 28:9 35:11 36:11 37:12 38:12 */
428\ static enum edid_returns edid_parseSVD(unsigned char *data_buf,unsigned char svd_len)  // Short Video Descriptor
429\ {
430\     for (unsigned char   dataOfs = 0; ++dataOfs <= svd_len; )  { // Skip the header
431\       unsigned char videoID = (data_buf[dataOfs] & 0x7F);          // Parse SVD
432\       if (videoID == 0 || videoID >= sizeof(video_code_map)/sizeof(struct cea_res_info))  {  continue; }         /* Don't add it */
433\       switch (videoID){
434\               /* See comment above */
435\       }
436\     }
437\     return EDID_ERR_OK;
438\ }
439
440\ LICENSE_BEGIN
441\ Copyright (c) 2010 FirmWorks
442\
443\ Permission is hereby granted, free of charge, to any person obtaining
444\ a copy of this software and associated documentation files (the
445\ "Software"), to deal in the Software without restriction, including
446\ without limitation the rights to use, copy, modify, merge, publish,
447\ distribute, sublicense, and/or sell copies of the Software, and to
448\ permit persons to whom the Software is furnished to do so, subject to
449\ the following conditions:
450\
451\ The above copyright notice and this permission notice shall be
452\ included in all copies or substantial portions of the Software.
453\
454\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
455\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
456\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
457\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
458\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
459\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
460\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
461\
462\ LICENSE_END
Note: See TracBrowser for help on using the repository browser.