Question about build process and mt7621.c

While investigating issue FS#4158 for mt7621/Archer C6v3, I've found that during the build for the mt7621 (Archer C6 v3) there are two different "mt7621.c" files in the build_dir:

dsouza@dsouza00:~/src/openwrt/master$ find . -name mt7621.c
./build_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/linux-5.4.159/arch/mips/ralink/mt7621.c
./build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/linux-5.4.159/arch/mips/ralink/mt7621.c

dsouza@dsouza00:~/src/openwrt/master$ ll ./build_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/linux-5.4.159/arch/mips/ralink/mt7621.c
-rw-r--r-- 1 dsouza dsouza 6718 Nov 12 10:43 ./build_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/linux-5.4.159/arch/mips/ralink/mt7621.c

dsouza@dsouza00:~/src/openwrt/master$ ll ./build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/linux-5.4.159/arch/mips/ralink/mt7621.c
-rw-r--r-- 1 dsouza dsouza 10684 Nov 28 07:24 ./build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/linux-5.4.159/arch/mips/ralink/mt7621.c
Complete diff
diff -u ./build_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/linux-5.4.159/arch/mips/r
alink/mt7621.c ./build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/linux-5.4.159/arch/mips/ralink/mt7621.c
--- ./build_dir/toolchain-mipsel_24kc_gcc-11.2.0_musl/linux-5.4.159/arch/mips/ralink/mt7621.c   2021-11-12 10:43:05.000000000 -0300
+++ ./build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/linux-5.4.159/arch/mips/ralink/mt7621.c     2021-11-28 07:24:50.540000000 -0300
@@ -7,22 +7,28 @@

 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/jiffies.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <dt-bindings/clock/mt7621-clk.h>

+#include <asm/bootinfo.h>
 #include <asm/mipsregs.h>
 #include <asm/smp-ops.h>
 #include <asm/mips-cps.h>
 #include <asm/mach-ralink/ralink_regs.h>
 #include <asm/mach-ralink/mt7621.h>
+#include <asm/mips-boards/launch.h>
+#include <asm/delay.h>
+#include <asm/time.h>

 #include <pinmux.h>

 #include "common.h"

-#define SYSC_REG_SYSCFG                0x10
-#define SYSC_REG_CPLL_CLKCFG0  0x2c
-#define SYSC_REG_CUR_CLK_STS   0x44
-#define CPU_CLK_SEL            (BIT(30) | BIT(31))
-
 #define MT7621_GPIO_MODE_UART1         1
 #define MT7621_GPIO_MODE_I2C           2
 #define MT7621_GPIO_MODE_UART3_MASK    0x3
@@ -52,6 +58,8 @@
 #define MT7621_GPIO_MODE_SDHCI_SHIFT   18
 #define MT7621_GPIO_MODE_SDHCI_GPIO    1

+static void *detect_magic __initdata = detect_memory_region;
+
 static struct rt2880_pmx_func uart1_grp[] =  { FUNC("uart1", 0, 1, 2) };
 static struct rt2880_pmx_func i2c_grp[] =  { FUNC("i2c", 0, 3, 2) };
 static struct rt2880_pmx_func uart3_grp[] = {
@@ -108,49 +116,111 @@
        { 0 }
 };

+static struct clk *clks[MT7621_CLK_MAX];
+static struct clk_onecell_data clk_data = {
+       .clks = clks,
+       .clk_num = ARRAY_SIZE(clks),
+};
+
 phys_addr_t mips_cpc_default_phys_base(void)
 {
        panic("Cannot detect cpc address");
 }

-void __init ralink_clk_init(void)
+static struct clk *__init mt7621_add_sys_clkdev(
+       const char *id, unsigned long rate)
 {
-       int cpu_fdiv = 0;
-       int cpu_ffrac = 0;
-       int fbdiv = 0;
-       u32 clk_sts, syscfg;
-       u8 clk_sel = 0, xtal_mode;
-       u32 cpu_clk;
+       struct clk *clk;
+       int err;
+
+       clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate);
+       if (IS_ERR(clk))
+               panic("failed to allocate %s clock structure", id);
+
+       err = clk_register_clkdev(clk, id, NULL);
+       if (err)
+               panic("unable to register %s clock device", id);

