// SPDX-License-Identifier: GPL-2.0
/*
* SAMA7D65 PMC code.
*
* Copyright (C) 2024 Microchip Technology Inc. and its subsidiaries
*
* Author: Ryan Wanner <ryan.wanner@microchip.com>
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/mfd/syscon.h>
#include <linux/slab.h>
#include <dt-bindings/clock/at91.h>
#include "pmc.h"
static DEFINE_SPINLOCK(pmc_pll_lock);
static DEFINE_SPINLOCK(pmc_mck0_lock);
static DEFINE_SPINLOCK(pmc_mckX_lock);
#define PMC_INDEX_MAX 25
/*
* PLL clocks identifiers
* @PLL_ID_CPU: CPU PLL identifier
* @PLL_ID_SYS: System PLL identifier
* @PLL_ID_DDR: DDR PLL identifier
* @PLL_ID_GPU: Graphics subsystem PLL identifier
* @PLL_ID_BAUD: Baud PLL identifier
* @PLL_ID_AUDIO: Audio PLL identifier
* @PLL_ID_ETH: Ethernet PLL identifier
* @PLL_ID_LVDS: LVDS PLL identifier
* @PLL_ID_USB: USB PLL identifier
*/
enum pll_ids {
PLL_ID_CPU,
PLL_ID_SYS,
PLL_ID_DDR,
PLL_ID_GPU,
PLL_ID_BAUD,
PLL_ID_AUDIO,
PLL_ID_ETH,
PLL_ID_LVDS,
PLL_ID_USB,
PLL_ID_MAX
};
/*
* PLL component identifier
* @PLL_COMPID_FRAC: Fractional PLL component identifier
* @PLL_COMPID_DIV0: 1st PLL divider component identifier
* @PLL_COMPID_DIV1: 2nd PLL divider component identifier
*/
enum pll_component_id {
PLL_COMPID_FRAC,
PLL_COMPID_DIV0,
PLL_COMPID_DIV1,
PLL_COMPID_MAX
};
/*
* PLL type identifiers
* @PLL_TYPE_FRAC: fractional PLL identifier
* @PLL_TYPE_DIV: divider PLL identifier
*/
enum pll_type {
PLL_TYPE_FRAC,
PLL_TYPE_DIV
};
/* Layout for fractional PLLs. */
static const struct clk_pll_layout pll_layout_frac = {
.mul_mask = GENMASK(31, 24),
.frac_mask = GENMASK(21, 0),
.mul_shift = 24,
.frac_shift = 0,
};
/* Layout for DIVPMC dividers. */
static const struct clk_pll_layout pll_layout_divpmc = {
.div_mask = GENMASK(7, 0),
.endiv_mask = BIT(29),
.div_shift = 0,
.endiv_shift = 29,
};
/* Layout for DIVIO dividers. */
static const struct clk_pll_layout pll_layout_divio = {
.div_mask = GENMASK(19, 12