Changeset 68338c6 in mainline


Ignore:
Timestamp:
2012-11-20T11:51:14Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0c12dfe
Parents:
52e020b
Message:

rootamdm37x: Implement MPU DPLL handling.

Reads current MPU freq.
Enables LP mode (disabled for now).

Location:
uspace/drv/infrastructure/rootamdm37x
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c

    r52e020b r68338c6  
    5151#include "cm/clock_control.h"
    5252#include "cm/usbhost.h"
     53#include "cm/mpu.h"
    5354#include "prm/clock_control.h"
    5455
     
    5960        tll_regs_t *tll;
    6061        struct {
     62                mpu_cm_regs_t *mpu;
    6163                core_cm_regs_t *core;
    6264                clock_control_cm_regs_t *clocks;
     
    9496                return ret;
    9597
     98        ret = pio_enable((void*)MPU_CM_BASE_ADDRESS,
     99                    MPU_CM_SIZE, (void**)&device->cm.mpu);
     100        if (ret != EOK)
     101                return ret;
     102
    96103        ret = pio_enable((void*)CLOCK_CONTROL_PRM_BASE_ADDRESS,
    97104            CLOCK_CONTROL_PRM_SIZE, (void**)&device->prm.clocks);
     
    113120                pio_trace_enable(device->cm.clocks, CLOCK_CONTROL_CM_SIZE, log, (void*)CLOCK_CONTROL_CM_BASE_ADDRESS);
    114121                pio_trace_enable(device->cm.core, CORE_CM_SIZE, log, (void*)CORE_CM_BASE_ADDRESS);
     122                pio_trace_enable(device->cm.mpu, MPU_CM_SIZE, log, (void*)MPU_CM_BASE_ADDRESS);
    115123                pio_trace_enable(device->cm.usbhost, USBHOST_CM_SIZE, log, (void*)USBHOST_CM_BASE_ADDRESS);
    116124                pio_trace_enable(device->uhh, AMDM37x_UHH_SIZE, log, (void*)AMDM37x_UHH_BASE_ADDRESS);
     
    131139{
    132140        assert(device);
    133         /* Get SYS_CLK value, it is used as reference clock by all DPLLs */
     141        /* Get SYS_CLK value, it is used as reference clock by all DPLLs,
     142         * NFI who sets this or why it is set to specific value. */
    134143        const unsigned base_clk = pio_read_32(&device->prm.clocks->clksel)
    135144            & CLOCK_CONTROL_PRM_CLKSEL_SYS_CLKIN_MASK;
     
    143152         * high frequency bypass (MPU then runs on L3 interconnect freq).
    144153         * It should be setup by fw or u-boot.*/
    145         // TODO: set to autoidle to save power.
    146         // TODO: compute current MPU frequency.
     154        mpu_cm_regs_t *mpu = device->cm.mpu;
     155
     156        /* Current MPU frequency. */
     157        if (pio_read_32(&mpu->clkstst) & MPU_CM_CLKSTST_CLKACTIVITY_MPU_ACTICE_FLAG) {
     158                if (pio_read_32(&mpu->idlest_pll) & MPU_CM_IDLEST_PLL_ST_MPU_CLK_LOCKED_FLAG) {
     159                        /* DPLL active and locked */
     160                        const uint32_t reg = pio_read_32(&mpu->clksel1_pll);
     161                        const unsigned multiplier =
     162                            (reg & MPU_CM_CLKSEL1_PLL_MPU_DPLL_MULT_MASK)
     163                                >> MPU_CM_CLKSEL1_PLL_MPU_DPLL_MULT_SHIFT;
     164                        const unsigned divisor =
     165                            (reg & MPU_CM_CLKSEL1_PLL_MPU_DPLL_MULT_MASK)
     166                                >> MPU_CM_CLKSEL1_PLL_MPU_DPLL_MULT_SHIFT;
     167                        const unsigned divisor2 =
     168                            (pio_read_32(&mpu->clksel2_pll)
     169                                & MPU_CM_CLKSEL2_PLL_MPU_DPLL_CLKOUT_DIV_MASK);
     170                        if (multiplier && divisor && divisor2) {
     171                                const unsigned freq =
     172                                    ((base_freq / divisor) * multiplier) / divisor2;
     173                                ddf_msg(LVL_NOTE, "MPU running at %d.%d MHz",
     174                                    freq / 1000, freq % 1000);
     175                        } else {
     176                                ddf_msg(LVL_WARN, "Frequency divisor and/or "
     177                                    "multiplier value invalid: %d %d %d",
     178                                    multiplier, divisor, divisor2);
     179                        }
     180                } else {
     181                        /* DPLL in LP bypass mode */
     182                        const unsigned divisor =
     183                            MPU_CM_CLKSEL1_PLL_MPU_CLK_SRC_VAL(
     184                                pio_read_32(&mpu->clksel1_pll));
     185                        ddf_msg(LVL_NOTE, "MPU DPLL in bypass mode, running at"
     186                            " CORE CLK / %d MHz", divisor);
     187                }
     188        } else {
     189                ddf_msg(LVL_WARN, "MPU clock domain is not active, we should not be running...");
     190        }
     191        // TODO: Enable this (automatic MPU downclocking):
     192#if 0
     193        /* Enable low power bypass mode, this will take effect the next lock or
     194         * relock sequence. */
     195        //TODO: We might need to force re-lock after enabling this
     196        pio_set_32(&mpu->clken_pll, MPU_CM_CLKEN_PLL_EN_MPU_DPLL_LP_MODE_FLAG, 5);
     197        /* Enable automatic relocking */
     198        pio_change_32(&mpu->autoidle_pll, MPU_CM_AUTOIDLE_PLL_AUTO_MPU_DPLL_ENABLED, MPU_CM_AUTOIDLE_PLL_AUTO_MPU_DPLL_MASK, 5);
     199#endif
    147200
    148201        /* DPLL2 provides IVA(video acceleration) clock.
Note: See TracChangeset for help on using the changeset viewer.