| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 3 | | - * under the terms of the GNU General Public License version 2 as published |
|---|
| 4 | | - * by the Free Software Foundation. |
|---|
| 5 | 3 | * |
|---|
| 6 | 4 | * Copyright (C) 2015 Nikolay Martynov <mar.kolya@gmail.com> |
|---|
| 7 | 5 | * Copyright (C) 2015 John Crispin <john@phrozen.org> |
|---|
| .. | .. |
|---|
| 9 | 7 | |
|---|
| 10 | 8 | #include <linux/kernel.h> |
|---|
| 11 | 9 | #include <linux/init.h> |
|---|
| 10 | +#include <linux/slab.h> |
|---|
| 11 | +#include <linux/sys_soc.h> |
|---|
| 12 | 12 | |
|---|
| 13 | 13 | #include <asm/mipsregs.h> |
|---|
| 14 | 14 | #include <asm/smp-ops.h> |
|---|
| .. | .. |
|---|
| 19 | 19 | #include <pinmux.h> |
|---|
| 20 | 20 | |
|---|
| 21 | 21 | #include "common.h" |
|---|
| 22 | | - |
|---|
| 23 | | -#define SYSC_REG_SYSCFG 0x10 |
|---|
| 24 | | -#define SYSC_REG_CPLL_CLKCFG0 0x2c |
|---|
| 25 | | -#define SYSC_REG_CUR_CLK_STS 0x44 |
|---|
| 26 | | -#define CPU_CLK_SEL (BIT(30) | BIT(31)) |
|---|
| 27 | 22 | |
|---|
| 28 | 23 | #define MT7621_GPIO_MODE_UART1 1 |
|---|
| 29 | 24 | #define MT7621_GPIO_MODE_I2C 2 |
|---|
| .. | .. |
|---|
| 115 | 110 | panic("Cannot detect cpc address"); |
|---|
| 116 | 111 | } |
|---|
| 117 | 112 | |
|---|
| 118 | | -void __init ralink_clk_init(void) |
|---|
| 119 | | -{ |
|---|
| 120 | | - int cpu_fdiv = 0; |
|---|
| 121 | | - int cpu_ffrac = 0; |
|---|
| 122 | | - int fbdiv = 0; |
|---|
| 123 | | - u32 clk_sts, syscfg; |
|---|
| 124 | | - u8 clk_sel = 0, xtal_mode; |
|---|
| 125 | | - u32 cpu_clk; |
|---|
| 126 | | - |
|---|
| 127 | | - if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0) |
|---|
| 128 | | - clk_sel = 1; |
|---|
| 129 | | - |
|---|
| 130 | | - switch (clk_sel) { |
|---|
| 131 | | - case 0: |
|---|
| 132 | | - clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS); |
|---|
| 133 | | - cpu_fdiv = ((clk_sts >> 8) & 0x1F); |
|---|
| 134 | | - cpu_ffrac = (clk_sts & 0x1F); |
|---|
| 135 | | - cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000; |
|---|
| 136 | | - break; |
|---|
| 137 | | - |
|---|
| 138 | | - case 1: |
|---|
| 139 | | - fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1; |
|---|
| 140 | | - syscfg = rt_sysc_r32(SYSC_REG_SYSCFG); |
|---|
| 141 | | - xtal_mode = (syscfg >> 6) & 0x7; |
|---|
| 142 | | - if (xtal_mode >= 6) { |
|---|
| 143 | | - /* 25Mhz Xtal */ |
|---|
| 144 | | - cpu_clk = 25 * fbdiv * 1000 * 1000; |
|---|
| 145 | | - } else if (xtal_mode >= 3) { |
|---|
| 146 | | - /* 40Mhz Xtal */ |
|---|
| 147 | | - cpu_clk = 40 * fbdiv * 1000 * 1000; |
|---|
| 148 | | - } else { |
|---|
| 149 | | - /* 20Mhz Xtal */ |
|---|
| 150 | | - cpu_clk = 20 * fbdiv * 1000 * 1000; |
|---|
| 151 | | - } |
|---|
| 152 | | - break; |
|---|
| 153 | | - } |
|---|
| 154 | | -} |
|---|
| 155 | | - |
|---|
| 156 | 113 | void __init ralink_of_remap(void) |
|---|
| 157 | 114 | { |
|---|
| 158 | 115 | rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc"); |
|---|
| .. | .. |
|---|
| 160 | 117 | |
|---|
| 161 | 118 | if (!rt_sysc_membase || !rt_memc_membase) |
|---|
| 162 | 119 | panic("Failed to remap core resources"); |
|---|
| 120 | +} |
|---|
| 121 | + |
|---|
| 122 | +static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev) |
|---|
| 123 | +{ |
|---|
| 124 | + struct soc_device *soc_dev; |
|---|
| 125 | + struct soc_device_attribute *soc_dev_attr; |
|---|
| 126 | + |
|---|
| 127 | + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); |
|---|
| 128 | + if (!soc_dev_attr) |
|---|
| 129 | + return; |
|---|
| 130 | + |
|---|
| 131 | + soc_dev_attr->soc_id = "mt7621"; |
|---|
| 132 | + soc_dev_attr->family = "Ralink"; |
|---|
| 133 | + |
|---|
| 134 | + if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 && |
|---|
| 135 | + (rev & CHIP_REV_ECO_MASK) == 1) |
|---|
| 136 | + soc_dev_attr->revision = "E2"; |
|---|
| 137 | + else |
|---|
| 138 | + soc_dev_attr->revision = "E1"; |
|---|
| 139 | + |
|---|
| 140 | + soc_dev_attr->data = soc_info; |
|---|
| 141 | + |
|---|
| 142 | + soc_dev = soc_device_register(soc_dev_attr); |
|---|
| 143 | + if (IS_ERR(soc_dev)) { |
|---|
| 144 | + kfree(soc_dev_attr); |
|---|
| 145 | + return; |
|---|
| 146 | + } |
|---|
| 163 | 147 | } |
|---|
| 164 | 148 | |
|---|
| 165 | 149 | void prom_soc_init(struct ralink_soc_info *soc_info) |
|---|
| .. | .. |
|---|
| 216 | 200 | |
|---|
| 217 | 201 | rt2880_pinmux_data = mt7621_pinmux_data; |
|---|
| 218 | 202 | |
|---|
| 203 | + soc_dev_init(soc_info, rev); |
|---|
| 219 | 204 | |
|---|
| 220 | 205 | if (!register_cps_smp_ops()) |
|---|
| 221 | 206 | return; |
|---|