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 struct clk * 109 at91_clk_register_utmi(struct pmc_data *pmc, const char *name, 110 struct clk *parent) 111 { 112 struct clk_utmi *utmi = NULL; 113 struct clk *clk = NULL; 114 115 clk = clk_alloc(name, &utmi_ops, &parent, 1); 116 if (!clk) 117 return NULL; 118 119 utmi = calloc(1, sizeof(*utmi)); 120 if (!utmi) { 121 clk_free(clk); 122 return NULL; 123 } 124 125 utmi->pmc_base = pmc->base; 126 utmi->sfr_base = sam_sfr_base(); 127 clk->flags = CLK_SET_RATE_GATE; 128 129 clk->priv = utmi; 130 131 if (clk_register(clk)) { 132 clk_free(clk); 133 free(utmi); 134 return NULL; 135 } 136 137 return clk; 138 } 139