uboot/drivers/reset/reset-zynqmp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2021 Xilinx, Inc. - Michal Simek
   4 */
   5
   6#define LOG_CATEGORY UCLASS_RESET
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <dm/device_compat.h>
  11#include <reset-uclass.h>
  12#include <zynqmp_firmware.h>
  13
  14#define ZYNQMP_NR_RESETS        (ZYNQMP_PM_RESET_END - ZYNQMP_PM_RESET_START)
  15#define ZYNQMP_RESET_ID         ZYNQMP_PM_RESET_START
  16
  17struct zynqmp_reset_priv {
  18        u32 reset_id;
  19        u32 nr_reset;
  20};
  21
  22static int zynqmp_pm_reset_assert(const u32 reset,
  23                                  const enum zynqmp_pm_reset_action assert_flag)
  24{
  25        return xilinx_pm_request(PM_RESET_ASSERT, reset, assert_flag, 0, 0,
  26                                 NULL);
  27}
  28
  29static int zynqmp_reset_assert(struct reset_ctl *rst)
  30{
  31        struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
  32
  33        dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id);
  34
  35        return zynqmp_pm_reset_assert(priv->reset_id + rst->id,
  36                                      PM_RESET_ACTION_ASSERT);
  37}
  38
  39static int zynqmp_reset_deassert(struct reset_ctl *rst)
  40{
  41        struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
  42
  43        dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id);
  44
  45        return zynqmp_pm_reset_assert(priv->reset_id + rst->id,
  46                                      PM_RESET_ACTION_RELEASE);
  47}
  48
  49static int zynqmp_reset_request(struct reset_ctl *rst)
  50{
  51        struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
  52
  53        dev_dbg(rst->dev, "%s(rst=%p) (id=%lu) (nr_reset=%d)\n", __func__,
  54                rst, rst->id, priv->nr_reset);
  55
  56        if (rst->id > priv->nr_reset)
  57                return -EINVAL;
  58
  59        return 0;
  60}
  61
  62static int zynqmp_reset_free(struct reset_ctl *rst)
  63{
  64        struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev);
  65
  66        dev_dbg(rst->dev, "%s(rst=%p) (id=%lu) (nr_reset=%d)\n", __func__,
  67                rst, rst->id, priv->nr_reset);
  68
  69        return 0;
  70}
  71
  72static int zynqmp_reset_probe(struct udevice *dev)
  73{
  74        struct zynqmp_reset_priv *priv = dev_get_priv(dev);
  75
  76        priv->reset_id = ZYNQMP_RESET_ID;
  77        priv->nr_reset = ZYNQMP_NR_RESETS;
  78        return 0;
  79}
  80
  81const struct reset_ops zynqmp_reset_ops = {
  82        .request = zynqmp_reset_request,
  83        .rfree = zynqmp_reset_free,
  84        .rst_assert = zynqmp_reset_assert,
  85        .rst_deassert = zynqmp_reset_deassert,
  86};
  87
  88static const struct udevice_id zynqmp_reset_ids[] = {
  89        { .compatible = "xlnx,zynqmp-reset" },
  90        { }
  91};
  92
  93U_BOOT_DRIVER(zynqmp_reset) = {
  94        .name           = "zynqmp_reset",
  95        .id             = UCLASS_RESET,
  96        .of_match       = zynqmp_reset_ids,
  97        .ops            = &zynqmp_reset_ops,
  98        .probe          = zynqmp_reset_probe,
  99        .priv_auto      = sizeof(struct zynqmp_reset_priv),
 100};
 101