162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (C) 2012-2019 ARM Limited (or its affiliates). */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "cc_driver.h" 562306a36Sopenharmony_ci#include "cc_sram_mgr.h" 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/** 862306a36Sopenharmony_ci * cc_sram_mgr_init() - Initializes SRAM pool. 962306a36Sopenharmony_ci * The pool starts right at the beginning of SRAM. 1062306a36Sopenharmony_ci * Returns zero for success, negative value otherwise. 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * @drvdata: Associated device driver context 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * Return: 1562306a36Sopenharmony_ci * 0 for success, negative error code for failure. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ciint cc_sram_mgr_init(struct cc_drvdata *drvdata) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci u32 start = 0; 2062306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(drvdata); 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci if (drvdata->hw_rev < CC_HW_REV_712) { 2362306a36Sopenharmony_ci /* Pool starts after ROM bytes */ 2462306a36Sopenharmony_ci start = cc_ioread(drvdata, CC_REG(HOST_SEP_SRAM_THRESHOLD)); 2562306a36Sopenharmony_ci if ((start & 0x3) != 0) { 2662306a36Sopenharmony_ci dev_err(dev, "Invalid SRAM offset 0x%x\n", start); 2762306a36Sopenharmony_ci return -EINVAL; 2862306a36Sopenharmony_ci } 2962306a36Sopenharmony_ci } 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci drvdata->sram_free_offset = start; 3262306a36Sopenharmony_ci return 0; 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/** 3662306a36Sopenharmony_ci * cc_sram_alloc() - Allocate buffer from SRAM pool. 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * @drvdata: Associated device driver context 3962306a36Sopenharmony_ci * @size: The requested numer of bytes to allocate 4062306a36Sopenharmony_ci * 4162306a36Sopenharmony_ci * Return: 4262306a36Sopenharmony_ci * Address offset in SRAM or NULL_SRAM_ADDR for failure. 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_ciu32 cc_sram_alloc(struct cc_drvdata *drvdata, u32 size) 4562306a36Sopenharmony_ci{ 4662306a36Sopenharmony_ci struct device *dev = drvdata_to_dev(drvdata); 4762306a36Sopenharmony_ci u32 p; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci if ((size & 0x3)) { 5062306a36Sopenharmony_ci dev_err(dev, "Requested buffer size (%u) is not multiple of 4", 5162306a36Sopenharmony_ci size); 5262306a36Sopenharmony_ci return NULL_SRAM_ADDR; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci if (size > (CC_CC_SRAM_SIZE - drvdata->sram_free_offset)) { 5562306a36Sopenharmony_ci dev_err(dev, "Not enough space to allocate %u B (at offset %u)\n", 5662306a36Sopenharmony_ci size, drvdata->sram_free_offset); 5762306a36Sopenharmony_ci return NULL_SRAM_ADDR; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci p = drvdata->sram_free_offset; 6162306a36Sopenharmony_ci drvdata->sram_free_offset += size; 6262306a36Sopenharmony_ci dev_dbg(dev, "Allocated %u B @ %u\n", size, p); 6362306a36Sopenharmony_ci return p; 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/** 6762306a36Sopenharmony_ci * cc_set_sram_desc() - Create const descriptors sequence to 6862306a36Sopenharmony_ci * set values in given array into SRAM. 6962306a36Sopenharmony_ci * Note: each const value can't exceed word size. 7062306a36Sopenharmony_ci * 7162306a36Sopenharmony_ci * @src: A pointer to array of words to set as consts. 7262306a36Sopenharmony_ci * @dst: The target SRAM buffer to set into 7362306a36Sopenharmony_ci * @nelement: The number of words in "src" array 7462306a36Sopenharmony_ci * @seq: A pointer to the given IN/OUT descriptor sequence 7562306a36Sopenharmony_ci * @seq_len: A pointer to the given IN/OUT sequence length 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_civoid cc_set_sram_desc(const u32 *src, u32 dst, unsigned int nelement, 7862306a36Sopenharmony_ci struct cc_hw_desc *seq, unsigned int *seq_len) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci u32 i; 8162306a36Sopenharmony_ci unsigned int idx = *seq_len; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci for (i = 0; i < nelement; i++, idx++) { 8462306a36Sopenharmony_ci hw_desc_init(&seq[idx]); 8562306a36Sopenharmony_ci set_din_const(&seq[idx], src[i], sizeof(u32)); 8662306a36Sopenharmony_ci set_dout_sram(&seq[idx], dst + (i * sizeof(u32)), sizeof(u32)); 8762306a36Sopenharmony_ci set_flow_mode(&seq[idx], BYPASS); 8862306a36Sopenharmony_ci } 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci *seq_len = idx; 9162306a36Sopenharmony_ci} 92