uboot/arch/arm/cpu/armv8/fsl-layerscape/fsl_lsch2_speed.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2015 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <linux/compiler.h>
   8#include <asm/io.h>
   9#include <asm/processor.h>
  10#include <asm/arch/clock.h>
  11#include <asm/arch/soc.h>
  12#include <fsl_ifc.h>
  13#include "cpu.h"
  14
  15DECLARE_GLOBAL_DATA_PTR;
  16
  17#ifndef CONFIG_SYS_FSL_NUM_CC_PLLS
  18#define CONFIG_SYS_FSL_NUM_CC_PLLS      2
  19#endif
  20
  21void get_sys_info(struct sys_info *sys_info)
  22{
  23        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
  24#if (defined(CONFIG_FSL_ESDHC) &&\
  25        defined(CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK)) ||\
  26        defined(CONFIG_SYS_DPAA_FMAN)
  27
  28        u32 rcw_tmp;
  29#endif
  30        struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_CLK_ADDR);
  31        unsigned int cpu;
  32        const u8 core_cplx_pll[8] = {
  33                [0] = 0,        /* CC1 PPL / 1 */
  34                [1] = 0,        /* CC1 PPL / 2 */
  35                [4] = 1,        /* CC2 PPL / 1 */
  36                [5] = 1,        /* CC2 PPL / 2 */
  37        };
  38
  39        const u8 core_cplx_pll_div[8] = {
  40                [0] = 1,        /* CC1 PPL / 1 */
  41                [1] = 2,        /* CC1 PPL / 2 */
  42                [4] = 1,        /* CC2 PPL / 1 */
  43                [5] = 2,        /* CC2 PPL / 2 */
  44        };
  45
  46        uint i, cluster;
  47        uint freq_c_pll[CONFIG_SYS_FSL_NUM_CC_PLLS];
  48        uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
  49        unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
  50        unsigned long cluster_clk;
  51
  52        sys_info->freq_systembus = sysclk;
  53#ifndef CONFIG_CLUSTER_CLK_FREQ
  54#define CONFIG_CLUSTER_CLK_FREQ CONFIG_SYS_CLK_FREQ
  55#endif
  56        cluster_clk = CONFIG_CLUSTER_CLK_FREQ;
  57
  58#ifdef CONFIG_DDR_CLK_FREQ
  59        sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
  60#else
  61        sys_info->freq_ddrbus = sysclk;
  62#endif
  63
  64        /* The freq_systembus is used to record frequency of platform PLL */
  65        sys_info->freq_systembus *= (gur_in32(&gur->rcwsr[0]) >>
  66                        FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_SHIFT) &
  67                        FSL_CHASSIS2_RCWSR0_SYS_PLL_RAT_MASK;
  68
  69#ifdef CONFIG_ARCH_LS1012A
  70        sys_info->freq_ddrbus = 2 * sys_info->freq_systembus;
  71#else
  72        sys_info->freq_ddrbus *= (gur_in32(&gur->rcwsr[0]) >>
  73                        FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_SHIFT) &
  74                        FSL_CHASSIS2_RCWSR0_MEM_PLL_RAT_MASK;
  75#endif
  76
  77        for (i = 0; i < CONFIG_SYS_FSL_NUM_CC_PLLS; i++) {
  78                ratio[i] = (in_be32(&clk->pllcgsr[i].pllcngsr) >> 1) & 0xff;
  79                if (ratio[i] > 4)
  80                        freq_c_pll[i] = cluster_clk * ratio[i];
  81                else
  82                        freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
  83        }
  84
  85        for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
  86                cluster = fsl_qoriq_core_to_cluster(cpu);
  87                u32 c_pll_sel = (in_be32(&clk->clkcsr[cluster].clkcncsr) >> 27)
  88                                & 0xf;
  89                u32 cplx_pll = core_cplx_pll[c_pll_sel];
  90
  91                sys_info->freq_processor[cpu] =
  92                        freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
  93        }
  94
  95#define HWA_CGA_M1_CLK_SEL      0xe0000000
  96#define HWA_CGA_M1_CLK_SHIFT    29
  97#ifdef CONFIG_SYS_DPAA_FMAN
  98        rcw_tmp = in_be32(&gur->rcwsr[7]);
  99        switch ((rcw_tmp & HWA_CGA_M1_CLK_SEL) >> HWA_CGA_M1_CLK_SHIFT) {
 100        case 2:
 101                sys_info->freq_fman[0] = freq_c_pll[0] / 2;
 102                break;
 103        case 3:
 104                sys_info->freq_fman[0] = freq_c_pll[0] / 3;
 105                break;
 106        case 4:
 107                sys_info->freq_fman[0] = freq_c_pll[0] / 4;
 108                break;
 109        case 5:
 110                sys_info->freq_fman[0] = sys_info->freq_systembus;
 111                break;
 112        case 6:
 113                sys_info->freq_fman[0] = freq_c_pll[1] / 2;
 114                break;
 115        case 7:
 116                sys_info->freq_fman[0] = freq_c_pll[1] / 3;
 117                break;
 118        default:
 119                printf("Error: Unknown FMan1 clock select!\n");
 120                break;
 121        }
 122#endif
 123
 124#define HWA_CGA_M2_CLK_SEL      0x00000007
 125#define HWA_CGA_M2_CLK_SHIFT    0
 126#ifdef CONFIG_FSL_ESDHC
 127#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
 128        rcw_tmp = in_be32(&gur->rcwsr[15]);
 129        switch ((rcw_tmp & HWA_CGA_M2_CLK_SEL) >> HWA_CGA_M2_CLK_SHIFT) {
 130        case 1:
 131                sys_info->freq_sdhc = freq_c_pll[1];
 132                break;
 133        case 2:
 134                sys_info->freq_sdhc = freq_c_pll[1] / 2;
 135                break;
 136        case 3:
 137                sys_info->freq_sdhc = freq_c_pll[1] / 3;
 138                break;
 139        case 6:
 140                sys_info->freq_sdhc = freq_c_pll[0] / 2;
 141                break;
 142        default:
 143                printf("Error: Unknown ESDHC clock select!\n");
 144                break;
 145        }
 146#else
 147        sys_info->freq_sdhc = (sys_info->freq_systembus /
 148                                CONFIG_SYS_FSL_PCLK_DIV) /
 149                                CONFIG_SYS_FSL_SDHC_CLK_DIV;
 150#endif
 151#endif
 152
 153#if defined(CONFIG_FSL_IFC)
 154        sys_info->freq_localbus = sys_info->freq_systembus /
 155                                                CONFIG_SYS_FSL_IFC_CLK_DIV;
 156#endif
 157#ifdef CONFIG_SYS_DPAA_QBMAN
 158        sys_info->freq_qman = (sys_info->freq_systembus /
 159                                CONFIG_SYS_FSL_PCLK_DIV) /
 160                                CONFIG_SYS_FSL_QMAN_CLK_DIV;
 161#endif
 162}
 163
 164#ifdef CONFIG_SYS_DPAA_QBMAN
 165unsigned long get_qman_freq(void)
 166{
 167        struct sys_info sys_info;
 168
 169        get_sys_info(&sys_info);
 170
 171        return sys_info.freq_qman;
 172}
 173#endif
 174
 175int get_clocks(void)
 176{
 177        struct sys_info sys_info;
 178
 179        get_sys_info(&sys_info);
 180        gd->cpu_clk = sys_info.freq_processor[0];
 181        gd->bus_clk = sys_info.freq_systembus / CONFIG_SYS_FSL_PCLK_DIV;
 182        gd->mem_clk = sys_info.freq_ddrbus;
 183
 184#ifdef CONFIG_FSL_ESDHC
 185        gd->arch.sdhc_clk = sys_info.freq_sdhc;
 186#endif
 187
 188        if (gd->cpu_clk != 0)
 189                return 0;
 190        else
 191                return 1;
 192}
 193
 194/********************************************
 195 * get_bus_freq
 196 * return platform clock in Hz
 197 *********************************************/
 198ulong get_bus_freq(ulong dummy)
 199{
 200        if (!gd->bus_clk)
 201                get_clocks();
 202
 203        return gd->bus_clk;
 204}
 205
 206ulong get_ddr_freq(ulong dummy)
 207{
 208        if (!gd->mem_clk)
 209                get_clocks();
 210
 211        return gd->mem_clk;
 212}
 213
 214#ifdef CONFIG_FSL_ESDHC
 215int get_sdhc_freq(ulong dummy)
 216{
 217        if (!gd->arch.sdhc_clk)
 218                get_clocks();
 219
 220        return gd->arch.sdhc_clk;
 221}
 222#endif
 223
 224int get_serial_clock(void)
 225{
 226        return get_bus_freq(0) / CONFIG_SYS_FSL_DUART_CLK_DIV;
 227}
 228
 229int get_i2c_freq(ulong dummy)
 230{
 231        return get_bus_freq(0) / CONFIG_SYS_FSL_I2C_CLK_DIV;
 232}
 233
 234int get_dspi_freq(ulong dummy)
 235{
 236        return get_bus_freq(0) / CONFIG_SYS_FSL_DSPI_CLK_DIV;
 237}
 238
 239#ifdef CONFIG_FSL_LPUART
 240int get_uart_freq(ulong dummy)
 241{
 242        return get_bus_freq(0) / CONFIG_SYS_FSL_LPUART_CLK_DIV;
 243}
 244#endif
 245
 246unsigned int mxc_get_clock(enum mxc_clock clk)
 247{
 248        switch (clk) {
 249        case MXC_I2C_CLK:
 250                return get_i2c_freq(0);
 251#if defined(CONFIG_FSL_ESDHC)
 252        case MXC_ESDHC_CLK:
 253                return get_sdhc_freq(0);
 254#endif
 255        case MXC_DSPI_CLK:
 256                return get_dspi_freq(0);
 257#ifdef CONFIG_FSL_LPUART
 258        case MXC_UART_CLK:
 259                return get_uart_freq(0);
 260#endif
 261        default:
 262                printf("Unsupported clock\n");
 263        }
 264        return 0;
 265}
 266