- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/plf/refip/src/driver/crm/v20/crm.c

Go to the documentation of this file.

    00001
    00019 /*
    00020  * INCLUDE FILES
    00021  ****************************************************************************************
    00022  */
    00023 #include "crm.h"
    00024 #include "phy.h"
    00025 #include "dbg.h"
    00026 #include "reg_mac_core.h"
    00027 #include "reg_mdm_stat.h"
    00028 #include "reg_mdm_cfg.h"
    00029 #include "reg_karst_if.h"
    00030 #include <string.h>
    00031
    00032 #ifdef CFG_VIRTEX6
    00033 #include "reg_fpgaa.h"
    00034 #endif /* CFG_VIRTEX6 */
    00035
    00036 #if NX_MDM_VER < 20 || NX_MDM_VER >= 30
    00037 #error "This version of CRM is valid for modem version 2x only"
    00038 #endif
    00039
    00042 #define MDM_CONF_0_9    1
    00043 // For older MDM version only 8 configurations are available
    00044 #if NX_MDM_VER == 20
    00045 #undef MDM_CONF_0_9
    00046 #define MDM_CONF_0_9    0
    00047 #endif
    00048
    00050 #define CRM_CLKCONF_UNDEFINED   ((uint8_t)-1)
    00051
    00053 struct crm_env_tag
    00054 {
    00056     uint8_t clk_conf;
    00058     uint8_t mac_freq;
    00060     uint32_t cpu_freq;
    00061 };
    00062
    00064 static struct crm_env_tag crm_env;
    00065
    00076 static int reg_poll(uint32_t reg, uint32_t val)
    00077 {
    00078     int loops = 1 << 20;
    00079
    00080     while ((REG_PL_RD(reg) & val) != val && --loops)
    00081         ;
    00082     if (!loops)
    00083     {
    00084         dbg(D_ERR D_PHY "%s @0x%08x 0x%08x failed\n", __func__, reg, val);
    00085         return -1;
    00086     }
    00087     return !loops;
    00088 }
    00089
    00097 static inline void udelay(uint32_t us)
    00098 {
    00099     uint32_t e = nxmac_monotonic_counter_2_lo_get() + us;
    00100
    00101     do {
    00102         volatile int n = 1 << 5; // relax
    00103         while (n--)
    00104             ;
    00105     } while ((int32_t)(nxmac_monotonic_counter_2_lo_get() - e) < 0);
    00106 }
    00107
    00108 #ifdef CFG_VIRTEX6
    00109 static bool p40m_ok(void)
    00110 {
    00111     uint32_t pmref40, i;
    00112     bool ok;
    00113
    00114     pmref40 = karst_pmetre_ref40_get();
    00115     ok = true;
    00116     for (i = 0; i < 2 * sizeof(uint32_t); i++) {
    00117         int dig = (pmref40 & ((uint32_t)0xF << (4 * i))) >> (4 * i);
    00118         if (dig != 3 && dig != 4) {
    00119             ok = false;
    00120             break;
    00121         }
    00122     }
    00123     return ok;
    00124 }
    00125 #endif /* CFG_VIRTEX6 */
    00126
    00127 /* Mixed Mode Clock Manager defines */
    00128 /* output addresses */
    00130 #define CLKOUT0  0x08
    00132 #define CLKOUT1  0x0A
    00134 #define CLKOUT2  0x0C
    00136 #define CLKOUT3  0x0E
    00138 #define CLKOUT4  0x10
    00140 #define CLKOUT5  0x06
    00142 #define CLKOUT6  0x12
    00144 #define CLKOUTFB 0x14
    00145
    00146
    00150 #define MMCM_REG1(mmcm, out)                    \
    00151     (KARST_DYNCFGMMC_WE_BIT |                   \
    00152      (mmcm << KARST_DYNCFGMMC_SEL_LSB) |        \
    00153      CLKOUT##out)
    00154
    00156 #define MMCM_VCO_MULT(clk_ref_freq, vco_freq)     \
    00157     ((((vco_freq/clk_ref_freq) + 1) / 2) << 6 |   \
    00158      (((vco_freq/clk_ref_freq)) / 2) |            \
    00159      0x1000)
    00160
    00162 #define MMCM_VCO_DIV(vco_freq, target_freq)    \
    00163     ((((vco_freq/target_freq) + 1) / 2) << 6 | \
    00164      (((vco_freq/target_freq)) / 2) |          \
    00165      0x1000)
    00166
    00168 #define MMCM_VCO_TO_NUM_DIV(vco_div) (((vco_div & 0x0FC0) >> 6) + (vco_div & 0x3F))
    00169
    00170 #if defined(CFG_VIRTEX6)
    00171 /* FPGA-A MMCM0 */
    00172 #define FPGAA_MMCM0_CLKIN 200
    00173 #define FPGAA_MMCM0_VCO   1200
    00174 #define MAC_CORE_CLK_ADDR   MMCM_REG1(0, 1)
    00175 #define MAC_WT_CLK_ADDR     MMCM_REG1(0, 2)
    00176 #define LP_120M_CLK_ADDR    MMCM_REG1(0, 3)
    00177 #define MAC_CORE_DIV(x)     MMCM_VCO_DIV(FPGAA_MMCM0_VCO, x)
    00178 #define MAC_WT_DIV(x)       MMCM_VCO_DIV(FPGAA_MMCM0_VCO, x)
    00179 #define LP_120M_DIV(x)      MMCM_VCO_DIV(FPGAA_MMCM0_VCO, x)
    00180 #define MAC_FREQ(x)         (FPGAA_MMCM0_VCO / MMCM_VCO_TO_NUM_DIV(x))
    00181
    00182 /* FPGA-A MMCM1 */
    00183 #define FPGAA_MMCM1_CLKIN 30
    00184 #define FPGAA_MMCM1_VCO   960
    00185 #define MPIF_FPGAA_CLK_ADDR MMCM_REG1(1, 1)
    00186 #define LA_CLK_ADDR         MMCM_REG1(1, 2)
    00187 #define LA_DIV(x)           MMCM_VCO_DIV(FPGAA_MMCM1_VCO, x)
    00188
    00189 /* FPGA-B MMCM0 */
    00190 #define KARST_MMCM0_CLKIN 30
    00191 #define KARST_MMCM0_VCO   960
    00192 #define MPIF_CLK_ADDR MMCM_REG1(0, 6)
    00193 #define MPIF_DIV(x)   MMCM_VCO_DIV(KARST_MMCM0_VCO, x)
    00194 #define FE_CLK_ADDR   MMCM_REG1(0, 4)
    00195 #define FE_DIV(x)     MMCM_VCO_DIV(KARST_MMCM0_VCO, x)
    00196 #define PHY_CLK_ADDR  MMCM_REG1(0, 5)
    00197 #define PHY_DIV(x)    MMCM_VCO_DIV(KARST_MMCM0_VCO, x)
    00198
    00199 /* FPGA-B MMCM1 */
    00200 #define KARST_MMCM1_CLKIN 30
    00201 #define KARST_MMCM1_VCO   840
    00202 #define BD_CLK_ADDR       MMCM_REG1(1, 6)
    00203 #define BD_DIV(x)         MMCM_VCO_DIV(840, x)
    00204 #define KARST_FB_CLK_ADDR MMCM_REG1(1, FB)
    00205
    00206 #elif defined(CFG_VIRTEX7)
    00207
    00208 /* MMCM0 */
    00209 #define KARST_MMCM0_CLKIN 40
    00210 #define KARST_MMCM0_VCO   960
    00211 #define MPIF_CLK_ADDR MMCM_REG1(0, 6)
    00212 #define MPIF_DIV(x)   MMCM_VCO_DIV(KARST_MMCM0_VCO, x)
    00213 #define FE_CLK_ADDR   MMCM_REG1(0, 4)
    00214 #define FE_DIV(x)     MMCM_VCO_DIV(KARST_MMCM0_VCO, x)
    00215 #define PHY_CLK_ADDR  MMCM_REG1(0, 5)
    00216 #define PHY_DIV(x)    MMCM_VCO_DIV(KARST_MMCM0_VCO, x)
    00217 #define LA_CLK_ADDR   MMCM_REG1(0, 0)
    00218 #define LA_DIV(x)     MMCM_VCO_DIV(KARST_MMCM0_VCO, x)
    00219
    00220 /* MMCM1 */
    00221 #define KARST_MMCM1_CLKIN 40
    00222 #define KARST_MMCM1_VCO   840
    00223 #define BD_CLK_ADDR       MMCM_REG1(1, 6)
    00224 #define BD_DIV(x)         MMCM_VCO_DIV(840, x)
    00225 #define KARST_FB_CLK_ADDR MMCM_REG1(1, FB)
    00226
    00227 /* MMCM 2 */
    00228 #define KARST_MMCM2_CLKIN 25
    00229 #define KARST_MMCM2_VCO   1200
    00230 #define MAC_CORE_CLK_ADDR MMCM_REG1(2, 1)
    00231 #define MAC_WT_CLK_ADDR   MMCM_REG1(2, 2)
    00232 #define MAC_CORE_DIV(x)   MMCM_VCO_DIV(KARST_MMCM2_VCO, x)
    00233 #define MAC_WT_DIV(x)     MMCM_VCO_DIV(KARST_MMCM2_VCO, x)
    00234 #define MAC_FREQ(x)       (KARST_MMCM2_VCO / MMCM_VCO_TO_NUM_DIV(x))
    00235
    00236 #endif /* CFG_VIRTEX6 */
    00237
    00239 struct clk_config {
    00241     struct mpif_config {
    00243         uint16_t mpif_div;
    00245         uint16_t la_div;
    00247         uint16_t la_clock;
    00248     } mpif[2];
    00249
    00250     struct mac_config {
    00252         uint16_t mac_div;
    00254         uint16_t wt_div;
    00255     } mac[2];
    00256
    00257     uint16_t fe_div;
    00259     uint16_t phy_div;
    00261     uint16_t bd_div;
    00262 };
    00263
    00265 static const struct clk_config clk_config[10] = {
    00266     // MDMCONF0: CBW=20MHz, NSS=1, 11nac, BCC
    00267     {
    00268         .mpif[0] = { .mpif_div = MPIF_DIV(30),
    00269                      .la_div   = LA_DIV(60),
    00270                      .la_clock = 60 },
    00271         .mpif[1] = { .mpif_div = MPIF_DIV(30),
    00272                      .la_div   = LA_DIV(60),
    00273                      .la_clock = 60 },
    00274         .mac[0] = { .mac_div = MAC_CORE_DIV(40),
    00275                     .wt_div = MAC_WT_DIV(80) },
    00276         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00277                     .wt_div = MAC_WT_DIV(80) },
    00278         .fe_div  = FE_DIV(40),
    00279         .phy_div = PHY_DIV(60),
    00280         .bd_div  = BD_DIV(60),
    00281     },
    00282
    00283     // MDMCONF1: CBW=20MHz, NSS=2, 11n, BCC
    00284     {
    00285         .mpif[0] = { .mpif_div = MPIF_DIV(30),
    00286                      .la_div   = LA_DIV(60),
    00287                      .la_clock = 60 },
    00288         .mpif[1] = { .mpif_div = MPIF_DIV(30),
    00289                      .la_div   = LA_DIV(60),
    00290                      .la_clock = 60 },
    00291         .mac[0] = { .mac_div = MAC_CORE_DIV(40),
    00292                     .wt_div = MAC_WT_DIV(80) },
    00293         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00294                     .wt_div = MAC_WT_DIV(80) },
    00295         .fe_div  = FE_DIV(40),
    00296         .phy_div = PHY_DIV(60),
    00297         .bd_div  = BD_DIV(84),
    00298     },
    00299
    00300     // MDMCONF2: CBW=40MHz, NSS=1, 11n, BCC/LDPC
    00301     {
    00302         .mpif[0] = { .mpif_div = MPIF_DIV(60),
    00303                      .la_div   = LA_DIV(120),
    00304                      .la_clock = 120 },
    00305         .mpif[1] = { .mpif_div = MPIF_DIV(60),
    00306                      .la_div   = LA_DIV(120),
    00307                      .la_clock = 120 },
    00308         .mac[0] = { .mac_div = MAC_CORE_DIV(40),
    00309                     .wt_div = MAC_WT_DIV(80) },
    00310         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00311                     .wt_div = MAC_WT_DIV(80) },
    00312         .fe_div  = FE_DIV(80),
    00313         .phy_div = PHY_DIV(120),
    00314         .bd_div  = BD_DIV(120),
    00315     },
    00316
    00317     // MDMCONF3: CBW=40MHz, NSS=2, 11nac, BCC/LDPC
    00318     {
    00319         .mpif[0] = { .mpif_div = MPIF_DIV(60),
    00320                      .la_div   = LA_DIV(120),
    00321                      .la_clock = 120 },
    00322         .mpif[1] = { .mpif_div = MPIF_DIV(60),
    00323                      .la_div   = LA_DIV(120),
    00324                      .la_clock = 120 },
    00325         .mac[0] = { .mac_div = MAC_CORE_DIV(80),
    00326                     .wt_div = MAC_WT_DIV(80) },
    00327         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00328                     .wt_div = MAC_WT_DIV(80) },
    00329         .fe_div  = FE_DIV(80),
    00330         .phy_div = PHY_DIV(120),
    00331         .bd_div  = BD_DIV(168),
    00332     },
    00333
    00334     // MDMCONF4: CBW=80MHz, NSS=1, BCC
    00335     {
    00336         .mpif[0] = { .mpif_div = MPIF_DIV(60),
    00337                      .la_div   = LA_DIV(120),
    00338                      .la_clock = 120 },
    00339         .mpif[1] = { .mpif_div = MPIF_DIV(60),
    00340                      .la_div   = LA_DIV(120),
    00341                      .la_clock = 120 },
    00342         .mac[0] = { .mac_div = MAC_CORE_DIV(80),
    00343                     .wt_div = MAC_WT_DIV(80) },
    00344         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00345                     .wt_div = MAC_WT_DIV(80) },
    00346         .fe_div  = FE_DIV(160),
    00347         .phy_div = PHY_DIV(120),
    00348         .bd_div  = BD_DIV(168),
    00349     },
    00350
    00351     // MDMCONF5: CBW=80MHz, NSS=2, BCC
    00352     {
    00353         .mpif[0] = { .mpif_div = MPIF_DIV(120),
    00354                      .la_div   = LA_DIV(120),
    00355                      .la_clock = 120 },
    00356         .mpif[1] = { .mpif_div = MPIF_DIV(80),
    00357                      .la_div   = LA_DIV(160),
    00358                      .la_clock = 160 },
    00359         .mac[0] = { .mac_div = MAC_CORE_DIV(100),
    00360                     .wt_div = MAC_WT_DIV(100) },
    00361         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00362                     .wt_div = MAC_WT_DIV(80) },
    00363         .fe_div  = FE_DIV(160),
    00364         .phy_div = PHY_DIV(120),
    00365         #if defined(CFG_VIRTEX6)
    00366         .bd_div  = BD_DIV(210),
    00367         #elif defined(CFG_VIRTEX7)
    00368         .bd_div  = BD_DIV(168),
    00369         #endif
    00370     },
    00371
    00372     // MDMCONF6: CBW=80MHz, NSS=2, BCC/LDPC
    00373     {
    00374         .mpif[0] = { .mpif_div = MPIF_DIV(120),
    00375                      .la_div   = LA_DIV(120),
    00376                      .la_clock = 120 },
    00377         .mpif[1] = { .mpif_div = MPIF_DIV(80),
    00378                      .la_div   = LA_DIV(160),
    00379                      .la_clock = 160 },
    00380         .mac[0] = { .mac_div = MAC_CORE_DIV(100),
    00381                     .wt_div = MAC_WT_DIV(100) },
    00382         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00383                     .wt_div = MAC_WT_DIV(80) },
    00384         .fe_div  = FE_DIV(160),
    00385         .phy_div = PHY_DIV(120),
    00386         #if defined(CFG_VIRTEX6)
    00387         .bd_div  = BD_DIV(210),
    00388         #elif defined(CFG_VIRTEX7)
    00389         .bd_div  = BD_DIV(168),
    00390         #endif
    00391     },
    00392
    00393     // MDMCONF7: CBW=80MHz, NSS=1, BCC/LDPC
    00394     {
    00395         .mpif[0] = { .mpif_div = MPIF_DIV(120),
    00396                      .la_div   = LA_DIV(120),
    00397                      .la_clock = 120 },
    00398         .mpif[1] = { .mpif_div = MPIF_DIV(80),
    00399                      .la_div   = LA_DIV(160),
    00400                      .la_clock = 160 },
    00401         .mac[0] = { .mac_div = MAC_CORE_DIV(80),
    00402                     .wt_div = MAC_WT_DIV(80) },
    00403         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00404                     .wt_div = MAC_WT_DIV(80) },
    00405         .fe_div  = FE_DIV(160),
    00406         .phy_div = PHY_DIV(120),
    00407         .bd_div  = BD_DIV(168),
    00408     },
    00409
    00410     // MDMCONF8: CBW=20MHz, NSS=1/2, 11nac, BCC/LDPC
    00411     {
    00412         .mpif[0] = { .mpif_div = MPIF_DIV(60),
    00413                      .la_div   = LA_DIV(120),
    00414                      .la_clock = 120 },
    00415         .mpif[1] = { .mpif_div = MPIF_DIV(60),
    00416                      .la_div   = LA_DIV(120),
    00417                      .la_clock = 120 },
    00418         .mac[0] = { .mac_div = MAC_CORE_DIV(80),
    00419                     .wt_div = MAC_WT_DIV(80) },
    00420         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00421                     .wt_div = MAC_WT_DIV(80) },
    00422         .fe_div  = FE_DIV(40),
    00423         .phy_div = PHY_DIV(60),
    00424         .bd_div  = BD_DIV(120),
    00425     },
    00426
    00427     // MDMCONF9: CBW=40MHz, NSS=2, 11nac, BCC/LDPC
    00428     {
    00429         .mpif[0] = { .mpif_div = MPIF_DIV(120),
    00430                      .la_div   = LA_DIV(120),
    00431                      .la_clock = 120 },
    00432         .mpif[1] = { .mpif_div = MPIF_DIV(80),
    00433                      .la_div   = LA_DIV(160),
    00434                      .la_clock = 160 },
    00435         .mac[0] = { .mac_div = MAC_CORE_DIV(80),
    00436                     .wt_div = MAC_WT_DIV(80) },
    00437         .mac[1] = { .mac_div = MAC_CORE_DIV(40),
    00438                     .wt_div = MAC_WT_DIV(80) },
    00439         .fe_div  = FE_DIV(80),
    00440         .phy_div = PHY_DIV(120),
    00441         #if defined(CFG_VIRTEX6)
    00442         .bd_div  = BD_DIV(210),
    00443         #elif defined(CFG_VIRTEX7)
    00444         .bd_div  = BD_DIV(168),
    00445         #endif
    00446     }
    00447 };
    00448
    00449
    00458 static void crm_mmc_clk_set(uint32_t addr, uint16_t data)
    00459 {
    00460     karst_dyncfgmmc_addr_set(addr);
    00461     karst_dyncfgmmc_data_set(data);
    00462     karst_dyncfgmmc_cntl_set(KARST_DYNCFGMMC_START_BIT);
    00463     reg_poll(KARST_DYNCFGMMC_CNTL_ADDR,  KARST_DYNCFGMMC_START_BIT | KARST_DYNCFGMMC_DONE_BIT);
    00464     karst_dyncfgmmc_cntl_set(0);
    00465 }
    00466
    00467 #ifdef CFG_VIRTEX6
    00468 static void fpgaa_mmc_clk_set(uint32_t addr, uint16_t data)
    00469 {
    00470     fpgaa_dyncfgmmc_addr_set(addr);
    00471     fpgaa_dyncfgmmc_data_set(data);
    00472     fpgaa_dyncfgmmc_cntl_set(FPGAA_DYNCFGMMC_START_BIT);
    00473     reg_poll(FPGAA_DYNCFGMMC_CNTL_ADDR, FPGAA_DYNCFGMMC_START_BIT | FPGAA_DYNCFGMMC_DONE_BIT);
    00474     fpgaa_dyncfgmmc_cntl_set(0);
    00475 }
    00476 #endif /* CFG_VIRTEX6 */
    00477
    00487 static int crm_clk_conf(uint8_t chan_type)
    00488 {
    00489     int nss = mdm_nss_getf();
    00490     int ldpc = mdm_ldpcdec_getf();
    00491     #if MDM_CONF_0_9
    00492     bool vht_supp = phy_vht_supported();
    00493     #endif
    00494     int clkconf = 0;
    00495
    00496     switch (chan_type)
    00497     {
    00498         case PHY_CHNL_BW_20:
    00499             #if MDM_CONF_0_9
    00500             if (ldpc)
    00501                 clkconf = 8;
    00502             else if (nss == 1)
    00503                 clkconf = 0;
    00504             else
    00505                 clkconf = 1;
    00506             #else
    00507             if (nss == 1)
    00508                 clkconf = 0;
    00509             else
    00510                 clkconf = 1;
    00511             #endif
    00512             break;
    00513         case PHY_CHNL_BW_40:
    00514             #if MDM_CONF_0_9
    00515             if (nss == 1)
    00516                 clkconf = 2;
    00517             else if (!vht_supp)
    00518                 clkconf = 3;
    00519             else
    00520                 clkconf = 9;
    00521             #else
    00522             if (nss == 1)
    00523                 clkconf = 2;
    00524             else
    00525                 clkconf = 3;
    00526             #endif
    00527             break;
    00528         case PHY_CHNL_BW_80:
    00529             if (nss == 1)
    00530             {
    00531                 if (ldpc)
    00532                     clkconf = 7;
    00533                 else
    00534                     clkconf = 4;
    00535             }
    00536             else
    00537             {
    00538                 if (ldpc)
    00539                     clkconf = 6;
    00540                 else
    00541                     clkconf = 5;
    00542             }
    00543             break;
    00544         default:
    00545             ASSERT_ERR(0);
    00546             break;
    00547     }
    00548
    00549     return clkconf;
    00550 }
    00551
    00552 void crm_clk_set(uint8_t chan_type)
    00553 {
    00554     int clkconf = crm_clk_conf(chan_type);
    00555
    00556     // Check if the clock configuration needs to be modified
    00557     if (clkconf == crm_env.clk_conf)
    00558         return;
    00559
    00560     crm_env.clk_conf = clkconf;
    00561
    00562     // Set the multiplier for the VCO source of the BD clock
    00563     crm_mmc_clk_set(KARST_FB_CLK_ADDR, MMCM_VCO_MULT(KARST_MMCM1_CLKIN, KARST_MMCM1_VCO));
    00564
    00565     crm_mmc_clk_set(FE_CLK_ADDR, clk_config[clkconf].fe_div);
    00566     crm_mmc_clk_set(PHY_CLK_ADDR, clk_config[clkconf].phy_div);
    00567     crm_mmc_clk_set(BD_CLK_ADDR, clk_config[clkconf].bd_div);
    00568
    00569     #ifdef CFG_VIRTEX6
    00570     // Switch to mmc0 in case last DYNCFGMMC_ADDR was for mmc1
    00571     karst_dyncfgmmc_addr_set(0);
    00572     do
    00573     {
    00574         karst_dyncfgmmc_cntl_set(KARST_DYNCFGMMC_START_BIT);
    00575         reg_poll(KARST_DYNCFGMMC_CNTL_ADDR,  KARST_DYNCFGMMC_START_BIT | KARST_DYNCFGMMC_DONE_BIT);
    00576         // mmc{0,1,2,3}_lock
    00577         reg_poll(KARST_CLKRST_STAT_ADDR, KARST_MMC_LOCK_MASK);
    00578         karst_dyncfgmmc_cntl_set(0);
    00579     } while (!p40m_ok() && ({udelay(0); 1;}));
    00580     #endif /* CFG_VIRTEX6 */
    00581
    00582     mdm_mdmconf_setf(clkconf);
    00583 }
    00584
    00585 void crm_init(void)
    00586 {
    00587     int clkconf = crm_clk_conf(mdm_chbw_getf());
    00588     int mac_clck_id;
    00589     uint16_t mac_div;
    00590
    00591     memset(&crm_env, 0, sizeof(crm_env));
    00592
    00593     // Check if the MAC clock is enough to use nominal MAC PHY clock values or
    00594     // reduced ones
    00595     mac_clck_id = (nxmac_mac_core_clk_freq_getf() < 60) ? 1 : 0;
    00596
    00597     crm_mmc_clk_set(MPIF_CLK_ADDR, clk_config[clkconf].mpif[mac_clck_id].mpif_div);
    00598
    00599     mac_div = clk_config[clkconf].mac[mac_clck_id].mac_div;
    00600
    00601     #if defined(CFG_VIRTEX6)
    00602     fpgaa_mmc_clk_set(MPIF_FPGAA_CLK_ADDR, clk_config[clkconf].mpif[mac_clck_id].mpif_div);
    00603     fpgaa_mmc_clk_set(LA_CLK_ADDR, clk_config[clkconf].mpif[mac_clck_id].la_div);
    00604     fpgaa_la_sampling_freq_set(clk_config[clkconf].mpif[mac_clck_id].la_clock);
    00605
    00606     fpgaa_mmc_clk_set(MAC_CORE_CLK_ADDR, mac_div);
    00607     fpgaa_mmc_clk_set(MAC_WT_CLK_ADDR, clk_config[clkconf].mac[mac_clck_id].wt_div);
    00608
    00609     #elif defined(CFG_VIRTEX7)
    00610     crm_mmc_clk_set(LA_CLK_ADDR, clk_config[clkconf].mpif[mac_clck_id].la_div);
    00611     karst_la_sampling_freq_set(clk_config[clkconf].mpif[mac_clck_id].la_clock);
    00612
    00613     crm_mmc_clk_set(MAC_CORE_CLK_ADDR, mac_div);
    00614     crm_mmc_clk_set(MAC_WT_CLK_ADDR, clk_config[clkconf].mac[mac_clck_id].wt_div);
    00615     #endif /* CFG_VIRTEX7 */
    00616
    00617     crm_env.clk_conf = CRM_CLKCONF_UNDEFINED;
    00618     crm_env.mac_freq = MAC_FREQ(mac_div);
    00619
    00620     #if defined(CFG_VIRTEX6)
    00621     crm_env.cpu_freq = 105000000;
    00622     #elif defined(CFG_VIRTEX7)
    00623     karst_fmetre_start_setf(1);
    00624     while(!karst_fmetre_done_getf()) {};
    00625     crm_env.cpu_freq = karst_fmetre_plf_getf() * 1000;
    00626     karst_dyncfgmmc_cntl_set(0);
    00627     #endif
    00628 }
    00629
    00630 bool crm_fe_160m(void)
    00631 {
    00632     if (crm_env.clk_conf != CRM_CLKCONF_UNDEFINED)
    00633     {
    00634         return (clk_config[crm_env.clk_conf].fe_div == FE_DIV(160));
    00635     }
    00636
    00637     return false;
    00638 }
    00639
    00640 uint8_t crm_get_mac_freq(void)
    00641 {
    00642     return (crm_env.mac_freq);
    00643 }
    00644
    00645 uint32_t crm_get_cpu_freq(void)
    00646 {
    00647     return (crm_env.cpu_freq);
    00648 }
    00649
    00650 void crm_mdm_reset(void)
    00651 {
    00652     mdm_swreset_set(MDM_AGCSWRESET_BIT | MDM_DSPSWRESET_BIT | MDM_MDMSWRESET_BIT);
    00653     udelay(10);
    00654     mdm_swreset_set(0x0);
    00655     udelay(10);
    00656 }
    00657
    00659