1 // SPDX-License-Identifier: GPL-2.0+ or BSD-3-Clause
2 /*
3  *  Copyright (C) 2014 Atmel
4  *
5  * Alexandre Belloni <alexandre.belloni@free-electrons.com>
6  */
7 
8 #include <io.h>
9 #include <kernel/delay.h>
10 #include <mm/core_memprot.h>
11 #include <types_ext.h>
12 
13 #include "at91_clk.h"
14 
15 #define H32MX_MAX_FREQ	90000000
16 
clk_sama5d4_h32mx_get_rate(struct clk * clk,unsigned long parent_rate)17 static unsigned long clk_sama5d4_h32mx_get_rate(struct clk *clk,
18 						unsigned long parent_rate)
19 {
20 	struct pmc_data *pmc = clk->priv;
21 	unsigned int mckr = io_read32(pmc->base + AT91_PMC_MCKR);
22 
23 	if (mckr & AT91_PMC_H32MXDIV)
24 		return parent_rate / 2;
25 
26 	if (parent_rate > H32MX_MAX_FREQ)
27 		IMSG("H32MX clock is too fast");
28 
29 	return parent_rate;
30 }
31 
clk_sama5d4_h32mx_set_rate(struct clk * clk,unsigned long rate,unsigned long parent_rate)32 static TEE_Result clk_sama5d4_h32mx_set_rate(struct clk *clk,
33 					     unsigned long rate,
34 					     unsigned long parent_rate)
35 {
36 	struct pmc_data *pmc = clk->priv;
37 	uint32_t mckr = 0;
38 
39 	if (parent_rate != rate && (parent_rate / 2) != rate)
40 		return TEE_ERROR_BAD_PARAMETERS;
41 
42 	if ((parent_rate / 2) == rate)
43 		mckr = AT91_PMC_H32MXDIV;
44 
45 	io_clrsetbits32(pmc->base + AT91_PMC_MCKR, AT91_PMC_H32MXDIV, mckr);
46 
47 	return TEE_SUCCESS;
48 }
49 
50 static const struct clk_ops h32mx_ops = {
51 	.get_rate = clk_sama5d4_h32mx_get_rate,
52 	.set_rate = clk_sama5d4_h32mx_set_rate,
53 };
54 
55 struct clk *
at91_clk_register_h32mx(struct pmc_data * pmc,const char * name,struct clk * parent)56 at91_clk_register_h32mx(struct pmc_data *pmc, const char *name,
57 			struct clk *parent)
58 {
59 	struct clk *clk = NULL;
60 
61 	clk = clk_alloc(name, &h32mx_ops, &parent, 1);
62 	if (!clk)
63 		return NULL;
64 
65 	clk->ops = &h32mx_ops;
66 	clk->priv = pmc;
67 	clk->name = name;
68 	clk->flags = CLK_SET_RATE_GATE;
69 
70 	if (clk_register(clk)) {
71 		clk_free(clk);
72 		return NULL;
73 	}
74 
75 	return clk;
76 }
77