1 /* 2 * Common clock and power management functionality. 3 * 4 * Copyright (C) 2023 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include "cpm.h" 23 #include "cpm-common.h" 24 25 26 27 Cpm_chip::Cpm_chip(l4_addr_t addr, Clock_base *clocks[]) 28 : _clocks(clocks), _cpm_regs(addr, clocks) 29 { 30 } 31 32 const char * 33 Cpm_chip::clock_type(enum Clock_identifiers clock) 34 { 35 return _clocks[clock]->clock_type(); 36 } 37 38 int 39 Cpm_chip::have_clock(enum Clock_identifiers clock) 40 { 41 return _clocks[clock]->have_clock(_cpm_regs); 42 } 43 44 void 45 Cpm_chip::start_clock(enum Clock_identifiers clock) 46 { 47 _clocks[clock]->start_clock(_cpm_regs); 48 } 49 50 void 51 Cpm_chip::stop_clock(enum Clock_identifiers clock) 52 { 53 _clocks[clock]->stop_clock(_cpm_regs); 54 } 55 56 int 57 Cpm_chip::get_parameters(enum Clock_identifiers clock, uint32_t parameters[]) 58 { 59 Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(_clocks[clock]); 60 61 if (clk != NULL) 62 return clk->get_parameters(_cpm_regs, parameters); 63 else 64 return 0; 65 } 66 67 int 68 Cpm_chip::set_parameters(enum Clock_identifiers clock, int num_parameters, uint32_t parameters[]) 69 { 70 Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(_clocks[clock]); 71 72 if (clk != NULL) 73 return clk->set_parameters(_cpm_regs, num_parameters, parameters); 74 else 75 return 0; 76 } 77 78 uint8_t 79 Cpm_chip::get_source(enum Clock_identifiers clock) 80 { 81 Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 82 83 if (clk != NULL) 84 return clk->get_source(_cpm_regs); 85 else 86 return 0; 87 } 88 89 enum Clock_identifiers 90 Cpm_chip::get_source_clock(enum Clock_identifiers clock) 91 { 92 Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 93 94 if (clk != NULL) 95 return clk->get_source_clock(_cpm_regs); 96 else 97 return Clock_undefined; 98 } 99 100 void 101 Cpm_chip::set_source_clock(enum Clock_identifiers clock, enum Clock_identifiers source) 102 { 103 Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 104 105 if (clk != NULL) 106 clk->set_source_clock(_cpm_regs, source); 107 } 108 109 void 110 Cpm_chip::set_source(enum Clock_identifiers clock, uint8_t source) 111 { 112 Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 113 114 if (clk != NULL) 115 clk->set_source(_cpm_regs, source); 116 } 117 118 uint32_t 119 Cpm_chip::get_source_frequency(enum Clock_identifiers clock) 120 { 121 Clock_active *clk = dynamic_cast<Clock_active *>(_clocks[clock]); 122 123 if (clk != NULL) 124 return clk->get_source_frequency(_cpm_regs); 125 else 126 return 0; 127 } 128 129 uint32_t 130 Cpm_chip::get_frequency(enum Clock_identifiers clock) 131 { 132 return _clocks[clock]->get_frequency(_cpm_regs); 133 } 134 135 int 136 Cpm_chip::set_frequency(enum Clock_identifiers clock, uint32_t frequency) 137 { 138 Clock_divided_base *clk = dynamic_cast<Clock_divided_base *>(_clocks[clock]); 139 140 if (clk != NULL) 141 return clk->set_frequency(_cpm_regs, frequency); 142 else 143 return 0; 144 }