Files
2026-08-24 10:03:24 +08:00

101 lines
2.4 KiB
C

/*
* Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
*
* SPDX-License-Identifier: MIT
*/
#include "FreeRTOS.h"
#include "semphr.h"
#include "hwspinlock.h"
#include "uart.h"
#include "register.h"
#ifndef PRINT_DBG
#define PRINT_DBG(...) //printf(__VA_ARGS__)
#define PRINT_ERR(...) printf(__VA_ARGS__)
#define PRINT(...) printf(__VA_ARGS__)
#endif
#define HWTAG "HWSPIN"
SemaphoreHandle_t xHwLockSemp[HWSPINLOCK_NUMS];
struct hwspinlock_prop {
uint32_t xAddr;
uint32_t xCpus;
};
struct hwspinlock_prop prop;
BaseType_t vHwspinLock_get(struct hwspinlock_t *hwspinlock, uint32_t id)
{
BaseType_t ret = pdTRUE;
uint32_t ulLockVal = hwspinlock->lock_data[0];
uint32_t ulCnt = 0;
if (ulLockVal != 0) {
PRINT_ERR("[%s]: locked0 idx %x by %x\n", HWTAG, id, ulLockVal);
return pdFALSE;
}
ret = xSemaphoreTake(xHwLockSemp[id], portMAX_DELAY);
if (ret == pdFALSE) {
PRINT_ERR("[%s]: Async get sempaphore fail\n", HWTAG);
configASSERT(ret);
}
lock_retry:
hwspinlock->lock_data[0] = AML_MUTEX_AO_PROC_ID;
ulLockVal = hwspinlock->lock_data[0];
if (ulLockVal == 0 && ulCnt < 3) {
ulCnt += 1;
goto lock_retry;
}
if (AML_MUTEX_AO_PROC_ID != ulLockVal) {
PRINT_ERR("[%s]: locked1 idx %x by %x\n", HWTAG, id, ulLockVal);
xSemaphoreGive(xHwLockSemp[id]);
ret = pdFALSE;
}
return ret;
}
void vHwspinLock_release(struct hwspinlock_t *hwspinlock, uint32_t id)
{
uint32_t ulLockVal = 0;
if (uxSemaphoreGetCount(xHwLockSemp[id])) {
PRINT_ERR("[%s]: No hwspinlock required before\n", HWTAG);
return;
}
ulLockVal = hwspinlock->lock_data[0];
if (ulLockVal != AML_MUTEX_AO_PROC_ID) {
PRINT_ERR("[%s]: Release idx %x locked by %x\n", HWTAG, id, ulLockVal);
return;
}
hwspinlock->lock_data[0] = AML_MUTEX_AO_PROC_ID;
xSemaphoreGive(xHwLockSemp[id]);
}
void vHwspinLock_init(struct hwspinlock_t **hwspinlock, uint32_t id,
void *hwspinlock_addr)
{
uint32_t xAddrOff = id * sizeof(struct hwspinlock_t);
if (!hwspinlock_addr)
hwspinlock_addr = (char *)prop.xAddr + xAddrOff;
*hwspinlock = hwspinlock_addr;
PRINT_DBG("hwspinlock addr %p\n", hwspinlock_addr);
}
void vHwLockInit(uint32_t xAddr, uint32_t xCpus)
{
int idx = 0;
prop.xAddr = xAddr;
prop.xCpus = xCpus;
for (idx = 0; idx < HWSPINLOCK_NUMS; idx++) {
xHwLockSemp[idx] = xSemaphoreCreateBinary();
configASSERT(xHwLockSemp[idx]);
xSemaphoreGive(xHwLockSemp[idx]);
}
PRINT_ERR("hwspinlock init\n");
}