xref: /optee_os/core/drivers/clk/sam/at91_sckc.c (revision 4c2665755e261e415df08e23ebc6846abbf0c4c5)
1 // SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause
2 /*
3  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
4  *  Copyright (C) 2021 Microchip
5  */
6 
7 #include "at91_clk.h"
8 #include <drivers/clk.h>
9 #include <drivers/clk_dt.h>
10 
11 static struct clk *slow_clk;
12 
13 #define SLOW_CLOCK_FREQ			32768
14 
at91_sckc_clk_get(void)15 struct clk *at91_sckc_clk_get(void)
16 {
17 	return slow_clk;
18 }
19 
sckc_get_rate(struct clk * clk __unused,unsigned long parent_rate __unused)20 static unsigned long sckc_get_rate(struct clk *clk __unused,
21 				   unsigned long parent_rate __unused)
22 {
23 	return SLOW_CLOCK_FREQ;
24 }
25 
26 static const struct clk_ops sckc_clk_ops = {
27 	.get_rate = sckc_get_rate,
28 };
29 
sckc_pmc_setup(const void * fdt __unused,int offs,const void * data __unused)30 static TEE_Result sckc_pmc_setup(const void *fdt __unused, int offs,
31 				 const void *data __unused)
32 {
33 	struct clk *clk = NULL;
34 	TEE_Result res = TEE_ERROR_GENERIC;
35 
36 	if (slow_clk)
37 		return TEE_ERROR_GENERIC;
38 
39 	clk = clk_alloc("slowck", &sckc_clk_ops, NULL, 0);
40 	if (!clk)
41 		return TEE_ERROR_OUT_OF_MEMORY;
42 
43 	res = clk_register(clk);
44 	if (res) {
45 		clk_free(clk);
46 		return res;
47 	}
48 
49 	res = clk_dt_register_clk_provider(fdt, offs, clk_dt_get_simple_clk,
50 					   clk);
51 	if (res)
52 		return res;
53 
54 	slow_clk = clk;
55 
56 	return TEE_SUCCESS;
57 }
58 
59 static const struct dt_device_match at91_sckc_match_table[] = {
60 	{ .compatible = "atmel,sama5d4-sckc" },
61 	{ .compatible = "microchip,sama7g5-sckc" },
62 	{ }
63 };
64 
65 DEFINE_DT_DRIVER(at91_sckc_dt_driver) = {
66 	.name = "at91_sckc",
67 	.type = DT_DRIVER_CLK,
68 	.match_table = at91_sckc_match_table,
69 	.probe = sckc_pmc_setup,
70 };
71