Revision 51fec3cc

b/hw/omap2.c
2727 2727

  
2728 2728
    uint32_t ev;
2729 2729
    uint32_t evtime[2];
2730

  
2731
    int dpll_lock, apll_lock[2];
2730 2732
};
2731 2733

  
2732 2734
static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
......
2739 2741
{
2740 2742
    struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
2741 2743
    int offset = addr - s->base;
2744
    uint32_t ret;
2742 2745

  
2743 2746
    switch (offset) {
2744 2747
    case 0x000:	/* PRCM_REVISION */
......
2922 2925
    case 0x500:	/* CM_CLKEN_PLL */
2923 2926
        return s->clken[9];
2924 2927
    case 0x520:	/* CM_IDLEST_CKGEN */
2925
        /* Core uses 32-kHz clock */
2928
        ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8);
2926 2929
        if (!(s->clksel[6] & 3))
2927
            return 0x00000377;
2928
        /* DPLL not in lock mode, core uses ref_clk */
2929
        if ((s->clken[9] & 3) != 3)
2930
            return 0x00000375;
2931
        /* Core uses DPLL */
2932
        return 0x00000376;
2930
            /* Core uses 32-kHz clock */
2931
            ret |= 3 << 0;
2932
        else if (!s->dpll_lock)
2933
            /* DPLL not locked, core uses ref_clk */
2934
            ret |= 1 << 0;
2935
        else
2936
            /* Core uses DPLL */
2937
            ret |= 2 << 0;
2938
        return ret;
2933 2939
    case 0x530:	/* CM_AUTOIDLE_PLL */
2934 2940
        return s->clkidle[5];
2935 2941
    case 0x540:	/* CM_CLKSEL1_PLL */
......
2976 2982
    return 0;
2977 2983
}
2978 2984

  
2985
static void omap_prcm_apll_update(struct omap_prcm_s *s)
2986
{
2987
    int mode[2];
2988

  
2989
    mode[0] = (s->clken[9] >> 6) & 3;
2990
    s->apll_lock[0] = (mode[0] == 3);
2991
    mode[1] = (s->clken[9] >> 2) & 3;
2992
    s->apll_lock[1] = (mode[1] == 3);
2993
    /* TODO: update clocks */
2994

  
2995
    if (mode[0] == 1 || mode[0] == 2 || mode[1] == 1 || mode[2] == 2)
2996
        fprintf(stderr, "%s: bad EN_54M_PLL or bad EN_96M_PLL\n",
2997
                        __FUNCTION__);
2998
}
2999

  
3000
static void omap_prcm_dpll_update(struct omap_prcm_s *s)
3001
{
3002
    omap_clk dpll = omap_findclk(s->mpu, "dpll");
3003
    omap_clk dpll_x2 = omap_findclk(s->mpu, "dpll");
3004
    omap_clk core = omap_findclk(s->mpu, "core_clk");
3005
    int mode = (s->clken[9] >> 0) & 3;
3006
    int mult, div;
3007

  
3008
    mult = (s->clksel[5] >> 12) & 0x3ff;
3009
    div = (s->clksel[5] >> 8) & 0xf;
3010
    if (mult == 0 || mult == 1)
3011
        mode = 1;	/* Bypass */
3012

  
3013
    s->dpll_lock = 0;
3014
    switch (mode) {
3015
    case 0:
3016
        fprintf(stderr, "%s: bad EN_DPLL\n", __FUNCTION__);
3017
        break;
3018
    case 1:	/* Low-power bypass mode (Default) */
3019
    case 2:	/* Fast-relock bypass mode */
3020
        omap_clk_setrate(dpll, 1, 1);
3021
        omap_clk_setrate(dpll_x2, 1, 1);
3022
        break;
3023
    case 3:	/* Lock mode */
3024
        s->dpll_lock = 1; /* After 20 FINT cycles (ref_clk / (div + 1)).  */
3025

  
3026
        omap_clk_setrate(dpll, div + 1, mult);
3027
        omap_clk_setrate(dpll_x2, div + 1, mult * 2);
3028
        break;
3029
    }
3030

  
3031
    switch ((s->clksel[6] >> 0) & 3) {
3032
    case 0:
3033
        omap_clk_reparent(core, omap_findclk(s->mpu, "clk32-kHz"));
3034
        break;
3035
    case 1:
3036
        omap_clk_reparent(core, dpll);
3037
        break;
3038
    case 2:
3039
        /* Default */
3040
        omap_clk_reparent(core, dpll_x2);
3041
        break;
3042
    case 3:
3043
        fprintf(stderr, "%s: bad CORE_CLK_SRC\n", __FUNCTION__);
3044
        break;
3045
    }
3046
}
3047

  
2979 3048
static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
2980 3049
                uint32_t value)
