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 <io.h> 8 #include <kernel/delay.h> 9 #include <mm/core_memprot.h> 10 #include <sam_sfr.h> 11 #include <types_ext.h> 12 13 #include "at91_clk.h" 14 15 /* 16 * The purpose of this clock is to generate a 480 MHz signal. A different 17 * rate can't be configured. 18 */ 19 #define UTMI_RATE 480000000 20 21 struct clk_utmi { 22 vaddr_t pmc_base; 23 vaddr_t sfr_base; 24 }; 25 26 static bool clk_utmi_ready(vaddr_t pmc_base) 27 { 28 uint32_t status = io_read32(pmc_base + AT91_PMC_SR); 29 30 return status & AT91_PMC_LOCKU; 31 } 32 33 static TEE_Result clk_utmi_enable(struct clk *clk) 34 { 35 struct clk *clk_parent = NULL; 36 struct clk_utmi *utmi = clk->priv; 37 unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT | 38 AT91_PMC_BIASEN; 39 unsigned int utmi_ref_clk_freq = 0; 40 unsigned long parent_rate = 0; 41 42 /* 43 * If mainck rate is different from 12 MHz, we have to configure the 44 * FREQ field of the SFR_UTMICKTRIM register to generate properly 45 * the utmi clock. 46 */ 47 clk_parent = clk_get_parent(clk); 48 parent_rate = clk_get_rate(clk_parent); 49 50 switch (parent_rate) { 51 case 12000000: 52 utmi_ref_clk_freq = 0; 53 break; 54 case 16000000: 55 utmi_ref_clk_freq = 1; 56 break; 57 case 24000000: 58 utmi_ref_clk_freq = 2; 59 break; 60 /* 61 * Not supported on SAMA5D2 but it's not an issue since MAINCK 62 * maximum value is 24 MHz. 63 */ 64 case 48000000: 65 utmi_ref_clk_freq = 3; 66 break; 67 default: 68 EMSG("UTMICK: unsupported mainck rate"); 69 return TEE_ERROR_BAD_PARAMETERS; 70 } 71 72 if (utmi->sfr_base) { 73 io_clrsetbits32(utmi->sfr_base + AT91_SFR_UTMICKTRIM, 74 AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq); 75 } else if (utmi_ref_clk_freq) { 76 EMSG("UTMICK: sfr node required"); 77 return TEE_ERROR_BAD_STATE; 78 } 79 80 io_clrsetbits32(utmi->pmc_base + AT91_CKGR_UCKR, uckr, uckr); 81 82 while (!clk_utmi_ready(utmi->pmc_base)) 83 ; 84 85 return TEE_SUCCESS; 86 } 87 88 static void clk_utmi_disable(struct clk *clk) 89 { 90 struct clk_utmi *utmi = clk->priv; 91 92 io_clrbits32(utmi->pmc_base + AT91_CKGR_UCKR, AT91_PMC_UPLLEN); 93 } 94 95 static unsigned long clk_utmi_get_rate(struct clk *clk __unused, 96 unsigned long parent_rate __unused) 97 { 98 /* UTMI clk rate is fixed. */ 99 return UTMI_RATE; 100 } 101 102 static const struct clk_ops utmi_ops = { 103 .enable = clk_utmi_enable, 104 .disable = clk_utmi_disable, 105 .get_rate = clk_utmi_get_rate, 106 }; 107 108 static struct clk *at91_clk_register_utmi_internal(struct pmc_data *pmc, 109 const char *name, 110 const struct clk_ops *ops, 111 struct clk *parent) 112 { 113 struct clk_utmi *utmi = NULL; 114 struct clk *clk = NULL; 115 116 clk = clk_alloc(name, ops, &parent, 1); 117 if (!clk) 118 return NULL; 119 120 utmi = calloc(1, sizeof(*utmi)); 121 if (!utmi) { 122 clk_free(clk); 123 return NULL; 124 } 125 126 utmi->pmc_base = pmc->base; 127 utmi->sfr_base = sam_sfr_base(); 128 clk->flags = CLK_SET_RATE_GATE; 129 130 clk->priv = utmi; 131 132 if (clk_register(clk)) { 133 clk_free(clk); 134 free(utmi); 135 return NULL; 136 } 137 138 return clk; 139 } 140 141 struct clk *at91_clk_register_utmi(struct pmc_data *pmc, 142 const char *name, 143 struct clk *parent) 144 { 145 return at91_clk_register_utmi_internal(pmc, name, &utmi_ops, parent); 146 } 147 148 static TEE_Result clk_utmi_sama7g5_prepare(struct clk *clk) 149 { 150 struct clk *clk_parent = NULL; 151 struct clk_utmi *utmi = clk->priv; 152 unsigned long parent_rate = 0; 153 uint32_t val = 0; 154 155 clk_parent = clk_get_parent(clk); 156 parent_rate = clk_get_rate(clk_parent); 157 158 switch (parent_rate) { 159 case 16000000: 160 val = 0; 161 break; 162 case 20000000: 163 val = 2; 164 break; 165 case 24000000: 166 val = 3; 167 break; 168 case 32000000: 169 val = 5; 170 break; 171 default: 172 EMSG("UTMICK: unsupported main_xtal rate"); 173 return TEE_ERROR_BAD_PARAMETERS; 174 } 175 176 io_clrsetbits32(utmi->pmc_base + AT91_PMC_XTALF, AT91_PMC_XTALF_XTALF, 177 val); 178 179 return TEE_SUCCESS; 180 } 181 182 static const struct clk_ops sama7g5_utmi_ops = { 183 .enable = clk_utmi_sama7g5_prepare, 184 .get_rate = clk_utmi_get_rate, 185 }; 186 187 struct clk *at91_clk_sama7g5_register_utmi(struct pmc_data *pmc, 188 const char *name, 189 struct clk *parent) 190 { 191 return at91_clk_register_utmi_internal(pmc, name, &sama7g5_utmi_ops, 192 parent); 193 } 194