198226f4aSClément Léger // SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause
298226f4aSClément Léger /*
398226f4aSClément Léger * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
498226f4aSClément Léger * Copyright (C) 2021 Microchip
598226f4aSClément Léger */
698226f4aSClément Léger
77b4f9fb1SClément Léger #include "at91_clk.h"
898226f4aSClément Léger #include <drivers/clk.h>
998226f4aSClément Léger #include <drivers/clk_dt.h>
1098226f4aSClément Léger
117b4f9fb1SClément Léger static struct clk *slow_clk;
127b4f9fb1SClément Léger
1398226f4aSClément Léger #define SLOW_CLOCK_FREQ 32768
1498226f4aSClément Léger
at91_sckc_clk_get(void)157b4f9fb1SClément Léger struct clk *at91_sckc_clk_get(void)
167b4f9fb1SClément Léger {
177b4f9fb1SClément Léger return slow_clk;
187b4f9fb1SClément Léger }
197b4f9fb1SClément Léger
sckc_get_rate(struct clk * clk __unused,unsigned long parent_rate __unused)2098226f4aSClément Léger static unsigned long sckc_get_rate(struct clk *clk __unused,
2198226f4aSClément Léger unsigned long parent_rate __unused)
2298226f4aSClément Léger {
2398226f4aSClément Léger return SLOW_CLOCK_FREQ;
2498226f4aSClément Léger }
2598226f4aSClément Léger
2698226f4aSClément Léger static const struct clk_ops sckc_clk_ops = {
2798226f4aSClément Léger .get_rate = sckc_get_rate,
2898226f4aSClément Léger };
2998226f4aSClément Léger
sckc_pmc_setup(const void * fdt __unused,int offs,const void * data __unused)3098226f4aSClément Léger static TEE_Result sckc_pmc_setup(const void *fdt __unused, int offs,
3198226f4aSClément Léger const void *data __unused)
3298226f4aSClément Léger {
3398226f4aSClément Léger struct clk *clk = NULL;
3498226f4aSClément Léger TEE_Result res = TEE_ERROR_GENERIC;
3598226f4aSClément Léger
367b4f9fb1SClément Léger if (slow_clk)
377b4f9fb1SClément Léger return TEE_ERROR_GENERIC;
387b4f9fb1SClément Léger
3998226f4aSClément Léger clk = clk_alloc("slowck", &sckc_clk_ops, NULL, 0);
4098226f4aSClément Léger if (!clk)
4198226f4aSClément Léger return TEE_ERROR_OUT_OF_MEMORY;
4298226f4aSClément Léger
4398226f4aSClément Léger res = clk_register(clk);
4498226f4aSClément Léger if (res) {
4598226f4aSClément Léger clk_free(clk);
4698226f4aSClément Léger return res;
4798226f4aSClément Léger }
4898226f4aSClément Léger
497b4f9fb1SClément Léger res = clk_dt_register_clk_provider(fdt, offs, clk_dt_get_simple_clk,
5098226f4aSClément Léger clk);
517b4f9fb1SClément Léger if (res)
527b4f9fb1SClément Léger return res;
537b4f9fb1SClément Léger
547b4f9fb1SClément Léger slow_clk = clk;
557b4f9fb1SClément Léger
567b4f9fb1SClément Léger return TEE_SUCCESS;
5798226f4aSClément Léger }
5898226f4aSClément Léger
59*4c266575STony Han static const struct dt_device_match at91_sckc_match_table[] = {
60*4c266575STony Han { .compatible = "atmel,sama5d4-sckc" },
61*4c266575STony Han { .compatible = "microchip,sama7g5-sckc" },
62*4c266575STony Han { }
63*4c266575STony Han };
64*4c266575STony Han
65*4c266575STony Han DEFINE_DT_DRIVER(at91_sckc_dt_driver) = {
66*4c266575STony Han .name = "at91_sckc",
67*4c266575STony Han .type = DT_DRIVER_CLK,
68*4c266575STony Han .match_table = at91_sckc_match_table,
69*4c266575STony Han .probe = sckc_pmc_setup,
70*4c266575STony Han };
71