-       if ((rt_sysc_r32(SYSC_REG_CPLL_CLKCFG0) & CPU_CLK_SEL) != 0)
-               clk_sel = 1;
+       return clk;
+}
+
+void __init mt7621_memory_detect(void)
+{
+       void *dm = &detect_magic;
+       phys_addr_t size;
+
+       for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
+               if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
+                       break;
+       }
+
+       if ((size == 256 * SZ_1M) &&
+           (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
+           __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
+               add_memory_region(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE,
+                                 BOOT_MEM_RAM);
+               add_memory_region(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE,
+                                 BOOT_MEM_RAM);
+       } else {
+               add_memory_region(MT7621_LOWMEM_BASE, size, BOOT_MEM_RAM);
+       }
+}
+
+void __init ralink_clk_init(void)
+{
+       u32 syscfg, xtal_sel, clkcfg, clk_sel, curclk, ffiv, ffrac;
+       u32 pll, prediv, fbdiv;
+       u32 xtal_clk, cpu_clk, bus_clk;
+       const static u32 prediv_tbl[] = {0, 1, 2, 2};
+
+       syscfg = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG0);
+       xtal_sel = (syscfg >> XTAL_MODE_SEL_SHIFT) & XTAL_MODE_SEL_MASK;
+
+       clkcfg = rt_sysc_r32(SYSC_REG_CLKCFG0);
+       clk_sel = (clkcfg >> CPU_CLK_SEL_SHIFT) & CPU_CLK_SEL_MASK;
+
+       curclk = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
+       ffiv = (curclk >> CUR_CPU_FDIV_SHIFT) & CUR_CPU_FDIV_MASK;
+       ffrac = (curclk >> CUR_CPU_FFRAC_SHIFT) & CUR_CPU_FFRAC_MASK;
+
+       if (xtal_sel <= 2)
+               xtal_clk = 20 * 1000 * 1000;
+       else if (xtal_sel <= 5)
+               xtal_clk = 40 * 1000 * 1000;
+       else
+               xtal_clk = 25 * 1000 * 1000;

        switch (clk_sel) {
        case 0:
-               clk_sts = rt_sysc_r32(SYSC_REG_CUR_CLK_STS);
-               cpu_fdiv = ((clk_sts >> 8) & 0x1F);
-               cpu_ffrac = (clk_sts & 0x1F);
-               cpu_clk = (500 * cpu_ffrac / cpu_fdiv) * 1000 * 1000;
+               cpu_clk = 500 * 1000 * 1000;
                break;
-
        case 1:
-               fbdiv = ((rt_sysc_r32(0x648) >> 4) & 0x7F) + 1;
-               syscfg = rt_sysc_r32(SYSC_REG_SYSCFG);
-               xtal_mode = (syscfg >> 6) & 0x7;
-               if (xtal_mode >= 6) {
-                       /* 25Mhz Xtal */
-                       cpu_clk = 25 * fbdiv * 1000 * 1000;
-               } else if (xtal_mode >= 3) {
-                       /* 40Mhz Xtal */
-                       cpu_clk = 40 * fbdiv * 1000 * 1000;
-               } else {
-                       /* 20Mhz Xtal */
-                       cpu_clk = 20 * fbdiv * 1000 * 1000;
-               }
+               pll = rt_memc_r32(MEMC_REG_CPU_PLL);
+               fbdiv = (pll >> CPU_PLL_FBDIV_SHIFT) & CPU_PLL_FBDIV_MASK;
+               prediv = (pll >> CPU_PLL_PREDIV_SHIFT) & CPU_PLL_PREDIV_MASK;
+               cpu_clk = ((fbdiv + 1) * xtal_clk) >> prediv_tbl[prediv];
                break;
+       default:
+               cpu_clk = xtal_clk;
        }
+
+       cpu_clk = cpu_clk / ffiv * ffrac;
+       bus_clk = cpu_clk / 4;
+
+       clks[MT7621_CLK_CPU] = mt7621_add_sys_clkdev("cpu", cpu_clk);
+       clks[MT7621_CLK_BUS] = mt7621_add_sys_clkdev("bus", bus_clk);
+
+       pr_info("CPU Clock: %dMHz\n", cpu_clk / 1000000);
+       mips_hpt_frequency = cpu_clk / 2;
+}
+
+static void __init mt7621_clocks_init_dt(struct device_node *np)
+{
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 }

