uboot/arch/arm/mach-mvebu/system-controller.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2// (C) 2021 Pali Rohár <pali@kernel.org>
   3
   4#include <common.h>
   5#include <dm.h>
   6#include <reset-uclass.h>
   7#include <asm/io.h>
   8
   9#define MVEBU_SOC_CONTROL_1_REG 0x4
  10
  11#define MVEBU_PCIE_ID 0
  12
  13struct mvebu_reset_data {
  14        void *base;
  15};
  16
  17static int mvebu_reset_of_xlate(struct reset_ctl *rst,
  18                                struct ofnode_phandle_args *args)
  19{
  20        if (args->args_count < 2)
  21                return -EINVAL;
  22
  23        rst->id = args->args[0];
  24        rst->data = args->args[1];
  25
  26        /* Currently only PCIe is implemented */
  27        if (rst->id != MVEBU_PCIE_ID)
  28                return -EINVAL;
  29
  30        /* Four PCIe enable bits are shared across more PCIe links */
  31        if (!(rst->data >= 0 && rst->data <= 3))
  32                return -EINVAL;
  33
  34        return 0;
  35}
  36
  37static int mvebu_reset_request(struct reset_ctl *rst)
  38{
  39        return 0;
  40}
  41
  42static int mvebu_reset_free(struct reset_ctl *rst)
  43{
  44        return 0;
  45}
  46
  47static int mvebu_reset_assert(struct reset_ctl *rst)
  48{
  49        struct mvebu_reset_data *data = dev_get_priv(rst->dev);
  50
  51        clrbits_32(data->base + MVEBU_SOC_CONTROL_1_REG, BIT(rst->data));
  52        return 0;
  53}
  54
  55static int mvebu_reset_deassert(struct reset_ctl *rst)
  56{
  57        struct mvebu_reset_data *data = dev_get_priv(rst->dev);
  58
  59        setbits_32(data->base + MVEBU_SOC_CONTROL_1_REG, BIT(rst->data));
  60        return 0;
  61}
  62
  63static int mvebu_reset_status(struct reset_ctl *rst)
  64{
  65        struct mvebu_reset_data *data = dev_get_priv(rst->dev);
  66
  67        return !(readl(data->base + MVEBU_SOC_CONTROL_1_REG) & BIT(rst->data));
  68}
  69
  70static int mvebu_reset_of_to_plat(struct udevice *dev)
  71{
  72        struct mvebu_reset_data *data = dev_get_priv(dev);
  73
  74        data->base = dev_read_addr_ptr(dev);
  75        if (!data->base)
  76                return -EINVAL;
  77
  78        return 0;
  79}
  80
  81static const struct udevice_id mvebu_reset_of_match[] = {
  82        { .compatible = "marvell,armada-370-xp-system-controller" },
  83        { .compatible = "marvell,armada-375-system-controller" },
  84        { .compatible = "marvell,armada-380-system-controller" },
  85        { .compatible = "marvell,armada-390-system-controller" },
  86        { },
  87};
  88
  89static const struct reset_ops mvebu_reset_ops = {
  90        .of_xlate = mvebu_reset_of_xlate,
  91        .request = mvebu_reset_request,
  92        .rfree = mvebu_reset_free,
  93        .rst_assert = mvebu_reset_assert,
  94        .rst_deassert = mvebu_reset_deassert,
  95        .rst_status = mvebu_reset_status,
  96};
  97
  98U_BOOT_DRIVER(mvebu_reset) = {
  99        .name = "mvebu-reset",
 100        .id = UCLASS_RESET,
 101        .of_match = mvebu_reset_of_match,
 102        .of_to_plat = mvebu_reset_of_to_plat,
 103        .priv_auto = sizeof(struct mvebu_reset_data),
 104        .ops = &mvebu_reset_ops,
 105};
 106