Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (c) 2019 Christoph Hellwig.
0004  * Copyright (c) 2019 Western Digital Corporation or its affiliates.
0005  */
0006 #include <linux/io.h>
0007 #include <linux/platform_device.h>
0008 #include <linux/of_platform.h>
0009 #include <linux/clk.h>
0010 #include <asm/soc.h>
0011 
0012 #include <soc/canaan/k210-sysctl.h>
0013 
0014 static int k210_sysctl_probe(struct platform_device *pdev)
0015 {
0016     struct device *dev = &pdev->dev;
0017     struct clk *pclk;
0018     int ret;
0019 
0020     dev_info(dev, "K210 system controller\n");
0021 
0022     /* Get power bus clock */
0023     pclk = devm_clk_get(dev, NULL);
0024     if (IS_ERR(pclk))
0025         return dev_err_probe(dev, PTR_ERR(pclk),
0026                      "Get bus clock failed\n");
0027 
0028     ret = clk_prepare_enable(pclk);
0029     if (ret) {
0030         dev_err(dev, "Enable bus clock failed\n");
0031         return ret;
0032     }
0033 
0034     /* Populate children */
0035     ret = devm_of_platform_populate(dev);
0036     if (ret)
0037         dev_err(dev, "Populate platform failed %d\n", ret);
0038 
0039     return ret;
0040 }
0041 
0042 static const struct of_device_id k210_sysctl_of_match[] = {
0043     { .compatible = "canaan,k210-sysctl", },
0044     { /* sentinel */ },
0045 };
0046 
0047 static struct platform_driver k210_sysctl_driver = {
0048     .driver = {
0049         .name       = "k210-sysctl",
0050         .of_match_table = k210_sysctl_of_match,
0051     },
0052     .probe          = k210_sysctl_probe,
0053 };
0054 builtin_platform_driver(k210_sysctl_driver);
0055 
0056 /*
0057  * System controller registers base address and size.
0058  */
0059 #define K210_SYSCTL_BASE_ADDR   0x50440000ULL
0060 #define K210_SYSCTL_BASE_SIZE   0x1000
0061 
0062 /*
0063  * This needs to be called very early during initialization, given that
0064  * PLL1 needs to be enabled to be able to use all SRAM.
0065  */
0066 static void __init k210_soc_early_init(const void *fdt)
0067 {
0068     void __iomem *sysctl_base;
0069 
0070     sysctl_base = ioremap(K210_SYSCTL_BASE_ADDR, K210_SYSCTL_BASE_SIZE);
0071     if (!sysctl_base)
0072         panic("k210-sysctl: ioremap failed");
0073 
0074     k210_clk_early_init(sysctl_base);
0075 
0076     iounmap(sysctl_base);
0077 }
0078 SOC_EARLY_INIT_DECLARE(k210_soc, "canaan,kendryte-k210", k210_soc_early_init);