2 * arch/sh/drivers/superhyway/ops-sh4-202.c
4 * SuperHyway bus support for SH4-202
6 * Copyright (C) 2005 Paul Mundt
8 * This file is subject to the terms and conditions of the GNU
9 * General Public License. See the file "COPYING" in the main
10 * directory of this archive for more details.
12 #include <linux/kernel.h>
13 #include <linux/init.h>
14 #include <linux/superhyway.h>
15 #include <linux/string.h>
16 #include <asm/addrspace.h>
19 #define PHYS_EMI_CBLOCK P4SEGADDR(0x1ec00000)
20 #define PHYS_EMI_DBLOCK P4SEGADDR(0x08000000)
21 #define PHYS_FEMI_CBLOCK P4SEGADDR(0x1f800000)
22 #define PHYS_FEMI_DBLOCK P4SEGADDR(0x00000000)
24 #define PHYS_EPBR_BLOCK P4SEGADDR(0x1de00000)
25 #define PHYS_DMAC_BLOCK P4SEGADDR(0x1fa00000)
26 #define PHYS_PBR_BLOCK P4SEGADDR(0x1fc00000)
28 static struct resource emi_resources
[] = {
30 .start
= PHYS_EMI_CBLOCK
,
31 .end
= PHYS_EMI_CBLOCK
+ 0x00300000 - 1,
32 .flags
= IORESOURCE_MEM
,
35 .start
= PHYS_EMI_DBLOCK
,
36 .end
= PHYS_EMI_DBLOCK
+ 0x08000000 - 1,
37 .flags
= IORESOURCE_MEM
,
41 static struct superhyway_device emi_device
= {
43 .num_resources
= ARRAY_SIZE(emi_resources
),
44 .resource
= emi_resources
,
47 static struct resource femi_resources
[] = {
49 .start
= PHYS_FEMI_CBLOCK
,
50 .end
= PHYS_FEMI_CBLOCK
+ 0x00100000 - 1,
51 .flags
= IORESOURCE_MEM
,
54 .start
= PHYS_FEMI_DBLOCK
,
55 .end
= PHYS_FEMI_DBLOCK
+ 0x08000000 - 1,
56 .flags
= IORESOURCE_MEM
,
60 static struct superhyway_device femi_device
= {
62 .num_resources
= ARRAY_SIZE(femi_resources
),
63 .resource
= femi_resources
,
66 static struct resource epbr_resources
[] = {
68 .start
= P4SEGADDR(0x1e7ffff8),
69 .end
= P4SEGADDR(0x1e7ffff8 + (sizeof(u32
) * 2) - 1),
70 .flags
= IORESOURCE_MEM
,
73 .start
= PHYS_EPBR_BLOCK
,
74 .end
= PHYS_EPBR_BLOCK
+ 0x00a00000 - 1,
75 .flags
= IORESOURCE_MEM
,
79 static struct superhyway_device epbr_device
= {
81 .num_resources
= ARRAY_SIZE(epbr_resources
),
82 .resource
= epbr_resources
,
85 static struct resource dmac_resource
= {
86 .start
= PHYS_DMAC_BLOCK
,
87 .end
= PHYS_DMAC_BLOCK
+ 0x00100000 - 1,
88 .flags
= IORESOURCE_MEM
,
91 static struct superhyway_device dmac_device
= {
94 .resource
= &dmac_resource
,
97 static struct resource pbr_resources
[] = {
99 .start
= P4SEGADDR(0x1ffffff8),
100 .end
= P4SEGADDR(0x1ffffff8 + (sizeof(u32
) * 2) - 1),
101 .flags
= IORESOURCE_MEM
,
104 .start
= PHYS_PBR_BLOCK
,
105 .end
= PHYS_PBR_BLOCK
+ 0x00400000 - (sizeof(u32
) * 2) - 1,
106 .flags
= IORESOURCE_MEM
,
110 static struct superhyway_device pbr_device
= {
112 .num_resources
= ARRAY_SIZE(pbr_resources
),
113 .resource
= pbr_resources
,
116 static struct superhyway_device
*sh4202_devices
[] __initdata
= {
117 &emi_device
, &femi_device
, &epbr_device
, &dmac_device
, &pbr_device
,
120 static int sh4202_read_vcr(unsigned long base
, struct superhyway_vcr_info
*vcr
)
126 * XXX: Even though the SH4-202 Evaluation Device documentation
127 * indicates that VCRL is mapped first with VCRH at a + 0x04
128 * offset, the opposite seems to be true.
130 * Some modules (PBR and ePBR for instance) also appear to have
131 * VCRL/VCRH flipped in the documentation, but on the SH4-202
132 * itself it appears that these are all consistently mapped with
133 * VCRH preceding VCRL.
135 * Do not trust the documentation, for it is evil.
137 vcrh
= __raw_readl(base
);
138 vcrl
= __raw_readl(base
+ sizeof(u32
));
140 tmp
= ((u64
)vcrh
<< 32) | vcrl
;
141 memcpy(vcr
, &tmp
, sizeof(u64
));
146 static int sh4202_write_vcr(unsigned long base
, struct superhyway_vcr_info vcr
)
148 u64 tmp
= *(u64
*)&vcr
;
150 __raw_writel((tmp
>> 32) & 0xffffffff, base
);
151 __raw_writel(tmp
& 0xffffffff, base
+ sizeof(u32
));
156 static struct superhyway_ops sh4202_superhyway_ops
= {
157 .read_vcr
= sh4202_read_vcr
,
158 .write_vcr
= sh4202_write_vcr
,
161 struct superhyway_bus superhyway_channels
[] = {
162 { &sh4202_superhyway_ops
, },
166 int __init
superhyway_scan_bus(struct superhyway_bus
*bus
)
168 return superhyway_add_devices(bus
, sh4202_devices
,
169 ARRAY_SIZE(sh4202_devices
));