1.1 --- a/pkg/devices/lib/cpm/src/x1600.cc Thu Sep 14 00:11:14 2023 +0200
1.2 +++ b/pkg/devices/lib/cpm/src/x1600.cc Thu Sep 14 00:13:02 2023 +0200
1.3 @@ -24,9 +24,12 @@
1.4 #include <l4/devices/hw_mmio_register_block.h>
1.5 #include "cpm-x1600.h"
1.6 #include <math.h>
1.7 +#include <stdio.h>
1.8
1.9
1.10
1.11 +// Register locations.
1.12 +
1.13 enum Regs : unsigned
1.14 {
1.15 Clock_control = 0x000, // CPCCR
1.16 @@ -67,21 +70,10 @@
1.17 Pll_fraction_A = 0x084, // CPAPACR
1.18 Pll_fraction_M = 0x088, // CPMPACR
1.19 Pll_fraction_E = 0x08c, // CPEPACR
1.20 -};
1.21 -
1.22 -enum Clock_bits : unsigned
1.23 -{
1.24 - // Clock_control
1.25
1.26 - Clock_gate_A = 23, // GATE_SCLKA
1.27 - Clock_cpu_change_enable = 22, // CE_CPU
1.28 - Clock_ahb0_change_enable = 21, // CE_AHB0
1.29 - Clock_ahb2_change_enable = 20, // CE_AHB2
1.30 - Clock_pclock_divider = 16, // PDIV (slow APB peripherals)
1.31 - Clock_hclock2_divider = 12, // H2DIV (fast AHB peripherals)
1.32 - Clock_hclock0_divider = 8, // H0DIV (fast AHB peripherals)
1.33 - Clock_l2cache_divider = 4, // L2CDIV
1.34 - Clock_cpu_divider = 0, // CDIV
1.35 + // Special value
1.36 +
1.37 + Reg_undefined = 0xfff,
1.38 };
1.39
1.40 enum Clock_source_bits : unsigned
1.41 @@ -93,84 +85,44 @@
1.42 Clock_source_hclock0 = 26, // SEL_H0PLL (output to AHB0)
1.43 Clock_source_hclock2 = 24, // SEL_H2PLL (output to AHB2)
1.44
1.45 - // Ddr_divider
1.46 -
1.47 - Clock_source_ddr = 30, // DCS
1.48 -
1.49 - // I2s_divider0
1.50 -
1.51 - Clock_source_i2s = 31, // I2PCS
1.52 -
1.53 - // Lcd_divider
1.54 -
1.55 - Clock_source_lcd = 30, // LPCS
1.56 -
1.57 - // Mac_divider
1.58 -
1.59 - Clock_source_mac = 30, // MACPCS
1.60 -
1.61 - // Msc_divider0, Msc_divider1
1.62 -
1.63 - Clock_source_msc0 = 30, // MPCS
1.64 - Clock_source_msc1 = 30, // MPCS
1.65 -
1.66 - // Sfc_divider
1.67 -
1.68 - Clock_source_sfc = 30, // SFCS
1.69 -
1.70 - // Ssi_divider
1.71 -
1.72 - Clock_source_ssi = 30, // SPCS
1.73 -
1.74 - // Cim_divider
1.75 -
1.76 - Clock_source_cim = 30, // CIMPCS
1.77 -
1.78 - // Pwm_divider
1.79 -
1.80 - Clock_source_pwm = 30, // PWMPCS
1.81 -
1.82 - // Can_divider0, Can_divider1
1.83 + // Divider registers
1.84
1.85 Clock_source_can0 = 30, // CA0CS
1.86 Clock_source_can1 = 30, // CA1CS
1.87 + Clock_source_cdbus = 30, // CDCS
1.88 + Clock_source_cim = 30, // CIMPCS
1.89 + Clock_source_ddr = 30, // DCS
1.90 + Clock_source_i2s = 31, // I2PCS
1.91 + Clock_source_lcd = 30, // LPCS
1.92 + Clock_source_mac = 30, // MACPCS
1.93 + Clock_source_msc0 = 30, // MPCS
1.94 + Clock_source_msc1 = 30, // MPCS
1.95 + Clock_source_pwm = 30, // PWMPCS
1.96 + Clock_source_sfc = 30, // SFCS
1.97 + Clock_source_ssi = 30, // SPCS
1.98
1.99 - // Cdbus_divider
1.100 + // Special value
1.101
1.102 - Clock_source_cdbus = 30, // CDCS
1.103 + Clock_source_undefined = 32,
1.104 };
1.105
1.106 -enum Clock_sources : unsigned
1.107 +enum Clock_source_values : unsigned
1.108 {
1.109 - // Clock_source_main
1.110 -
1.111 - Source_external = 1, // EXCLK
1.112 - Source_pll_A = 2, // APLL
1.113 -
1.114 - // Stoppable clock sources:
1.115 - // Clock_source_cpu, Clock_source_hclock0, Clock_source_hclock2,
1.116 - // Clock_source_ddr
1.117 + Source_mME_main = 0,
1.118 + Source_mME_pll_M = 1,
1.119 + Source_mME_pll_E = 2,
1.120
1.121 - Source_mux_stopped = 0,
1.122 - Source_mux_main = 1, // SCLK_A
1.123 - Source_mux_pll_M = 2, // MPLL
1.124 + // Special value
1.125
1.126 - // Unstoppable clock sources:
1.127 - // Clock_source_mac, Clock_source_i2s, Clock_source_lcd, Clock_source_msc0,
1.128 - // Clock_source_msc1, Clock_source_sfc, Clock_source_ssi, Clock_source_cim,
1.129 - // Clock_source_pwm, Clock_source_can0, Clock_source_can1, Clock_source_cdbus
1.130 -
1.131 - Source_main = 0, // SCLK_A
1.132 - Source_pll_M = 1, // MPLL
1.133 - Source_pll_E = 2, // EPLL
1.134 -
1.135 - Source_i2s_pll_E = 1, // EPLL
1.136 -
1.137 - Source_can_external = 3, // EXCLK
1.138 + Source_mask = 0x3,
1.139 };
1.140
1.141 enum Clock_gate_bits : unsigned
1.142 {
1.143 + // Clock_control
1.144 +
1.145 + Clock_gate_main = 23, // GATE_SCLKA
1.146 +
1.147 // Clock_gate0
1.148
1.149 Clock_gate_ddr = 31, // DDR
1.150 @@ -220,111 +172,74 @@
1.151 Clock_gate_undefined = 32,
1.152 };
1.153
1.154 -// Clock gate register correspondences.
1.155 +enum Clock_change_enable_bits : unsigned
1.156 +{
1.157 + Clock_change_enable_cpu = 22,
1.158 + Clock_change_enable_ahb0 = 21,
1.159 + Clock_change_enable_ahb2 = 20,
1.160 + Clock_change_enable_ddr = 29,
1.161 + Clock_change_enable_mac = 29,
1.162 + Clock_change_enable_i2s = 29,
1.163 + Clock_change_enable_lcd = 29,
1.164 + Clock_change_enable_msc0 = 29,
1.165 + Clock_change_enable_msc1 = 29,
1.166 + Clock_change_enable_sfc = 29,
1.167 + Clock_change_enable_ssi = 29,
1.168 + Clock_change_enable_cim = 29,
1.169 + Clock_change_enable_pwm = 29,
1.170 + Clock_change_enable_can0 = 29,
1.171 + Clock_change_enable_can1 = 29,
1.172 + Clock_change_enable_cdbus = 29,
1.173
1.174 -static uint32_t clock_gate_reg[Clock_identifier_count] = {
1.175 - /* Clock_aic_bitclk */ 0,
1.176 - /* Clock_aic_pclk */ 0,
1.177 - /* Clock_can0 */ Clock_gate1,
1.178 - /* Clock_can1 */ Clock_gate1,
1.179 - /* Clock_cdbus */ Clock_gate1,
1.180 - /* Clock_cim */ Clock_gate0,
1.181 - /* Clock_ddr */ Clock_gate0,
1.182 - /* Clock_dma */ Clock_gate0,
1.183 - /* Clock_emac */ 0,
1.184 - /* Clock_hdmi */ 0,
1.185 - /* Clock_i2c */ Clock_gate0,
1.186 - /* Clock_i2c0 */ Clock_gate0,
1.187 - /* Clock_i2c1 */ Clock_gate0,
1.188 - /* Clock_i2s */ 0,
1.189 - /* Clock_i2s0_rx */ Clock_gate1,
1.190 - /* Clock_i2s0_tx */ Clock_gate1,
1.191 - /* Clock_kbc */ 0,
1.192 - /* Clock_lcd */ 0,
1.193 - /* Clock_lcd_pixel */ Clock_gate0,
1.194 - /* Clock_mac */ Clock_gate1,
1.195 - /* Clock_msc */ Clock_gate0,
1.196 - /* Clock_msc0 */ Clock_gate0,
1.197 - /* Clock_msc1 */ Clock_gate0,
1.198 - /* Clock_pwm */ Clock_gate1,
1.199 - /* Clock_pwm0 */ Clock_gate1,
1.200 - /* Clock_pwm1 */ 0,
1.201 - /* Clock_scc */ 0,
1.202 - /* Clock_sfc */ Clock_gate0,
1.203 - /* Clock_smb0 */ 0,
1.204 - /* Clock_smb1 */ 0,
1.205 - /* Clock_smb2 */ 0,
1.206 - /* Clock_smb3 */ 0,
1.207 - /* Clock_smb4 */ 0,
1.208 - /* Clock_ssi */ Clock_gate0,
1.209 - /* Clock_timer */ Clock_gate0,
1.210 - /* Clock_uart0 */ Clock_gate0,
1.211 - /* Clock_uart1 */ Clock_gate0,
1.212 - /* Clock_uart2 */ Clock_gate0,
1.213 - /* Clock_uart3 */ Clock_gate1,
1.214 - /* Clock_udc */ 0,
1.215 - /* Clock_uhc */ 0,
1.216 - /* Clock_uprt */ 0,
1.217 + // Special value
1.218 +
1.219 + Clock_change_enable_undefined = 32,
1.220 };
1.221
1.222 -// Clock gate register bit correspondences.
1.223 +enum Clock_busy_bits : unsigned
1.224 +{
1.225 + Clock_busy_cpu = 0,
1.226 + Clock_busy_ddr = 28,
1.227 + Clock_busy_mac = 28,
1.228 + Clock_busy_lcd = 28,
1.229 + Clock_busy_msc0 = 28,
1.230 + Clock_busy_msc1 = 28,
1.231 + Clock_busy_sfc = 28,
1.232 + Clock_busy_ssi = 28,
1.233 + Clock_busy_cim = 28,
1.234 + Clock_busy_pwm = 28,
1.235 + Clock_busy_can0 = 28,
1.236 + Clock_busy_can1 = 28,
1.237 + Clock_busy_cdbus = 28,
1.238
1.239 -static enum Clock_gate_bits clock_gate_bit[Clock_identifier_count] = {
1.240 - /* Clock_aic_bitclk */ Clock_gate_undefined,
1.241 - /* Clock_aic_pclk */ Clock_gate_undefined,
1.242 - /* Clock_can0 */ Clock_gate_can0,
1.243 - /* Clock_can1 */ Clock_gate_can1,
1.244 - /* Clock_cdbus */ Clock_gate_cdbus,
1.245 - /* Clock_cim */ Clock_gate_cim,
1.246 - /* Clock_ddr */ Clock_gate_ddr,
1.247 - /* Clock_dma */ Clock_gate_dma,
1.248 - /* Clock_emac */ Clock_gate_undefined,
1.249 - /* Clock_hdmi */ Clock_gate_undefined,
1.250 - /* Clock_i2c */ Clock_gate_i2c0,
1.251 - /* Clock_i2c0 */ Clock_gate_i2c0,
1.252 - /* Clock_i2c1 */ Clock_gate_i2c1,
1.253 - /* Clock_i2s */ Clock_gate_undefined,
1.254 - /* Clock_i2s0_rx */ Clock_gate_i2s0_rx,
1.255 - /* Clock_i2s0_tx */ Clock_gate_i2s0_tx,
1.256 - /* Clock_kbc */ Clock_gate_undefined,
1.257 - /* Clock_lcd */ Clock_gate_undefined,
1.258 - /* Clock_lcd_pixel */ Clock_gate_lcd_pixel,
1.259 - /* Clock_mac */ Clock_gate_gmac0,
1.260 - /* Clock_msc */ Clock_gate_msc0,
1.261 - /* Clock_msc0 */ Clock_gate_msc0,
1.262 - /* Clock_msc1 */ Clock_gate_msc1,
1.263 - /* Clock_pwm */ Clock_gate_pwm,
1.264 - /* Clock_pwm0 */ Clock_gate_pwm,
1.265 - /* Clock_pwm1 */ Clock_gate_undefined,
1.266 - /* Clock_scc */ Clock_gate_undefined,
1.267 - /* Clock_sfc */ Clock_gate_sfc,
1.268 - /* Clock_smb0 */ Clock_gate_undefined,
1.269 - /* Clock_smb1 */ Clock_gate_undefined,
1.270 - /* Clock_smb2 */ Clock_gate_undefined,
1.271 - /* Clock_smb3 */ Clock_gate_undefined,
1.272 - /* Clock_smb4 */ Clock_gate_undefined,
1.273 - /* Clock_ssi */ Clock_gate_ssi0,
1.274 - /* Clock_timer */ Clock_gate_timer,
1.275 - /* Clock_uart0 */ Clock_gate_uart0,
1.276 - /* Clock_uart1 */ Clock_gate_uart1,
1.277 - /* Clock_uart2 */ Clock_gate_uart2,
1.278 - /* Clock_uart3 */ Clock_gate_uart3,
1.279 - /* Clock_udc */ Clock_gate_undefined,
1.280 - /* Clock_uhc */ Clock_gate_undefined,
1.281 - /* Clock_uprt */ Clock_gate_undefined,
1.282 + // Special value
1.283 +
1.284 + Clock_busy_undefined = 32,
1.285 };
1.286
1.287 -enum Divider_bits : unsigned
1.288 +enum Clock_divider_bits : unsigned
1.289 {
1.290 - Ddr_divider_value = 0, // DDRCDR
1.291 - Lcd_divider_value = 0, // LPCDR
1.292 -};
1.293 + Clock_divider_can0 = 0, // CAN0CDR
1.294 + Clock_divider_can1 = 0, // CAN1CDR
1.295 + Clock_divider_cdbus = 0, // CDBUSCDR
1.296 + Clock_divider_cim = 0, // CIMCDR
1.297 + Clock_divider_cpu = 0, // CDIV
1.298 + Clock_divider_ddr = 0, // DDRCDR
1.299 + Clock_divider_hclock0 = 8, // H0DIV (fast AHB peripherals)
1.300 + Clock_divider_hclock2 = 12, // H2DIV (fast AHB peripherals)
1.301 + Clock_divider_l2cache = 4, // L2CDIV
1.302 + Clock_divider_lcd = 0, // LPCDR
1.303 + Clock_divider_mac = 0, // MACCDR
1.304 + Clock_divider_msc0 = 0, // MSC0CDR
1.305 + Clock_divider_msc1 = 0, // MSC1CDR
1.306 + Clock_divider_pclock = 16, // PDIV (slow APB peripherals)
1.307 + Clock_divider_pwm = 0, // PWMCDR
1.308 + Clock_divider_sfc = 0, // SFCCDR
1.309 + Clock_divider_ssi = 0, // SSICDR
1.310
1.311 -enum Clock_status_values : unsigned
1.312 -{
1.313 - Lcd_change_enable = 0x20000000, // CE_LCD
1.314 - Lcd_change_busy = 0x10000000, // LCD_BUSY
1.315 - Lcd_clock_stop = 0x08000000, // LCD_STOP
1.316 + // Special value
1.317 +
1.318 + Clock_divider_undefined = 32,
1.319 };
1.320
1.321 enum Pll_bits : unsigned
1.322 @@ -348,6 +263,335 @@
1.323
1.324
1.325
1.326 +// Clock input descriptions.
1.327 +
1.328 +struct Clock_input_desc
1.329 +{
1.330 + uint32_t source_reg;
1.331 + enum Clock_source_bits source_bit;
1.332 + int num_inputs;
1.333 + enum Clock_input_identifiers inputs[3];
1.334 +};
1.335 +
1.336 +struct Clock_input_desc clock_input_desc[Clock_input_identifier_count] = {
1.337 +
1.338 + /* Clock_input_ahb2_apb */ {Clock_control, Clock_source_hclock2,
1.339 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
1.340 +
1.341 + /* Clock_input_external */ {Reg_undefined, Clock_source_undefined,
1.342 + 0, {}},
1.343 +
1.344 + /* Clock_input_main */ {Clock_control, Clock_source_main,
1.345 + 3, {Clock_input_none, Clock_input_external, Clock_input_pll_A}},
1.346 +
1.347 + /* Clock_input_none */ {Reg_undefined, Clock_source_undefined,
1.348 + 0, {}},
1.349 +
1.350 + /* Clock_input_pll_A */ {Reg_undefined, Clock_source_undefined,
1.351 + 1, {Clock_input_external}},
1.352 +
1.353 + /* Clock_input_pll_E */ {Reg_undefined, Clock_source_undefined,
1.354 + 1, {Clock_input_external}},
1.355 +
1.356 + /* Clock_input_pll_M */ {Reg_undefined, Clock_source_undefined,
1.357 + 1, {Clock_input_external}},
1.358 +};
1.359 +
1.360 +
1.361 +
1.362 +// Clock descriptions.
1.363 +
1.364 +struct Clock_desc
1.365 +{
1.366 + uint32_t source_reg;
1.367 + enum Clock_source_bits source_bit;
1.368 + uint32_t gate_reg;
1.369 + enum Clock_gate_bits gate_bit;
1.370 + uint32_t change_enable_reg;
1.371 + enum Clock_change_enable_bits change_enable_bit;
1.372 + uint32_t busy_reg;
1.373 + enum Clock_busy_bits busy_bit;
1.374 + uint32_t divider_reg;
1.375 + enum Clock_divider_bits divider_bit;
1.376 + uint32_t divider_mask;
1.377 + int num_inputs;
1.378 + enum Clock_input_identifiers inputs[4];
1.379 +};
1.380 +
1.381 +#define Clock_undefined {Reg_undefined, Clock_source_undefined, \
1.382 + Reg_undefined, Clock_gate_undefined, \
1.383 + Reg_undefined, Clock_change_enable_undefined, \
1.384 + Reg_undefined, Clock_busy_undefined, \
1.385 + Reg_undefined, Clock_divider_undefined, 0, \
1.386 + 0, {}}
1.387 +
1.388 +static struct Clock_desc clock_desc[Clock_identifier_count] = {
1.389 +
1.390 + /* Clock_aic_bitclk */ Clock_undefined,
1.391 +
1.392 + /* Clock_aic_pclk */ Clock_undefined,
1.393 +
1.394 + /* Clock_can0 */ {Can_divider0, Clock_source_can0,
1.395 + Clock_gate1, Clock_gate_can0,
1.396 + Can_divider0, Clock_change_enable_can0,
1.397 + Can_divider0, Clock_busy_can0,
1.398 + Can_divider0, Clock_divider_can0, 0xff,
1.399 + 4, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E, Clock_input_external}},
1.400 +
1.401 + /* Clock_can1 */ {Can_divider1, Clock_source_can1,
1.402 + Clock_gate1, Clock_gate_can1,
1.403 + Can_divider1, Clock_change_enable_can1,
1.404 + Can_divider1, Clock_busy_can1,
1.405 + Can_divider1, Clock_divider_can1, 0xff,
1.406 + 4, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E, Clock_input_external}},
1.407 +
1.408 + /* Clock_cdbus */ {Cdbus_divider, Clock_source_cdbus,
1.409 + Clock_gate1, Clock_gate_cdbus,
1.410 + Cdbus_divider, Clock_change_enable_cdbus,
1.411 + Cdbus_divider, Clock_busy_cdbus,
1.412 + Cdbus_divider, Clock_divider_cdbus, 0xff,
1.413 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.414 +
1.415 + /* Clock_cim */ {Cim_divider, Clock_source_cim,
1.416 + Clock_gate0, Clock_gate_cim,
1.417 + Cim_divider, Clock_change_enable_cim,
1.418 + Cim_divider, Clock_busy_cim,
1.419 + Cim_divider, Clock_divider_cim, 0xff,
1.420 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.421 +
1.422 + /* Clock_cpu */ {Clock_control, Clock_source_cpu,
1.423 + Reg_undefined, Clock_gate_undefined,
1.424 + Clock_control, Clock_change_enable_cpu,
1.425 + Clock_status, Clock_busy_cpu,
1.426 + Clock_control, Clock_divider_cpu, 0x0f,
1.427 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
1.428 +
1.429 + /* Clock_ddr */ {Ddr_divider, Clock_source_ddr,
1.430 + Clock_gate0, Clock_gate_ddr,
1.431 + Ddr_divider, Clock_change_enable_ddr,
1.432 + Ddr_divider, Clock_busy_ddr,
1.433 + Ddr_divider, Clock_divider_ddr, 0x0f,
1.434 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
1.435 +
1.436 + /* Clock_dma */ {Reg_undefined, Clock_source_undefined,
1.437 + Clock_gate0, Clock_gate_dma,
1.438 + Reg_undefined, Clock_change_enable_undefined,
1.439 + Reg_undefined, Clock_busy_undefined,
1.440 + Reg_undefined, Clock_divider_undefined, 0,
1.441 + 1, {Clock_input_ahb2_apb}},
1.442 +
1.443 + /* Clock_emac */ Clock_undefined,
1.444 +
1.445 + /* Clock_hclock0 */ {Clock_control, Clock_source_hclock0,
1.446 + Clock_gate0, Clock_gate_ahb0,
1.447 + Clock_control, Clock_change_enable_ahb0,
1.448 + Reg_undefined, Clock_busy_undefined,
1.449 + Clock_control, Clock_divider_hclock0, 0x0f,
1.450 + 3, {Clock_input_none, Clock_input_main, Clock_input_pll_M}},
1.451 +
1.452 + /* Clock_hclock2 */ {Reg_undefined, Clock_source_undefined,
1.453 + Clock_gate0, Clock_gate_apb0,
1.454 + Clock_control, Clock_change_enable_ahb2,
1.455 + Reg_undefined, Clock_busy_undefined,
1.456 + Clock_control, Clock_divider_hclock2, 0x0f,
1.457 + 1, {Clock_input_ahb2_apb}},
1.458 +
1.459 + /* Clock_hdmi */ Clock_undefined,
1.460 +
1.461 + /* Clock_i2c */ {Reg_undefined, Clock_source_undefined,
1.462 + Clock_gate0, Clock_gate_i2c0,
1.463 + Reg_undefined, Clock_change_enable_undefined,
1.464 + Reg_undefined, Clock_busy_undefined,
1.465 + Reg_undefined, Clock_divider_undefined, 0,
1.466 + 1, {Clock_input_ahb2_apb}},
1.467 +
1.468 + /* Clock_i2c0 */ {Reg_undefined, Clock_source_undefined,
1.469 + Clock_gate0, Clock_gate_i2c0,
1.470 + Reg_undefined, Clock_change_enable_undefined,
1.471 + Reg_undefined, Clock_busy_undefined,
1.472 + Reg_undefined, Clock_divider_undefined, 0,
1.473 + 1, {Clock_input_ahb2_apb}},
1.474 +
1.475 + /* Clock_i2c1 */ {Reg_undefined, Clock_source_undefined,
1.476 + Clock_gate0, Clock_gate_i2c1,
1.477 + Reg_undefined, Clock_change_enable_undefined,
1.478 + Reg_undefined, Clock_busy_undefined,
1.479 + Reg_undefined, Clock_divider_undefined, 0,
1.480 + 1, {Clock_input_ahb2_apb}},
1.481 +
1.482 + /* Clock_i2s */ Clock_undefined,
1.483 +
1.484 + /* Clock_i2s0_rx */ {I2s_divider0, Clock_source_i2s,
1.485 + Clock_gate1, Clock_gate_i2s0_rx,
1.486 + I2s_divider0, Clock_change_enable_i2s,
1.487 + Reg_undefined, Clock_busy_undefined,
1.488 + Reg_undefined, Clock_divider_undefined, 0, // NOTE: To define.
1.489 + 2, {Clock_input_main, Clock_input_pll_E}},
1.490 +
1.491 + /* Clock_i2s0_tx */ {I2s_divider0, Clock_source_i2s,
1.492 + Clock_gate1, Clock_gate_i2s0_tx,
1.493 + I2s_divider0, Clock_change_enable_i2s,
1.494 + Reg_undefined, Clock_busy_undefined,
1.495 + Reg_undefined, Clock_divider_undefined, 0, // NOTE: To define.
1.496 + 2, {Clock_input_main, Clock_input_pll_E}},
1.497 +
1.498 + /* Clock_kbc */ Clock_undefined,
1.499 +
1.500 + /* Clock_lcd */ Clock_undefined,
1.501 +
1.502 + /* Clock_lcd_pixel */ {Lcd_divider, Clock_source_lcd,
1.503 + Clock_gate0, Clock_gate_lcd_pixel,
1.504 + Lcd_divider, Clock_change_enable_lcd,
1.505 + Lcd_divider, Clock_busy_lcd,
1.506 + Lcd_divider, Clock_divider_lcd, 0xff,
1.507 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.508 +
1.509 + /* Clock_mac */ {Mac_divider, Clock_source_mac,
1.510 + Clock_gate1, Clock_gate_gmac0,
1.511 + Mac_divider, Clock_change_enable_mac,
1.512 + Mac_divider, Clock_busy_mac,
1.513 + Mac_divider, Clock_divider_mac, 0xff,
1.514 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.515 +
1.516 + /* Clock_main */ {Reg_undefined, Clock_source_undefined,
1.517 + Clock_control, Clock_gate_main,
1.518 + Reg_undefined, Clock_change_enable_undefined,
1.519 + Reg_undefined, Clock_busy_undefined,
1.520 + Reg_undefined, Clock_divider_undefined, 0,
1.521 + 1, {Clock_input_main}},
1.522 +
1.523 + /* Clock_msc */ {Msc_divider0, Clock_source_msc0,
1.524 + Clock_gate0, Clock_gate_msc0,
1.525 + Msc_divider0, Clock_change_enable_msc0,
1.526 + Msc_divider0, Clock_busy_msc0,
1.527 + Msc_divider0, Clock_divider_msc0, 0xff,
1.528 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.529 +
1.530 + /* Clock_msc0 */ {Msc_divider0, Clock_source_msc0,
1.531 + Clock_gate0, Clock_gate_msc0,
1.532 + Msc_divider0, Clock_change_enable_msc0,
1.533 + Msc_divider0, Clock_busy_msc0,
1.534 + Msc_divider0, Clock_divider_msc0, 0xff,
1.535 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.536 +
1.537 + /* Clock_msc1 */ {Msc_divider1, Clock_source_msc1,
1.538 + Clock_gate0, Clock_gate_msc1,
1.539 + Msc_divider1, Clock_change_enable_msc1,
1.540 + Msc_divider1, Clock_busy_msc1,
1.541 + Msc_divider1, Clock_divider_msc1, 0xff,
1.542 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.543 +
1.544 + /* Clock_pclock */ {Reg_undefined, Clock_source_undefined,
1.545 + Clock_gate0, Clock_gate_apb0,
1.546 + Reg_undefined, Clock_change_enable_undefined,
1.547 + Reg_undefined, Clock_busy_undefined,
1.548 + Clock_control, Clock_divider_pclock, 0x0f,
1.549 + 1, {Clock_input_ahb2_apb}},
1.550 +
1.551 + /* Clock_pwm */ {Pwm_divider, Clock_source_pwm,
1.552 + Clock_gate1, Clock_gate_pwm,
1.553 + Pwm_divider, Clock_change_enable_pwm,
1.554 + Pwm_divider, Clock_busy_pwm,
1.555 + Pwm_divider, Clock_divider_pwm, 0x0f,
1.556 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.557 +
1.558 + /* Clock_pwm0 */ {Pwm_divider, Clock_source_pwm,
1.559 + Clock_gate1, Clock_gate_pwm,
1.560 + Pwm_divider, Clock_change_enable_pwm,
1.561 + Pwm_divider, Clock_busy_pwm,
1.562 + Pwm_divider, Clock_divider_pwm, 0x0f,
1.563 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.564 +
1.565 + /* Clock_pwm1 */ Clock_undefined,
1.566 +
1.567 + /* Clock_scc */ Clock_undefined,
1.568 +
1.569 + /* Clock_sfc */ {Sfc_divider, Clock_source_sfc,
1.570 + Clock_gate0, Clock_gate_sfc,
1.571 + Sfc_divider, Clock_change_enable_sfc,
1.572 + Sfc_divider, Clock_busy_sfc,
1.573 + Sfc_divider, Clock_divider_sfc, 0xff,
1.574 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.575 +
1.576 + /* Clock_smb0 */ Clock_undefined,
1.577 +
1.578 + /* Clock_smb1 */ Clock_undefined,
1.579 +
1.580 + /* Clock_smb2 */ Clock_undefined,
1.581 +
1.582 + /* Clock_smb3 */ Clock_undefined,
1.583 +
1.584 + /* Clock_smb4 */ Clock_undefined,
1.585 +
1.586 + /* Clock_ssi */ {Ssi_divider, Clock_source_ssi,
1.587 + Clock_gate0, Clock_gate_ssi0,
1.588 + Ssi_divider, Clock_change_enable_ssi,
1.589 + Ssi_divider, Clock_busy_ssi,
1.590 + Ssi_divider, Clock_divider_ssi, 0xff,
1.591 + 3, {Clock_input_main, Clock_input_pll_M, Clock_input_pll_E}},
1.592 +
1.593 + /* Clock_timer */ {Reg_undefined, Clock_source_undefined,
1.594 + Clock_gate0, Clock_gate_timer,
1.595 + Reg_undefined, Clock_change_enable_undefined,
1.596 + Reg_undefined, Clock_busy_undefined,
1.597 + Reg_undefined, Clock_divider_undefined, 0,
1.598 + 1, {Clock_input_ahb2_apb}},
1.599 +
1.600 + /* Clock_uart0 */ {Reg_undefined, Clock_source_undefined,
1.601 + Clock_gate0, Clock_gate_uart0,
1.602 + Reg_undefined, Clock_change_enable_undefined,
1.603 + Reg_undefined, Clock_busy_undefined,
1.604 + Reg_undefined, Clock_divider_undefined, 0,
1.605 + 1, {Clock_input_ahb2_apb}},
1.606 +
1.607 + /* Clock_uart1 */ {Reg_undefined, Clock_source_undefined,
1.608 + Clock_gate0, Clock_gate_uart1,
1.609 + Reg_undefined, Clock_change_enable_undefined,
1.610 + Reg_undefined, Clock_busy_undefined,
1.611 + Reg_undefined, Clock_divider_undefined, 0,
1.612 + 1, {Clock_input_ahb2_apb}},
1.613 +
1.614 + /* Clock_uart2 */ {Reg_undefined, Clock_source_undefined,
1.615 + Clock_gate0, Clock_gate_uart2,
1.616 + Reg_undefined, Clock_change_enable_undefined,
1.617 + Reg_undefined, Clock_busy_undefined,
1.618 + Reg_undefined, Clock_divider_undefined, 0,
1.619 + 1, {Clock_input_ahb2_apb}},
1.620 +
1.621 + /* Clock_uart3 */ {Reg_undefined, Clock_source_undefined,
1.622 + Clock_gate1, Clock_gate_uart3,
1.623 + Reg_undefined, Clock_change_enable_undefined,
1.624 + Reg_undefined, Clock_busy_undefined,
1.625 + Reg_undefined, Clock_divider_undefined, 0,
1.626 + 1, {Clock_input_ahb2_apb}},
1.627 +
1.628 + /* Clock_udc */ Clock_undefined,
1.629 +
1.630 + /* Clock_uhc */ Clock_undefined,
1.631 +
1.632 + /* Clock_uprt */ Clock_undefined,
1.633 +};
1.634 +
1.635 +
1.636 +
1.637 +// Convenience functions.
1.638 +
1.639 +static uint8_t get_clock_gate_bit(enum Clock_identifiers clock)
1.640 +{
1.641 + enum Clock_gate_bits bit = clock_desc[clock].gate_bit;
1.642 +
1.643 + return bit != Clock_gate_undefined ? (uint8_t) bit : 0;
1.644 +}
1.645 +
1.646 +static uint32_t get_clock_gate_mask(enum Clock_identifiers clock)
1.647 +{
1.648 + enum Clock_gate_bits bit = clock_desc[clock].gate_bit;
1.649 +
1.650 + return bit != Clock_gate_undefined ? 1 : 0;
1.651 +}
1.652 +
1.653 +
1.654 +
1.655 // If implemented as a Hw::Device, various properties would be
1.656 // initialised in the constructor and obtained from the device tree
1.657 // definitions.
1.658 @@ -362,42 +606,6 @@
1.659 // register_property("exclk_freq", &_exclk_freq);
1.660 }
1.661
1.662 -// Clock/timer control.
1.663 -
1.664 -uint32_t
1.665 -Cpm_x1600_chip::get_clock_gate_register(enum Clock_identifiers clock)
1.666 -{
1.667 - return clock_gate_reg[clock];
1.668 -}
1.669 -
1.670 -uint32_t
1.671 -Cpm_x1600_chip::get_clock_gate_value(enum Clock_identifiers clock)
1.672 -{
1.673 - return 1 << clock_gate_bit[clock];
1.674 -}
1.675 -
1.676 -int
1.677 -Cpm_x1600_chip::have_clock(enum Clock_identifiers clock)
1.678 -{
1.679 - return !(_regs[get_clock_gate_register(clock)] & get_clock_gate_value(clock));
1.680 -}
1.681 -
1.682 -void
1.683 -Cpm_x1600_chip::start_clock(enum Clock_identifiers clock)
1.684 -{
1.685 - uint32_t gate = get_clock_gate_register(clock);
1.686 -
1.687 - _regs[gate] = _regs[gate] & ~get_clock_gate_value(clock);
1.688 -}
1.689 -
1.690 -void
1.691 -Cpm_x1600_chip::stop_clock(enum Clock_identifiers clock)
1.692 -{
1.693 - uint32_t gate = get_clock_gate_register(clock);
1.694 -
1.695 - _regs[gate] = _regs[gate] | get_clock_gate_value(clock);
1.696 -}
1.697 -
1.698
1.699
1.700 // Utility methods.
1.701 @@ -414,12 +622,61 @@
1.702 _regs[reg] = (_regs[reg] & (~(mask << shift))) | ((mask & value) << shift);
1.703 }
1.704
1.705 -// General clock divider access.
1.706 +
1.707 +
1.708 +// Clock/timer control.
1.709 +
1.710 +void
1.711 +Cpm_x1600_chip::change_disable(enum Clock_identifiers clock)
1.712 +{
1.713 + enum Clock_change_enable_bits bit = clock_desc[clock].change_enable_bit;
1.714 +
1.715 + if (bit != Clock_change_enable_undefined)
1.716 + set_field(clock_desc[clock].change_enable_reg, 1, bit, 0);
1.717 +}
1.718 +
1.719 +void
1.720 +Cpm_x1600_chip::change_enable(enum Clock_identifiers clock)
1.721 +{
1.722 + enum Clock_change_enable_bits bit = clock_desc[clock].change_enable_bit;
1.723 +
1.724 + if (bit != Clock_change_enable_undefined)
1.725 + set_field(clock_desc[clock].change_enable_reg, 1, bit, 1);
1.726 +}
1.727
1.728 -uint8_t
1.729 -Cpm_x1600_chip::_get_divider(uint32_t reg, uint32_t mask, uint8_t shift)
1.730 +int
1.731 +Cpm_x1600_chip::have_clock(enum Clock_identifiers clock)
1.732 +{
1.733 + if (clock_desc[clock].gate_bit != Clock_gate_undefined)
1.734 + return !get_field(clock_desc[clock].gate_reg, get_clock_gate_mask(clock),
1.735 + get_clock_gate_bit(clock));
1.736 + else
1.737 + return true;
1.738 +}
1.739 +
1.740 +void
1.741 +Cpm_x1600_chip::start_clock(enum Clock_identifiers clock)
1.742 {
1.743 - return get_field(reg, mask, shift) + 1;
1.744 + if (clock_desc[clock].gate_bit != Clock_gate_undefined)
1.745 + set_field(clock_desc[clock].gate_reg, get_clock_gate_mask(clock),
1.746 + get_clock_gate_bit(clock), 0);
1.747 +}
1.748 +
1.749 +void
1.750 +Cpm_x1600_chip::stop_clock(enum Clock_identifiers clock)
1.751 +{
1.752 + if (clock_desc[clock].gate_bit != Clock_gate_undefined)
1.753 + set_field(clock_desc[clock].gate_reg, get_clock_gate_mask(clock),
1.754 + get_clock_gate_bit(clock), 1);
1.755 +}
1.756 +
1.757 +void
1.758 +Cpm_x1600_chip::wait_busy(enum Clock_identifiers clock)
1.759 +{
1.760 + enum Clock_busy_bits bit = clock_desc[clock].busy_bit;
1.761 +
1.762 + if (bit != Clock_busy_undefined)
1.763 + while (get_field(clock_desc[clock].busy_reg, 1, bit));
1.764 }
1.765
1.766
1.767 @@ -431,43 +688,44 @@
1.768 int
1.769 Cpm_x1600_chip::have_pll(uint32_t pll_reg)
1.770 {
1.771 - return _regs[pll_reg] & (1 << Pll_stable);
1.772 + return get_field(pll_reg, 1, Pll_stable);
1.773 }
1.774
1.775 int
1.776 Cpm_x1600_chip::pll_enabled(uint32_t pll_reg)
1.777 {
1.778 - return _regs[pll_reg] & (1 << Pll_enabled);
1.779 + return get_field(pll_reg, 1, Pll_enabled);
1.780 }
1.781
1.782 int
1.783 Cpm_x1600_chip::pll_bypassed(uint32_t pll_reg)
1.784 {
1.785 - uint32_t mask;
1.786 + uint8_t bit;
1.787 + unsigned mask = 1;
1.788
1.789 switch (pll_reg)
1.790 {
1.791 - case Pll_control_A: mask = (1 << Pll_bypass_A); break;
1.792 - case Pll_control_M: mask = (1 << Pll_bypass_M); break;
1.793 - case Pll_control_E: mask = (1 << Pll_bypass_E); break;
1.794 - default: mask = 0; break;
1.795 + case Pll_control_A: bit = Pll_bypass_A; break;
1.796 + case Pll_control_M: bit = Pll_bypass_M; break;
1.797 + case Pll_control_E: bit = Pll_bypass_E; break;
1.798 + default: bit = 0; mask = 0; break;
1.799 }
1.800
1.801 - return _regs[Pll_control] & mask;
1.802 + return get_field(Pll_control, mask, bit);
1.803 }
1.804
1.805 void
1.806 Cpm_x1600_chip::pll_enable(uint32_t pll_reg)
1.807 {
1.808 - _regs[pll_reg] = _regs[pll_reg] | (1 << Pll_enabled);
1.809 - while (!(_regs[pll_reg] & (1 << Pll_stable)));
1.810 + set_field(pll_reg, 1, Pll_enabled, 1);
1.811 + while (!have_pll(pll_reg));
1.812 }
1.813
1.814 void
1.815 Cpm_x1600_chip::pll_disable(uint32_t pll_reg)
1.816 {
1.817 - _regs[pll_reg] = _regs[pll_reg] & ~(1 << Pll_enabled);
1.818 - while (_regs[pll_reg] & (1 << Pll_stable));
1.819 + set_field(pll_reg, 1, Pll_enabled, 0);
1.820 + while (have_pll(pll_reg));
1.821 }
1.822
1.823 // Feedback (13-bit) multiplier.
1.824 @@ -547,78 +805,29 @@
1.825
1.826
1.827
1.828 -// CPU clock (CCLK) divider.
1.829 +// Clock dividers.
1.830
1.831 -uint8_t
1.832 -Cpm_x1600_chip::get_cpu_divider()
1.833 -{
1.834 - return _get_divider(Clock_control, 0xf, Clock_cpu_divider);
1.835 -}
1.836 -
1.837 -// Fast peripheral clock (H0CLK) divider.
1.838 -
1.839 -uint8_t
1.840 -Cpm_x1600_chip::get_hclock0_divider()
1.841 +uint32_t
1.842 +Cpm_x1600_chip::get_divider(enum Clock_identifiers clock)
1.843 {
1.844 - return _get_divider(Clock_control, 0xf, Clock_hclock0_divider);
1.845 -}
1.846 -
1.847 -// Fast peripheral clock (H2CLK) divider.
1.848 -
1.849 -uint8_t
1.850 -Cpm_x1600_chip::get_hclock2_divider()
1.851 -{
1.852 - return _get_divider(Clock_control, 0xf, Clock_hclock2_divider);
1.853 -}
1.854 -
1.855 -// Slow peripheral clock (PCLK) divider.
1.856 -
1.857 -uint8_t
1.858 -Cpm_x1600_chip::get_pclock_divider()
1.859 -{
1.860 - return _get_divider(Clock_control, 0xf, Clock_pclock_divider);
1.861 + if (clock_desc[clock].divider_bit != Clock_divider_undefined)
1.862 + return get_field(clock_desc[clock].divider_reg, clock_desc[clock].divider_mask,
1.863 + clock_desc[clock].divider_bit) + 1;
1.864 + else
1.865 + return 1;
1.866 }
1.867
1.868 -// LCD clock (LPCLK) divider for LCD pixel clock.
1.869 -
1.870 -uint8_t
1.871 -Cpm_x1600_chip::get_lcd_pixel_divider(uint8_t controller)
1.872 +void
1.873 +Cpm_x1600_chip::set_divider(enum Clock_identifiers clock, uint32_t division)
1.874 {
1.875 - (void) controller;
1.876 - return _get_divider(Lcd_divider, 0xff, Lcd_divider_value);
1.877 -}
1.878 -
1.879 -// Memory clock (DDR_CLK) divider.
1.880 -
1.881 -uint8_t
1.882 -Cpm_x1600_chip::get_memory_divider()
1.883 -{
1.884 - return _get_divider(Ddr_divider, 0xf, Ddr_divider_value);
1.885 -}
1.886 -
1.887 -// LCD pixel clock divider.
1.888 -
1.889 -void
1.890 -Cpm_x1600_chip::set_lcd_pixel_divider(uint8_t controller, uint16_t division)
1.891 -{
1.892 - if (controller > 0)
1.893 + if (clock_desc[clock].divider_bit == Clock_divider_undefined)
1.894 return;
1.895
1.896 - if ((division < 1) || (division > 256))
1.897 - return;
1.898 -
1.899 - // Enable change.
1.900 -
1.901 - _regs[Lcd_divider] = _regs[Lcd_divider] | Lcd_change_enable;
1.902 -
1.903 - // Set the divider.
1.904 -
1.905 - set_field(Lcd_divider, 0xff, Lcd_divider_value, division - 1);
1.906 -
1.907 - // Restart clock and disable change.
1.908 -
1.909 - while (_regs[Lcd_divider] & Lcd_change_busy);
1.910 - _regs[Lcd_divider] = _regs[Lcd_divider] & ~Lcd_change_enable;
1.911 + change_enable(clock);
1.912 + set_field(clock_desc[clock].divider_reg, clock_desc[clock].divider_mask,
1.913 + clock_desc[clock].divider_bit, division - 1);
1.914 + wait_busy(clock);
1.915 + change_disable(clock);
1.916 }
1.917
1.918
1.919 @@ -626,251 +835,106 @@
1.920 // Clock sources.
1.921
1.922 uint8_t
1.923 -Cpm_x1600_chip::get_memory_source()
1.924 -{
1.925 - return get_field(Ddr_divider, 0x3, Clock_source_ddr);
1.926 -}
1.927 -
1.928 -uint32_t
1.929 -Cpm_x1600_chip::get_memory_source_frequency()
1.930 -{
1.931 - switch (get_memory_source())
1.932 - {
1.933 - case Source_mux_main:
1.934 - return get_main_frequency();
1.935 - case Source_mux_pll_M:
1.936 - return get_pll_frequency(Pll_control_M);
1.937 - default:
1.938 - return 0;
1.939 - }
1.940 -}
1.941 -
1.942 -uint8_t
1.943 -Cpm_x1600_chip::get_cpu_source()
1.944 -{
1.945 - return get_field(Clock_control, 0x3, Clock_source_cpu);
1.946 -}
1.947 -
1.948 -uint32_t
1.949 -Cpm_x1600_chip::get_cpu_source_frequency()
1.950 +Cpm_x1600_chip::get_source(enum Clock_identifiers clock)
1.951 {
1.952 - switch (get_cpu_source())
1.953 - {
1.954 - case Source_mux_main:
1.955 - return get_main_frequency();
1.956 - case Source_mux_pll_M:
1.957 - return get_pll_frequency(Pll_control_M);
1.958 - default:
1.959 - return 0;
1.960 - }
1.961 -}
1.962 -
1.963 -uint8_t
1.964 -Cpm_x1600_chip::get_hclock0_source()
1.965 -{
1.966 - return get_field(Clock_control, 0x3, Clock_source_hclock0);
1.967 -}
1.968 -
1.969 -uint32_t
1.970 -Cpm_x1600_chip::get_hclock0_source_frequency()
1.971 -{
1.972 - switch (get_hclock0_source())
1.973 - {
1.974 - case Source_mux_main:
1.975 - return get_main_frequency();
1.976 - case Source_mux_pll_M:
1.977 - return get_pll_frequency(Pll_control_M);
1.978 - default:
1.979 - return 0;
1.980 - }
1.981 -}
1.982 -
1.983 -uint8_t
1.984 -Cpm_x1600_chip::get_hclock2_source()
1.985 -{
1.986 - return get_field(Clock_control, 0x3, Clock_source_hclock2);
1.987 -}
1.988 -
1.989 -uint32_t
1.990 -Cpm_x1600_chip::get_hclock2_source_frequency()
1.991 -{
1.992 - switch (get_hclock2_source())
1.993 - {
1.994 - case Source_mux_main:
1.995 - return get_main_frequency();
1.996 - case Source_mux_pll_M:
1.997 - return get_pll_frequency(Pll_control_M);
1.998 - default:
1.999 - return 0;
1.1000 - }
1.1001 + if (clock_desc[clock].source_bit != Clock_source_undefined)
1.1002 + return get_field(clock_desc[clock].source_reg, Source_mask, clock_desc[clock].source_bit);
1.1003 + else
1.1004 + return 0;
1.1005 }
1.1006
1.1007 void
1.1008 -Cpm_x1600_chip::set_hclock2_source(uint8_t source)
1.1009 -{
1.1010 - set_field(Clock_control, 0x3, Clock_source_hclock2, source);
1.1011 -}
1.1012 -
1.1013 -uint8_t
1.1014 -Cpm_x1600_chip::get_lcd_source(uint8_t controller)
1.1015 -{
1.1016 - (void) controller;
1.1017 - return get_field(Lcd_divider, 0x3, Clock_source_lcd);
1.1018 -}
1.1019 -
1.1020 -uint32_t
1.1021 -Cpm_x1600_chip::get_lcd_source_frequency(uint8_t controller)
1.1022 +Cpm_x1600_chip::set_source(enum Clock_identifiers clock, uint8_t source)
1.1023 {
1.1024 - switch (get_lcd_source(controller))
1.1025 - {
1.1026 - case Source_main:
1.1027 - return get_main_frequency();
1.1028 - case Source_pll_M:
1.1029 - return get_pll_frequency(Pll_control_M);
1.1030 - case Source_pll_E:
1.1031 - return get_pll_frequency(Pll_control_E);
1.1032 - default:
1.1033 - return 0;
1.1034 - }
1.1035 -}
1.1036 -
1.1037 -void
1.1038 -Cpm_x1600_chip::set_lcd_source(uint8_t controller, uint8_t source)
1.1039 -{
1.1040 - if (controller > 0)
1.1041 + if (clock_desc[clock].source_bit == Clock_source_undefined)
1.1042 return;
1.1043
1.1044 - // Stop clock and enable change.
1.1045 -
1.1046 - _regs[Lcd_divider] = _regs[Lcd_divider] | Lcd_change_enable | Lcd_clock_stop;
1.1047 -
1.1048 - // Set the source.
1.1049 -
1.1050 - set_field(Lcd_divider, 0x03, Clock_source_lcd, source);
1.1051 -
1.1052 - // Restart clock and disable change.
1.1053 -
1.1054 - while (_regs[Lcd_divider] & Lcd_change_busy);
1.1055 - _regs[Lcd_divider] = _regs[Lcd_divider] & ~(Lcd_change_enable | Lcd_clock_stop);
1.1056 -}
1.1057 -
1.1058 -uint8_t
1.1059 -Cpm_x1600_chip::get_pclock_source()
1.1060 -{
1.1061 - return get_hclock2_source();
1.1062 -}
1.1063 -
1.1064 -uint32_t
1.1065 -Cpm_x1600_chip::get_pclock_source_frequency()
1.1066 -{
1.1067 - return get_hclock2_source_frequency();
1.1068 -}
1.1069 -
1.1070 -void
1.1071 -Cpm_x1600_chip::set_pclock_source(uint8_t source)
1.1072 -{
1.1073 - set_hclock2_source(source);
1.1074 + change_enable(clock);
1.1075 + set_field(clock_desc[clock].source_reg, Source_mask, clock_desc[clock].source_bit, source);
1.1076 + wait_busy(clock);
1.1077 + change_disable(clock);
1.1078 }
1.1079
1.1080
1.1081
1.1082 -// Source frequency, used by various clock sources.
1.1083 +// Clock source frequencies.
1.1084 +
1.1085 +uint32_t
1.1086 +Cpm_x1600_chip::get_input_frequency(enum Clock_input_identifiers clock)
1.1087 +{
1.1088 + struct Clock_input_desc desc = clock_input_desc[clock];
1.1089 +
1.1090 + // Clocks with no inputs provide a frequency.
1.1091 +
1.1092 + if (desc.num_inputs == 0)
1.1093 + {
1.1094 + switch (clock)
1.1095 + {
1.1096 + case Clock_input_external: return _exclk_freq;
1.1097 + default: return 0;
1.1098 + }
1.1099 + }
1.1100 +
1.1101 + // Of the input clocks, only PLLs have a single input.
1.1102
1.1103 -uint8_t
1.1104 -Cpm_x1600_chip::get_main_source()
1.1105 -{
1.1106 - return get_field(Clock_control, 0x3, Clock_source_main);
1.1107 + else if (desc.num_inputs == 1)
1.1108 + {
1.1109 + switch (clock)
1.1110 + {
1.1111 + case Clock_input_pll_A: return get_pll_frequency(Pll_control_A);
1.1112 + case Clock_input_pll_E: return get_pll_frequency(Pll_control_E);
1.1113 + case Clock_input_pll_M: return get_pll_frequency(Pll_control_M);
1.1114 + default: return 0;
1.1115 + }
1.1116 + }
1.1117 +
1.1118 + // With multiple sources, obtain the selected source for the clock.
1.1119 +
1.1120 + uint8_t source = get_field(desc.source_reg, Source_mask, desc.source_bit);
1.1121 +
1.1122 + // Return the frequency of the source.
1.1123 +
1.1124 + if (source < desc.num_inputs)
1.1125 + return get_input_frequency(desc.inputs[source]);
1.1126 + else
1.1127 + return 0;
1.1128 }
1.1129
1.1130 uint32_t
1.1131 -Cpm_x1600_chip::get_main_frequency()
1.1132 -{
1.1133 - switch (get_main_source())
1.1134 - {
1.1135 - case Source_pll_A:
1.1136 - return get_pll_frequency(Pll_control_A);
1.1137 - case Source_external:
1.1138 - return _exclk_freq;
1.1139 - default:
1.1140 - return 0;
1.1141 - }
1.1142 -}
1.1143 -
1.1144 -// Clock frequency for the CPU.
1.1145 -
1.1146 -uint32_t
1.1147 -Cpm_x1600_chip::get_cpu_frequency()
1.1148 -{
1.1149 - return get_cpu_source_frequency() / get_cpu_divider();
1.1150 -}
1.1151 -
1.1152 -// Clock frequency for fast peripherals.
1.1153 -
1.1154 -uint32_t
1.1155 -Cpm_x1600_chip::get_hclock0_frequency()
1.1156 -{
1.1157 - return get_hclock0_source_frequency() / get_hclock0_divider();
1.1158 -}
1.1159 -
1.1160 -// Clock frequency for fast peripherals.
1.1161 -
1.1162 -uint32_t
1.1163 -Cpm_x1600_chip::get_hclock2_frequency()
1.1164 +Cpm_x1600_chip::get_source_frequency(enum Clock_identifiers clock)
1.1165 {
1.1166 - return get_hclock2_source_frequency() / get_hclock2_divider();
1.1167 -}
1.1168 + struct Clock_desc desc = clock_desc[clock];
1.1169
1.1170 -// Clock frequency for slow peripherals.
1.1171 + // Undefined clocks return zero.
1.1172
1.1173 -uint32_t
1.1174 -Cpm_x1600_chip::get_pclock_frequency()
1.1175 -{
1.1176 - return get_pclock_source_frequency() / get_pclock_divider();
1.1177 -}
1.1178 + if (desc.num_inputs == 0)
1.1179 + return 0;
1.1180
1.1181 -// Clock frequency for the memory.
1.1182 + // Clocks with one source yield that input frequency.
1.1183
1.1184 -uint32_t
1.1185 -Cpm_x1600_chip::get_memory_frequency()
1.1186 -{
1.1187 - return get_memory_source_frequency() / get_memory_divider();
1.1188 -}
1.1189 + else if (desc.num_inputs == 1)
1.1190 + return get_input_frequency(desc.inputs[0]);
1.1191 +
1.1192 + // With multiple sources, obtain the selected source for the clock.
1.1193 +
1.1194 + uint8_t source = get_source(clock);
1.1195
1.1196 -uint32_t
1.1197 -Cpm_x1600_chip::get_apll_frequency()
1.1198 -{
1.1199 - return get_pll_frequency(Pll_control_A);
1.1200 -}
1.1201 + // Return the frequency of the source.
1.1202
1.1203 -uint32_t
1.1204 -Cpm_x1600_chip::get_epll_frequency()
1.1205 -{
1.1206 - return get_pll_frequency(Pll_control_E);
1.1207 -}
1.1208 -
1.1209 -uint32_t
1.1210 -Cpm_x1600_chip::get_mpll_frequency()
1.1211 -{
1.1212 - return get_pll_frequency(Pll_control_M);
1.1213 + if (source < desc.num_inputs)
1.1214 + return get_input_frequency(desc.inputs[source]);
1.1215 + else
1.1216 + return 0;
1.1217 }
1.1218
1.1219
1.1220
1.1221 +// Output clock frequencies.
1.1222 +
1.1223 uint32_t
1.1224 Cpm_x1600_chip::get_frequency(enum Clock_identifiers clock)
1.1225 {
1.1226 - switch (clock)
1.1227 - {
1.1228 - // NOTE: Returning only the frequency for controller 0.
1.1229 -
1.1230 - case Clock_lcd_pixel:
1.1231 - return get_lcd_source_frequency(0) / get_lcd_pixel_divider(0);
1.1232 -
1.1233 - // NOTE: Consider a better error result.
1.1234 -
1.1235 - default:
1.1236 - return 0;
1.1237 - }
1.1238 + return get_source_frequency(clock) / get_divider(clock);
1.1239 }
1.1240
1.1241 void
1.1242 @@ -885,9 +949,9 @@
1.1243
1.1244 // Switch to the MPLL and attempt to set the divider.
1.1245
1.1246 - set_lcd_source(0, Source_pll_M);
1.1247 + set_source(Clock_lcd_pixel, Source_mME_pll_M);
1.1248 pll_enable(Pll_control_M);
1.1249 - set_lcd_pixel_divider(0, get_lcd_source_frequency() / frequency);
1.1250 + set_divider(Clock_lcd_pixel, get_source_frequency(clock) / frequency);
1.1251 break;
1.1252
1.1253 default:
1.1254 @@ -928,172 +992,38 @@
1.1255
1.1256
1.1257
1.1258 -uint8_t
1.1259 -x1600_cpm_get_cpu_divider(void *cpm)
1.1260 +uint32_t
1.1261 +x1600_cpm_get_divider(void *cpm, enum Clock_identifiers clock)
1.1262 {
1.1263 - return static_cast<Cpm_x1600_chip *>(cpm)->get_cpu_divider();
1.1264 -}
1.1265 -
1.1266 -uint8_t
1.1267 -x1600_cpm_get_hclock0_divider(void *cpm)
1.1268 -{
1.1269 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_divider();
1.1270 + return static_cast<Cpm_x1600_chip *>(cpm)->get_divider(clock);
1.1271 }
1.1272
1.1273 -uint8_t
1.1274 -x1600_cpm_get_hclock2_divider(void *cpm)
1.1275 -{
1.1276 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_divider();
1.1277 -}
1.1278 -
1.1279 -uint8_t
1.1280 -x1600_cpm_get_lcd_pixel_divider(void *cpm)
1.1281 +void
1.1282 +x1600_cpm_set_divider(void *cpm, enum Clock_identifiers clock, uint32_t divider)
1.1283 {
1.1284 - return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_pixel_divider();
1.1285 -}
1.1286 -
1.1287 -uint8_t
1.1288 -x1600_cpm_get_memory_divider(void *cpm)
1.1289 -{
1.1290 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_divider();
1.1291 -}
1.1292 -
1.1293 -uint8_t
1.1294 -x1600_cpm_get_pclock_divider(void *cpm)
1.1295 -{
1.1296 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_divider();
1.1297 + return static_cast<Cpm_x1600_chip *>(cpm)->set_divider(clock, divider);
1.1298 }
1.1299
1.1300
1.1301
1.1302 uint8_t
1.1303 -x1600_cpm_get_hclock0_source(void *cpm)
1.1304 -{
1.1305 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_source();
1.1306 -}
1.1307 -
1.1308 -uint8_t
1.1309 -x1600_cpm_get_hclock2_source(void *cpm)
1.1310 -{
1.1311 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_source();
1.1312 -}
1.1313 -
1.1314 -uint8_t
1.1315 -x1600_cpm_get_lcd_source(void *cpm)
1.1316 +x1600_cpm_get_source(void *cpm, enum Clock_identifiers clock)
1.1317 {
1.1318 - return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_source();
1.1319 -}
1.1320 -
1.1321 -uint8_t
1.1322 -x1600_cpm_get_memory_source(void *cpm)
1.1323 -{
1.1324 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_source();
1.1325 -}
1.1326 -
1.1327 -uint8_t
1.1328 -x1600_cpm_get_pclock_source(void *cpm)
1.1329 -{
1.1330 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_source();
1.1331 + return static_cast<Cpm_x1600_chip *>(cpm)->get_source(clock);
1.1332 }
1.1333
1.1334 void
1.1335 -x1600_cpm_set_pclock_source(void *cpm, uint8_t source)
1.1336 +x1600_cpm_set_source(void *cpm, enum Clock_identifiers clock, uint8_t source)
1.1337 {
1.1338 - static_cast<Cpm_x1600_chip *>(cpm)->set_pclock_source(source);
1.1339 + static_cast<Cpm_x1600_chip *>(cpm)->set_source(clock, source);
1.1340 }
1.1341
1.1342
1.1343
1.1344 uint32_t
1.1345 -x1600_cpm_get_hclock0_source_frequency(void *cpm)
1.1346 -{
1.1347 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_source_frequency();
1.1348 -}
1.1349 -
1.1350 -uint32_t
1.1351 -x1600_cpm_get_hclock2_source_frequency(void *cpm)
1.1352 -{
1.1353 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_source_frequency();
1.1354 -}
1.1355 -
1.1356 -uint32_t
1.1357 -x1600_cpm_get_lcd_source_frequency(void *cpm)
1.1358 -{
1.1359 - return static_cast<Cpm_x1600_chip *>(cpm)->get_lcd_source_frequency();
1.1360 -}
1.1361 -
1.1362 -uint32_t
1.1363 -x1600_cpm_get_memory_source_frequency(void *cpm)
1.1364 -{
1.1365 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_source_frequency();
1.1366 -}
1.1367 -
1.1368 -uint32_t
1.1369 -x1600_cpm_get_pclock_source_frequency(void *cpm)
1.1370 -{
1.1371 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_source_frequency();
1.1372 -}
1.1373 -
1.1374 -
1.1375 -
1.1376 -uint8_t
1.1377 -x1600_cpm_get_main_source(void *cpm)
1.1378 -{
1.1379 - return static_cast<Cpm_x1600_chip *>(cpm)->get_main_source();
1.1380 -}
1.1381 -
1.1382 -uint32_t
1.1383 -x1600_cpm_get_main_frequency(void *cpm)
1.1384 +x1600_cpm_get_source_frequency(void *cpm, enum Clock_identifiers clock)
1.1385 {
1.1386 - return static_cast<Cpm_x1600_chip *>(cpm)->get_main_frequency();
1.1387 -}
1.1388 -
1.1389 -uint32_t
1.1390 -x1600_cpm_get_cpu_frequency(void *cpm)
1.1391 -{
1.1392 - return static_cast<Cpm_x1600_chip *>(cpm)->get_cpu_frequency();
1.1393 -}
1.1394 -
1.1395 -uint32_t
1.1396 -x1600_cpm_get_hclock0_frequency(void *cpm)
1.1397 -{
1.1398 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock0_frequency();
1.1399 -}
1.1400 -
1.1401 -uint32_t
1.1402 -x1600_cpm_get_hclock2_frequency(void *cpm)
1.1403 -{
1.1404 - return static_cast<Cpm_x1600_chip *>(cpm)->get_hclock2_frequency();
1.1405 -}
1.1406 -
1.1407 -uint32_t
1.1408 -x1600_cpm_get_memory_frequency(void *cpm)
1.1409 -{
1.1410 - return static_cast<Cpm_x1600_chip *>(cpm)->get_memory_frequency();
1.1411 -}
1.1412 -
1.1413 -uint32_t
1.1414 -x1600_cpm_get_pclock_frequency(void *cpm)
1.1415 -{
1.1416 - return static_cast<Cpm_x1600_chip *>(cpm)->get_pclock_frequency();
1.1417 -}
1.1418 -
1.1419 -uint32_t
1.1420 -x1600_cpm_get_apll_frequency(void *cpm)
1.1421 -{
1.1422 - return static_cast<Cpm_x1600_chip *>(cpm)->get_apll_frequency();
1.1423 -}
1.1424 -
1.1425 -uint32_t
1.1426 -x1600_cpm_get_epll_frequency(void *cpm)
1.1427 -{
1.1428 - return static_cast<Cpm_x1600_chip *>(cpm)->get_epll_frequency();
1.1429 -}
1.1430 -
1.1431 -uint32_t
1.1432 -x1600_cpm_get_mpll_frequency(void *cpm)
1.1433 -{
1.1434 - return static_cast<Cpm_x1600_chip *>(cpm)->get_mpll_frequency();
1.1435 + return static_cast<Cpm_x1600_chip *>(cpm)->get_source_frequency(clock);
1.1436 }
1.1437
1.1438
1.1439 @@ -1110,6 +1040,8 @@
1.1440 static_cast<Cpm_x1600_chip *>(cpm)->set_frequency(clock, frequency);
1.1441 }
1.1442
1.1443 +
1.1444 +
1.1445 void
1.1446 x1600_cpm_set_mpll_parameters(void *cpm, uint16_t multiplier, uint8_t in_divider, uint8_t out_divider)
1.1447 {