drivers: clock_control: microchip: add drivers for sama7g5 PMC
Initialize the configurations for PMC driver. Add implement of the API for PMC clocks. Signed-off-by: Tony Han <tony.han@microchip.com>
This commit is contained in:
@@ -27,6 +27,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_DRIVER_CALIBRATION nrf_clo
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RV32M1_PCC clock_control_rv32m1_pcc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_INFINEON_CAT1 clock_control_ifx_cat1.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SAM clock_control_sam_pmc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SAMA7G5 clock_control_sama7g5_pmc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SILABS_SIWX91X clock_control_silabs_siwx91x.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SILABS_SERIES clock_control_silabs_series.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SI32_PLL clock_control_si32_pll.c)
|
||||
|
||||
@@ -7,3 +7,10 @@ config CLOCK_CONTROL_SAM
|
||||
depends on DT_HAS_ATMEL_SAM_PMC_ENABLED
|
||||
help
|
||||
Enable driver for Atmel SAM Clock Control.
|
||||
|
||||
config CLOCK_CONTROL_SAMA7G5
|
||||
bool "Microchip SAMA7G5 Power Management Controller (PMC)"
|
||||
default y
|
||||
depends on DT_HAS_MICROCHIP_SAM_PMC_ENABLED
|
||||
help
|
||||
Enable driver for Microchip SAMA7G5 Power Management Controller (PMC).
|
||||
|
||||
141
drivers/clock_control/clock_control_sama7g5_pmc.c
Normal file
141
drivers/clock_control/clock_control_sama7g5_pmc.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT microchip_sam_pmc
|
||||
|
||||
#include <pmc.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/clock_control/mchp_sam_pmc.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(pmc, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
|
||||
|
||||
static int get_pmc_clk(const struct device *dev, clock_control_subsys_t sys,
|
||||
struct device **clk)
|
||||
{
|
||||
const struct sam_clk_cfg *cfg = (const struct sam_clk_cfg *)sys;
|
||||
const struct sam_pmc_data *data = dev->data;
|
||||
|
||||
if (cfg == NULL || data == NULL) {
|
||||
LOG_ERR("The PMC config and data can not be NULL.");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
LOG_DBG("Type: %x, Id: %d", cfg->clock_type, cfg->clock_id);
|
||||
|
||||
*clk = sam_pmc_get_clock(cfg, data->pmc);
|
||||
if (*clk) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG_ERR("The PMC clock type is not implemented.");
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int sam_clock_control_on(const struct device *dev,
|
||||
clock_control_subsys_t sys)
|
||||
{
|
||||
struct device *clk;
|
||||
int ret = get_pmc_clk(dev, sys, &clk);
|
||||
|
||||
if (!ret) {
|
||||
return clock_control_on(clk, sys);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sam_clock_control_off(const struct device *dev,
|
||||
clock_control_subsys_t sys)
|
||||
{
|
||||
struct device *clk;
|
||||
int ret = get_pmc_clk(dev, sys, &clk);
|
||||
|
||||
if (!ret) {
|
||||
return clock_control_off(clk, sys);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sam_clock_control_get_rate(const struct device *dev,
|
||||
clock_control_subsys_t sys,
|
||||
uint32_t *rate)
|
||||
{
|
||||
struct device *clk;
|
||||
int ret = get_pmc_clk(dev, sys, &clk);
|
||||
|
||||
if (!ret) {
|
||||
return clock_control_get_rate(clk, sys, rate);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static enum clock_control_status
|
||||
sam_clock_control_get_status(const struct device *dev,
|
||||
clock_control_subsys_t sys)
|
||||
{
|
||||
struct device *clk;
|
||||
int ret = get_pmc_clk(dev, sys, &clk);
|
||||
|
||||
if (!ret) {
|
||||
return clock_control_get_status(clk, sys);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clock_control_sam_pmc_init(const struct device *dev)
|
||||
{
|
||||
sam_pmc_setup(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_API(clock_control, sam_clock_control_api) = {
|
||||
.on = sam_clock_control_on,
|
||||
.off = sam_clock_control_off,
|
||||
.get_rate = sam_clock_control_get_rate,
|
||||
.get_status = sam_clock_control_get_status,
|
||||
};
|
||||
|
||||
#define PMC_INIT_CFG_SLCK(n, slck) \
|
||||
COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(n, slck), \
|
||||
( \
|
||||
.slck = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(n, slck)), \
|
||||
.slck##_cfg = { \
|
||||
.crystal_osc = DT_INST_CLOCKS_CELL_BY_NAME(n, slck, \
|
||||
clock_crystal_osc), \
|
||||
}, \
|
||||
), ())
|
||||
|
||||
#define PMC_INIT_CFG_CLK(n, clk) \
|
||||
COND_CODE_1(DT_INST_CLOCKS_HAS_NAME(n, clk), \
|
||||
( \
|
||||
.clk = DEVICE_DT_GET(DT_CLOCKS_CTLR_BY_NAME(DT_DRV_INST(n), clk)), \
|
||||
), ())
|
||||
|
||||
#define PMC_CFG_DEFN(n) \
|
||||
static const struct sam_pmc_cfg pmc##n##_cfg = { \
|
||||
.reg = (uint32_t *)DT_INST_REG_ADDR(n), \
|
||||
PMC_INIT_CFG_SLCK(n, td_slck) \
|
||||
PMC_INIT_CFG_SLCK(n, md_slck) \
|
||||
PMC_INIT_CFG_CLK(n, main_xtal) \
|
||||
}
|
||||
#define SAM_PMC_DEVICE_INIT(n) \
|
||||
static struct sam_pmc_data pmc##n##data; \
|
||||
PMC_CFG_DEFN(n); \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, clock_control_sam_pmc_init, NULL, \
|
||||
&pmc##n##data, \
|
||||
&pmc##n##_cfg, \
|
||||
PRE_KERNEL_1, \
|
||||
CONFIG_CLOCK_CONTROL_INIT_PRIORITY, \
|
||||
&sam_clock_control_api); \
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(SAM_PMC_DEVICE_INIT)
|
||||
22
dts/bindings/clock/microchip,sam-pmc.yaml
Normal file
22
dts/bindings/clock/microchip,sam-pmc.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
# Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
description: |
|
||||
Microchip Power Management Controller (PMC)
|
||||
|
||||
compatible: "microchip,sam-pmc"
|
||||
|
||||
include: [clock-controller.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
"#clock-cells":
|
||||
const: 2
|
||||
|
||||
clock-cells:
|
||||
- clock-type
|
||||
- peripheral-id
|
||||
57
include/zephyr/drivers/clock_control/mchp_sam_pmc.h
Normal file
57
include/zephyr/drivers/clock_control/mchp_sam_pmc.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MICROCHIP_SAM_PMC_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MICROCHIP_SAM_PMC_H_
|
||||
|
||||
#include <soc.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/dt-bindings/clock/microchip_sam_pmc.h>
|
||||
|
||||
struct sam_sckc_config {
|
||||
uint32_t crystal_osc: 1;
|
||||
uint32_t reserved: 31;
|
||||
};
|
||||
|
||||
struct sam_clk_cfg {
|
||||
uint32_t clock_type;
|
||||
uint32_t clock_id;
|
||||
};
|
||||
|
||||
/* Device constant configuration parameters */
|
||||
struct sam_pmc_cfg {
|
||||
uint32_t *const reg;
|
||||
const struct device *td_slck;
|
||||
const struct device *md_slck;
|
||||
const struct device *main_xtal;
|
||||
const struct sam_sckc_config td_slck_cfg;
|
||||
const struct sam_sckc_config md_slck_cfg;
|
||||
};
|
||||
|
||||
/* Device run time data */
|
||||
struct sam_pmc_data {
|
||||
struct pmc_data *pmc;
|
||||
};
|
||||
|
||||
#define SAM_DT_CLOCK_PMC_CFG(clock, node_id) { \
|
||||
.clock_type = DT_CLOCKS_CELL_BY_IDX(node_id, \
|
||||
clock, \
|
||||
clock_type), \
|
||||
.clock_id = DT_CLOCKS_CELL_BY_IDX(node_id, \
|
||||
clock, \
|
||||
peripheral_id) \
|
||||
}
|
||||
|
||||
#define SAM_DT_INST_CLOCK_PMC_CFG(inst) SAM_DT_CLOCK_PMC_CFG(0, DT_DRV_INST(inst))
|
||||
|
||||
#define SAM_DT_CLOCKS_PMC_CFG(node_id) { \
|
||||
LISTIFY(DT_NUM_CLOCKS(node_id), \
|
||||
SAM_DT_CLOCK_PMC_CFG, (,), node_id) \
|
||||
}
|
||||
|
||||
#define SAM_DT_INST_CLOCKS_PMC_CFG(inst) SAM_DT_CLOCKS_PMC_CFG(DT_DRV_INST(inst))
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_MICROCHIP_SAM_PMC_H_ */
|
||||
36
include/zephyr/dt-bindings/clock/microchip_sam_pmc.h
Normal file
36
include/zephyr/dt-bindings/clock/microchip_sam_pmc.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MICROCHIP_SAM_PMC_H_
|
||||
#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MICROCHIP_SAM_PMC_H_
|
||||
|
||||
#define PMC_TYPE_CORE 0
|
||||
#define PMC_TYPE_SYSTEM 1
|
||||
#define PMC_TYPE_PERIPHERAL 2
|
||||
#define PMC_TYPE_GCK 3
|
||||
#define PMC_TYPE_PROGRAMMABLE 4
|
||||
|
||||
#define PMC_SLOW 0
|
||||
#define PMC_MCK 1
|
||||
#define PMC_UTMI 2
|
||||
#define PMC_MAIN 3
|
||||
|
||||
/* SAMA7G5 */
|
||||
#define PMC_CPUPLL (PMC_MAIN + 1)
|
||||
#define PMC_SYSPLL (PMC_MAIN + 2)
|
||||
#define PMC_DDRPLL (PMC_MAIN + 3)
|
||||
#define PMC_IMGPLL (PMC_MAIN + 4)
|
||||
#define PMC_BAUDPLL (PMC_MAIN + 5)
|
||||
#define PMC_AUDIOPMCPLL (PMC_MAIN + 6)
|
||||
#define PMC_AUDIOIOPLL (PMC_MAIN + 7)
|
||||
#define PMC_ETHPLL (PMC_MAIN + 8)
|
||||
#define PMC_CPU (PMC_MAIN + 9)
|
||||
#define PMC_MCK1 (PMC_MAIN + 10)
|
||||
#define UTMI1 0
|
||||
#define UTMI2 1
|
||||
#define UTMI3 2
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_MICROCHIP_SAM_PMC_H_ */
|
||||
Reference in New Issue
Block a user