blob: 93635a766f9cded6c93e8cc011e47e35e62da0c1 [file] [log] [blame]
Mike Frysingerc8f36dc2009-05-14 14:55:50 +00001/* Load firmware into Core B on a BF561
Bryan Wu1394f032007-05-06 14:50:22 -07002 *
Mike Frysingerc8f36dc2009-05-14 14:55:50 +00003 * Copyright 2004-2009 Analog Devices Inc.
4 * Licensed under the GPL-2 or later.
Bryan Wu1394f032007-05-06 14:50:22 -07005 */
6
Mike Frysingerc8f36dc2009-05-14 14:55:50 +00007/* The Core B reset func requires code in the application that is loaded into
8 * Core B. In order to reset, the application needs to install an interrupt
9 * handler for Supplemental Interrupt 0, that sets RETI to 0xff600000 and
10 * writes bit 11 of SICB_SYSCR when bit 5 of SICA_SYSCR is 0. This causes Core
11 * B to stall when Supplemental Interrupt 0 is set, and will reset PC to
12 * 0xff600000 when COREB_SRAM_INIT is cleared.
13 */
14
Bryan Wu1394f032007-05-06 14:50:22 -070015#include <linux/device.h>
Enrik Berkhan76a7f402007-12-24 19:51:31 +080016#include <linux/fs.h>
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000017#include <linux/kernel.h>
18#include <linux/miscdevice.h>
19#include <linux/module.h>
Bryan Wu1394f032007-05-06 14:50:22 -070020
Bryan Wu1394f032007-05-06 14:50:22 -070021#define CMD_COREB_START 2
22#define CMD_COREB_STOP 3
23#define CMD_COREB_RESET 4
24
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000025static int
26coreb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
Bryan Wu1394f032007-05-06 14:50:22 -070027{
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000028 int ret = 0;
Bryan Wu1394f032007-05-06 14:50:22 -070029
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000030 switch (cmd) {
31 case CMD_COREB_START:
32 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020);
Bryan Wu1394f032007-05-06 14:50:22 -070033 break;
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000034 case CMD_COREB_STOP:
35 bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020);
36 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
37 break;
38 case CMD_COREB_RESET:
39 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080);
40 break;
Bryan Wu1394f032007-05-06 14:50:22 -070041 default:
42 ret = -EINVAL;
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000043 break;
Bryan Wu1394f032007-05-06 14:50:22 -070044 }
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000045
46 CSYNC();
47
Bryan Wu1394f032007-05-06 14:50:22 -070048 return ret;
49}
50
Bryan Wu1394f032007-05-06 14:50:22 -070051static struct file_operations coreb_fops = {
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000052 .owner = THIS_MODULE,
53 .ioctl = coreb_ioctl,
Bryan Wu1394f032007-05-06 14:50:22 -070054};
55
56static struct miscdevice coreb_dev = {
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000057 .minor = MISC_DYNAMIC_MINOR,
58 .name = "coreb",
59 .fops = &coreb_fops,
Bryan Wu1394f032007-05-06 14:50:22 -070060};
61
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000062static int __init bf561_coreb_init(void)
Bryan Wu1394f032007-05-06 14:50:22 -070063{
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000064 return misc_register(&coreb_dev);
Bryan Wu1394f032007-05-06 14:50:22 -070065}
Bryan Wu1394f032007-05-06 14:50:22 -070066module_init(bf561_coreb_init);
Mike Frysingerc8f36dc2009-05-14 14:55:50 +000067
68static void __exit bf561_coreb_exit(void)
69{
70 misc_deregister(&coreb_dev);
71}
Bryan Wu1394f032007-05-06 14:50:22 -070072module_exit(bf561_coreb_exit);
73
74MODULE_AUTHOR("Bas Vermeulen <bvermeul@blackstar.xs4all.nl>");
75MODULE_DESCRIPTION("BF561 Core B Support");