3.1 --- a/pkg/devices/lib/cpm/src/x1600.cc Thu Sep 14 00:11:14 2023 +0200
3.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Thu Sep 14 00:13:02 2023 +0200
3.3 @@ -24,9 +24,12 @@
3.4 #include <l4/devices/hw_mmio_register_block.h>
3.5 #include "cpm-x1600.h"
3.6 #include <math.h>
3.7 +#include <stdio.h>
3.8
3.9
3.10
3.11 +// Register locations.
3.12 +
3.13 enum Regs : unsigned
3.14 {
3.15 Clock_control = 0x000, // CPCCR
3.16 @@ -67,21 +70,10 @@
3.17 Pll_fraction_A = 0x084, // CPAPACR
3.18 Pll_fraction_M = 0x088, // CPMPACR
3.19 Pll_fraction_E = 0x08c, // CPEPACR
3.20 -};
3.21 -
3.22 -enum Clock_bits : unsigned
3.23 -{
3.24 - // Clock_control
3.25
3.26 - Clock_gate_A = 23, // GATE_SCLKA
3.27 - Clock_cpu_change_enable = 22, // CE_CPU
3.28 - Clock_ahb0_change_enable = 21, // CE_AHB0
3.29 - Clock_ahb2_change_enable = 20, // CE_AHB2
3.30 - Clock_pclock_divider = 16, // PDIV (slow APB peripherals)
3.31 - Clock_hclock2_divider = 12, // H2DIV (fast AHB peripherals)
3.32 - Clock_hclock0_divider = 8, // H0DIV (fast AHB peripherals)
3.33 - Clock_l2cache_divider = 4, // L2CDIV
3.34 - Clock_cpu_divider = 0, // CDIV
3.35 + // Special value
3.36 +
3.37 + Reg_undefined = 0xfff,
3.38 };
3.39
3.40 enum Clock_source_bits : unsigned
3.41 @@ -93,84 +85,44 @@
3.42 Clock_source_hclock0 = 26, // SEL_H0PLL (output to AHB0)
3.43 Clock_source_hclock2 = 24, // SEL_H2PLL (output to AHB2)
3.44
3.45 - // Ddr_divider
3.46 -
3.47 - Clock_source_ddr = 30, // DCS
3.48 -
3.49 - // I2s_divider0
3.50 -
3.51 - Clock_source_i2s = 31, // I2PCS
3.52 -
3.53 - // Lcd_divider
3.54 -
3.55 - Clock_source_lcd = 30, // LPCS
3.56 -
3.57 - // Mac_divider
3.58 -
3.59 - Clock_source_mac = 30, // MACPCS
3.60 -
3.61 - // Msc_divider0, Msc_divider1
3.62 -
3.63 - Clock_source_msc0 = 30, // MPCS
3.64 - Clock_source_msc1 = 30, // MPCS
3.65 -
3.66 - // Sfc_divider
3.67 -
3.68 - Clock_source_sfc = 30, // SFCS
3.69 -
3.70 - // Ssi_divider
3.71 -
3.72 - Clock_source_ssi = 30, // SPCS
3.73 -
3.74 - // Cim_divider
3.75 -
3.76 - Clock_source_cim = 30, // CIMPCS
3.77 -
3.78 - // Pwm_divider
3.79 -
3.80 - Clock_source_pwm = 30, // PWMPCS
3.81 -
3.82 - // Can_divider0, Can_divider1
3.83 + // Divider registers
3.84
3.85 Clock_source_can0 = 30, // CA0CS
3.86 Clock_source_can1 = 30, // CA1CS
3.87 + Clock_source_cdbus = 30, // CDCS
3.88 + Clock_source_cim = 30, // CIMPCS
3.89 + Clock_source_ddr = 30, // DCS
3.90 + Clock_source_i2s = 31, // I2PCS
3.91 + Clock_source_lcd = 30, // LPCS
3.92 + Clock_source_mac = 30, // MACPCS
3.93 + Clock_source_msc0 = 30, // MPCS
3.94 + Clock_source_msc1 = 30, // MPCS
3.95 + Clock_source_pwm = 30, // PWMPCS
3.96 + Clock_source_sfc = 30, // SFCS
3.97 + Clock_source_ssi = 30, // SPCS
3.98
3.99 - // Cdbus_divider
3.100 + // Special value
3.101
3.102 - Clock_source_cdbus = 30, // CDCS
3.103 + Clock_source_undefined = 32,
3.104 };
3.105
3.106 -enum Clock_sources : unsigned
3.107 +enum Clock_source_values : unsigned
3.108 {
3.109 - // Clock_source_main
3.110 -
3.111 - Source_external = 1, // EXCLK
3.112 - Source_pll_A = 2, // APLL
3.113 -
3.114 - // Stoppable clock sources:
3.115 - // Clock_source_cpu, Clock_source_hclock0, Clock_source_hclock2,
3.116 - // Clock_source_ddr
3.117 + Source_mME_main = 0,
3.118 + Source_mME_pll_M = 1,
3.119 + Source_mME_pll_E = 2,
3.120
3.121 - Source_mux_stopped = 0,
3.122 - Source_mux_main = 1, // SCLK_A
3.123 - Source_mux_pll_M = 2, // MPLL
3.124 + // Special value
3.125
3.126 - // Unstoppable clock sources:
3.127 - // Clock_source_mac, Clock_source_i2s, Clock_source_lcd, Clock_source_msc0,
3.128 - // Clock_source_msc1, Clock_source_sfc, Clock_source_ssi, Clock_source_cim,
3.129 - // Clock_source_pwm, Clock_source_can0, Clock_source_can1, Clock_source_cdbus
3.130 -
3.131 - Source_main = 0, // SCLK_A
3.132 - Source_pll_M = 1, // MPLL
3.133 - Source_pll_E = 2, // EPLL
3.134 -
3.135 - Source_i2s_pll_E = 1, // EPLL
3.136 -
3.137 - Source_can_external = 3, // EXCLK
3.138 + Source_mask = 0x3,
3.139 };
3.140
3.141 enum Clock_gate_bits : unsigned
3.142 {
3.143 + // Clock_control
3.144 +
3.145 + Clock_gate_main = 23, // GATE_SCLKA
3.146 +
3.147 // Clock_gate0
3.148
3.149 Clock_gate_ddr = 31, // DDR
3.150 @@ -220,111 +172,74 @@
3.151 Clock_gate_undefined = 32,
3.152 };
3.153
3.154 -// Clock gate register correspondences.
3.155 +enum Clock_change_enable_bits : unsigned
3.156 +{
3.157 + Clock_change_enable_cpu = 22,
3.158 + Clock_change_enable_ahb0 = 21,
3.159 + Clock_change_enable_ahb2 = 20,
3.160 + Clock_change_enable_ddr = 29,
3.161 + Clock_change_enable_mac = 29,
3.162 + Clock_change_enable_i2s = 29,
3.163 + Clock_change_enable_lcd = 29,
3.164 + Clock_change_enable_msc0 = 29,
3.165 + Clock_change_enable_msc1 = 29,
3.166 + Clock_change_enable_sfc = 29,
3.167 + Clock_change_enable_ssi = 29,
3.168 + Clock_change_enable_cim = 29,
3.169 + Clock_change_enable_pwm = 29,
3.170 + Clock_change_enable_can0 = 29,
3.171 + Clock_change_enable_can1 = 29,
3.172 + Clock_change_enable_cdbus = 29,
3.173
3.174 -static uint32_t clock_gate_reg[Clock_identifier_count] = {
3.175 - /* Clock_aic_bitclk */ 0,
3.176 - /* Clock_aic_pclk */ 0,
3.177 - /* Clock_can0 */ Clock_gate1,
3.178 - /* Clock_can1 */ Clock_gate1,
3.179 - /* Clock_cdbus */ Clock_gate1,
3.180 - /* Clock_cim */ Clock_gate0,
3.181 - /* Clock_ddr */ Clock_gate0,
3.182 - /* Clock_dma */ Clock_gate0,
3.183 - /* Clock_emac */ 0,
3.184 - /* Clock_hdmi */ 0,
3.185 - /* Clock_i2c */ Clock_gate0,
3.186 - /* Clock_i2c0 */ Clock_gate0,
3.187 - /* Clock_i2c1 */ Clock_gate0,
3.188 - /* Clock_i2s */ 0,
3.189 - /* Clock_i2s0_rx */ Clock_gate1,
3.190 - /* Clock_i2s0_tx */ Clock_gate1,
3.191 - /* Clock_kbc */ 0,
3.192 - /* Clock_lcd */ 0,
3.193 - /* Clock_lcd_pixel */ Clock_gate0,
3.194 - /* Clock_mac */ Clock_gate1,
3.195 - /* Clock_msc */ Clock_gate0,
3.196 - /* Clock_msc0 */ Clock_gate0,
3.197 - /* Clock_msc1 */ Clock_gate0,
3.198 - /* Clock_pwm */ Clock_gate1,
3.199 - /* Clock_pwm0 */ Clock_gate1,
3.200 - /* Clock_pwm1 */ 0,
3.201 - /* Clock_scc */ 0,
3.202 - /* Clock_sfc */ Clock_gate0,
3.203 - /* Clock_smb0 */ 0,
3.204 - /* Clock_smb1 */ 0,
3.205 - /* Clock_smb2 */ 0,
3.206 - /* Clock_smb3 */ 0,
3.207 - /* Clock_smb4 */ 0,
3.208 - /* Clock_ssi */ Clock_gate0,
3.209 - /* Clock_timer */ Clock_gate0,
3.210 - /* Clock_uart0 */ Clock_gate0,
3.211 - /* Clock_uart1 */ Clock_gate0,
3.212 - /* Clock_uart2 */ Clock_gate0,
3.213 - /* Clock_uart3 */ Clock_gate1,
3.214 - /* Clock_udc */ 0,
3.215 - /* Clock_uhc */ 0,
3.216 - /* Clock_uprt */ 0,
3.217 + // Special value
3.218 +
3.219 + Clock_change_enable_undefined = 32,
3.220 };
3.221
3.222 -// Clock gate register bit correspondences.
3.223 +enum Clock_busy_bits : unsigned
3.224 +{
3.225 + Clock_busy_cpu = 0,
3.226 + Clock_busy_ddr = 28,
3.227 + Clock_busy_mac = 28,
3.228 + Clock_busy_lcd = 28,
3.229 + Clock_busy_msc0 = 28,
3.230 + Clock_busy_msc1 = 28,
3.231 + Clock_busy_sfc = 28,
3.232 + Clock_busy_ssi = 28,
3.233 + Clock_busy_cim = 28,
3.234 + Clock_busy_pwm = 28,
3.235 + Clock_busy_can0 = 28,
3.236 + Clock_busy_can1 = 28,
3.237 + Clock_busy_cdbus = 28,
3.238
3.239 -static enum Clock_gate_bits clock_gate_bit[Clock_identifier_count] = {
3.240 - /* Clock_aic_bitclk */ Clock_gate_undefined,
3.241 - /* Clock_aic_pclk */ Clock_gate_undefined,
3.242 - /* Clock_can0 */ Clock_gate_can0,
3.243 - /* Clock_can1 */ Clock_gate_can1,
3.244 - /* Clock_cdbus */ Clock_gate_cdbus,
3.245 - /* Clock_cim */ Clock_gate_cim,
3.246 - /* Clock_ddr */ Clock_gate_ddr,
3.247 - /* Clock_dma */ Clock_gate_dma,
3.248 - /* Clock_emac */ Clock_gate_undefined,
3.249 - /* Clock_hdmi */ Clock_gate_undefined,
3.250 - /* Clock_i2c */ Clock_gate_i2c0,
3.251 - /* Clock_i2c0 */ Clock_gate_i2c0,
3.252 - /* Clock_i2c1 */ Clock_gate_i2c1,
3.253 - /* Clock_i2s */ Clock_gate_undefined,
3.254 - /* Clock_i2s0_rx */ Clock_gate_i2s0_rx,
3.255 - /* Clock_i2s0_tx */ Clock_gate_i2s0_tx,
3.256 - /* Clock_kbc */ Clock_gate_undefined,
3.257 - /* Clock_lcd */ Clock_gate_undefined,
3.258 - /* Clock_lcd_pixel */ Clock_gate_lcd_pixel,
3.259 - /* Clock_mac */ Clock_gate_gmac0,
3.260 - /* Clock_msc */ Clock_gate_msc0,
3.261 - /* Clock_msc0 */ Clock_gate_msc0,
3.262 - /* Clock_msc1 */ Clock_gate_msc1,
3.263 - /* Clock_pwm */ Clock_gate_pwm,
3.264 - /* Clock_pwm0 */ Clock_gate_pwm,
3.265 - /* Clock_pwm1 */ Clock_gate_undefined,
3.266 - /* Clock_scc */ Clock_gate_undefined,
3.267 - /* Clock_sfc */ Clock_gate_sfc,
3.268 - /* Clock_smb0 */ Clock_gate_undefined,
3.269 - /* Clock_smb1 */ Clock_gate_undefined,
3.270 - /* Clock_smb2 */ Clock_gate_undefined,
3.271 - /* Clock_smb3 */ Clock_gate_undefined,
3.272 - /* Clock_smb4 */ Clock_gate_undefined,
3.273 - /* Clock_ssi */ Clock_gate_ssi0,
3.274 - /* Clock_timer */ Clock_gate_timer,
3.275 - /* Clock_uart0 */ Clock_gate_uart0,
3.276 - /* Clock_uart1 */ Clock_gate_uart1,
3.277 - /* Clock_uart2 */ Clock_gate_uart2,
3.278 - /* Clock_uart3 */ Clock_gate_uart3,
3.279 - /* Clock_udc */ Clock_gate_undefined,
3.280 - /* Clock_uhc */ Clock_gate_undefined,
3.281 - /* Clock_uprt */ Clock_gate_undefined,
3.282 + // Special value
3.283 +
3.284 + Clock_busy_undefined = 32,
3.285 };
3.286
3.287 -enum Divider_bits : unsigned
3.288 +enum Clock_divider_bits : unsigned
3.289 {
3.290 - Ddr_divider_value = 0, // DDRCDR
3.291 - Lcd_divider_value = 0, // LPCDR
3.292 -};
3.293 + Clock_divider_can0 = 0, // CAN0CDR
3.294 + Clock_divider_can1 = 0, // CAN1CDR
3.295 + Clock_divider_cdbus = 0, // CDBUSCDR
3.296 + Clock_divider_cim = 0, // CIMCDR
3.297 + Clock_divider_cpu = 0, // CDIV
3.298 + Clock_divider_ddr = 0, // DDRCDR
3.299 + Clock_divider_hclock0 = 8, // H0DIV (fast AHB peripherals)
3.300 + Clock_divider_hclock2 = 12, // H2DIV (fast AHB peripherals)
3.301 + Clock_divider_l2cache = 4, // L2CDIV
3.302 + Clock_divider_lcd = 0, // LPCDR
3.303 + Clock_divider_mac = 0, // MACCDR
3.304 + Clock_divider_msc0 = 0, // MSC0CDR
3.305 + Clock_divider_msc1 = 0, // MSC1CDR
3.306 + Clock_divider_pclock = 16, // PDIV (slow APB peripherals)
3.307 + Clock_divider_pwm = 0, // PWMCDR
3.308 + Clock_divider_sfc = 0, // SFCCDR
3.309 + Clock_divider_ssi = 0, // SSICDR
3.310
3.311 -enum Clock_status_values : unsigned
3.312 -{
3.313 - Lcd_change_enable = 0x20000000, // CE_LCD
3.314 - Lcd_change_busy = 0x10000000, // LCD_BUSY
3.315 - Lcd_clock_stop = 0x08000000, // LCD_STOP
3.316 + // Special value
3.317 +
3.318 + Clock_divider_undefined = 32,
3.319 };
3.320
3.321 enum Pll_bits : unsigned
3.322 @@ -348,6 +263,335 @@
3.323
3.324
3.325
3.326 +// Clock input descriptions.
3.327 +
3.328 +struct Clock_input_desc
3.329 +{
3.330 + uint32_t source_reg;
3.331 + enum Clock_source_bits source_bit;
3.332 + int num_inputs;
3.333 + enum Clock_input_identifiers inputs[3];
3.334 +};
3.335 +
3.336 +struct Clock_input_desc clock_input_desc[Clock_input_identifier_count] = {
3.337 +
3.338 + /* Clock_input_ahb2_apb */ {Clock_control, Clock_source_hclock2,
3.339 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
3.340 +
3.341 + /* Clock_input_external */ {Reg_undefined, Clock_source_undefined,
3.342 + 0, {}},
3.343 +
3.344 + /* Clock_input_main */ {Clock_control, Clock_source_main,
3.345 + 3, {Clock_input_none, Clock_input_external, Clock_input_pll_A}},
3.346 +
3.347 + /* Clock_input_none */ {Reg_undefined, Clock_source_undefined,
3.348 + 0, {}},
3.349 +
3.350 + /* Clock_input_pll_A */ {Reg_undefined, Clock_source_undefined,
3.351 + 1, {Clock_input_external}},
3.352 +
3.353 + /* Clock_input_pll_E */ {Reg_undefined, Clock_source_undefined,
3.354 + 1, {Clock_input_external}},
3.355 +
3.356 + /* Clock_input_pll_M */ {Reg_undefined, Clock_source_undefined,
3.357 + 1, {Clock_input_external}},
3.358 +};
3.359 +
3.360 +
3.361 +
3.362 +// Clock descriptions.
3.363 +
3.364 +struct Clock_desc
3.365 +{
3.366 + uint32_t source_reg;
3.367 + enum Clock_source_bits source_bit;
3.368 + uint32_t gate_reg;
3.369 + enum Clock_gate_bits gate_bit;
3.370 + uint32_t change_enable_reg;
3.371 + enum Clock_change_enable_bits change_enable_bit;
3.372 + uint32_t busy_reg;
3.373 + enum Clock_busy_bits busy_bit;
3.374 + uint32_t divider_reg;
3.375 + enum Clock_divider_bits divider_bit;
3.376 + uint32_t divider_mask;
3.377 + int num_inputs;
3.378 + enum Clock_input_identifiers inputs[4];
3.379 +};
3.380 +
3.381 +#define Clock_undefined {Reg_undefined, Clock_source_undefined, \
3.382 + Reg_undefined, Clock_gate_undefined, \
3.383 + Reg_undefined, Clock_change_enable_undefined, \
3.384 + Reg_undefined, Clock_busy_undefined, \
3.385 + Reg_undefined, Clock_divider_undefined, 0, \
3.386 + 0, {}}
3.387 +
3.388 +static struct Clock_desc clock_desc[Clock_identifier_count] = {
3.389 +
3.390 + /* Clock_aic_bitclk */ Clock_undefined,
3.391 +
3.392 + /* Clock_aic_pclk */ Clock_undefined,
3.393 +
3.394 + /* Clock_can0 */ {Can_divider0, Clock_source_can0,
3.395 + Clock_gate1, Clock_gate_can0,
3.396 + Can_divider0, Clock_change_enable_can0,
3.397 + Can_divider0, Clock_busy_can0,
3.398 + Can_divider0, Clock_divider_can0, 0xff,
3.399 + 4, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E, Clock_input_external}},
3.400 +
3.401 + /* Clock_can1 */ {Can_divider1, Clock_source_can1,
3.402 + Clock_gate1, Clock_gate_can1,
3.403 + Can_divider1, Clock_change_enable_can1,
3.404 + Can_divider1, Clock_busy_can1,
3.405 + Can_divider1, Clock_divider_can1, 0xff,
3.406 + 4, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E, Clock_input_external}},
3.407 +
3.408 + /* Clock_cdbus */ {Cdbus_divider, Clock_source_cdbus,
3.409 + Clock_gate1, Clock_gate_cdbus,
3.410 + Cdbus_divider, Clock_change_enable_cdbus,
3.411 + Cdbus_divider, Clock_busy_cdbus,
3.412 + Cdbus_divider, Clock_divider_cdbus, 0xff,
3.413 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.414 +
3.415 + /* Clock_cim */ {Cim_divider, Clock_source_cim,
3.416 + Clock_gate0, Clock_gate_cim,
3.417 + Cim_divider, Clock_change_enable_cim,
3.418 + Cim_divider, Clock_busy_cim,
3.419 + Cim_divider, Clock_divider_cim, 0xff,
3.420 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.421 +
3.422 + /* Clock_cpu */ {Clock_control, Clock_source_cpu,
3.423 + Reg_undefined, Clock_gate_undefined,
3.424 + Clock_control, Clock_change_enable_cpu,
3.425 + Clock_status, Clock_busy_cpu,
3.426 + Clock_control, Clock_divider_cpu, 0x0f,
3.427 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
3.428 +
3.429 + /* Clock_ddr */ {Ddr_divider, Clock_source_ddr,
3.430 + Clock_gate0, Clock_gate_ddr,
3.431 + Ddr_divider, Clock_change_enable_ddr,
3.432 + Ddr_divider, Clock_busy_ddr,
3.433 + Ddr_divider, Clock_divider_ddr, 0x0f,
3.434 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
3.435 +
3.436 + /* Clock_dma */ {Reg_undefined, Clock_source_undefined,
3.437 + Clock_gate0, Clock_gate_dma,
3.438 + Reg_undefined, Clock_change_enable_undefined,
3.439 + Reg_undefined, Clock_busy_undefined,
3.440 + Reg_undefined, Clock_divider_undefined, 0,
3.441 + 1, {Clock_input_ahb2_apb}},
3.442 +
3.443 + /* Clock_emac */ Clock_undefined,
3.444 +
3.445 + /* Clock_hclock0 */ {Clock_control, Clock_source_hclock0,
3.446 + Clock_gate0, Clock_gate_ahb0,
3.447 + Clock_control, Clock_change_enable_ahb0,
3.448 + Reg_undefined, Clock_busy_undefined,
3.449 + Clock_control, Clock_divider_hclock0, 0x0f,
3.450 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
3.451 +
3.452 + /* Clock_hclock2 */ {Reg_undefined, Clock_source_undefined,
3.453 + Clock_gate0, Clock_gate_apb0,
3.454 + Clock_control, Clock_change_enable_ahb2,
3.455 + Reg_undefined, Clock_busy_undefined,
3.456 + Clock_control, Clock_divider_hclock2, 0x0f,
3.457 + 1, {Clock_input_ahb2_apb}},
3.458 +
3.459 + /* Clock_hdmi */ Clock_undefined,
3.460 +
3.461 + /* Clock_i2c */ {Reg_undefined, Clock_source_undefined,
3.462 + Clock_gate0, Clock_gate_i2c0,
3.463 + Reg_undefined, Clock_change_enable_undefined,
3.464 + Reg_undefined, Clock_busy_undefined,
3.465 + Reg_undefined, Clock_divider_undefined, 0,
3.466 + 1, {Clock_input_ahb2_apb}},
3.467 +
3.468 + /* Clock_i2c0 */ {Reg_undefined, Clock_source_undefined,
3.469 + Clock_gate0, Clock_gate_i2c0,
3.470 + Reg_undefined, Clock_change_enable_undefined,
3.471 + Reg_undefined, Clock_busy_undefined,
3.472 + Reg_undefined, Clock_divider_undefined, 0,
3.473 + 1, {Clock_input_ahb2_apb}},
3.474 +
3.475 + /* Clock_i2c1 */ {Reg_undefined, Clock_source_undefined,
3.476 + Clock_gate0, Clock_gate_i2c1,
3.477 + Reg_undefined, Clock_change_enable_undefined,
3.478 + Reg_undefined, Clock_busy_undefined,
3.479 + Reg_undefined, Clock_divider_undefined, 0,
3.480 + 1, {Clock_input_ahb2_apb}},
3.481 +
3.482 + /* Clock_i2s */ Clock_undefined,
3.483 +
3.484 + /* Clock_i2s0_rx */ {I2s_divider0, Clock_source_i2s,
3.485 + Clock_gate1, Clock_gate_i2s0_rx,
3.486 + I2s_divider0, Clock_change_enable_i2s,
3.487 + Reg_undefined, Clock_busy_undefined,
3.488 + Reg_undefined, Clock_divider_undefined, 0, // NOTE: To define.
3.489 + 2, {Clock_input_main, Clock_input_pll_E}},
3.490 +
3.491 + /* Clock_i2s0_tx */ {I2s_divider0, Clock_source_i2s,
3.492 + Clock_gate1, Clock_gate_i2s0_tx,
3.493 + I2s_divider0, Clock_change_enable_i2s,
3.494 + Reg_undefined, Clock_busy_undefined,
3.495 + Reg_undefined, Clock_divider_undefined, 0, // NOTE: To define.
3.496 + 2, {Clock_input_main, Clock_input_pll_E}},
3.497 +
3.498 + /* Clock_kbc */ Clock_undefined,
3.499 +
3.500 + /* Clock_lcd */ Clock_undefined,
3.501 +
3.502 + /* Clock_lcd_pixel */ {Lcd_divider, Clock_source_lcd,
3.503 + Clock_gate0, Clock_gate_lcd_pixel,
3.504 + Lcd_divider, Clock_change_enable_lcd,
3.505 + Lcd_divider, Clock_busy_lcd,
3.506 + Lcd_divider, Clock_divider_lcd, 0xff,
3.507 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.508 +
3.509 + /* Clock_mac */ {Mac_divider, Clock_source_mac,
3.510 + Clock_gate1, Clock_gate_gmac0,
3.511 + Mac_divider, Clock_change_enable_mac,
3.512 + Mac_divider, Clock_busy_mac,
3.513 + Mac_divider, Clock_divider_mac, 0xff,
3.514 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.515 +
3.516 + /* Clock_main */ {Reg_undefined, Clock_source_undefined,
3.517 + Clock_control, Clock_gate_main,
3.518 + Reg_undefined, Clock_change_enable_undefined,
3.519 + Reg_undefined, Clock_busy_undefined,
3.520 + Reg_undefined, Clock_divider_undefined, 0,
3.521 + 1, {Clock_input_main}},
3.522 +
3.523 + /* Clock_msc */ {Msc_divider0, Clock_source_msc0,
3.524 + Clock_gate0, Clock_gate_msc0,
3.525 + Msc_divider0, Clock_change_enable_msc0,
3.526 + Msc_divider0, Clock_busy_msc0,
3.527 + Msc_divider0, Clock_divider_msc0, 0xff,
3.528 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.529 +
3.530 + /* Clock_msc0 */ {Msc_divider0, Clock_source_msc0,
3.531 + Clock_gate0, Clock_gate_msc0,
3.532 + Msc_divider0, Clock_change_enable_msc0,
3.533 + Msc_divider0, Clock_busy_msc0,
3.534 + Msc_divider0, Clock_divider_msc0, 0xff,
3.535 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.536 +
3.537 + /* Clock_msc1 */ {Msc_divider1, Clock_source_msc1,
3.538 + Clock_gate0, Clock_gate_msc1,
3.539 + Msc_divider1, Clock_change_enable_msc1,
3.540 + Msc_divider1, Clock_busy_msc1,
3.541 + Msc_divider1, Clock_divider_msc1, 0xff,
3.542 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.543 +
3.544 + /* Clock_pclock */ {Reg_undefined, Clock_source_undefined,
3.545 + Clock_gate0, Clock_gate_apb0,
3.546 + Reg_undefined, Clock_change_enable_undefined,
3.547 + Reg_undefined, Clock_busy_undefined,
3.548 + Clock_control, Clock_divider_pclock, 0x0f,
3.549 + 1, {Clock_input_ahb2_apb}},
3.550 +
3.551 + /* Clock_pwm */ {Pwm_divider, Clock_source_pwm,
3.552 + Clock_gate1, Clock_gate_pwm,
3.553 + Pwm_divider, Clock_change_enable_pwm,
3.554 + Pwm_divider, Clock_busy_pwm,
3.555 + Pwm_divider, Clock_divider_pwm, 0x0f,
3.556 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.557 +
3.558 + /* Clock_pwm0 */ {Pwm_divider, Clock_source_pwm,
3.559 + Clock_gate1, Clock_gate_pwm,
3.560 + Pwm_divider, Clock_change_enable_pwm,
3.561 + Pwm_divider, Clock_busy_pwm,
3.562 + Pwm_divider, Clock_divider_pwm, 0x0f,
3.563 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.564 +
3.565 + /* Clock_pwm1 */ Clock_undefined,
3.566 +
3.567 + /* Clock_scc */ Clock_undefined,
3.568 +
3.569 + /* Clock_sfc */ {Sfc_divider, Clock_source_sfc,
3.570 + Clock_gate0, Clock_gate_sfc,
3.571 + Sfc_divider, Clock_change_enable_sfc,
3.572 + Sfc_divider, Clock_busy_sfc,
3.573 + Sfc_divider, Clock_divider_sfc, 0xff,
3.574 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.575 +
3.576 + /* Clock_smb0 */ Clock_undefined,
3.577 +
3.578 + /* Clock_smb1 */ Clock_undefined,
3.579 +
3.580 + /* Clock_smb2 */ Clock_undefined,
3.581 +
3.582 + /* Clock_smb3 */ Clock_undefined,
3.583 +
3.584 + /* Clock_smb4 */ Clock_undefined,
3.585 +
3.586 + /* Clock_ssi */ {Ssi_divider, Clock_source_ssi,
3.587 + Clock_gate0, Clock_gate_ssi0,
3.588 + Ssi_divider, Clock_change_enable_ssi,
3.589 + Ssi_divider, Clock_busy_ssi,
3.590 + Ssi_divider, Clock_divider_ssi, 0xff,
3.591 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
3.592 +
3.593 + /* Clock_timer */ {Reg_undefined, Clock_source_undefined,
3.594 + Clock_gate0, Clock_gate_timer,
3.595 + Reg_undefined, Clock_change_enable_undefined,
3.596 + Reg_undefined, Clock_busy_undefined,
3.597 + Reg_undefined, Clock_divider_undefined, 0,
3.598 + 1, {Clock_input_ahb2_apb}},
3.599 +
3.600 + /* Clock_uart0 */ {Reg_undefined, Clock_source_undefined,
3.601 + Clock_gate0, Clock_gate_uart0,
3.602 + Reg_undefined, Clock_change_enable_undefined,
3.603 + Reg_undefined, Clock_busy_undefined,
3.604 + Reg_undefined, Clock_divider_undefined, 0,
3.605 + 1, {Clock_input_ahb2_apb}},
3.606 +
3.607 + /* Clock_uart1 */ {Reg_undefined, Clock_source_undefined,
3.608 + Clock_gate0, Clock_gate_uart1,
3.609 + Reg_undefined, Clock_change_enable_undefined,
3.610 + Reg_undefined, Clock_busy_undefined,
3.611 + Reg_undefined, Clock_divider_undefined, 0,
3.612 + 1, {Clock_input_ahb2_apb}},
3.613 +
3.614 + /* Clock_uart2 */ {Reg_undefined, Clock_source_undefined,
3.615 + Clock_gate0, Clock_gate_uart2,
3.616 + Reg_undefined, Clock_change_enable_undefined,
3.617 + Reg_undefined, Clock_busy_undefined,
3.618 + Reg_undefined, Clock_divider_undefined, 0,
3.619 + 1, {Clock_input_ahb2_apb}},
3.620 +
3.621 + /* Clock_uart3 */ {Reg_undefined, Clock_source_undefined,
3.622 + Clock_gate1, Clock_gate_uart3,
3.623 + Reg_undefined, Clock_change_enable_undefined,
3.624 + Reg_undefined, Clock_busy_undefined,
3.625 + Reg_undefined, Clock_divider_undefined, 0,
3.626 + 1, {Clock_input_ahb2_apb}},
3.627 +
3.628 + /* Clock_udc */ Clock_undefined,
3.629 +
3.630 + /* Clock_uhc */ Clock_undefined,
3.631 +
3.632 + /* Clock_uprt */ Clock_undefined,
3.633 +};
3.634 +
3.635 +
3.636 +
3.637 +// Convenience functions.
3.638 +
3.639 +static uint8_t get_clock_gate_bit(enum Clock_identifiers clock)
3.640 +{
3.641 + enum Clock_gate_bits bit = clock_desc[clock].gate_bit;
3.642 +
3.643 + return bit != Clock_gate_undefined ? (uint8_t) bit : 0;
3.644 +}
3.645 +
3.646 +static uint32_t get_clock_gate_mask(enum Clock_identifiers clock)
3.647 +{
3.648 + enum Clock_gate_bits bit = clock_desc[clock].gate_bit;
3.649 +
3.650 + return bit != Clock_gate_undefined ? 1 : 0;
3.651 +}
3.652 +
3.653 +
3.654 +
3.655 // If implemented as a Hw::Device, various properties would be
3.656 // initialised in the constructor and obtained from the device tree
3.657 // definitions.
3.658 @@ -362,42 +606,6 @@
3.659 // register_property("exclk_freq", &_exclk_freq);
3.660 }
3.661
3.662 -// Clock/timer control.
3.663 -
3.664 -uint32_t
3.665 -Cpm_x1600_chip::get_clock_gate_register(enum Clock_identifiers clock)
3.666 -{
3.667 - return clock_gate_reg[clock];
3.668 -}
3.669 -
3.670 -uint32_t
3.671 -Cpm_x1600_chip::get_clock_gate_value(enum Clock_identifiers clock)
3.672 -{
3.673 - return 1 << clock_gate_bit[clock];
3.674 -}
3.675 -
3.676 -int
3.677 -Cpm_x1600_chip::have_clock(enum Clock_identifiers clock)
3.678 -{
3.679 - return !(_regs[get_clock_gate_register(clock)] & get_clock_gate_value(clock));
3.680 -}
3.681 -
3.682 -void
3.683 -Cpm_x1600_chip::start_clock(enum Clock_identifiers clock)
3.684 -{
3.685 - uint32_t gate = get_clock_gate_register(clock);
3.686 -
3.687 - _regs[gate] = _regs[gate] & ~get_clock_gate_value(clock);
3.688 -}
3.689 -
3.690 -void
3.691 -Cpm_x1600_chip::stop_clock(enum Clock_identifiers clock)
3.692 -{
3.693 - uint32_t gate = get_clock_gate_register(clock);
3.694 -
3.695 - _regs[gate] = _regs[gate] | get_clock_gate_value(clock);
3.696 -}
3.697 -
3.698
3.699
3.700 // Utility methods.
3.701 @@ -414,12 +622,61 @@
3.702 _regs[reg] = (_regs[reg] & (~(mask << shift))) | ((mask & value) << shift);
3.703 }
3.704
3.705 -// General clock divider access.
3.706 +
3.707 +
3.708 +// Clock/timer control.
3.709 +
3.710 +void
3.711 +Cpm_x1600_chip::change_disable(enum Clock_identifiers clock)
3.712 +{
3.713 + enum Clock_change_enable_bits bit = clock_desc[clock].change_enable_bit;
3.714 +
3.715 + if (bit != Clock_change_enable_undefined)
3.716 + set_field(clock_desc[clock].change_enable_reg, 1, bit, 0);
3.717 +}
3.718 +
3.719 +void
3.720 +Cpm_x1600_chip::change_enable(enum Clock_identifiers clock)
3.721 +{
3.722 + enum Clock_change_enable_bits bit = clock_desc[clock].change_enable_bit;
3.723 +
3.724 + if (bit != Clock_change_enable_undefined)
3.725 + set_field(clock_desc[clock].change_enable_reg, 1, bit, 1);
3.726 +}
3.727
3.728 -uint8_t
3.729 -Cpm_x1600_chip::_get_divider(uint32_t reg, uint32_t mask, uint8_t shift)
3.730 +int
3.731 +Cpm_x1600_chip::have_clock(enum Clock_identifiers clock)
3.732 +{
3.733 + if (clock_desc[clock].gate_bit != Clock_gate_undefined)
3.734 + return !get_field(clock_desc[clock].gate_reg, get_clock_gate_mask(clock),
3.735 + get_clock_gate_bit(clock));
3.736 + else
3.737 + return true;
3.738 +}
3.739 +
3.740 +void
3.741 +Cpm_x1600_chip::start_clock(enum Clock_identifiers clock)
3.742 {
3.743 - return get_field(reg, mask, shift) + 1;
3.744 + if (clock_desc[clock].gate_bit != Clock_gate_undefined)
3.745 + set_field(clock_desc[clock].gate_reg, get_clock_gate_mask(clock),
3.746 + get_clock_gate_bit(clock), 0);
3.747 +}
3.748 +
3.749 +void
3.750 +Cpm_x1600_chip::stop_clock(enum Clock_identifiers clock)
3.751 +{
3.752 + if (clock_desc[clock].gate_bit != Clock_gate_undefined)
3.753 + set_field(clock_desc[clock].gate_reg, get_clock_gate_mask(clock),
3.754 + get_clock_gate_bit(clock), 1);
3.755 +}
3.756 +
3.757 +void
3.758 +Cpm_x1600_chip::wait_busy(enum Clock_identifiers clock)
3.759 +{
3.760 + enum Clock_busy_bits bit = clock_desc[clock].busy_bit;
3.761 +
3.762 + if (bit != Clock_busy_undefined)
3.763 + while (get_field(clock_desc[clock].busy_reg, 1, bit));
3.764 }
3.765
3.766
3.767 @@ -431,43 +688,44 @@
3.768 int
3.769 Cpm_x1600_chip::have_pll(uint32_t pll_reg)
3.770 {
3.771 - return _regs[pll_reg] & (1 << Pll_stable);
3.772 + return get_field(pll_reg, 1, Pll_stable);
3.773 }
3.774
3.775 int
3.776 Cpm_x1600_chip::pll_enabled(uint32_t pll_reg)
3.777 {
3.778 - return _regs[pll_reg] & (1 << Pll_enabled);
3.779 + return get_field(pll_reg, 1, Pll_enabled);
3.780 }
3.781
3.782 int
3.783 Cpm_x1600_chip::pll_bypassed(uint32_t pll_reg)
3.784 {
3.785 - uint32_t mask;
3.786 + uint8_t bit;
3.787 + unsigned mask = 1;
3.788
3.789 switch (pll_reg)
3.790 {
3.791 - case Pll_control_A: mask = (1 << Pll_bypass_A); break;
3.792 - case Pll_control_M: mask = (1 << Pll_bypass_M); break;
3.793 - case Pll_control_E: mask = (1 << Pll_bypass_E); break;
3.794 - default: mask = 0; break;
3.795 + case Pll_control_A: bit = Pll_bypass_A; break;
3.796 + case Pll_control_M: bit = Pll_bypass_M; break;
3.797 + case Pll_control_E: bit = Pll_bypass_E; break;
3.798 + default: bit = 0; mask = 0; break;
3.799 }
3.800
3.801 - return _regs[Pll_control] & mask;
3.802 + return get_field(Pll_control, mask, bit);
3.803 }
3.804
3.805 void
3.806 Cpm_x1600_chip::pll_enable(uint32_t pll_reg)
3.807 {
3.808 - _regs[pll_reg] = _regs[pll_reg] | (1 << Pll_enabled);
3.809 - while (!(_regs[pll_reg] & (1 << Pll_stable)));
3.810 + set_field(pll_reg, 1, Pll_enabled, 1);
3.811 + while (!have_pll(pll_reg));
3.812 }
3.813
3.814 void
3.815 Cpm_x1600_chip::pll_disable(uint32_t pll_reg)
3.816 {
3.817 - _regs[pll_reg] = _regs[pll_reg] & ~(1 << Pll_enabled);
3.818 - while (_regs[pll_reg] & (1 << Pll_stable));
3.819 + set_field(pll_reg, 1, Pll_enabled, 0);
3.820 + while (have_pll(pll_reg));
3.821 }
3.822
3.823 // Feedback (13-bit) multiplier.
3.824 @@ -547,78 +805,29 @@
3.825
3.826
3.827
3.828 -// CPU clock (CCLK) divider.
3.829 +// Clock dividers.
3.830
3.831 -uint8_t
3.832 -Cpm_x1600_chip::get_cpu_divider()
3.833 -{
3.834 - return _get_divider(Clock_control, 0xf, Clock_cpu_divider);
3.835 -}
3.836 -
3.837 -// Fast peripheral clock (H0CLK) divider.
3.838 -
3.839 -uint8_t
3.840 -Cpm_x1600_chip::get_hclock0_divider()
3.841 +uint32_t
3.842 +Cpm_x1600_chip::get_divider(enum Clock_identifiers clock)
3.843 {
3.844 - return _get_divider(Clock_control, 0xf, Clock_hclock0_divider);
3.845 -}
3.846 -
3.847 -// Fast peripheral clock (H2CLK) divider.
3.848 -
3.849 -uint8_t
3.850 -Cpm_x1600_chip::get_hclock2_divider()
3.851 -{
3.852 - return _get_divider(Clock_control, 0xf, Clock_hclock2_divider);
3.853 -}
3.854 -
3.855 -// Slow peripheral clock (PCLK) divider.
3.856 -
3.857 -uint8_t
3.858 -Cpm_x1600_chip::get_pclock_divider()
3.859 -{
3.860 - return _get_divider(Clock_control, 0xf, Clock_pclock_divider);
3.861 + if (clock_desc[clock].divider_bit != Clock_divider_undefined)
3.862 + return get_field(clock_desc[clock].divider_reg, clock_desc[clock].divider_mask,
3.863 + clock_desc[clock].divider_bit) + 1;
3.864 + else
3.865 + return 1;
3.866 }
3.867
3.868 -// LCD clock (LPCLK) divider for LCD pixel clock.
3.869 -
3.870 -uint8_t
3.871 -Cpm_x1600_chip::get_lcd_pixel_divider(uint8_t controller)
3.872 +void
3.873 +Cpm_x1600_chip::set_divider(enum Clock_identifiers clock, uint32_t division)
3.874 {
3.875 - (void) controller;
3.876 - return _get_divider(Lcd_divider, 0xff, Lcd_divider_value);
3.877 -}
3.878 -
3.879 -// Memory clock (DDR_CLK) divider.
3.880 -
3.881 -uint8_t
3.882 -Cpm_x1600_chip::get_memory_divider()
3.883 -{
3.884 - return _get_divider(Ddr_divider, 0xf, Ddr_divider_value);
3.885 -}
3.886 -
3.887 -// LCD pixel clock divider.
3.888 -
3.889 -void
3.890 -Cpm_x1600_chip::set_lcd_pixel_divider(uint8_t controller, uint16_t division)
3.891 -{
3.892 - if (controller > 0)
3.893 + if (clock_desc[clock].divider_bit == Clock_divider_undefined)
3.894 return;
3.895
3.896 - if ((division < 1) || (division > 256))
3.897 - return;
3.898 -
3.899 - // Enable change.
3.900 -
3.901 - _regs[Lcd_divider] = _regs[Lcd_divider] | Lcd_change_enable;
3.902 -
3.903 - // Set the divider.
3.904 -
3.905 - set_field(Lcd_divider, 0xff, Lcd_divider_value, division - 1);
3.906 -
3.907 - // Restart clock and disable change.
3.908 -
3.909 - while (_regs[Lcd_divider] & Lcd_change_busy);
3.910 - _regs[Lcd_divider] = _regs[Lcd_divider] & ~Lcd_change_enable;
3.911 + change_enable(clock);
3.912 + set_field(clock_desc[clock].divider_reg, clock_desc[clock].divider_mask,
3.913 + clock_desc[clock].divider_bit, division - 1);
3.914 + wait_busy(clock);
3.915 + change_disable(clock);
3.916 }
3.917
3.918
3.919 @@ -626,251 +835,106 @@
3.920 // Clock sources.
3.921
3.922 uint8_t
3.923 -Cpm_x1600_chip::get_memory_source()
3.924 -{
3.925 - return get_field(Ddr_divider, 0x3, Clock_source_ddr);
3.926 -}
3.927 -
3.928 -uint32_t
3.929 -Cpm_x1600_chip::get_memory_source_frequency()
3.930 -{
3.931 - switch (get_memory_source())
3.932 - {
3.933 - case Source_mux_main:
3.934 - return get_main_frequency();
3.935 - case Source_mux_pll_M:
3.936 - return get_pll_frequency(Pll_control_M);
3.937 - default:
3.938 - return 0;
3.939 - }
3.940 -}
3.941 -
3.942 -uint8_t
3.943 -Cpm_x1600_chip::get_cpu_source()
3.944 -{
3.945 - return get_field(Clock_control, 0x3, Clock_source_cpu);
3.946 -}
3.947 -
3.948 -uint32_t
3.949 -Cpm_x1600_chip::get_cpu_source_frequency()
3.950 +Cpm_x1600_chip::get_source(enum Clock_identifiers clock)
3.951 {
3.952 - switch (get_cpu_source())
3.953 - {
3.954 - case Source_mux_main:
3.955 - return get_main_frequency();
3.956 - case Source_mux_pll_M:
3.957 - return get_pll_frequency(Pll_control_M);
3.958 - default:
3.959 - return 0;
3.960 - }
3.961 -}
3.962 -
3.963 -uint8_t
3.964 -Cpm_x1600_chip::get_hclock0_source()
3.965 -{
3.966 - return get_field(Clock_control, 0x3, Clock_source_hclock0);
3.967 -}
3.968 -
3.969 -uint32_t
3.970 -Cpm_x1600_chip::get_hclock0_source_frequency()
3.971 -{
3.972 - switch (get_hclock0_source())
3.973 - {
3.974 - case Source_mux_main:
3.975 - return get_main_frequency();
3.976 - case Source_mux_pll_M:
3.977 - return get_pll_frequency(Pll_control_M);
3.978 - default:
3.979 - return 0;
3.980 - }
3.981 -}
3.982 -
3.983 -uint8_t
3.984 -Cpm_x1600_chip::get_hclock2_source()
3.985 -{
3.986 - return get_field(Clock_control, 0x3, Clock_source_hclock2);
3.987 -}
3.988 -
3.989 -uint32_t
3.990 -Cpm_x1600_chip::get_hclock2_source_frequency()
3.991 -{
3.992 - switch (get_hclock2_source())
3.993 - {
3.994 - case Source_mux_main:
3.995 - return get_main_frequency();
3.996 - case Source_mux_pll_M:
3.997 - return get_pll_frequency(Pll_control_M);
3.998 - default:
3.999 - return 0;
3.1000 - }
3.1001 + if (clock_desc[clock].source_bit != Clock_source_undefined)
3.1002 + return get_field(clock_desc[clock].source_reg, Source_mask, clock_desc[clock].source_bit);
3.1003 + else
3.1004 + return 0;
3.1005 }
3.1006
3.1007 void
3.1008 -Cpm_x1600_chip::set_hclock2_source(uint8_t source)
3.1009 -{
3.1010 - set_field(Clock_control, 0x3, Clock_source_hclock2, source);
3.1011 -}
3.1012 -
3.1013 -uint8_t
3.1014 -Cpm_x1600_chip::get_lcd_source(uint8_t controller)
3.1015 -{
3.1016 - (void) controller;
3.1017 - return get_field(Lcd_divider, 0x3, Clock_source_lcd);
3.1018 -}
3.1019 -
3.1020 -uint32_t
3.1021 -Cpm_x1600_chip::get_lcd_source_frequency(uint8_t controller)
3.1022 +Cpm_x1600_chip::set_source(enum Clock_identifiers clock, uint8_t source)
3.1023 {
3.1024 - switch (get_lcd_source(controller))
3.1025 - {
3.1026 - case Source_main:
3.1027 - return get_main_frequency();
3.1028 - case Source_pll_M:
3.1029 - return get_pll_frequency(Pll_control_M);
3.1030 - case Source_pll_E:
3.1031 - return get_pll_frequency(Pll_control_E);
3.1032 - default:
3.1033 - return 0;
3.1034 - }
3.1035 -}
3.1036 -
3.1037 -void
3.1038 -Cpm_x1600_chip::set_lcd_source(uint8_t controller, uint8_t source)
3.1039 -{
3.1040 - if (controller > 0)
3.1041 + if (clock_desc[clock].source_bit == Clock_source_undefined)
3.1042 return;
3.1043
3.1044 - // Stop clock and enable change.
3.1045 -
3.1046 - _regs[Lcd_divider] = _regs[Lcd_divider] | Lcd_change_enable | Lcd_clock_stop;
3.1047 -
3.1048 - // Set the source.
3.1049 -
3.1050 - set_field(Lcd_divider, 0x03, Clock_source_lcd, source);
3.1051 -
3.1052 - // Restart clock and disable change.
3.1053 -
3.1054 - while (_regs[Lcd_divider] & Lcd_change_busy);
3.1055 - _regs[Lcd_divider] = _regs[Lcd_divider] & ~(Lcd_change_enable | Lcd_clock_stop);
3.1056 -}
3.1057 -
3.1058 -uint8_t
3.1059 -Cpm_x1600_chip::get_pclock_source()
3.1060 -{
3.1061 - return get_hclock2_source();
3.1062 -}
3.1063 -
3.1064 -uint32_t
3.1065 -Cpm_x1600_chip::get_pclock_source_frequency()
3.1066 -{
3.1067 - return get_hclock2_source_frequency();
3.1068 -}
3.1069 -
3.1070 -void
3.1071 -Cpm_x1600_chip::set_pclock_source(uint8_t source)
3.1072 -{
3.1073 - set_hclock2_source(source);
3.1074 + change_enable(clock);
3.1075 + set_field(clock_desc[clock].source_reg, Source_mask, clock_desc[clock].source_bit, source);
3.1076 + wait_busy(clock);
3.1077 + change_disable(clock);
3.1078 }
3.1079
3.1080
3.1081
3.1082 -// Source frequency, used by various clock sources.
3.1083 +// Clock source frequencies.
3.1084 +
3.1085 +uint32_t
3.1086 +Cpm_x1600_chip::get_input_frequency(enum Clock_input_identifiers clock)
3.1087 +{
3.1088 + struct Clock_input_desc desc = clock_input_desc[clock];
3.1089 +
3.1090 + // Clocks with no inputs provide a frequency.
3.1091 +
3.1092 + if (desc.num_inputs == 0)
3.1093 + {
3.1094 + switch (clock)
3.1095 + {
3.1096 + case Clock_input_external: return _exclk_freq;
3.1097 + default: return 0;
3.1098 + }
3.1099 + }
3.1100 +
3.1101 + // Of the input clocks, only PLLs have a single input.
3.1102
3.1103 -uint8_t
3.1104 -Cpm_x1600_chip::get_main_source()
3.1105 -{
3.1106 - return get_field(Clock_control, 0x3, Clock_source_main);
3.1107 + else if (desc.num_inputs == 1)
3.1108 + {
3.1109 + switch (clock)
3.1110 + {
3.1111 + case Clock_input_pll_A: return get_pll_frequency(Pll_control_A);
3.1112 + case Clock_input_pll_E: return get_pll_frequency(Pll_control_E);
3.1113 + case Clock_input_pll_M: return get_pll_frequency(Pll_control_M);
3.1114 + default: return 0;
3.1115 + }
3.1116 + }
3.1117 +
3.1118 + // With multiple sources, obtain the selected source for the clock.
3.1119 +
3.1120 + uint8_t source = get_field(desc.source_reg, Source_mask, desc.source_bit);
3.1121 +
3.1122 + // Return the frequency of the source.
3.1123 +
3.1124 + if (source < desc.num_inputs)
3.1125 + return get_input_frequency(desc.inputs[source]);
3.1126 + else
3.1127 + return 0;
3.1128 }
3.1129
3.1130 uint32_t
3.1131 -Cpm_x1600_chip::get_main_frequency()
3.1132 -{
3.1133 - switch (get_main_source())
3.1134 - {
3.1135 - case Source_pll_A:
3.1136 - return get_pll_frequency(Pll_control_A);
3.1137 - case Source_external:
3.1138 - return _exclk_freq;
3.1139 - default:
3.1140 - return 0;
3.1141 - }
3.1142 -}
3.1143 -
3.1144 -// Clock frequency for the CPU.
3.1145 -
3.1146 -uint32_t
3.1147 -Cpm_x1600_chip::get_cpu_frequency()
3.1148 -{
3.1149 - return get_cpu_source_frequency() / get_cpu_divider();
3.1150 -}
3.1151 -
3.1152 -// Clock frequency for fast peripherals.
3.1153 -
3.1154 -uint32_t
3.1155 -Cpm_x1600_chip::get_hclock0_frequency()
3.1156 -{
3.1157 - return get_hclock0_source_frequency() / get_hclock0_divider();
3.1158 -}
3.1159 -
3.1160 -// Clock frequency for fast peripherals.
3.1161 -
3.1162 -uint32_t
3.1163 -Cpm_x1600_chip::get_hclock2_frequency()
3.1164 +Cpm_x1600_chip::get_source_frequency(enum Clock_identifiers clock)
3.1165 {
3.1166 - return get_hclock2_source_frequency() / get_hclock2_divider();
3.1167 -}
3.1168 + struct Clock_desc desc = clock_desc[clock];
3.1169
3.1170 -// Clock frequency for slow peripherals.
3.1171 + // Undefined clocks return zero.
3.1172
3.1173 -uint32_t
3.1174 -Cpm_x1600_chip::get_pclock_frequency()
3.1175 -{
3.1176 - return get_pclock_source_frequency() / get_pclock_divider();
3.1177 -}
3.1178 + if (desc.num_inputs == 0)
3.1179 + return 0;
3.1180
3.1181 -// Clock frequency for the memory.
3.1182 + // Clocks with one source yield that input frequency.
3.1183
3.1184 -uint32_t
3.1185 -Cpm_x1600_chip::get_memory_frequency()
3.1186 -{
3.1187 - return get_memory_source_frequency() / get_memory_divider();
3.1188 -}
3.1189 + else if (desc.num_inputs == 1)
3.1190 + return get_input_frequency(desc.inputs[0]);
3.1191 +
3.1192 + // With multiple sources, obtain the selected source for the clock.
3.1193 +
3.1194 + uint8_t source = get_source(clock);
3.1195
3.1196 -uint32_t
3.1197 -Cpm_x1600_chip::get_apll_frequency()
3.1198 -{
3.1199 - return get_pll_frequency(Pll_control_A);
3.1200 -}
3.1201 + // Return the frequency of the source.
3.1202
3.1203 -uint32_t
3.1204 -Cpm_x1600_chip::get_epll_frequency()
3.1205 -{
3.1206 - return get_pll_frequency(Pll_control_E);
3.1207 -}
3.1208 -
3.1209 -uint32_t
3.1210 -Cpm_x1600_chip::get_mpll_frequency()
3.1211 -{
3.1212 - return get_pll_frequency(Pll_control_M);
3.1213 + if (source < desc.num_inputs)
3.1214 + return get_input_frequency(desc.inputs[source]);
3.1215 + else
3.1216 + return 0;
3.1217 }
3.1218
3.1219
3.1220
3.1221 +// Output clock frequencies.
3.1222 +
3.1223 uint32_t
3.1224 Cpm_x1600_chip::get_frequency(enum Clock_identifiers clock)
3.1225 {
3.1226 - switch (clock)
3.1227 - {
3.1228 - // NOTE: Returning only the frequency for controller 0.
3.1229 -
3.1230 - case Clock_lcd_pixel:
3.1231 - return get_lcd_source_frequency(0) / get_lcd_pixel_divider(0);
3.1232 -
3.1233 - // NOTE: Consider a better error result.
3.1234 -
3.1235 - default:
3.1236 - return 0;
3.1237 - }
3.1238 + return get_source_frequency(clock) / get_divider(clock);
3.1239 }
3.1240
3.1241 void
3.1242 @@ -885,9 +949,9 @@
3.1243
3.1244 // Switch to the MPLL and attempt to set the divider.
3.1245
3.1246 - set_lcd_source(0, Source_pll_M);
3.1247 + set_source(Clock_lcd_pixel, Source_mME_pll_M);
3.1248 pll_enable(Pll_control_M);
3.1249 - set_lcd_pixel_divider(0, get_lcd_source_frequency() / frequency);
3.1250 + set_divider(Clock_lcd_pixel, get_source_frequency(clock) / frequency);
3.1251 break;
3.1252
3.1253 default:
3.1254 @@ -928,172 +992,38 @@
3.1255
3.1256
3.1257
3.1258 -uint8_t
3.1259 -x1600_cpm_get_cpu_divider(void *cpm)
3.1260 +uint32_t
3.1261 +x1600_cpm_get_divider(void *cpm, enum Clock_identifiers clock)
3.1262 {
3.1263 - return static_cast<Cpm_x1600_chip *>(cpm)->get_cpu_divider();
3.1264 -}
3.1265 -
3.1266 -uint8_t
3.1267 -x1600_cpm_get_hclock0_divider(void *cpm)
3.1268 -{
3.1269 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_divider();
3.1270 + return static_cast<Cpm_x1600_chip *>(cpm)->get_divider(clock);
3.1271 }
3.1272
3.1273 -uint8_t
3.1274 -x1600_cpm_get_hclock2_divider(void *cpm)
3.1275 -{
3.1276 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_divider();
3.1277 -}
3.1278 -
3.1279 -uint8_t
3.1280 -x1600_cpm_get_lcd_pixel_divider(void *cpm)
3.1281 +void
3.1282 +x1600_cpm_set_divider(void *cpm, enum Clock_identifiers clock, uint32_t divider)
3.1283 {
3.1284 - return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_pixel_divider();
3.1285 -}
3.1286 -
3.1287 -uint8_t
3.1288 -x1600_cpm_get_memory_divider(void *cpm)
3.1289 -{
3.1290 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_divider();
3.1291 -}
3.1292 -
3.1293 -uint8_t
3.1294 -x1600_cpm_get_pclock_divider(void *cpm)
3.1295 -{
3.1296 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_divider();
3.1297 + return static_cast<Cpm_x1600_chip *>(cpm)->set_divider(clock, divider);
3.1298 }
3.1299
3.1300
3.1301
3.1302 uint8_t
3.1303 -x1600_cpm_get_hclock0_source(void *cpm)
3.1304 -{
3.1305 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_source();
3.1306 -}
3.1307 -
3.1308 -uint8_t
3.1309 -x1600_cpm_get_hclock2_source(void *cpm)
3.1310 -{
3.1311 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_source();
3.1312 -}
3.1313 -
3.1314 -uint8_t
3.1315 -x1600_cpm_get_lcd_source(void *cpm)
3.1316 +x1600_cpm_get_source(void *cpm, enum Clock_identifiers clock)
3.1317 {
3.1318 - return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_source();
3.1319 -}
3.1320 -
3.1321 -uint8_t
3.1322 -x1600_cpm_get_memory_source(void *cpm)
3.1323 -{
3.1324 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_source();
3.1325 -}
3.1326 -
3.1327 -uint8_t
3.1328 -x1600_cpm_get_pclock_source(void *cpm)
3.1329 -{
3.1330 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_source();
3.1331 + return static_cast<Cpm_x1600_chip *>(cpm)->get_source(clock);
3.1332 }
3.1333
3.1334 void
3.1335 -x1600_cpm_set_pclock_source(void *cpm, uint8_t source)
3.1336 +x1600_cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source)
3.1337 {
3.1338 - static_cast<Cpm_x1600_chip *>(cpm)->set_pclock_source(source);
3.1339 + static_cast<Cpm_x1600_chip *>(cpm)->set_source(clock, source);
3.1340 }
3.1341
3.1342
3.1343
3.1344 uint32_t
3.1345 -x1600_cpm_get_hclock0_source_frequency(void *cpm)
3.1346 -{
3.1347 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_source_frequency();
3.1348 -}
3.1349 -
3.1350 -uint32_t
3.1351 -x1600_cpm_get_hclock2_source_frequency(void *cpm)
3.1352 -{
3.1353 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_source_frequency();
3.1354 -}
3.1355 -
3.1356 -uint32_t
3.1357 -x1600_cpm_get_lcd_source_frequency(void *cpm)
3.1358 -{
3.1359 - return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_source_frequency();
3.1360 -}
3.1361 -
3.1362 -uint32_t
3.1363 -x1600_cpm_get_memory_source_frequency(void *cpm)
3.1364 -{
3.1365 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_source_frequency();
3.1366 -}
3.1367 -
3.1368 -uint32_t
3.1369 -x1600_cpm_get_pclock_source_frequency(void *cpm)
3.1370 -{
3.1371 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_source_frequency();
3.1372 -}
3.1373 -
3.1374 -
3.1375 -
3.1376 -uint8_t
3.1377 -x1600_cpm_get_main_source(void *cpm)
3.1378 -{
3.1379 - return static_cast<Cpm_x1600_chip *>(cpm)->get_main_source();
3.1380 -}
3.1381 -
3.1382 -uint32_t
3.1383 -x1600_cpm_get_main_frequency(void *cpm)
3.1384 +x1600_cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock)
3.1385 {
3.1386 - return static_cast<Cpm_x1600_chip *>(cpm)->get_main_frequency();
3.1387 -}
3.1388 -
3.1389 -uint32_t
3.1390 -x1600_cpm_get_cpu_frequency(void *cpm)
3.1391 -{
3.1392 - return static_cast<Cpm_x1600_chip *>(cpm)->get_cpu_frequency();
3.1393 -}
3.1394 -
3.1395 -uint32_t
3.1396 -x1600_cpm_get_hclock0_frequency(void *cpm)
3.1397 -{
3.1398 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_frequency();
3.1399 -}
3.1400 -
3.1401 -uint32_t
3.1402 -x1600_cpm_get_hclock2_frequency(void *cpm)
3.1403 -{
3.1404 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_frequency();
3.1405 -}
3.1406 -
3.1407 -uint32_t
3.1408 -x1600_cpm_get_memory_frequency(void *cpm)
3.1409 -{
3.1410 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_frequency();
3.1411 -}
3.1412 -
3.1413 -uint32_t
3.1414 -x1600_cpm_get_pclock_frequency(void *cpm)
3.1415 -{
3.1416 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_frequency();
3.1417 -}
3.1418 -
3.1419 -uint32_t
3.1420 -x1600_cpm_get_apll_frequency(void *cpm)
3.1421 -{
3.1422 - return static_cast<Cpm_x1600_chip *>(cpm)->get_apll_frequency();
3.1423 -}
3.1424 -
3.1425 -uint32_t
3.1426 -x1600_cpm_get_epll_frequency(void *cpm)
3.1427 -{
3.1428 - return static_cast<Cpm_x1600_chip *>(cpm)->get_epll_frequency();
3.1429 -}
3.1430 -
3.1431 -uint32_t
3.1432 -x1600_cpm_get_mpll_frequency(void *cpm)
3.1433 -{
3.1434 - return static_cast<Cpm_x1600_chip *>(cpm)->get_mpll_frequency();
3.1435 + return static_cast<Cpm_x1600_chip *>(cpm)->get_source_frequency(clock);
3.1436 }
3.1437
3.1438
3.1439 @@ -1110,6 +1040,8 @@
3.1440 static_cast<Cpm_x1600_chip *>(cpm)->set_frequency(clock, frequency);
3.1441 }
3.1442
3.1443 +
3.1444 +
3.1445 void
3.1446 x1600_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider)
3.1447 {