Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/clk/sophgo/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 10 kB image not shown  

Quelle  clk-sg2042-rpgate.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Sophgo SG2042 RP clock Driver
 *
 * Copyright (C) 2024 Sophgo Technology Inc.
 * Copyright (C) 2024 Chen Wang <unicorn_wang@outlook.com>
 */


#include <linux/array_size.h>
#include <linux/clk-provider.h>
#include <linux/platform_device.h>

#include <dt-bindings/clock/sophgo,sg2042-rpgate.h>

#include "clk-sg2042.h"

#define R_SYSGATE_BEGIN  0x0368
#define R_RP_RXU_CLK_ENABLE (0x0368 - R_SYSGATE_BEGIN)
#define R_MP0_STATUS_REG (0x0380 - R_SYSGATE_BEGIN)
#define R_MP0_CONTROL_REG (0x0384 - R_SYSGATE_BEGIN)
#define R_MP1_STATUS_REG (0x0388 - R_SYSGATE_BEGIN)
#define R_MP1_CONTROL_REG (0x038C - R_SYSGATE_BEGIN)
#define R_MP2_STATUS_REG (0x0390 - R_SYSGATE_BEGIN)
#define R_MP2_CONTROL_REG (0x0394 - R_SYSGATE_BEGIN)
#define R_MP3_STATUS_REG (0x0398 - R_SYSGATE_BEGIN)
#define R_MP3_CONTROL_REG (0x039C - R_SYSGATE_BEGIN)
#define R_MP4_STATUS_REG (0x03A0 - R_SYSGATE_BEGIN)
#define R_MP4_CONTROL_REG (0x03A4 - R_SYSGATE_BEGIN)
#define R_MP5_STATUS_REG (0x03A8 - R_SYSGATE_BEGIN)
#define R_MP5_CONTROL_REG (0x03AC - R_SYSGATE_BEGIN)
#define R_MP6_STATUS_REG (0x03B0 - R_SYSGATE_BEGIN)
#define R_MP6_CONTROL_REG (0x03B4 - R_SYSGATE_BEGIN)
#define R_MP7_STATUS_REG (0x03B8 - R_SYSGATE_BEGIN)
#define R_MP7_CONTROL_REG (0x03BC - R_SYSGATE_BEGIN)
#define R_MP8_STATUS_REG (0x03C0 - R_SYSGATE_BEGIN)
#define R_MP8_CONTROL_REG (0x03C4 - R_SYSGATE_BEGIN)
#define R_MP9_STATUS_REG (0x03C8 - R_SYSGATE_BEGIN)
#define R_MP9_CONTROL_REG (0x03CC - R_SYSGATE_BEGIN)
#define R_MP10_STATUS_REG (0x03D0 - R_SYSGATE_BEGIN)
#define R_MP10_CONTROL_REG (0x03D4 - R_SYSGATE_BEGIN)
#define R_MP11_STATUS_REG (0x03D8 - R_SYSGATE_BEGIN)
#define R_MP11_CONTROL_REG (0x03DC - R_SYSGATE_BEGIN)
#define R_MP12_STATUS_REG (0x03E0 - R_SYSGATE_BEGIN)
#define R_MP12_CONTROL_REG (0x03E4 - R_SYSGATE_BEGIN)
#define R_MP13_STATUS_REG (0x03E8 - R_SYSGATE_BEGIN)
#define R_MP13_CONTROL_REG (0x03EC - R_SYSGATE_BEGIN)
#define R_MP14_STATUS_REG (0x03F0 - R_SYSGATE_BEGIN)
#define R_MP14_CONTROL_REG (0x03F4 - R_SYSGATE_BEGIN)
#define R_MP15_STATUS_REG (0x03F8 - R_SYSGATE_BEGIN)
#define R_MP15_CONTROL_REG (0x03FC - R_SYSGATE_BEGIN)

/**
 * struct sg2042_rpgate_clock - Gate clock for RP(riscv processors) subsystem
 * @hw: clk_hw for initialization
 * @id: used to map clk_onecell_data
 * @offset_enable: offset of gate enable registers
 * @bit_idx: which bit in the register controls gating of this clock
 */

struct sg2042_rpgate_clock {
 struct clk_hw hw;

 unsigned int id;

 u32 offset_enable;
 u8 bit_idx;
};

/*
 * Clock initialization macro naming rules:
 * FW: use CLK_HW_INIT_FW_NAME
 */

