uboot/drivers/firmware/scmi/smccc_agent.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2020 Linaro Limited.
   4 */
   5
   6#define LOG_CATEGORY UCLASS_SCMI_AGENT
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <errno.h>
  11#include <scmi_agent.h>
  12#include <scmi_agent-uclass.h>
  13#include <dm/devres.h>
  14#include <dm/device_compat.h>
  15#include <dm/device-internal.h>
  16#include <linux/arm-smccc.h>
  17#include <linux/compat.h>
  18
  19#include "smt.h"
  20
  21#define SMCCC_RET_NOT_SUPPORTED         ((unsigned long)-1)
  22
  23/**
  24 * struct scmi_smccc_channel - Description of an SCMI SMCCC transport
  25 * @func_id:    SMCCC function ID used by the SCMI transport
  26 * @smt:        Shared memory buffer
  27 */
  28struct scmi_smccc_channel {
  29        ulong func_id;
  30        struct scmi_smt smt;
  31};
  32
  33static int scmi_smccc_process_msg(struct udevice *dev, struct scmi_msg *msg)
  34{
  35        struct scmi_smccc_channel *chan = dev_get_priv(dev);
  36        struct arm_smccc_res res;
  37        int ret;
  38
  39        ret = scmi_write_msg_to_smt(dev, &chan->smt, msg);
  40        if (ret)
  41                return ret;
  42
  43        arm_smccc_smc(chan->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
  44        if (res.a0 == SMCCC_RET_NOT_SUPPORTED)
  45                ret = -ENXIO;
  46        else
  47                ret = scmi_read_resp_from_smt(dev, &chan->smt, msg);
  48
  49        scmi_clear_smt_channel(&chan->smt);
  50
  51        return ret;
  52}
  53
  54static int scmi_smccc_probe(struct udevice *dev)
  55{
  56        struct scmi_smccc_channel *chan = dev_get_priv(dev);
  57        u32 func_id;
  58        int ret;
  59
  60        if (dev_read_u32(dev, "arm,smc-id", &func_id)) {
  61                dev_err(dev, "Missing property func-id\n");
  62                return -EINVAL;
  63        }
  64
  65        chan->func_id = func_id;
  66
  67        ret = scmi_dt_get_smt_buffer(dev, &chan->smt);
  68        if (ret) {
  69                dev_err(dev, "Failed to get smt resources: %d\n", ret);
  70                return ret;
  71        }
  72
  73        return 0;
  74}
  75
  76static const struct udevice_id scmi_smccc_ids[] = {
  77        { .compatible = "arm,scmi-smc" },
  78        { }
  79};
  80
  81static const struct scmi_agent_ops scmi_smccc_ops = {
  82        .process_msg = scmi_smccc_process_msg,
  83};
  84
  85U_BOOT_DRIVER(scmi_smccc) = {
  86        .name           = "scmi-over-smccc",
  87        .id             = UCLASS_SCMI_AGENT,
  88        .of_match       = scmi_smccc_ids,
  89        .priv_auto      = sizeof(struct scmi_smccc_channel),
  90        .probe          = scmi_smccc_probe,
  91        .ops            = &scmi_smccc_ops,
  92};
  93