2 * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
18 #include <linux/uaccess.h>
20 #include <linux/sched.h>
21 #include <linux/slab.h>
23 #include <linux/mmc/core.h>
24 #include <linux/mmc/card.h>
25 #include <linux/mmc/sdio_func.h>
29 #define TYPE_A_HEADER_SIZE 4
30 #define TYPE_A_LOOKAHEAD_SIZE 16
31 #define YMEM0_SIZE 0x8000 /* 32kbytes */
32 #define DOWNLOAD_SIZE (YMEM0_SIZE - TYPE_A_HEADER_SIZE)
34 #define KRN_PATH "/lib/firmware/gdm72xx/gdmskrn.bin"
35 #define RFS_PATH "/lib/firmware/gdm72xx/gdmsrfs.bin"
39 static int ack_ready(struct sdio_func
*func
)
41 unsigned long start
= jiffies
;
45 while ((jiffies
- start
) < HZ
) {
46 val
= sdio_readb(func
, 0x13, &ret
);
55 static int download_image(struct sdio_func
*func
, char *img_name
)
57 int ret
= 0, len
, size
, pno
;
58 struct file
*filp
= NULL
;
59 struct inode
*inode
= NULL
;
63 filp
= filp_open(img_name
, O_RDONLY
| O_LARGEFILE
, 0);
65 printk(KERN_ERR
"Can't find %s.\n", img_name
);
69 inode
= filp
->f_dentry
->d_inode
;
70 if (!S_ISREG(inode
->i_mode
)) {
71 printk(KERN_ERR
"Invalid file type: %s\n", img_name
);
76 size
= i_size_read(inode
->i_mapping
->host
);
78 printk(KERN_ERR
"Unable to find file size: %s\n", img_name
);
84 while ((len
= filp
->f_op
->read(filp
, buf
+ TYPE_A_HEADER_SIZE
,
85 DOWNLOAD_SIZE
, &pos
))) {
92 buf
[1] = (len
>> 8) & 0xff;
93 buf
[2] = (len
>> 16) & 0xff;
95 if (pos
>= size
) /* The last packet */
100 ret
= sdio_memcpy_toio(func
, 0, buf
, len
+ TYPE_A_HEADER_SIZE
);
102 printk(KERN_ERR
"gdmwm: send image error: "
103 "packet number = %d ret = %d\n", pno
, ret
);
106 if (buf
[3] == 2) /* The last packet */
108 if (!ack_ready(func
)) {
110 printk(KERN_ERR
"gdmwm: Ack is not ready.\n");
113 ret
= sdio_memcpy_fromio(func
, buf
, 0, TYPE_A_LOOKAHEAD_SIZE
);
115 printk(KERN_ERR
"gdmwm: receive ack error: "
116 "packet number = %d ret = %d\n", pno
, ret
);
119 sdio_writeb(func
, 0x01, 0x13, &ret
);
120 sdio_writeb(func
, 0x00, 0x10, &ret
); /* PCRRT */
125 filp_close(filp
, NULL
);
129 int sdio_boot(struct sdio_func
*func
)
131 static mm_segment_t fs
;
134 tx_buf
= kmalloc(YMEM0_SIZE
, GFP_KERNEL
);
135 if (tx_buf
== NULL
) {
136 printk(KERN_ERR
"Error: kmalloc: %s %d\n", __func__
, __LINE__
);
143 ret
= download_image(func
, KRN_PATH
);
146 printk(KERN_INFO
"GCT: Kernel download success.\n");
148 ret
= download_image(func
, RFS_PATH
);
151 printk(KERN_INFO
"GCT: Filesystem download success.\n");
This page took 0.039611 seconds and 5 git commands to generate.