Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Broadcom specific AMBA
  3 * System on Chip (SoC) Host
  4 *
  5 * Licensed under the GNU/GPL. See COPYING for details.
  6 */
  7
  8#include "bcma_private.h"
  9#include "scan.h"
 10#include <linux/bcma/bcma.h>
 11#include <linux/bcma/bcma_soc.h>
 12
 13static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
 14{
 15	return readb(core->io_addr + offset);
 16}
 17
 18static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
 19{
 20	return readw(core->io_addr + offset);
 21}
 22
 23static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
 24{
 25	return readl(core->io_addr + offset);
 26}
 27
 28static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
 29				 u8 value)
 30{
 31	writeb(value, core->io_addr + offset);
 32}
 33
 34static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
 35				 u16 value)
 36{
 37	writew(value, core->io_addr + offset);
 38}
 39
 40static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
 41				 u32 value)
 42{
 43	writel(value, core->io_addr + offset);
 44}
 45
 46#ifdef CONFIG_BCMA_BLOCKIO
 47static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
 48				     size_t count, u16 offset, u8 reg_width)
 49{
 50	void __iomem *addr = core->io_addr + offset;
 51
 52	switch (reg_width) {
 53	case sizeof(u8): {
 54		u8 *buf = buffer;
 55
 56		while (count) {
 57			*buf = __raw_readb(addr);
 58			buf++;
 59			count--;
 60		}
 61		break;
 62	}
 63	case sizeof(u16): {
 64		__le16 *buf = buffer;
 65
 66		WARN_ON(count & 1);
 67		while (count) {
 68			*buf = (__force __le16)__raw_readw(addr);
 69			buf++;
 70			count -= 2;
 71		}
 72		break;
 73	}
 74	case sizeof(u32): {
 75		__le32 *buf = buffer;
 76
 77		WARN_ON(count & 3);
 78		while (count) {
 79			*buf = (__force __le32)__raw_readl(addr);
 80			buf++;
 81			count -= 4;
 82		}
 83		break;
 84	}
 85	default:
 86		WARN_ON(1);
 87	}
 88}
 89
 90static void bcma_host_soc_block_write(struct bcma_device *core,
 91				      const void *buffer,
 92				      size_t count, u16 offset, u8 reg_width)
 93{
 94	void __iomem *addr = core->io_addr + offset;
 95
 96	switch (reg_width) {
 97	case sizeof(u8): {
 98		const u8 *buf = buffer;
 99
100		while (count) {
101			__raw_writeb(*buf, addr);
102			buf++;
103			count--;
104		}
105		break;
106	}
107	case sizeof(u16): {
108		const __le16 *buf = buffer;
109
110		WARN_ON(count & 1);
111		while (count) {
112			__raw_writew((__force u16)(*buf), addr);
113			buf++;
114			count -= 2;
115		}
116		break;
117	}
118	case sizeof(u32): {
119		const __le32 *buf = buffer;
120
121		WARN_ON(count & 3);
122		while (count) {
123			__raw_writel((__force u32)(*buf), addr);
124			buf++;
125			count -= 4;
126		}
127		break;
128	}
129	default:
130		WARN_ON(1);
131	}
132}
133#endif /* CONFIG_BCMA_BLOCKIO */
134
135static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
136{
137	return readl(core->io_wrap + offset);
138}
139
140static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
141				  u32 value)
142{
143	writel(value, core->io_wrap + offset);
144}
145
146const struct bcma_host_ops bcma_host_soc_ops = {
147	.read8		= bcma_host_soc_read8,
148	.read16		= bcma_host_soc_read16,
149	.read32		= bcma_host_soc_read32,
150	.write8		= bcma_host_soc_write8,
151	.write16	= bcma_host_soc_write16,
152	.write32	= bcma_host_soc_write32,
153#ifdef CONFIG_BCMA_BLOCKIO
154	.block_read	= bcma_host_soc_block_read,
155	.block_write	= bcma_host_soc_block_write,
156#endif
157	.aread32	= bcma_host_soc_aread32,
158	.awrite32	= bcma_host_soc_awrite32,
159};
160
161int __init bcma_host_soc_register(struct bcma_soc *soc)
162{
163	struct bcma_bus *bus = &soc->bus;
164	int err;
165
166	/* iomap only first core. We have to read some register on this core
167	 * to scan the bus.
168	 */
169	bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
170	if (!bus->mmio)
171		return -ENOMEM;
172
173	/* Host specific */
174	bus->hosttype = BCMA_HOSTTYPE_SOC;
175	bus->ops = &bcma_host_soc_ops;
176
177	/* Register */
178	err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
179	if (err)
180		iounmap(bus->mmio);
181
182	return err;
183}