1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
; Copyright 2009 Castle Technology Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
GET Hdr:ListOpts
GET Hdr:Macros
GET Hdr:System
GET Hdr:Machine.<Machine>
GET Hdr:ImageSize.<ImageSize>
$GetIO
GET Hdr:Proc
GET Hdr:OSEntries
GET Hdr:HALEntries
GET hdr.omap3530
GET hdr.StaticWS
GET hdr.PRCM
GET hdr.GPIO
GET hdr.CoPro15ops
GET hdr.Timers
GET hdr.SPI
AREA |Asm$$Code|, CODE, READONLY, PIC
EXPORT Video_Init
EXPORT VideoDevice_Init
EXPORT Video_Power_VBC_DVI
EXPORT Video_Power_VBC_Pandora
EXPORT Video_Power_VBC_TouchBook
EXPORT Video_SetPandoraGamma
IMPORT memcpy
IMPORT GPIOx_SetAsOutput
IMPORT GPIOx_SetOutput
IMPORT HAL_CounterDelay
IMPORT TPSWrite
Video_Init
; Configure GPIO pins so we can turn the DVI framer on/off
LDRB a1, [sb, #BoardConfig_VideoGPIO]
CMP a1, #255
MOV a2, #0
BNE GPIOx_SetAsOutput ; Turn DVI framer off
MOV pc, lr
VideoDevice_Init
; Not much to do here - just register our HAL device
Push "v1,lr"
ADRL v1, VideoDevice
MOV a1, v1
ADR a2, VideoDeviceTemplate
MOV a3, #Video_DeviceSize
BL memcpy
LDR a1, L4_Display_Log
STR a1, [v1, #HALDevice_Address]
ADRL a3, VideoBoardConfig
STR a3, [v1, #HALDevice_VDUDeviceSpecificField]
STR sb, [v1, #:INDEX:VideoWorkspace]
; Fill in the board config
LDR a2, sys_clk
STR a2, [a3, #VideoBoardConfig_sys_clk]
BL Determine_PorchSync_Limits
STRH a1, [a3, #VideoBoardConfig_Max_Porch]
STRH a2, [a3, #VideoBoardConfig_Max_Sync]
LDR a2, L4_sDMA_Log
STR a2, [a3, #VideoBoardConfig_DMA_Ptr]
MOV a2, #SDMA_IRQ_1
STR a2, [a3, #VideoBoardConfig_DMA_Device]
ASSERT SDMA_NumDevices = 31
MOV a2, #&80000000
STR a2, [a3, #VideoBoardConfig_DMA_Chans]
LDRB a2, [sb, #BoardConfig_VBC_Flags]
STRB a2, [a3, #VideoBoardConfig_Flags]
LDRB a2, [sb, #BoardConfig_VBC_LCDNum]
STRB a2, [a3, #VideoBoardConfig_Num_LCDs]
MOV a2, #VideoBoardConfig_Size
STRH a2, [a3, #VideoBoardConfig_MySize]
LDR a2, [sb, #BoardConfig_VBC_LCDPtr]
STR a2, [a3, #VideoBoardConfig_LCD_Configs]
ADR a2, Video_TVDet_Func
STR a2, [a3, #VideoBoardConfig_TVDet_Func]
ADR a2, Video_TVPower_Func
STR a2, [a3, #VideoBoardConfig_TVPower_Func]
MOV a1, #0
MOV a2, v1
CallOS OS_AddDevice
[ {FALSE}
; Pandora hack - point GFX overlay at the start of physical memory so we can catch any early error messages
; This will treat the 8bpp display as 16bpp, so it'll be a bit squashed, but better than nothing
LDR a1, L4_Display_Log
MOV a2, #&80000000
STR a2, [a1, #&480]
STR a2, [a1, #&484]
LDR a2, =319+(479<<16)
STR a2, [a1, #&48c]
LDR a2, =&18329
STR a2, [a1, #&440]
]
Pull "v1,pc"
VideoDeviceTemplate
DCW HALDeviceType_Video + HALDeviceVideo_VDU
DCW HALDeviceID_VDU_OMAP3
DCD HALDeviceBus_Interconnect + HALDeviceInterconnectBus_L3
DCD 0 ; API version 0
DCD VideoDevice_Desc
DCD 0 ; Address - filled in later
% 12 ; Reserved
DCD VideoDevice_Activate
DCD VideoDevice_Deactivate
DCD VideoDevice_Reset
DCD VideoDevice_Sleep
DCD VIDEO_IRQ ; Device.
DCD 0 ; TestIRQ cannot be called
% 8
DCD 0 ; Pointer to board config stuff - filled in later
ASSERT (.-VideoDeviceTemplate) = HALDevice_VDU_Size
DCD 0 ; HAL workspace pointer - filled in later
ASSERT (.-VideoDeviceTemplate) = Video_DeviceSize
VideoDevice_Desc
= "OMAP3 video controller", 0
ALIGN
VideoDevice_Activate
Entry "sb"
LDR sb, VideoWorkspace
; Enable DSS power
; TODO - should disable interrupts for this bit!
LDR a1, L4_ClockMan_Log
LDR a2, [a1, #CM_ICLKEN_DSS]
ORR a2, a2, #1 ; EN_DSS (correct to enable iclk before fclk?)
STR a2, [a1, #CM_ICLKEN_DSS]
LDR a2, [a1, #CM_FCLKEN_DSS]
ORR a2, a2, #7 ; EN_DSS1, EN_DSS2, EN_TV (required for reset)
STR a2, [a1, #CM_FCLKEN_DSS]
MOV a1, #1
EXIT
VideoDevice_Deactivate ; TODO!
VideoDevice_Reset
MOV pc, lr
VideoDevice_Sleep
MOV a1, #0
MOV pc, lr
Video_Power_VBC_Pandora
Video_Power_VBC_DVI
; a1 = HAL device
; a2 = brightness 0-65536, which we treat as a simple on/off flag
Entry "sb"
LDR sb, VideoWorkspace
[ DebugTiming
CMP a2, #0
BEQ %FT10
DebugTime a1, "Video on @ "
10
]
; Just set the GPIO to the right value
LDRB a1, [sb, #BoardConfig_VideoGPIO]
CMP a1, #255
BLNE GPIOx_SetOutput
EXIT
Video_Power_VBC_TouchBook
; a1 = HAL device
; a2 = brightness 0-65536
Entry "sb"
LDR sb, VideoWorkspace
; TODO - Proper brightness controls
; For now, just toggle on/off, via the SCPWM bit of GPTIMER9.TCLR
LDR a3, Timers_Log
ADD a3, a3, #L4_GPTIMER9-TIMER_BASE
CMP a2, #0
LDR a4, [a3, #TCLR]
BICEQ a4, a4, #&80
ORRNE a4, a4, #&80
STR a4, [a3, #TCLR]
; Also toggle the GPIO that controls the DVI framer
LDRB a1, [sb, #BoardConfig_VideoGPIO]
CMP a1, #255
BLNE GPIOx_SetOutput
EXIT
Determine_PorchSync_Limits
; Returns:
; a1 = max porch value
; a2 = max sync value
; Get the OMAP revision so we can find out how large the timing registers are. OMAP35x errata shows that in ES 3.1+ the registers were increased from 8/6 bits to 12/8 bits.
LDR a2, L4_Wakeup_Log
ADD a2, a2, #(L4_CONTROL_IDCODE-L4_Wakeup) :AND: &FF00
LDR a2, [a2, #(L4_CONTROL_IDCODE-L4_Wakeup) :AND: &00FF]
; Check revision first
CMP a2, #REVISION_ES31 :SHL: 28
MOVHS a1, #1:SHL:12
MOVHS a2, #1:SHL:8
MOVHS pc, lr
; Revision check failed - check if this is OMAP35x
; If not, assume it's something newer which supports the larger timings
LDR a1, =HAWKEYE_OMAP35x_ES10
MOV a2, a2, LSL #4
CMP a1, a2, LSR #16
LDRNE a1, =HAWKEYE_OMAP35x
CMPNE a1, a2, LSR #16
MOVNE a1, #1:SHL:12
MOVNE a2, #1:SHL:8
MOVEQ a1, #1:SHL:8
MOVEQ a2, #1:SHL:6
MOV pc, lr
Video_TVDet_Func
Entry "sb"
LDR sb, VideoWorkspace
; The TV detect signal is internally hardwired to GPIO 33
GPIO_PrepareC a1, a2, 33
GPIO_GetInput a1, a1, a2
EXIT
Video_TVPower_Func
Entry "v1-v2,sb", 4
LDR sb, VideoWorkspace
LDR v1, OSentries+4*OS_IICOpV
MOVS ip, a2
MOV a3, #1
MOV a2, sp
BEQ %FT50
; Configure VDAC for 1.8V output
MOV a1, #&4b*2
MOV ip, #3
MOV a4, #&99 ; VDAC_DEDICATED
STR ip, [a2]
BL TPSWrite
; Enable it
MOV ip, #&20
50 ; Arrive here with ip=0 when disabling
MOV a1, #&4b*2
MOV a4, #&96 ; VDAC_DEV_GRP
STR ip, [a2]
BL TPSWrite
EXIT
Video_SetPandoraGamma ROUT
Entry "v1-v4"
ADR a1, PandoraGamma
; Reset McSPI1 and configure channel 1
LDR a2, L4_Core_Log
ADD a2, a2, #L4_McSPI1-L4_Core
MOV a3, #2
STR a3, [a2, #MCSPI_SYSCONFIG]
10
LDR a3, [a2, #MCSPI_SYSSTATUS]
TST a3, #1
BEQ %BT10
MOV a3, #1
STR a3, [a2, #MCSPI_MODULCTRL]
LDR v4, =(7<<2)+(1<<6)+(15<<7)+(2<<12)+(1<<16)
ADD a2, a2, #MCSPI_STRIDE
STR v4, [a2, #MCSPI_CHxCONF]
; Configure display
MOV a3, #2
MOV a4, #&f
BL td043_write
MOV a3, #3
MOV a4, #&df
BL td043_write
MOV a3, #&20
MOV a4, #&f0
BL td043_write
MOV a3, #&21
MOV a4, #&f0
BL td043_write
; Process gamma table
; Bits 9-8 of table entries
MOV v1, #2
20
MOV a4, #0
MOV v2, #3
30
ADD v3, v2, v1, LSL #2
ADD v3, a1, v3, LSL #1
ADD ip, v2, #1
LDRH v3, [v3]
MOV ip, ip, LSL #1
AND v3, v3, #&300
ORR a4, a4, v3, LSR ip
SUBS v2, v2, #1
BGE %BT30
ADD a3, v1, #&11
BL td043_write
SUBS v1, v1, #1
BGE %BT20
; bits 7-0
MOV v1, #0
40
LDRH a4, [a1], #2
ADD a3, v1, #&14
AND a4, a4, #255
BL td043_write
ADD v1, v1, #1
CMP v1, #12
BLT %BT40
; Done
EXIT
td043_write ROUT
Entry "a1-a2"
; In:
; a2 = SPI register block
; a3 = register
; a4 = data
; v4 = channel config
; Out:
; a3-a4 corrupt
; Construct 16 bit SPI data word
ORR a3, a4, a3, LSL #10
ORR a3, a3, #1<<8
; Set force flag
ORR a4, v4, #1<<20
STR a4, [a2, #MCSPI_CHxCONF]
; Enable channel
MOV a4, #1
STR a4, [a2, #MCSPI_CHxCTRL]
; Write data
STR a3, [a2, #MCSPI_TXx]
; Wait for transmission
10
LDR a4, [a2, #MCSPI_CHxSTAT]
AND a4, a4, #6
TEQ a4, #6
BNE %BT10
; Disable channel
MOV a4, #0
STR a4, [a2, #MCSPI_CHxCTRL]
; Clear force flag
STR v4, [a2, #MCSPI_CHxCONF]
; TD043 datasheet says a minimum 1ns period is needed between transfers
; Chances are that amount of time has already passed, but play it safe
; and wait for 1us
MOV a1, #1
BL HAL_CounterDelay
EXIT
; Default gamma table used by Linux
PandoraGamma
DCW 105
DCW 315
DCW 381
DCW 431
DCW 490
DCW 537
DCW 579
DCW 686
DCW 780
DCW 837
DCW 880
DCW 1023
END