linux/drivers/clk/hisilicon/clk-hi3519.c
<<
>>
Prefs
   1/*
   2 * Hi3519 Clock Driver
   3 *
   4 * Copyright (c) 2015-2016 HiSilicon Technologies Co., Ltd.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include <dt-bindings/clock/hi3519-clock.h>
  21#include <linux/clk-provider.h>
  22#include <linux/module.h>
  23#include <linux/platform_device.h>
  24#include "clk.h"
  25#include "reset.h"
  26
  27#define HI3519_INNER_CLK_OFFSET 64
  28#define HI3519_FIXED_24M        65
  29#define HI3519_FIXED_50M        66
  30#define HI3519_FIXED_75M        67
  31#define HI3519_FIXED_125M       68
  32#define HI3519_FIXED_150M       69
  33#define HI3519_FIXED_200M       70
  34#define HI3519_FIXED_250M       71
  35#define HI3519_FIXED_300M       72
  36#define HI3519_FIXED_400M       73
  37#define HI3519_FMC_MUX          74
  38
  39#define HI3519_NR_CLKS          128
  40
  41static const struct hisi_fixed_rate_clock hi3519_fixed_rate_clks[] = {
  42        { HI3519_FIXED_24M, "24m", NULL, 0, 24000000, },
  43        { HI3519_FIXED_50M, "50m", NULL, 0, 50000000, },
  44        { HI3519_FIXED_75M, "75m", NULL, 0, 75000000, },
  45        { HI3519_FIXED_125M, "125m", NULL, 0, 125000000, },
  46        { HI3519_FIXED_150M, "150m", NULL, 0, 150000000, },
  47        { HI3519_FIXED_200M, "200m", NULL, 0, 200000000, },
  48        { HI3519_FIXED_250M, "250m", NULL, 0, 250000000, },
  49        { HI3519_FIXED_300M, "300m", NULL, 0, 300000000, },
  50        { HI3519_FIXED_400M, "400m", NULL, 0, 400000000, },
  51};
  52
  53static const char *const fmc_mux_p[] = {
  54                "24m", "75m", "125m", "150m", "200m", "250m", "300m", "400m", };
  55static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7};
  56
  57static const struct hisi_mux_clock hi3519_mux_clks[] = {
  58        { HI3519_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p),
  59                CLK_SET_RATE_PARENT, 0xc0, 2, 3, 0, fmc_mux_table, },
  60};
  61
  62static const struct hisi_gate_clock hi3519_gate_clks[] = {
  63        { HI3519_FMC_CLK, "clk_fmc", "fmc_mux",
  64                CLK_SET_RATE_PARENT, 0xc0, 1, 0, },
  65        { HI3519_UART0_CLK, "clk_uart0", "24m",
  66                CLK_SET_RATE_PARENT, 0xe4, 20, 0, },
  67        { HI3519_UART1_CLK, "clk_uart1", "24m",
  68                CLK_SET_RATE_PARENT, 0xe4, 21, 0, },
  69        { HI3519_UART2_CLK, "clk_uart2", "24m",
  70                CLK_SET_RATE_PARENT, 0xe4, 22, 0, },
  71        { HI3519_UART3_CLK, "clk_uart3", "24m",
  72                CLK_SET_RATE_PARENT, 0xe4, 23, 0, },
  73        { HI3519_UART4_CLK, "clk_uart4", "24m",
  74                CLK_SET_RATE_PARENT, 0xe4, 24, 0, },
  75        { HI3519_SPI0_CLK, "clk_spi0", "50m",
  76                CLK_SET_RATE_PARENT, 0xe4, 16, 0, },
  77        { HI3519_SPI1_CLK, "clk_spi1", "50m",
  78                CLK_SET_RATE_PARENT, 0xe4, 17, 0, },
  79        { HI3519_SPI2_CLK, "clk_spi2", "50m",
  80                CLK_SET_RATE_PARENT, 0xe4, 18, 0, },
  81};
  82
  83static int hi3519_clk_probe(struct platform_device *pdev)
  84{
  85        struct device_node *np = pdev->dev.of_node;
  86        struct hisi_clock_data *clk_data;
  87        struct hisi_reset_controller *rstc;
  88
  89        rstc = hisi_reset_init(np);
  90        if (!rstc)
  91                return -ENOMEM;
  92
  93        clk_data = hisi_clk_init(np, HI3519_NR_CLKS);
  94        if (!clk_data) {
  95                hisi_reset_exit(rstc);
  96                return -ENODEV;
  97        }
  98
  99        hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks,
 100                                     ARRAY_SIZE(hi3519_fixed_rate_clks),
 101                                     clk_data);
 102        hisi_clk_register_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks),
 103                                        clk_data);
 104        hisi_clk_register_gate(hi3519_gate_clks,
 105                        ARRAY_SIZE(hi3519_gate_clks), clk_data);
 106
 107        return 0;
 108}
 109
 110static const struct of_device_id hi3519_clk_match_table[] = {
 111        { .compatible = "hisilicon,hi3519-crg" },
 112        { }
 113};
 114MODULE_DEVICE_TABLE(of, hi3519_clk_match_table);
 115
 116static struct platform_driver hi3519_clk_driver = {
 117        .probe          = hi3519_clk_probe,
 118        .driver         = {
 119                .name   = "hi3519-clk",
 120                .of_match_table = hi3519_clk_match_table,
 121        },
 122};
 123
 124static int __init hi3519_clk_init(void)
 125{
 126        return platform_driver_register(&hi3519_clk_driver);
 127}
 128core_initcall(hi3519_clk_init);
 129
 130MODULE_LICENSE("GPL v2");
 131MODULE_DESCRIPTION("HiSilicon Hi3519 Clock Driver");
 132