+CLK_OF_DECLARE(ar7100, "mediatek,mt7621-pll", mt7621_clocks_init_dt);
+
 void __init ralink_of_remap(void)
 {
        rt_sysc_membase = plat_of_remap_node("mtk,mt7621-sysc");
@@ -160,6 +230,99 @@
                panic("Failed to remap core resources");
 }

+bool plat_cpu_core_present(int core)
+{
+       struct cpulaunch *launch = (struct cpulaunch *)CKSEG0ADDR(CPULAUNCH);
+
+       if (!core)
+               return true;
+       launch += core * 2; /* 2 VPEs per core */
+       if (!(launch->flags & LAUNCH_FREADY))
+               return false;
+       if (launch->flags & (LAUNCH_FGO | LAUNCH_FGONE))
+               return false;
+       return true;
+}
+
+#define LPS_PREC 8
+/*
+*  Re-calibration lpj(loop-per-jiffy).
+*  (derived from kernel/calibrate.c)
+*/
+static int udelay_recal(void)
+{
+       unsigned int i, lpj = 0;
+       unsigned long ticks, loopbit;
+       int lps_precision = LPS_PREC;
+
+       lpj = (1<<12);
+
+       while ((lpj <<= 1) != 0) {
+               /* wait for "start of" clock tick */
+               ticks = jiffies;
+               while (ticks == jiffies)
+                       /* nothing */;
+
+               /* Go .. */
+               ticks = jiffies;
+               __delay(lpj);
+               ticks = jiffies - ticks;
+               if (ticks)
+                       break;
+       }
+
+       /*
+        * Do a binary approximation to get lpj set to
+        * equal one clock (up to lps_precision bits)
+        */
+       lpj >>= 1;
+       loopbit = lpj;
+       while (lps_precision-- && (loopbit >>= 1)) {
+               lpj |= loopbit;
+               ticks = jiffies;
+               while (ticks == jiffies)
+                       /* nothing */;
+               ticks = jiffies;
+               __delay(lpj);
+               if (jiffies != ticks)   /* longer than 1 tick */
+                       lpj &= ~loopbit;
+       }
+       printk(KERN_INFO "%d CPUs re-calibrate udelay(lpj = %d)\n", NR_CPUS, lpj);
+
+       for(i=0; i< NR_CPUS; i++)
+               cpu_data[i].udelay_val = lpj;
+
+       return 0;
+}
+device_initcall(udelay_recal);
+
+static void soc_dev_init(struct ralink_soc_info *soc_info, u32 rev)
+{
+       struct soc_device *soc_dev;
+       struct soc_device_attribute *soc_dev_attr;
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               return;
+
+       soc_dev_attr->soc_id = "mt7621";
+       soc_dev_attr->family = "Ralink";
+
+       if (((rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK) == 1 &&
+           (rev & CHIP_REV_ECO_MASK) == 1)
+               soc_dev_attr->revision = "E2";
+       else
+               soc_dev_attr->revision = "E1";
+
+       soc_dev_attr->data = soc_info;
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR(soc_dev)) {
+               kfree(soc_dev_attr);
+               return;
+       }
+}
+
 void prom_soc_init(struct ralink_soc_info *soc_info)
 {
        void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7621_SYSC_BASE);
@@ -208,17 +371,15 @@
                (rev >> CHIP_REV_VER_SHIFT) & CHIP_REV_VER_MASK,
                (rev & CHIP_REV_ECO_MASK));

-       soc_info->mem_size_min = MT7621_DDR2_SIZE_MIN;
-       soc_info->mem_size_max = MT7621_DDR2_SIZE_MAX;
-       soc_info->mem_base = MT7621_DRAM_BASE;
-
+       soc_info->mem_detect = mt7621_memory_detect;
        rt2880_pinmux_data = mt7621_pinmux_data;

-
        if (!register_cps_smp_ops())
                return;
        if (!register_cmp_smp_ops())
                return;
        if (!register_vsmp_smp_ops())
                return;
+
+       soc_dev_init(soc_info, rev);

}

I understand that the file in "./build_dir/target-mipsel_24kc_musl/" is the one used in the build, can anyone confirm this?

Thanks!

Yes.
"target/" is the source for the actual firmware components

"toolchain/" is sources/headers/references for the build process of the compilation toolchain and C library etc.

2 Likes

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.