lipengfei28 commented on code in PR #16798: URL: https://github.com/apache/nuttx/pull/16798#discussion_r2262316798
########## arch/arm64/src/imx9/imx9_scmi.c: ########## @@ -0,0 +1,1384 @@ +/**************************************************************************** + * arch/arm64/src/imx9/imx9_scmi.c + * + * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: 2024 NXP + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <assert.h> +#include <debug.h> +#include <errno.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> + +#include <nuttx/arch.h> +#include <nuttx/clock.h> +#include <nuttx/crc32.h> +#include <nuttx/irq.h> +#include <nuttx/spinlock.h> +#include <nuttx/semaphore.h> + +#include <arch/board/board.h> + +#include "arm64_internal.h" +#include "hardware/imx95/imx95_memorymap.h" +#include "imx9_mu.h" +#include "imx9_scmi.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SCMI_PLATFORM_MU_INST 0 +#define SCMI_TFORM_SMA_ADDR 0 +#define SCMI_MAX_CHN 3 + +#define SCMI_FREE (1UL << 0u) +#define SCMI_ERROR (1UL << 1u) +#define SCMI_COMP_INT (1UL << 0u) + +#define SCMI_BUFFER_SIZE 128u /* SCMI buffer size */ +#define SCMI_BUFFER_HEADER 24u /* SCMI buffer header size */ +#define SCMI_BUFFER_PAYLOAD (SCMI_BUFFER_SIZE - SCMI_BUFFER_HEADER - 4u) +#define SCMI_CRC_NONE 0u /* No CRC */ +#define SCMI_CRC_XOR 1u /* Simple and fast 32-bit exclusive-OR sum */ +#define SCMI_CRC_J1850 2u /* J1850 standard CRC */ +#define SCMI_CRC_CRC32 3u /* CRC32 standard CRC */ + +/* SCMI protocol message IDs */ + +#define SCMI_PROTOCOL_BASE 0x10u /* Base protocol */ +#define SCMI_PROTOCOL_POWER 0x11u /* Power domain management protocol */ +#define SCMI_PROTOCOL_SYS 0x12u /* System power management protocol */ +#define SCMI_PROTOCOL_PERF 0x13u /* Performance domain protocol */ + +#define SCMI_PROTOCOL_CLOCK 0x14u /* Clock management protocol */ +#define SCMI_PROTOCOL_SENSOR 0x15u /* Sensor management protocol */ +#define SCMI_PROTOCOL_RESET 0x16u /* Reset domain management protocol */ +#define SCMI_PROTOCOL_VOLTAGE 0x17u /* Voltage domain management protocol */ +#define SCMI_PROTOCOL_PINCTRL 0x19u /* Pin control protocol */ +#define SCMI_PROTOCOL_LMM 0x80u /* LM management protocol */ +#define SCMI_PROTOCOL_BBM 0x81u /* BBM management protocol */ +#define SCMI_PROTOCOL_CPU 0x82u /* CPU management protocol */ +#define SCMI_PROTOCOL_FUSA 0x83u /* FuSa protocol */ +#define SCMI_PROTOCOL_MISC 0x84u /* Misc protocol */ + +/* SCMI clock protocol message IDs */ + +#define SCMI_MSG_CLOCK_ATTRIBUTES 0x3u /* Get clock attributes */ +#define SCMI_MSG_CLOCK_DESCRIBE_RATES 0x4u /* Get clock rate description */ +#define SCMI_MSG_CLOCK_RATE_SET 0x5u /* Set clock rate */ +#define SCMI_MSG_CLOCK_RATE_GET 0x6u /* Get clock rate */ +#define SCMI_MSG_CLOCK_CONFIG_SET 0x7u /* Set clock configuration */ +#define SCMI_MSG_CLOCK_CONFIG_GET 0xbu /* Get clock configuration */ +#define SCMI_MSG_CLOCK_POSB_PARENTS_GET 0xcu /* Get all possible parents*/ +#define SCMI_MSG_CLOCK_PARENT_SET 0xdu /* Set clock parent */ +#define SCMI_MSG_CLOCK_PARENT_GET 0xeu /* Get clock parent */ +#define SCMI_MSG_CLOCK_GET_PERMISSIONS 0xfu /* Get clock permissions */ + +/* SCMI pinctrl protocol message IDs */ + +#define SCMI_MSG_PINCTRL_ATTRIBUTES 0x3u /* Get pin attributes */ +#define SCMI_MSG_PINCTRL_CONFIG_GET 0x5u /* Get pin configuration */ +#define SCMI_MSG_PINCTRL_CONFIG_SET 0x6u /* Set pin configuration */ +#define SCMI_MSG_PINCTRL_FUNCTION_SELECT 0x7u /* Select a function for a pin */ +#define SCMI_MSG_PINCTRL_REQUEST 0x8u /* Request a pin */ +#define SCMI_MSG_PINCTRL_RELEASE 0x9u /* Release a pin */ + +/* SCMI power protocol message IDs and masks */ + +#define SCMI_MSG_POWER_STATE_SET 0x4U +#define SCMI_MSG_POWER_STATE_GET 0x5U + +/* SCMI power domain states */ + +#define SCMI_POWER_DOMAIN_STATE_ON 0x00000000U +#define SCMI_POWER_DOMAIN_STATE_OFF 0x40000000U + +/* SCMI power domain attributes */ + +#define SCMI_POWER_ATTR_CHANGE(x) (((x) & 0x1U) << 31U) +#define SCMI_POWER_ATTR_ASYNC(x) (((x) & 0x1U) << 30U) +#define SCMI_POWER_ATTR_SYNC(x) (((x) & 0x1U) << 29U) +#define SCMI_POWER_ATTR_CHANGE_REQ(x) (((x) & 0x1U) << 28U) +#define SCMI_POWER_ATTR_EXT_NAME(x) (((x) & 0x1U) << 27U) + +/* SCMI power state set flags */ + +#define SCMI_POWER_FLAGS_ASYNC(x) (((x) & 0x1U) >> 0U) + +/* SCMI header creation */ + +#define SCMI_HEADER_MSG(x) (((x) & 0xffu) << 0u) +#define SCMI_HEADER_TYPE(x) (((x) & 0x3u) << 8u) +#define SCMI_HEADER_PROTOCOL(x) (((x) & 0xffu) << 10u) +#define SCMI_HEADER_TOKEN(x) (((x) & 0x3ffu) << 18u) + +/* SCMI header extraction */ + +#define SCMI_HEADER_MSG_EX(x) (((x) & 0xffu) >> 0u) +#define SCMI_HEADER_TYPE_EX(x) (((x) & 0x300u) >> 8u) +#define SCMI_HEADER_PROTOCOL_EX(x) (((x) & 0x3fc00u) >> 10u) +#define SCMI_HEADER_TOKEN_EX(x) (((x) & 0x0ffc0000u) >> 18u) + +/* Max payload length */ + +#define SCMI_PAYLOAD_LEN 100u + +/* Calc number of array elements */ + +#define SCMI_ARRAY(X, Y) ((SCMI_PAYLOAD_LEN - (X)) / sizeof(Y)) + +#define SCMI_PINCTRL_MAX_NAME 16u +#define SCMI_PINCTRL_MAX_CONFIGS SCMI_ARRAY(8u, scmi_pin_config_t) +#define SCMI_PINCTRL_MAX_CONFIGS_T SCMI_ARRAY(8u, scmi_pin_config_t) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct +{ + bool valid; + uint8_t mb_inst; + uint8_t mb_doorbell; + uint32_t shared_memory_address; +} smt_chn_config_t; + +typedef struct +{ + uint32_t header; + int32_t status; +} msg_status_t; + +typedef struct +{ + uint32_t resv; + volatile uint32_t channel_status; + uint32_t impStatus; + uint32_t imp_crc; + uint32_t channel_flags; + uint32_t length; + uint32_t header; + uint32_t payload[SCMI_BUFFER_PAYLOAD / 4u]; +} smt_buf_t; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static smt_chn_config_t g_smtconfig[SCMI_MAX_CHN]; +static struct imx9_mu_dev_s *g_mudev; +static spinlock_t g_lock = SP_UNLOCKED; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static uint32_t imx9_crcxor(const uint32_t *addr, uint32_t size) +{ + const uint32_t *a = addr; + uint32_t sz = size; + uint32_t crc = 0u; + + /* Loop over data */ + + while (sz > 0u) + { + /* Update CRC */ + + crc ^= *a; + a++; + sz--; + } + + /* Return CRC */ + + return crc; +} + +static uint32_t imx9_crc32(const uint8_t *addr, uint32_t size) +{ + const uint8_t *a = addr; + uint32_t sz = size; + uint32_t crc = 0u; + + /* Poly table */ + + static uint32_t const crc_table[] = + + { + 0x4dbdf21cu, 0x500ae278u, 0x76d3d2d4u, 0x6b64c2b0u, + 0x3b61b38cu, 0x26d6a3e8u, 0x000f9344u, 0x1db88320u, + 0xa005713cu, 0xbdb26158u, 0x9b6b51f4u, 0x86dc4190u, + 0xd6d930acu, 0xcb6e20c8u, 0xedb71064u, 0xf0000000u + }; + + /* Loop over data */ + + while (sz > 0u) + { + crc = (crc >> 4u) ^ + crc_table[(crc ^ (((uint32_t)(*a)) >> 0u)) & 0x0fu]; + crc = (crc >> 4u) ^ + crc_table[(crc ^ (((uint32_t)(*a)) >> 4u)) & 0x0fu]; + a++; + sz--; + } + + /* Return CRC */ + + return crc; +} + +static smt_buf_t *imx9_smt_smaget(uint32_t smtchannel) +{ + smt_buf_t *rtn = NULL; + + /* Check channel */ + + if ((smtchannel < SCMI_MAX_CHN) && (g_smtconfig[smtchannel].valid)) + { + uint8_t db = g_smtconfig[smtchannel].mb_doorbell; + + uintptr_t shared_memory_address + = g_smtconfig[smtchannel].shared_memory_address; + + /* Allow use of internal MU SRAM */ + + if (shared_memory_address == 0u) + { + shared_memory_address = IMX9_MU2_MUA_BASE + 0x1000u; + } + + /* Apply channel spacing */ + + shared_memory_address += ((uint32_t)db) * SCMI_BUFFER_SIZE; Review Comment: done -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org