tizen 2.3.1 release
[platform/kernel/u-boot.git] / arch / arm / cpu / arm1176 / s5p64xx / usb_downloader.c
1 /*
2  * Copyright (C) 2009 Samsung Electronics
3  * Minkyu Kang <mk7.kang@samsung.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA
19  *
20  */
21
22 #include <common.h>
23 #include "usbd.h"
24 #include "usb-hs-otg.h"
25 #ifdef CONFIG_S5PC1XXFB
26 #include <fbutils.h>
27 #endif
28
29 static char tx_data[8] = "MPL";
30 static long tx_len = 4;
31
32 static char rx_data[2048];
33 static long rx_len = 64;
34
35 extern int s5p_receive_done;
36 extern int s5p_usb_connected;
37 extern otg_dev_t otg;
38
39 static int __usb_board_init(void)
40 {
41         return 0;
42 }
43
44 int usb_board_init(void) __attribute__((weak, alias("__usb_board_init")));
45
46 /* clear download informations */
47 static void s5p_usb_clear_dnfile_info(void)
48 {
49         otg.dn_addr = 0;
50         otg.dn_filesize = 0;
51         otg.dn_ptr = 0;
52 }
53
54 /* clear upload informations */
55 static void s5p_usb_clear_upfile_info(void)
56 {
57         otg.up_addr = 0;
58         otg.up_size = 0;
59         otg.up_ptr = 0;
60 }
61
62 /* start the usb controller */
63 static void usb_init(void)
64 {
65         if (usb_board_init()) {
66                 printf("Failed to usb_board_init\n");
67                 return;
68         }
69
70 #ifdef CONFIG_S5PC1XXFB
71         init_font();
72         set_font_color(FONT_WHITE);
73         fb_printf("Ready to USB Connection\n");
74 #endif
75
76         s5p_usbctl_init();
77         s5p_usbc_activate();
78
79         printf("USB Start!! - %s Speed\n",
80                         otg.speed ? "Full" : "High");
81
82         while (!s5p_usb_connected) {
83                 if (s5p_usb_detect_irq()) {
84                         s5p_udc_int_hndlr();
85                         s5p_usb_clear_irq();
86                 }
87         }
88
89         s5p_usb_clear_dnfile_info();
90
91         printf("Connected!!\n");
92
93 #ifdef CONFIG_S5PC1XXFB
94         fb_printf("Download Start\n");
95         draw_progress(40, 0, FONT_WHITE);
96 #endif
97 }
98
99 static void usb_stop(void)
100 {
101         s5p_usb_stop();
102 #ifdef CONFIG_S5PC1XXFB
103         exit_font();
104
105         /* it uses fb3 as default window. */
106         s5pc_fimd_lcd_off(3);
107         s5pc_fimd_window_off(3);
108 #endif
109 }
110
111 /*
112  * receive the packet from host PC
113  * return received size
114  */
115 static int usb_receive_packet(void)
116 {
117         while (1) {
118                 if (s5p_usb_detect_irq()) {
119                         s5p_udc_int_hndlr();
120                         s5p_usb_clear_irq();
121                 }
122
123                 if (s5p_receive_done) {
124                         s5p_receive_done = 0;
125                         return otg.dn_filesize;
126                 }
127         }
128 }
129
130 /* setup the download informations */
131 static void recv_setup(char *addr, int len)
132 {
133         s5p_usb_clear_dnfile_info();
134
135         otg.dn_addr = (u32)addr;
136         otg.dn_ptr = (u8 *) addr;
137         otg.dn_filesize = len;
138 }
139
140 #ifdef CONFIG_GENERIC_MMC
141 #include <mmc.h>
142
143 static void usbd_set_mmc_dev(struct usbd_ops *usbd)
144 {
145         struct mmc *mmc;
146
147         usbd->mmc_dev = 0;
148         /* FIX 0x400 */
149         usbd->mmc_max = 0x400;
150         /* get from mmc->capacity?? */
151         usbd->mmc_total = 0xf50000;     /* 8GB / 0x200  */
152
153         mmc = find_mmc_device(usbd->mmc_dev);
154         mmc_init(mmc);
155
156         usbd->mmc_blk = mmc->read_bl_len;
157 }
158 #endif
159
160 #ifdef CONFIG_S5PC1XXFB
161 static void set_progress(int progress)
162 {
163         draw_progress(40, progress, FONT_WHITE);
164 }
165 #endif
166 /*
167  * This function is interfaced between
168  * USB Device Controller and USB Downloader
169  */
170 struct usbd_ops *usbd_set_interface(struct usbd_ops *usbd)
171 {
172         usbd->usb_init = usb_init;
173         usbd->usb_stop = usb_stop;
174         usbd->send_data = s5p_usb_tx;
175         usbd->recv_data = usb_receive_packet;
176         usbd->recv_setup = recv_setup;
177         usbd->tx_data = tx_data;
178         usbd->rx_data = rx_data;
179         usbd->tx_len = tx_len;
180         usbd->rx_len = rx_len;
181         usbd->ram_addr = CONFIG_SYS_DOWN_ADDR;
182 #ifdef CONFIG_S5PC1XXFB
183         usbd->set_progress = set_progress;
184 #endif
185 #ifdef CONFIG_GENERIC_MMC
186         usbd_set_mmc_dev(usbd);
187 #endif
188
189         return usbd;
190 }