2981 3050
{
......
3235 3304
        break;
3236 3305

  
3237 3306
    case 0x500:	/* CM_CLKEN_PLL */
3238
        s->clken[9] = value & 0xcf;
3239
        /* TODO update clocks */
3307
        if (value & 0xffffff30)
3308
            fprintf(stderr, "%s: write 0s in CM_CLKEN_PLL for "
3309
                            "future compatiblity\n", __FUNCTION__);
3310
        if ((s->clken[9] ^ value) & 0xcc) {
3311
            s->clken[9] &= ~0xcc;
3312
            s->clken[9] |= value & 0xcc;
3313
            omap_prcm_apll_update(s);
3314
        }
3315
        if ((s->clken[9] ^ value) & 3) {
3316
            s->clken[9] &= ~3;
3317
            s->clken[9] |= value & 3;
3318
            omap_prcm_dpll_update(s);
3319
        }
3240 3320
        break;
3241 3321
    case 0x530:	/* CM_AUTOIDLE_PLL */
3242 3322
        s->clkidle[5] = value & 0x000000cf;
3243 3323
        /* TODO update clocks */
3244 3324
        break;
3245 3325
    case 0x540:	/* CM_CLKSEL1_PLL */
3326
        if (value & 0xfc4000d7)
3327
            fprintf(stderr, "%s: write 0s in CM_CLKSEL1_PLL for "
3328
                            "future compatiblity\n", __FUNCTION__);
3329
        if ((s->clksel[5] ^ value) & 0x003fff00) {
3330
            s->clksel[5] = value & 0x03bfff28;
3331
            omap_prcm_dpll_update(s);
3332
        }
3333
        /* TODO update the other clocks */
3334

  
3246 3335
        s->clksel[5] = value & 0x03bfff28;
3247
        /* TODO update clocks */
3248 3336
        break;
3249 3337
    case 0x544:	/* CM_CLKSEL2_PLL */
3250
        s->clksel[6] = value & 3;
3251
        /* TODO update clocks */
3338
        if (value & ~3)
3339
            fprintf(stderr, "%s: write 0s in CM_CLKSEL2_PLL[31:2] for "
3340
                            "future compatiblity\n", __FUNCTION__);
3341
        if (s->clksel[6] != (value & 3)) {
3342
            s->clksel[6] = value & 3;
3343
            omap_prcm_dpll_update(s);
3344
        }
3252 3345
        break;
3253 3346

  
3254 3347
    case 0x800:	/* CM_FCLKEN_DSP */
......
3373 3466
    s->power[3] = 0x14;
3374 3467
    s->rstctrl[0] = 1;
3375 3468
    s->rst[3] = 1;
3469
    omap_prcm_apll_update(s);
3470
    omap_prcm_dpll_update(s);
3376 3471
}
3377 3472

  
3378 3473
static void omap_prcm_coldreset(struct omap_prcm_s *s)
b/hw/omap_clk.c
510 510
    .parent	= &xtal_osc32k,
511 511
};
512 512

  
513
static struct clk ref_clk = {
514
    .name	= "ref_clk",
515
    .flags	= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
516
    .rate	= 12000000,	/* 12 MHz or 13 MHz or 19.2 MHz */
517
    /*.parent	= sys.xtalin */
518
};
519

  
513 520
static struct clk apll_96m = {
514 521
    .name	= "apll_96m",
515 522
    .flags	= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
516 523
    .rate	= 96000000,
517
    /*.parent	= sys.xtalin */
524
    /*.parent	= ref_clk */
518 525
};
519 526

  
520 527
static struct clk apll_54m = {
521 528
    .name	= "apll_54m",
522 529
    .flags	= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
523 530
    .rate	= 54000000,
524
    /*.parent	= sys.xtalin */
531
    /*.parent	= ref_clk */
525 532
};
526 533

  
527 534
static struct clk sys_clk = {
......
541 548
static struct clk dpll_ck = {
542 549
    .name	= "dpll",
543 550
    .flags	= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
544
    /*.parent	= sys.xtalin */
551
    .parent	= &ref_clk,
545 552
};
546 553

  
547 554
static struct clk dpll_x2_ck = {
548 555
    .name	= "dpll_x2",
549 556
    .flags	= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
550
    /*.parent	= sys.xtalin */
557
    .parent	= &ref_clk,
551 558
};
552 559

  
553 560
static struct clk wdt1_sys_clk = {
......
600 607
static struct clk core_clk = {
601 608
    .name	= "core_clk",
602 609
    .flags	= CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
603
    .parent	= &dpll_ck,
610
    .parent	= &dpll_x2_ck,	/* Switchable between dpll_ck and clk32k */
604 611
};
605 612

  
606 613
static struct clk l3_clk = {
......
1009 1016

  
1010 1017
    /* OMAP 2 */
1011 1018

  
1019
    &ref_clk,
1012 1020
    &apll_96m,
1013 1021
    &apll_54m,
1014 1022
    &sys_clk,
b/hw/omap_i2c.c
395 395
                            (~value >> 9) & 1);			/* TRX */
396 396
            s->stat |= nack << 1;				/* NACK */
397 397
            s->control &= ~(1 << 0);				/* STT */
398
            s->fifo = 0;
398 399
            if (nack)
399 400
                s->control &= ~(1 << 1);			/* STP */
400 401
            else {

Also available in: Unified diff