at v5.2 2.6 kB view raw
1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2// 3// This file is provided under a dual BSD/GPLv2 license. When using or 4// redistributing this file, you may do so under either license. 5// 6// Copyright(c) 2018 Intel Corporation. All rights reserved. 7// 8// Author: Keyon Jie <yang.jie@linux.intel.com> 9// 10 11#include <linux/io-64-nonatomic-lo-hi.h> 12#include <linux/platform_device.h> 13#include <sound/soc.h> 14#include <sound/sof.h> 15#include "sof-priv.h" 16 17/* 18 * Register IO 19 * 20 * The sof_io_xyz() wrappers are typically referenced in snd_sof_dsp_ops 21 * structures and cannot be inlined. 22 */ 23 24void sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value) 25{ 26 writel(value, addr); 27} 28EXPORT_SYMBOL(sof_io_write); 29 30u32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr) 31{ 32 return readl(addr); 33} 34EXPORT_SYMBOL(sof_io_read); 35 36void sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value) 37{ 38 writeq(value, addr); 39} 40EXPORT_SYMBOL(sof_io_write64); 41 42u64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr) 43{ 44 return readq(addr); 45} 46EXPORT_SYMBOL(sof_io_read64); 47 48/* 49 * IPC Mailbox IO 50 */ 51 52void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset, 53 void *message, size_t bytes) 54{ 55 void __iomem *dest = sdev->bar[sdev->mailbox_bar] + offset; 56 57 memcpy_toio(dest, message, bytes); 58} 59EXPORT_SYMBOL(sof_mailbox_write); 60 61void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset, 62 void *message, size_t bytes) 63{ 64 void __iomem *src = sdev->bar[sdev->mailbox_bar] + offset; 65 66 memcpy_fromio(message, src, bytes); 67} 68EXPORT_SYMBOL(sof_mailbox_read); 69 70/* 71 * Memory copy. 72 */ 73 74void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src, 75 size_t size) 76{ 77 void __iomem *dest = sdev->bar[bar] + offset; 78 const u8 *src_byte = src; 79 u32 affected_mask; 80 u32 tmp; 81 int m, n; 82 83 m = size / 4; 84 n = size % 4; 85 86 /* __iowrite32_copy use 32bit size values so divide by 4 */ 87 __iowrite32_copy(dest, src, m); 88 89 if (n) { 90 affected_mask = (1 << (8 * n)) - 1; 91 92 /* first read the 32bit data of dest, then change affected 93 * bytes, and write back to dest. For unaffected bytes, it 94 * should not be changed 95 */ 96 tmp = ioread32(dest + m * 4); 97 tmp &= ~affected_mask; 98 99 tmp |= *(u32 *)(src_byte + m * 4) & affected_mask; 100 iowrite32(tmp, dest + m * 4); 101 } 102} 103EXPORT_SYMBOL(sof_block_write); 104 105void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest, 106 size_t size) 107{ 108 void __iomem *src = sdev->bar[bar] + offset; 109 110 memcpy_fromio(dest, src, size); 111} 112EXPORT_SYMBOL(sof_block_read);