uboot/arch/arm/mach-rockchip/rk3288/rk3288.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2016 Rockchip Electronics Co., Ltd
   4 */
   5#include <common.h>
   6#include <command.h>
   7#include <dm.h>
   8#include <env.h>
   9#include <clk.h>
  10#include <init.h>
  11#include <malloc.h>
  12#include <asm/armv7.h>
  13#include <asm/global_data.h>
  14#include <asm/io.h>
  15#include <asm/arch-rockchip/bootrom.h>
  16#include <asm/arch-rockchip/clock.h>
  17#include <asm/arch-rockchip/cpu_rk3288.h>
  18#include <asm/arch-rockchip/cru.h>
  19#include <asm/arch-rockchip/hardware.h>
  20#include <asm/arch-rockchip/grf_rk3288.h>
  21#include <asm/arch-rockchip/pmu_rk3288.h>
  22#include <asm/arch-rockchip/qos_rk3288.h>
  23#include <asm/arch-rockchip/sdram.h>
  24#include <linux/err.h>
  25
  26DECLARE_GLOBAL_DATA_PTR;
  27
  28#define GRF_BASE        0xff770000
  29
  30const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
  31        [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
  32        [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
  33};
  34
  35#ifdef CONFIG_SPL_BUILD
  36static void configure_l2ctlr(void)
  37{
  38        u32 l2ctlr;
  39
  40        l2ctlr = read_l2ctlr();
  41        l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
  42
  43        /*
  44         * Data RAM write latency: 2 cycles
  45         * Data RAM read latency: 2 cycles
  46         * Data RAM setup latency: 1 cycle
  47         * Tag RAM write latency: 1 cycle
  48         * Tag RAM read latency: 1 cycle
  49         * Tag RAM setup latency: 1 cycle
  50         */
  51        l2ctlr |= (1 << 3 | 1 << 0);
  52        write_l2ctlr(l2ctlr);
  53}
  54#endif
  55
  56int rk3288_qos_init(void)
  57{
  58        int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
  59        /* set vop qos to higher priority */
  60        writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
  61        writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
  62
  63        if (!fdt_node_check_compatible(gd->fdt_blob, 0,
  64                                       "rockchip,rk3288-tinker")) {
  65                /* set isp qos to higher priority */
  66                writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
  67                writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
  68                writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
  69        }
  70
  71        return 0;
  72}
  73
  74int arch_cpu_init(void)
  75{
  76#ifdef CONFIG_SPL_BUILD
  77        configure_l2ctlr();
  78#else
  79        /* We do some SoC one time setting here. */
  80        struct rk3288_grf * const grf = (void *)GRF_BASE;
  81
  82        /* Use rkpwm by default */
  83        rk_setreg(&grf->soc_con2, 1 << 0);
  84
  85        /*
  86         * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is
  87         * cleared
  88         */
  89        rk_clrreg(&grf->soc_con0, 1 << 12);
  90
  91        rk3288_qos_init();
  92#endif
  93
  94        return 0;
  95}
  96
  97#ifdef CONFIG_DEBUG_UART_BOARD_INIT
  98void board_debug_uart_init(void)
  99{
 100        /* Enable early UART on the RK3288 */
 101        struct rk3288_grf * const grf = (void *)GRF_BASE;
 102
 103        rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
 104                     GPIO7C6_MASK << GPIO7C6_SHIFT,
 105                     GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
 106                     GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
 107}
 108#endif
 109
 110__weak int rk3288_board_late_init(void)
 111{
 112        return 0;
 113}
 114
 115int rk_board_late_init(void)
 116{
 117        return rk3288_board_late_init();
 118}
 119
 120static int ft_rk3288w_setup(void *blob)
 121{
 122        const char *path;
 123        int offs, ret;
 124
 125        path = "/clock-controller@ff760000";
 126        offs = fdt_path_offset(blob, path);
 127        if (offs < 0) {
 128                debug("failed to found fdt path %s\n", path);
 129                return offs;
 130        }
 131
 132        ret = fdt_setprop_string(blob, offs, "compatible", "rockchip,rk3288w-cru");
 133        if (ret) {
 134                printf("failed to set rk3288w-cru compatible (ret=%d)\n", ret);
 135                return ret;
 136        }
 137
 138        return ret;
 139}
 140
 141int ft_board_setup(void *blob, struct bd_info *bd)
 142{
 143        if (soc_is_rk3288w())
 144                return ft_rk3288w_setup(blob);
 145
 146        return 0;
 147}
 148
 149static int do_clock(struct cmd_tbl *cmdtp, int flag, int argc,
 150                    char *const argv[])
 151{
 152        static const struct {
 153                char *name;
 154                int id;
 155        } clks[] = {
 156                { "osc", CLK_OSC },
 157                { "apll", CLK_ARM },
 158                { "dpll", CLK_DDR },
 159                { "cpll", CLK_CODEC },
 160                { "gpll", CLK_GENERAL },
 161#ifdef CONFIG_ROCKCHIP_RK3036
 162                { "mpll", CLK_NEW },
 163#else
 164                { "npll", CLK_NEW },
 165#endif
 166        };
 167        int ret, i;
 168        struct udevice *dev;
 169
 170        ret = rockchip_get_clk(&dev);
 171        if (ret) {
 172                printf("clk-uclass not found\n");
 173                return 0;
 174        }
 175
 176        for (i = 0; i < ARRAY_SIZE(clks); i++) {
 177                struct clk clk;
 178                ulong rate;
 179
 180                clk.id = clks[i].id;
 181                ret = clk_request(dev, &clk);
 182                if (ret < 0)
 183                        continue;
 184
 185                rate = clk_get_rate(&clk);
 186                printf("%s: %lu\n", clks[i].name, rate);
 187
 188                clk_free(&clk);
 189        }
 190
 191        return 0;
 192}
 193
 194U_BOOT_CMD(
 195        clock, 2, 1, do_clock,
 196        "display information about clocks",
 197        ""
 198);
 199