func: static void ppc405cr_clk_setup (ppc405cr_cpc_t *cpc)
  
  {
  
      uint64_t VCO_out, PLL_out;
  
      uint32_t CPU_clk, TMR_clk, SDRAM_clk, PLB_clk, OPB_clk, EXT_clk, UART_clk;
  
      int M, D0, D1, D2;
  
  
  
      D0 = ((cpc->pllmr >> 26) & 0x3) + 1; /* CBDV */
  
      if (cpc->pllmr & 0x80000000) {
  
          D1 = (((cpc->pllmr >> 20) - 1) & 0xF) + 1; /* FBDV */
  
          D2 = 8 - ((cpc->pllmr >> 16) & 0x7); /* FWDVA */
  
          M = D0 * D1 * D2;
  
          VCO_out = cpc->sysclk * M;
  
          if (VCO_out < 400000000 || VCO_out > 800000000) {
  
              /* PLL cannot lock */
  
              cpc->pllmr &= ~0x80000000;
  
              goto bypass_pll;
  
          }
  
          PLL_out = VCO_out / D2;
  
      } else {
  
          /* Bypass PLL */
  
      bypass_pll:
  
          M = D0;
  
          PLL_out = cpc->sysclk * M;
  
      }
  
      CPU_clk = PLL_out;
  
      if (cpc->cr1 & 0x00800000)
  
          TMR_clk = cpc->sysclk; /* Should have a separate clock */
  
      else
  
          TMR_clk = CPU_clk;
  
      PLB_clk = CPU_clk / D0;
  
      SDRAM_clk = PLB_clk;
  
      D0 = ((cpc->pllmr >> 10) & 0x3) + 1;
  
      OPB_clk = PLB_clk / D0;
  
      D0 = ((cpc->pllmr >> 24) & 0x3) + 2;
  
      EXT_clk = PLB_clk / D0;
  
      D0 = ((cpc->cr0 >> 1) & 0x1F) + 1;
  
      UART_clk = CPU_clk / D0;
  
      /* Setup CPU clocks */
  
      clk_setup(&cpc->clk_setup[PPC405CR_CPU_CLK], CPU_clk);
  
      /* Setup time-base clock */
  
      clk_setup(&cpc->clk_setup[PPC405CR_TMR_CLK], TMR_clk);
  
      /* Setup PLB clock */
  
      clk_setup(&cpc->clk_setup[PPC405CR_PLB_CLK], PLB_clk);
  
      /* Setup SDRAM clock */
  
      clk_setup(&cpc->clk_setup[PPC405CR_SDRAM_CLK], SDRAM_clk);
  
      /* Setup OPB clock */
  
      clk_setup(&cpc->clk_setup[PPC405CR_OPB_CLK], OPB_clk);
  
      /* Setup external clock */
  
      clk_setup(&cpc->clk_setup[PPC405CR_EXT_CLK], EXT_clk);
  
      /* Setup UART clock */
  
      clk_setup(&cpc->clk_setup[PPC405CR_UART_CLK], UART_clk);
  
  }
  