Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/third_party/rust/h2/src/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 1 kB image not shown  

Quelle  starfive_starlink_cache.c   Sprache: unbekannt

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Cache Management Operations for StarFive's Starlink cache controller
 *
 * Copyright (C) 2024 Shanghai StarFive Technology Co., Ltd.
 *
 * Author: Joshua Yeong <joshua.yeong@starfivetech.com>
 */


#include <linux/bitfield.h>
#include <linux/cacheflush.h>
#include <linux/iopoll.h>
#include <linux/of_address.h>

#include <asm/dma-noncoherent.h>

#define STARLINK_CACHE_FLUSH_START_ADDR   0x0
#define STARLINK_CACHE_FLUSH_END_ADDR   0x8
#define STARLINK_CACHE_FLUSH_CTL   0x10
#define STARLINK_CACHE_ALIGN    0x40

#define STARLINK_CACHE_ADDRESS_RANGE_MASK  GENMASK(39, 0)
#define STARLINK_CACHE_FLUSH_CTL_MODE_MASK  GENMASK(2, 1)
#define STARLINK_CACHE_FLUSH_CTL_ENABLE_MASK  BIT(0)

#define STARLINK_CACHE_FLUSH_CTL_CLEAN_INVALIDATE 0
#define STARLINK_CACHE_FLUSH_CTL_MAKE_INVALIDATE 1
#define STARLINK_CACHE_FLUSH_CTL_CLEAN_SHARED  2
#define STARLINK_CACHE_FLUSH_POLL_DELAY_US  1
#define STARLINK_CACHE_FLUSH_TIMEOUT_US   5000000

static void __iomem *starlink_cache_base;

static void starlink_cache_flush_complete(void)
{
 volatile void __iomem *ctl = starlink_cache_base + STARLINK_CACHE_FLUSH_CTL;
 u64 v;
 int ret;

 ret = readq_poll_timeout_atomic(ctl, v, !(v & STARLINK_CACHE_FLUSH_CTL_ENABLE_MASK),
     STARLINK_CACHE_FLUSH_POLL_DELAY_US,
     STARLINK_CACHE_FLUSH_TIMEOUT_US);
 if (ret)
  WARN(1, "StarFive Starlink cache flush operation timeout\n");
}

static void starlink_cache_dma_cache_wback(phys_addr_t paddr, unsigned long size)
{
 writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, paddr),
        starlink_cache_base + STARLINK_CACHE_FLUSH_START_ADDR);
 writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, paddr + size),
        starlink_cache_base + STARLINK_CACHE_FLUSH_END_ADDR);

 mb();
 writeq(FIELD_PREP(STARLINK_CACHE_FLUSH_CTL_MODE_MASK,
     STARLINK_CACHE_FLUSH_CTL_CLEAN_SHARED),
        starlink_cache_base + STARLINK_CACHE_FLUSH_CTL);

 starlink_cache_flush_complete();
}

static void starlink_cache_dma_cache_invalidate(phys_addr_t paddr, unsigned long size)
{
 writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, paddr),
        starlink_cache_base + STARLINK_CACHE_FLUSH_START_ADDR);
 writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, paddr + size),
        starlink_cache_base + STARLINK_CACHE_FLUSH_END_ADDR);

 mb();
 writeq(FIELD_PREP(STARLINK_CACHE_FLUSH_CTL_MODE_MASK,
     STARLINK_CACHE_FLUSH_CTL_MAKE_INVALIDATE),
        starlink_cache_base + STARLINK_CACHE_FLUSH_CTL);

 starlink_cache_flush_complete();
}

static void starlink_cache_dma_cache_wback_inv(phys_addr_t paddr, unsigned long size)
{
 writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, paddr),
        starlink_cache_base + STARLINK_CACHE_FLUSH_START_ADDR);
 writeq(FIELD_PREP(STARLINK_CACHE_ADDRESS_RANGE_MASK, paddr + size),
        starlink_cache_base + STARLINK_CACHE_FLUSH_END_ADDR);

 mb();
 writeq(FIELD_PREP(STARLINK_CACHE_FLUSH_CTL_MODE_MASK,
     STARLINK_CACHE_FLUSH_CTL_CLEAN_INVALIDATE),
        starlink_cache_base + STARLINK_CACHE_FLUSH_CTL);

 starlink_cache_flush_complete();
}

static const struct riscv_nonstd_cache_ops starlink_cache_ops = {
 .wback = &starlink_cache_dma_cache_wback,
 .inv = &starlink_cache_dma_cache_invalidate,
 .wback_inv = &starlink_cache_dma_cache_wback_inv,
};

static const struct of_device_id starlink_cache_ids[] = {
 { .compatible = "starfive,jh8100-starlink-cache" },
 { /* sentinel */ }
};

static int __init starlink_cache_init(void)
{
 struct device_node *np;
 u32 block_size;
 int ret;

 np = of_find_matching_node(NULL, starlink_cache_ids);
 if (!of_device_is_available(np))
  return -ENODEV;

 ret = of_property_read_u32(np, "cache-block-size", &block_size);
 if (ret)
  return ret;

 if (block_size % STARLINK_CACHE_ALIGN)
  return -EINVAL;

 starlink_cache_base = of_iomap(np, 0);
 if (!starlink_cache_base)
  return -ENOMEM;

 riscv_cbom_block_size = block_size;
 riscv_noncoherent_supported();
 riscv_noncoherent_register_cache_ops(&starlink_cache_ops);

 return 0;
}
arch_initcall(starlink_cache_init);

Messung V0.5
C=95 H=95 G=94

[ Dauer der Verarbeitung: 0.7 Sekunden  (vorverarbeitet)  ]