75b8adca15ac1de7213135db17a76bc6b42f3776
[platform/kernel/u-boot.git] / board / bf533-stamp / video.c
1 /*
2  * BF533-STAMP splash driver
3  *
4  * Copyright (c) 2006-2008 Analog Devices Inc.
5  * (C) Copyright 2000
6  * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
7  * (C) Copyright 2002
8  * Wolfgang Denk, wd@denx.de
9  *
10  * Licensed under the GPL-2 or later.
11  */
12
13 #include <stdarg.h>
14 #include <common.h>
15 #include <config.h>
16 #include <malloc.h>
17 #include <asm/blackfin.h>
18 #include <asm/mach-common/bits/dma.h>
19 #include <i2c.h>
20 #include <linux/types.h>
21 #include <stdio_dev.h>
22
23 #define DMA_SIZE16      2
24
25 #include <asm/mach-common/bits/ppi.h>
26
27 #define NTSC_FRAME_ADDR 0x06000000
28 #include "video.h"
29
30 /* NTSC OUTPUT SIZE  720 * 240 */
31 #define VERTICAL        2
32 #define HORIZONTAL      4
33
34 int is_vblank_line(const int line)
35 {
36         /*
37          *  This array contains a single bit for each line in
38          *  an NTSC frame.
39          */
40         if ((line <= 18) || (line >= 264 && line <= 281) || (line == 528))
41                 return true;
42
43         return false;
44 }
45
46 int NTSC_framebuffer_init(char *base_address)
47 {
48         const int NTSC_frames = 1;
49         const int NTSC_lines = 525;
50         char *dest = base_address;
51         int frame_num, line_num;
52
53         for (frame_num = 0; frame_num < NTSC_frames; ++frame_num) {
54                 for (line_num = 1; line_num <= NTSC_lines; ++line_num) {
55                         unsigned int code;
56                         int offset = 0;
57                         int i;
58
59                         if (is_vblank_line(line_num))
60                                 offset++;
61
62                         if (line_num > 266 || line_num < 3)
63                                 offset += 2;
64
65                         /* Output EAV code */
66                         code = system_code_map[offset].eav;
67                         write_dest_byte((char)(code >> 24) & 0xff);
68                         write_dest_byte((char)(code >> 16) & 0xff);
69                         write_dest_byte((char)(code >> 8) & 0xff);
70                         write_dest_byte((char)(code) & 0xff);
71
72                         /* Output horizontal blanking */
73                         for (i = 0; i < 67 * 2; ++i) {
74                                 write_dest_byte(0x80);
75                                 write_dest_byte(0x10);
76                         }
77
78                         /* Output SAV */
79                         code = system_code_map[offset].sav;
80                         write_dest_byte((char)(code >> 24) & 0xff);
81                         write_dest_byte((char)(code >> 16) & 0xff);
82                         write_dest_byte((char)(code >> 8) & 0xff);
83                         write_dest_byte((char)(code) & 0xff);
84
85                         /* Output empty horizontal data */
86                         for (i = 0; i < 360 * 2; ++i) {
87                                 write_dest_byte(0x80);
88                                 write_dest_byte(0x10);
89                         }
90                 }
91         }
92
93         return dest - base_address;
94 }
95
96 void fill_frame(char *Frame, int Value)
97 {
98         int *OddPtr32;
99         int OddLine;
100         int *EvenPtr32;
101         int EvenLine;
102         int i;
103         int *data;
104         int m, n;
105
106         /* fill odd and even frames */
107         for (OddLine = 22, EvenLine = 285; OddLine < 263; OddLine++, EvenLine++) {
108                 OddPtr32 = (int *)((Frame + (OddLine * 1716)) + 276);
109                 EvenPtr32 = (int *)((Frame + (EvenLine * 1716)) + 276);
110                 for (i = 0; i < 360; i++, OddPtr32++, EvenPtr32++) {
111                         *OddPtr32 = Value;
112                         *EvenPtr32 = Value;
113                 }
114         }
115
116         for (m = 0; m < VERTICAL; m++) {
117                 data = (int *)u_boot_logo.data;
118                 for (OddLine = (22 + m), EvenLine = (285 + m);
119                      OddLine < (u_boot_logo.height * VERTICAL) + (22 + m);
120                      OddLine += VERTICAL, EvenLine += VERTICAL) {
121                         OddPtr32 = (int *)((Frame + ((OddLine) * 1716)) + 276);
122                         EvenPtr32 =
123                             (int *)((Frame + ((EvenLine) * 1716)) + 276);
124                         for (i = 0; i < u_boot_logo.width / 2; i++) {
125                                 /* enlarge one pixel to m x n */
126                                 for (n = 0; n < HORIZONTAL; n++) {
127                                         *OddPtr32++ = *data;
128                                         *EvenPtr32++ = *data;
129                                 }
130                                 data++;
131                         }
132                 }
133         }
134 }
135
136 static void video_init(char *NTSCFrame)
137 {
138         NTSC_framebuffer_init(NTSCFrame);
139         fill_frame(NTSCFrame, BLUE);
140
141         bfin_write_PPI_CONTROL(0x0082);
142         bfin_write_PPI_FRAME(0x020D);
143
144         bfin_write_DMA0_START_ADDR(NTSCFrame);
145         bfin_write_DMA0_X_COUNT(0x035A);
146         bfin_write_DMA0_X_MODIFY(0x0002);
147         bfin_write_DMA0_Y_COUNT(0x020D);
148         bfin_write_DMA0_Y_MODIFY(0x0002);
149         bfin_write_DMA0_CONFIG(0x1015);
150         bfin_write_PPI_CONTROL(0x0083);
151 }
152
153 void video_stop(void)
154 {
155         bfin_write_PPI_CONTROL(0);
156         bfin_write_DMA0_CONFIG(0);
157 }
158
159 int drv_video_init(void)
160 {
161         struct stdio_dev videodev;
162
163         video_init((void *)NTSC_FRAME_ADDR);
164
165         memset(&videodev, 0, sizeof(videodev));
166         strcpy(videodev.name, "video");
167         videodev.ext = DEV_EXT_VIDEO;
168         videodev.flags = DEV_FLAGS_SYSTEM;
169
170         return stdio_register(&videodev);
171 }