#define SG2042_GATE_FW(_id, _name, _parent, _flags, \
         _r_enable, _bit_idx) {  \
  .hw.init = CLK_HW_INIT_FW_NAME(  \
    _name,   \
    _parent,  \
    NULL,   \
    _flags),  \
  .id = _id,    \
  .offset_enable = _r_enable,  \
  .bit_idx = _bit_idx,   \
 }

/*
 * Gate clocks for RP subsystem (including the MP subsystem), which control
 * registers are defined in SYS_CTRL.
 */

static const struct sg2042_rpgate_clock sg2042_gate_rp[] = {
 /* downstream of clk_gate_rp_cpu_normal about rxu */
 SG2042_GATE_FW(GATE_CLK_RXU0, "clk_gate_rxu0""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 0),
 SG2042_GATE_FW(GATE_CLK_RXU1, "clk_gate_rxu1""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 1),
 SG2042_GATE_FW(GATE_CLK_RXU2, "clk_gate_rxu2""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 2),
 SG2042_GATE_FW(GATE_CLK_RXU3, "clk_gate_rxu3""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 3),
 SG2042_GATE_FW(GATE_CLK_RXU4, "clk_gate_rxu4""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 4),
 SG2042_GATE_FW(GATE_CLK_RXU5, "clk_gate_rxu5""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 5),
 SG2042_GATE_FW(GATE_CLK_RXU6, "clk_gate_rxu6""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 6),
 SG2042_GATE_FW(GATE_CLK_RXU7, "clk_gate_rxu7""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 7),
 SG2042_GATE_FW(GATE_CLK_RXU8, "clk_gate_rxu8""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 8),
 SG2042_GATE_FW(GATE_CLK_RXU9, "clk_gate_rxu9""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 9),
 SG2042_GATE_FW(GATE_CLK_RXU10, "clk_gate_rxu10""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 10),
 SG2042_GATE_FW(GATE_CLK_RXU11, "clk_gate_rxu11""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 11),
 SG2042_GATE_FW(GATE_CLK_RXU12, "clk_gate_rxu12""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 12),
 SG2042_GATE_FW(GATE_CLK_RXU13, "clk_gate_rxu13""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 13),
 SG2042_GATE_FW(GATE_CLK_RXU14, "clk_gate_rxu14""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 14),
 SG2042_GATE_FW(GATE_CLK_RXU15, "clk_gate_rxu15""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 15),
 SG2042_GATE_FW(GATE_CLK_RXU16, "clk_gate_rxu16""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 16),
 SG2042_GATE_FW(GATE_CLK_RXU17, "clk_gate_rxu17""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 17),
 SG2042_GATE_FW(GATE_CLK_RXU18, "clk_gate_rxu18""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 18),
 SG2042_GATE_FW(GATE_CLK_RXU19, "clk_gate_rxu19""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 19),
 SG2042_GATE_FW(GATE_CLK_RXU20, "clk_gate_rxu20""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 20),
 SG2042_GATE_FW(GATE_CLK_RXU21, "clk_gate_rxu21""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 21),
 SG2042_GATE_FW(GATE_CLK_RXU22, "clk_gate_rxu22""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 22),
 SG2042_GATE_FW(GATE_CLK_RXU23, "clk_gate_rxu23""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 23),
 SG2042_GATE_FW(GATE_CLK_RXU24, "clk_gate_rxu24""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 24),
 SG2042_GATE_FW(GATE_CLK_RXU25, "clk_gate_rxu25""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 25),
 SG2042_GATE_FW(GATE_CLK_RXU26, "clk_gate_rxu26""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 26),
 SG2042_GATE_FW(GATE_CLK_RXU27, "clk_gate_rxu27""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 27),
 SG2042_GATE_FW(GATE_CLK_RXU28, "clk_gate_rxu28""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 28),
 SG2042_GATE_FW(GATE_CLK_RXU29, "clk_gate_rxu29""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 29),
 SG2042_GATE_FW(GATE_CLK_RXU30, "clk_gate_rxu30""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 30),
 SG2042_GATE_FW(GATE_CLK_RXU31, "clk_gate_rxu31""rpgate",
         0, R_RP_RXU_CLK_ENABLE, 31),

 /* downstream of clk_gate_rp_cpu_normal about mp */
 SG2042_GATE_FW(GATE_CLK_MP0, "clk_gate_mp0""rpgate",
         CLK_IS_CRITICAL, R_MP0_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP1, "clk_gate_mp1""rpgate",
         CLK_IS_CRITICAL, R_MP1_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP2, "clk_gate_mp2""rpgate",
         CLK_IS_CRITICAL, R_MP2_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP3, "clk_gate_mp3""rpgate",
         CLK_IS_CRITICAL, R_MP3_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP4, "clk_gate_mp4""rpgate",
         CLK_IS_CRITICAL, R_MP4_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP5, "clk_gate_mp5""rpgate",
         CLK_IS_CRITICAL, R_MP5_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP6, "clk_gate_mp6""rpgate",
         CLK_IS_CRITICAL, R_MP6_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP7, "clk_gate_mp7""rpgate",
         CLK_IS_CRITICAL, R_MP7_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP8, "clk_gate_mp8""rpgate",
         CLK_IS_CRITICAL, R_MP8_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP9, "clk_gate_mp9""rpgate",
         CLK_IS_CRITICAL, R_MP9_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP10, "clk_gate_mp10""rpgate",
         CLK_IS_CRITICAL, R_MP10_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP11, "clk_gate_mp11""rpgate",
         CLK_IS_CRITICAL, R_MP11_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP12, "clk_gate_mp12""rpgate",
         CLK_IS_CRITICAL, R_MP12_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP13, "clk_gate_mp13""rpgate",
         CLK_IS_CRITICAL, R_MP13_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP14, "clk_gate_mp14""rpgate",
         CLK_IS_CRITICAL, R_MP14_CONTROL_REG, 0),
 SG2042_GATE_FW(GATE_CLK_MP15, "clk_gate_mp15""rpgate",
         CLK_IS_CRITICAL, R_MP15_CONTROL_REG, 0),
};

static DEFINE_SPINLOCK(sg2042_clk_lock);

static int sg2042_clk_register_rpgates(struct device *dev,
           struct sg2042_clk_data *clk_data,
           const struct sg2042_rpgate_clock gate_clks[],
           int num_gate_clks)
{
 const struct sg2042_rpgate_clock *gate;
 struct clk_hw *hw;
 int i, ret = 0;

 for (i = 0; i < num_gate_clks; i++) {
  gate = &gate_clks[i];
  hw = devm_clk_hw_register_gate_parent_data
   (dev,
    gate->hw.init->name,
    gate->hw.init->parent_data,
    gate->hw.init->flags,
    clk_data->iobase + gate->offset_enable,
    gate->bit_idx,
    0,
    &sg2042_clk_lock);
  if (IS_ERR(hw)) {
   pr_err("failed to register clock %s\n", gate->hw.init->name);
   ret = PTR_ERR(hw);
   break;
  }

  clk_data->onecell_data.hws[gate->id] = hw;
 }

 return ret;
}

static int sg2042_init_clkdata(struct platform_device *pdev,
          int num_clks,
          struct sg2042_clk_data **pp_clk_data)
{
 struct sg2042_clk_data *clk_data;

 clk_data = devm_kzalloc(&pdev->dev,
    struct_size(clk_data, onecell_data.hws, num_clks),
    GFP_KERNEL);
 if (!clk_data)
  return -ENOMEM;

 clk_data->iobase = devm_platform_ioremap_resource(pdev, 0);
 if (WARN_ON(IS_ERR(clk_data->iobase)))
  return PTR_ERR(clk_data->iobase);

 clk_data->onecell_data.num = num_clks;

 *pp_clk_data = clk_data;

 return 0;
}

static int sg2042_rpgate_probe(struct platform_device *pdev)
{
 struct sg2042_clk_data *clk_data = NULL;
 int num_clks;
 int ret;

 num_clks = ARRAY_SIZE(sg2042_gate_rp);

 ret = sg2042_init_clkdata(pdev, num_clks, &clk_data);
 if (ret)
  goto error_out;

 ret = sg2042_clk_register_rpgates(&pdev->dev, clk_data, sg2042_gate_rp,
       num_clks);
 if (ret)
  goto error_out;

 return devm_of_clk_add_hw_provider(&pdev->dev,
        of_clk_hw_onecell_get,
        &clk_data->onecell_data);

error_out:
 pr_err("%s failed error number %d\n", __func__, ret);
 return ret;
}

static const struct of_device_id sg2042_rpgate_match[] = {
 { .compatible = "sophgo,sg2042-rpgate" },
 { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sg2042_rpgate_match);

static struct platform_driver sg2042_rpgate_driver = {
 .probe = sg2042_rpgate_probe,
 .driver = {
  .name = "clk-sophgo-sg2042-rpgate",
  .of_match_table = sg2042_rpgate_match,
  .suppress_bind_attrs = true,
 },
};
module_platform_driver(sg2042_rpgate_driver);

MODULE_AUTHOR("Chen Wang");
MODULE_DESCRIPTION("Sophgo SG2042 rp subsystem clock driver");
MODULE_LICENSE("GPL");

Messung V0.5
C=96 H=91 G=93

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.