2 * Sonics Silicon Backplane SoC host related functions.
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
8 * Licensed under the GNU/GPL. See COPYING for details.
11 #include <linux/bcm47xx_nvram.h>
12 #include <linux/ssb/ssb.h>
14 #include "ssb_private.h"
16 static u8
ssb_host_soc_read8(struct ssb_device
*dev
, u16 offset
)
18 struct ssb_bus
*bus
= dev
->bus
;
20 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
21 return readb(bus
->mmio
+ offset
);
24 static u16
ssb_host_soc_read16(struct ssb_device
*dev
, u16 offset
)
26 struct ssb_bus
*bus
= dev
->bus
;
28 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
29 return readw(bus
->mmio
+ offset
);
32 static u32
ssb_host_soc_read32(struct ssb_device
*dev
, u16 offset
)
34 struct ssb_bus
*bus
= dev
->bus
;
36 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
37 return readl(bus
->mmio
+ offset
);
40 #ifdef CONFIG_SSB_BLOCKIO
41 static void ssb_host_soc_block_read(struct ssb_device
*dev
, void *buffer
,
42 size_t count
, u16 offset
, u8 reg_width
)
44 struct ssb_bus
*bus
= dev
->bus
;
47 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
48 addr
= bus
->mmio
+ offset
;
55 *buf
= __raw_readb(addr
);
64 SSB_WARN_ON(count
& 1);
66 *buf
= (__force __le16
)__raw_readw(addr
);
75 SSB_WARN_ON(count
& 3);
77 *buf
= (__force __le32
)__raw_readl(addr
);
87 #endif /* CONFIG_SSB_BLOCKIO */
89 static void ssb_host_soc_write8(struct ssb_device
*dev
, u16 offset
, u8 value
)
91 struct ssb_bus
*bus
= dev
->bus
;
93 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
94 writeb(value
, bus
->mmio
+ offset
);
97 static void ssb_host_soc_write16(struct ssb_device
*dev
, u16 offset
, u16 value
)
99 struct ssb_bus
*bus
= dev
->bus
;
101 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
102 writew(value
, bus
->mmio
+ offset
);
105 static void ssb_host_soc_write32(struct ssb_device
*dev
, u16 offset
, u32 value
)
107 struct ssb_bus
*bus
= dev
->bus
;
109 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
110 writel(value
, bus
->mmio
+ offset
);
113 #ifdef CONFIG_SSB_BLOCKIO
114 static void ssb_host_soc_block_write(struct ssb_device
*dev
, const void *buffer
,
115 size_t count
, u16 offset
, u8 reg_width
)
117 struct ssb_bus
*bus
= dev
->bus
;
120 offset
+= dev
->core_index
* SSB_CORE_SIZE
;
121 addr
= bus
->mmio
+ offset
;
125 const u8
*buf
= buffer
;
128 __raw_writeb(*buf
, addr
);
135 const __le16
*buf
= buffer
;
137 SSB_WARN_ON(count
& 1);
139 __raw_writew((__force u16
)(*buf
), addr
);
146 const __le32
*buf
= buffer
;
148 SSB_WARN_ON(count
& 3);
150 __raw_writel((__force u32
)(*buf
), addr
);
160 #endif /* CONFIG_SSB_BLOCKIO */
162 /* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
163 const struct ssb_bus_ops ssb_host_soc_ops
= {
164 .read8
= ssb_host_soc_read8
,
165 .read16
= ssb_host_soc_read16
,
166 .read32
= ssb_host_soc_read32
,
167 .write8
= ssb_host_soc_write8
,
168 .write16
= ssb_host_soc_write16
,
169 .write32
= ssb_host_soc_write32
,
170 #ifdef CONFIG_SSB_BLOCKIO
171 .block_read
= ssb_host_soc_block_read
,
172 .block_write
= ssb_host_soc_block_write
,
176 int ssb_host_soc_get_invariants(struct ssb_bus
*bus
,
177 struct ssb_init_invariants
*iv
)
182 /* Fill boardinfo structure */
183 memset(&iv
->boardinfo
, 0, sizeof(struct ssb_boardinfo
));
185 len
= bcm47xx_nvram_getenv("boardvendor", buf
, sizeof(buf
));
187 err
= kstrtou16(strim(buf
), 0, &iv
->boardinfo
.vendor
);
189 pr_warn("Couldn't parse nvram board vendor entry with value \"%s\"\n",
192 if (!iv
->boardinfo
.vendor
)
193 iv
->boardinfo
.vendor
= SSB_BOARDVENDOR_BCM
;
195 len
= bcm47xx_nvram_getenv("boardtype", buf
, sizeof(buf
));
197 err
= kstrtou16(strim(buf
), 0, &iv
->boardinfo
.type
);
199 pr_warn("Couldn't parse nvram board type entry with value \"%s\"\n",
203 memset(&iv
->sprom
, 0, sizeof(struct ssb_sprom
));
204 ssb_fill_sprom_with_fallback(bus
, &iv
->sprom
);
206 if (bcm47xx_nvram_getenv("cardbus", buf
, sizeof(buf
)) >= 0)
207 iv
->has_cardbus_slot
= !!simple_strtoul(buf
, NULL
, 10);