xref: /optee_os/core/drivers/microchip_pit.c (revision 9145b71b03839431b217e2548a452c42efcfb329)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2024, Microchip
4  */
5 
6 #include <assert.h>
7 #include <drivers/clk.h>
8 #include <drivers/clk_dt.h>
9 #include <kernel/dt_driver.h>
10 #include <string.h>
11 
12 #define MCHP_PIT64B_FREQ		UL(5000000)	/* 5 MHz */
13 
microchip_pit_probe(const void * fdt,int node,const void * compat_data __unused)14 static TEE_Result microchip_pit_probe(const void *fdt, int node,
15 				      const void *compat_data __unused)
16 {
17 	TEE_Result res = TEE_ERROR_GENERIC;
18 	struct clk *parent = NULL;
19 	struct clk *pclk = NULL;
20 	struct clk *gclk = NULL;
21 	size_t i = 0;
22 
23 	res = clk_dt_get_by_name(fdt, node, "pclk", &pclk);
24 	if (res)
25 		return res;
26 
27 	res = clk_dt_get_by_name(fdt, node, "gclk", &gclk);
28 	if (res)
29 		return res;
30 
31 	res = clk_enable(pclk);
32 	if (res)
33 		panic();
34 
35 	while (1) {
36 		parent = clk_get_parent_by_index(gclk, i++);
37 		if (!parent)
38 			panic();
39 		if (!memcmp("syspll", clk_get_name(parent),
40 			    sizeof("syspll") - 1))
41 			break;
42 	}
43 
44 	res = clk_set_parent(gclk, parent);
45 	if (res)
46 		panic();
47 
48 	res = clk_set_rate(gclk, MCHP_PIT64B_FREQ);
49 	if (res)
50 		panic();
51 
52 	return clk_enable(gclk);
53 }
54 
55 static const struct dt_device_match microchip_pit_match_table[] = {
56 	{ .compatible = "microchip,sama7g5-pit64b" },
57 	{ }
58 };
59 
60 DEFINE_DT_DRIVER(microchip_pit_dt_driver) = {
61 	.name = "microchip_pit",
62 	.type = DT_DRIVER_NOTYPE,
63 	.match_table = microchip_pit_match_table,
64 	.probe = microchip_pit_probe,
65 };
66