Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com>
0005  * Copyright (C) 2011 John Crispin <john@phrozen.org>
0006  */
0007 
0008 #include <linux/ioport.h>
0009 #include <linux/export.h>
0010 #include <linux/clkdev.h>
0011 #include <linux/of_address.h>
0012 #include <asm/delay.h>
0013 
0014 #include <lantiq_soc.h>
0015 
0016 #include "../clk.h"
0017 
0018 /* infrastructure control register */
0019 #define SYS1_INFRAC     0x00bc
0020 /* Configuration fuses for drivers and pll */
0021 #define STATUS_CONFIG       0x0040
0022 
0023 /* GPE frequency selection */
0024 #define GPPC_OFFSET     24
0025 #define GPEFREQ_MASK        0x0000C00
0026 #define GPEFREQ_OFFSET      10
0027 /* Clock status register */
0028 #define SYSCTL_CLKS     0x0000
0029 /* Clock enable register */
0030 #define SYSCTL_CLKEN        0x0004
0031 /* Clock clear register */
0032 #define SYSCTL_CLKCLR       0x0008
0033 /* Activation Status Register */
0034 #define SYSCTL_ACTS     0x0020
0035 /* Activation Register */
0036 #define SYSCTL_ACT      0x0024
0037 /* Deactivation Register */
0038 #define SYSCTL_DEACT        0x0028
0039 /* reboot Register */
0040 #define SYSCTL_RBT      0x002c
0041 /* CPU0 Clock Control Register */
0042 #define SYS1_CPU0CC     0x0040
0043 /* HRST_OUT_N Control Register */
0044 #define SYS1_HRSTOUTC       0x00c0
0045 /* clock divider bit */
0046 #define CPU0CC_CPUDIV       0x0001
0047 
0048 /* Activation Status Register */
0049 #define ACTS_ASC0_ACT   0x00001000
0050 #define ACTS_SSC0   0x00002000
0051 #define ACTS_ASC1_ACT   0x00000800
0052 #define ACTS_I2C_ACT    0x00004000
0053 #define ACTS_P0     0x00010000
0054 #define ACTS_P1     0x00010000
0055 #define ACTS_P2     0x00020000
0056 #define ACTS_P3     0x00020000
0057 #define ACTS_P4     0x00040000
0058 #define ACTS_PADCTRL0   0x00100000
0059 #define ACTS_PADCTRL1   0x00100000
0060 #define ACTS_PADCTRL2   0x00200000
0061 #define ACTS_PADCTRL3   0x00200000
0062 #define ACTS_PADCTRL4   0x00400000
0063 
0064 #define sysctl_w32(m, x, y) ltq_w32((x), sysctl_membase[m] + (y))
0065 #define sysctl_r32(m, x)    ltq_r32(sysctl_membase[m] + (x))
0066 #define sysctl_w32_mask(m, clear, set, reg) \
0067         sysctl_w32(m, (sysctl_r32(m, reg) & ~(clear)) | (set), reg)
0068 
0069 #define status_w32(x, y)    ltq_w32((x), status_membase + (y))
0070 #define status_r32(x)       ltq_r32(status_membase + (x))
0071 
0072 static void __iomem *sysctl_membase[3], *status_membase;
0073 void __iomem *ltq_sys1_membase, *ltq_ebu_membase;
0074 
0075 void falcon_trigger_hrst(int level)
0076 {
0077     sysctl_w32(SYSCTL_SYS1, level & 1, SYS1_HRSTOUTC);
0078 }
0079 
0080 static inline void sysctl_wait(struct clk *clk,
0081         unsigned int test, unsigned int reg)
0082 {
0083     int err = 1000000;
0084 
0085     do {} while (--err && ((sysctl_r32(clk->module, reg)
0086                     & clk->bits) != test));
0087     if (!err)
0088         pr_err("module de/activation failed %d %08X %08X %08X\n",
0089             clk->module, clk->bits, test,
0090             sysctl_r32(clk->module, reg) & clk->bits);
0091 }
0092 
0093 static int sysctl_activate(struct clk *clk)
0094 {
0095     sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN);
0096     sysctl_w32(clk->module, clk->bits, SYSCTL_ACT);
0097     sysctl_wait(clk, clk->bits, SYSCTL_ACTS);
0098     return 0;
0099 }
0100 
0101 static void sysctl_deactivate(struct clk *clk)
0102 {
0103     sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR);
0104     sysctl_w32(clk->module, clk->bits, SYSCTL_DEACT);
0105     sysctl_wait(clk, 0, SYSCTL_ACTS);
0106 }
0107 
0108 static int sysctl_clken(struct clk *clk)
0109 {
0110     sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN);
0111     sysctl_w32(clk->module, clk->bits, SYSCTL_ACT);
0112     sysctl_wait(clk, clk->bits, SYSCTL_CLKS);
0113     return 0;
0114 }
0115 
0116 static void sysctl_clkdis(struct clk *clk)
0117 {
0118     sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR);
0119     sysctl_wait(clk, 0, SYSCTL_CLKS);
0120 }
0121 
0122 static void sysctl_reboot(struct clk *clk)
0123 {
0124     unsigned int act;
0125     unsigned int bits;
0126 
0127     act = sysctl_r32(clk->module, SYSCTL_ACT);
0128     bits = ~act & clk->bits;
0129     if (bits != 0) {
0130         sysctl_w32(clk->module, bits, SYSCTL_CLKEN);
0131         sysctl_w32(clk->module, bits, SYSCTL_ACT);
0132         sysctl_wait(clk, bits, SYSCTL_ACTS);
0133     }
0134     sysctl_w32(clk->module, act & clk->bits, SYSCTL_RBT);
0135     sysctl_wait(clk, clk->bits, SYSCTL_ACTS);
0136 }
0137 
0138 /* enable the ONU core */
0139 static void falcon_gpe_enable(void)
0140 {
0141     unsigned int freq;
0142     unsigned int status;
0143 
0144     /* if the clock is already enabled */
0145     status = sysctl_r32(SYSCTL_SYS1, SYS1_INFRAC);
0146     if (status & (1 << (GPPC_OFFSET + 1)))
0147         return;
0148 
0149     freq = (status_r32(STATUS_CONFIG) &
0150         GPEFREQ_MASK) >>
0151         GPEFREQ_OFFSET;
0152     if (freq == 0)
0153         freq = 1; /* use 625MHz on unfused chip */
0154 
0155     /* apply new frequency */
0156     sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1),
0157         freq << (GPPC_OFFSET + 2) , SYS1_INFRAC);
0158     udelay(1);
0159 
0160     /* enable new frequency */
0161     sysctl_w32_mask(SYSCTL_SYS1, 0, 1 << (GPPC_OFFSET + 1), SYS1_INFRAC);
0162     udelay(1);
0163 }
0164 
0165 static inline void clkdev_add_sys(const char *dev, unsigned int module,
0166                     unsigned int bits)
0167 {
0168     struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
0169 
0170     if (!clk)
0171         return;
0172     clk->cl.dev_id = dev;
0173     clk->cl.con_id = NULL;
0174     clk->cl.clk = clk;
0175     clk->module = module;
0176     clk->bits = bits;
0177     clk->activate = sysctl_activate;
0178     clk->deactivate = sysctl_deactivate;
0179     clk->enable = sysctl_clken;
0180     clk->disable = sysctl_clkdis;
0181     clk->reboot = sysctl_reboot;
0182     clkdev_add(&clk->cl);
0183 }
0184 
0185 void __init ltq_soc_init(void)
0186 {
0187     struct device_node *np_status =
0188         of_find_compatible_node(NULL, NULL, "lantiq,status-falcon");
0189     struct device_node *np_ebu =
0190         of_find_compatible_node(NULL, NULL, "lantiq,ebu-falcon");
0191     struct device_node *np_sys1 =
0192         of_find_compatible_node(NULL, NULL, "lantiq,sys1-falcon");
0193     struct device_node *np_syseth =
0194         of_find_compatible_node(NULL, NULL, "lantiq,syseth-falcon");
0195     struct device_node *np_sysgpe =
0196         of_find_compatible_node(NULL, NULL, "lantiq,sysgpe-falcon");
0197     struct resource res_status, res_ebu, res_sys[3];
0198     int i;
0199 
0200     /* check if all the core register ranges are available */
0201     if (!np_status || !np_ebu || !np_sys1 || !np_syseth || !np_sysgpe)
0202         panic("Failed to load core nodes from devicetree");
0203 
0204     if (of_address_to_resource(np_status, 0, &res_status) ||
0205             of_address_to_resource(np_ebu, 0, &res_ebu) ||
0206             of_address_to_resource(np_sys1, 0, &res_sys[0]) ||
0207             of_address_to_resource(np_syseth, 0, &res_sys[1]) ||
0208             of_address_to_resource(np_sysgpe, 0, &res_sys[2]))
0209         panic("Failed to get core resources");
0210 
0211     of_node_put(np_status);
0212     of_node_put(np_ebu);
0213     of_node_put(np_sys1);
0214     of_node_put(np_syseth);
0215     of_node_put(np_sysgpe);
0216 
0217     if ((request_mem_region(res_status.start, resource_size(&res_status),
0218                 res_status.name) < 0) ||
0219         (request_mem_region(res_ebu.start, resource_size(&res_ebu),
0220                 res_ebu.name) < 0) ||
0221         (request_mem_region(res_sys[0].start,
0222                 resource_size(&res_sys[0]),
0223                 res_sys[0].name) < 0) ||
0224         (request_mem_region(res_sys[1].start,
0225                 resource_size(&res_sys[1]),
0226                 res_sys[1].name) < 0) ||
0227         (request_mem_region(res_sys[2].start,
0228                 resource_size(&res_sys[2]),
0229                 res_sys[2].name) < 0))
0230         pr_err("Failed to request core resources");
0231 
0232     status_membase = ioremap(res_status.start,
0233                     resource_size(&res_status));
0234     ltq_ebu_membase = ioremap(res_ebu.start,
0235                     resource_size(&res_ebu));
0236 
0237     if (!status_membase || !ltq_ebu_membase)
0238         panic("Failed to remap core resources");
0239 
0240     for (i = 0; i < 3; i++) {
0241         sysctl_membase[i] = ioremap(res_sys[i].start,
0242                         resource_size(&res_sys[i]));
0243         if (!sysctl_membase[i])
0244             panic("Failed to remap sysctrl resources");
0245     }
0246     ltq_sys1_membase = sysctl_membase[0];
0247 
0248     falcon_gpe_enable();
0249 
0250     /* get our 3 static rates for cpu, fpi and io clocks */
0251     if (ltq_sys1_r32(SYS1_CPU0CC) & CPU0CC_CPUDIV)
0252         clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M, 0);
0253     else
0254         clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M, 0);
0255 
0256     /* add our clock domains */
0257     clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0);
0258     clkdev_add_sys("1d810100.gpio", SYSCTL_SYSETH, ACTS_P2);
0259     clkdev_add_sys("1e800100.gpio", SYSCTL_SYS1, ACTS_P1);
0260     clkdev_add_sys("1e800200.gpio", SYSCTL_SYS1, ACTS_P3);
0261     clkdev_add_sys("1e800300.gpio", SYSCTL_SYS1, ACTS_P4);
0262     clkdev_add_sys("1db01000.pad", SYSCTL_SYSETH, ACTS_PADCTRL0);
0263     clkdev_add_sys("1db02000.pad", SYSCTL_SYSETH, ACTS_PADCTRL2);
0264     clkdev_add_sys("1e800400.pad", SYSCTL_SYS1, ACTS_PADCTRL1);
0265     clkdev_add_sys("1e800500.pad", SYSCTL_SYS1, ACTS_PADCTRL3);
0266     clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4);
0267     clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT);
0268     clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT);
0269     clkdev_add_sys("1e100d00.spi", SYSCTL_SYS1, ACTS_SSC0);
0270     clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT);
0271 }