1 #include <linux/kernel.h>
2 #include <linux/module.h>
4 #include <linux/platform_device.h>
5 #include <linux/slab.h>
8 #include <ifxmips_cgu.h>
10 #include <ifxmips_prom.h>
11 #include <ifxmips_irq.h>
15 extern int mps_irq_init(struct mps
*mps
);
16 extern void mps_irq_exit(struct mps
*mps
);
18 #define MPS_CPU0_BOOT_RVEC 0x1c0
19 #define MPS_CPU0_BOOT_NVEC 0x1c4
20 #define MPS_CPU0_BOOT_EVEC 0x1c8
21 #define MPS_CPU0_CP0_STATUS 0x1cc
22 #define MPS_CPU0_CP0_EEPC 0x1d0
23 #define MPS_CPU0_CP0_EPC 0x1d4
24 #define MPS_CPU0_BOOT_SIZE 0x1d8
25 #define MPS_CPU0_CFG_STAT 0x1dc
26 #define MPS_CPU1_BOOT_RVEC 0x1e0
27 #define MPS_CPU1_BOOT_NVEC 0x1e4
28 #define MPS_CPU1_BOOT_EVEC 0x1e8
29 #define MPS_CPU1_CP0_STATUS 0x1ec
30 #define MPS_CPU1_CP0_EEPC 0x1f0
31 #define MPS_CPU1_CP0_EPC 0x1f4
32 #define MPS_CPU1_BOOT_SIZE 0x1f8
33 #define MPS_CPU1_CFG_STAT 0x1fc
35 static void mps_reset(void)
37 ifxmips_w32(ifxmips_r32(IFXMIPS_RCU_RST
) | IFXMIPS_RCU_RST_CPU1
,
42 static void mps_release(void)
45 val
= ifxmips_r32(IFXMIPS_RCU_RST
);
47 val
&= ~IFXMIPS_RCU_RST_CPU1
;
48 ifxmips_w32(val
, IFXMIPS_RCU_RST
);
52 void mps_load_firmware(struct mps
*mps
, const void *data
, size_t size
,
53 enum mps_boot_config config
)
56 uint32_t fw_size
= size
;
58 if (config
== MPS_BOOT_LEGACY
) {
60 fw_size
-= sizeof(uint32_t);
62 if(config
== MPS_BOOT_ENCRYPTED
) {
63 cfg
= __raw_readl(mps
->mbox_base
+ MPS_CPU1_CFG_STAT
);
72 memcpy_toio(mps
->cp1_base
, data
, size
);
74 __raw_writel(cfg
, mps
->mbox_base
+ MPS_CPU1_CFG_STAT
);
75 __raw_writel(fw_size
, mps
->mbox_base
+ MPS_CPU1_BOOT_SIZE
);
76 __raw_writel((uint32_t)mps
->cp1_base
, mps
->mbox_base
+ MPS_CPU1_BOOT_RVEC
);
80 EXPORT_SYMBOL_GPL(mps_load_firmware
);
82 void mps_configure_fifo(struct mps
*mps
, struct mps_fifo
*fifo
,
83 const struct mps_fifo_config
*config
)
85 mps_fifo_init(fifo
, mps
->mbox_base
+ config
->base
,
86 mps
->mbox_base
+ config
->head_addr
,
87 mps
->mbox_base
+ config
->tail_addr
,
90 __raw_writel(config
->size
, mps
->mbox_base
+ config
->size_addr
);
91 __raw_writel(mps
->mbox_res
->start
+ config
->base
,
92 mps
->mbox_base
+ config
->base_addr
);
94 EXPORT_SYMBOL_GPL(mps_configure_fifo
);
96 void mps_configure_mailbox(struct mps
*mps
, struct mps_mailbox
*mbox
,
97 const struct mps_fifo_config
*upstream_config
,
98 const struct mps_fifo_config
*downstream_config
)
100 mps_configure_fifo(mps
, &mbox
->upstream
, upstream_config
);
101 mps_configure_fifo(mps
, &mbox
->downstream
, downstream_config
);
103 EXPORT_SYMBOL_GPL(mps_configure_mailbox
);
105 static int __devinit
mps_probe(struct platform_device
*pdev
)
109 struct resource
*res
;
111 mps
= kzalloc(sizeof(*mps
), GFP_KERNEL
);
116 mps
->dev
= &pdev
->dev
;
118 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "mem");
120 dev_err(&pdev
->dev
, "Failed to get mem resource");
125 res
= request_mem_region(res
->start
, resource_size(res
),
126 dev_name(&pdev
->dev
));
129 dev_err(&pdev
->dev
, "Failed to request mem resource");
134 mps
->base
= ioremap_nocache(res
->start
, resource_size(res
));
137 dev_err(&pdev
->dev
, "Failed to ioremap mem region\n");
139 goto err_release_mem_region
;
145 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "mailbox");
147 dev_err(&pdev
->dev
, "Failed to get mailbox mem region\n");
152 res
= request_mem_region(res
->start
, resource_size(res
),
153 dev_name(&pdev
->dev
));
156 dev_err(&pdev
->dev
, "Failed to request mailbox mem region\n");
161 mps
->mbox_base
= ioremap_nocache(res
->start
, resource_size(res
));
163 if (!mps
->mbox_base
) {
164 dev_err(&pdev
->dev
, "Failed to ioremap mailbox mem region\n");
166 goto err_release_mem_region
;
171 mps
->cp1_base
= ioremap_nocache((unsigned int)pdev
->dev
.platform_data
, 1 << 20);
173 if (!mps
->cp1_base
) {
174 dev_err(&pdev
->dev
, "Failed to ioremap cp1 address\n");
176 goto err_release_mem_region
;
179 mps
->irq_ad0
= INT_NUM_IM4_IRL18
;
180 mps
->irq_ad1
= INT_NUM_IM4_IRL19
;
183 ret
= mps_irq_init(mps
);
187 platform_set_drvdata(pdev
, mps
);
192 iounmap(mps
->mbox_base
);
193 err_release_mem_region
:
194 release_mem_region(res
->start
, resource_size(res
));
201 static int __devexit
mps_remove(struct platform_device
*pdev
)
203 struct mps
*mps
= platform_get_drvdata(pdev
);
207 iounmap(mps
->mbox_base
);
208 release_mem_region(mps
->mbox_res
->start
, resource_size(mps
->mbox_res
));
210 release_mem_region(mps
->res
->start
, resource_size(mps
->res
));
216 static struct platform_driver mps_driver
= {
218 .remove
= __devexit_p(mps_remove
),
225 static int __init
mps_init(void)
227 return platform_driver_register(&mps_driver
);
229 module_init(mps_init
);
231 static void __exit
mps_exit(void)
233 platform_driver_unregister(&mps_driver
);
235 module_exit(mps_exit
);
237 MODULE_LICENSE("GPL");
238 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");