18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright (C) 2012-2019 ARM Limited (or its affiliates). */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "cc_driver.h" 58c2ecf20Sopenharmony_ci#include "cc_sram_mgr.h" 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci/** 88c2ecf20Sopenharmony_ci * cc_sram_mgr_init() - Initializes SRAM pool. 98c2ecf20Sopenharmony_ci * The pool starts right at the beginning of SRAM. 108c2ecf20Sopenharmony_ci * Returns zero for success, negative value otherwise. 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * @drvdata: Associated device driver context 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * Return: 158c2ecf20Sopenharmony_ci * 0 for success, negative error code for failure. 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ciint cc_sram_mgr_init(struct cc_drvdata *drvdata) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci u32 start = 0; 208c2ecf20Sopenharmony_ci struct device *dev = drvdata_to_dev(drvdata); 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci if (drvdata->hw_rev < CC_HW_REV_712) { 238c2ecf20Sopenharmony_ci /* Pool starts after ROM bytes */ 248c2ecf20Sopenharmony_ci start = cc_ioread(drvdata, CC_REG(HOST_SEP_SRAM_THRESHOLD)); 258c2ecf20Sopenharmony_ci if ((start & 0x3) != 0) { 268c2ecf20Sopenharmony_ci dev_err(dev, "Invalid SRAM offset 0x%x\n", start); 278c2ecf20Sopenharmony_ci return -EINVAL; 288c2ecf20Sopenharmony_ci } 298c2ecf20Sopenharmony_ci } 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci drvdata->sram_free_offset = start; 328c2ecf20Sopenharmony_ci return 0; 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/** 368c2ecf20Sopenharmony_ci * cc_sram_alloc() - Allocate buffer from SRAM pool. 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * @drvdata: Associated device driver context 398c2ecf20Sopenharmony_ci * @size: The requested numer of bytes to allocate 408c2ecf20Sopenharmony_ci * 418c2ecf20Sopenharmony_ci * Return: 428c2ecf20Sopenharmony_ci * Address offset in SRAM or NULL_SRAM_ADDR for failure. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ciu32 cc_sram_alloc(struct cc_drvdata *drvdata, u32 size) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci struct device *dev = drvdata_to_dev(drvdata); 478c2ecf20Sopenharmony_ci u32 p; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if ((size & 0x3)) { 508c2ecf20Sopenharmony_ci dev_err(dev, "Requested buffer size (%u) is not multiple of 4", 518c2ecf20Sopenharmony_ci size); 528c2ecf20Sopenharmony_ci return NULL_SRAM_ADDR; 538c2ecf20Sopenharmony_ci } 548c2ecf20Sopenharmony_ci if (size > (CC_CC_SRAM_SIZE - drvdata->sram_free_offset)) { 558c2ecf20Sopenharmony_ci dev_err(dev, "Not enough space to allocate %u B (at offset %u)\n", 568c2ecf20Sopenharmony_ci size, drvdata->sram_free_offset); 578c2ecf20Sopenharmony_ci return NULL_SRAM_ADDR; 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci p = drvdata->sram_free_offset; 618c2ecf20Sopenharmony_ci drvdata->sram_free_offset += size; 628c2ecf20Sopenharmony_ci dev_dbg(dev, "Allocated %u B @ %u\n", size, p); 638c2ecf20Sopenharmony_ci return p; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/** 678c2ecf20Sopenharmony_ci * cc_set_sram_desc() - Create const descriptors sequence to 688c2ecf20Sopenharmony_ci * set values in given array into SRAM. 698c2ecf20Sopenharmony_ci * Note: each const value can't exceed word size. 708c2ecf20Sopenharmony_ci * 718c2ecf20Sopenharmony_ci * @src: A pointer to array of words to set as consts. 728c2ecf20Sopenharmony_ci * @dst: The target SRAM buffer to set into 738c2ecf20Sopenharmony_ci * @nelement: The number of words in "src" array 748c2ecf20Sopenharmony_ci * @seq: A pointer to the given IN/OUT descriptor sequence 758c2ecf20Sopenharmony_ci * @seq_len: A pointer to the given IN/OUT sequence length 768c2ecf20Sopenharmony_ci */ 778c2ecf20Sopenharmony_civoid cc_set_sram_desc(const u32 *src, u32 dst, unsigned int nelement, 788c2ecf20Sopenharmony_ci struct cc_hw_desc *seq, unsigned int *seq_len) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci u32 i; 818c2ecf20Sopenharmony_ci unsigned int idx = *seq_len; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci for (i = 0; i < nelement; i++, idx++) { 848c2ecf20Sopenharmony_ci hw_desc_init(&seq[idx]); 858c2ecf20Sopenharmony_ci set_din_const(&seq[idx], src[i], sizeof(u32)); 868c2ecf20Sopenharmony_ci set_dout_sram(&seq[idx], dst + (i * sizeof(u32)), sizeof(u32)); 878c2ecf20Sopenharmony_ci set_flow_mode(&seq[idx], BYPASS); 888c2ecf20Sopenharmony_ci } 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci *seq_len = idx; 918c2ecf20Sopenharmony_ci} 92