forked from Minki/linux
1802d0beec
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms of the gnu general public license version 2 as published by the free software foundation this program is distributed in the hope that it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 655 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org> Reviewed-by: Richard Fontana <rfontana@redhat.com> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190527070034.575739538@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
100 lines
2.1 KiB
C
100 lines
2.1 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (c) 2015 MediaTek Inc.
|
|
* Author: James Liao <jamesjj.liao@mediatek.com>
|
|
*/
|
|
|
|
#include <linux/delay.h>
|
|
#include <linux/of_address.h>
|
|
#include <linux/slab.h>
|
|
|
|
#include "clk-mtk.h"
|
|
|
|
#define REF2USB_TX_EN BIT(0)
|
|
#define REF2USB_TX_LPF_EN BIT(1)
|
|
#define REF2USB_TX_OUT_EN BIT(2)
|
|
#define REF2USB_EN_MASK (REF2USB_TX_EN | REF2USB_TX_LPF_EN | \
|
|
REF2USB_TX_OUT_EN)
|
|
|
|
struct mtk_ref2usb_tx {
|
|
struct clk_hw hw;
|
|
void __iomem *base_addr;
|
|
};
|
|
|
|
static inline struct mtk_ref2usb_tx *to_mtk_ref2usb_tx(struct clk_hw *hw)
|
|
{
|
|
return container_of(hw, struct mtk_ref2usb_tx, hw);
|
|
}
|
|
|
|
static int mtk_ref2usb_tx_is_prepared(struct clk_hw *hw)
|
|
{
|
|
struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
|
|
|
|
return (readl(tx->base_addr) & REF2USB_EN_MASK) == REF2USB_EN_MASK;
|
|
}
|
|
|
|
static int mtk_ref2usb_tx_prepare(struct clk_hw *hw)
|
|
{
|
|
struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
|
|
u32 val;
|
|
|
|
val = readl(tx->base_addr);
|
|
|
|
val |= REF2USB_TX_EN;
|
|
writel(val, tx->base_addr);
|
|
udelay(100);
|
|
|
|
val |= REF2USB_TX_LPF_EN;
|
|
writel(val, tx->base_addr);
|
|
|
|
val |= REF2USB_TX_OUT_EN;
|
|
writel(val, tx->base_addr);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void mtk_ref2usb_tx_unprepare(struct clk_hw *hw)
|
|
{
|
|
struct mtk_ref2usb_tx *tx = to_mtk_ref2usb_tx(hw);
|
|
u32 val;
|
|
|
|
val = readl(tx->base_addr);
|
|
val &= ~REF2USB_EN_MASK;
|
|
writel(val, tx->base_addr);
|
|
}
|
|
|
|
static const struct clk_ops mtk_ref2usb_tx_ops = {
|
|
.is_prepared = mtk_ref2usb_tx_is_prepared,
|
|
.prepare = mtk_ref2usb_tx_prepare,
|
|
.unprepare = mtk_ref2usb_tx_unprepare,
|
|
};
|
|
|
|
struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
|
|
const char *parent_name, void __iomem *reg)
|
|
{
|
|
struct mtk_ref2usb_tx *tx;
|
|
struct clk_init_data init = {};
|
|
struct clk *clk;
|
|
|
|
tx = kzalloc(sizeof(*tx), GFP_KERNEL);
|
|
if (!tx)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
tx->base_addr = reg;
|
|
tx->hw.init = &init;
|
|
|
|
init.name = name;
|
|
init.ops = &mtk_ref2usb_tx_ops;
|
|
init.parent_names = &parent_name;
|
|
init.num_parents = 1;
|
|
|
|
clk = clk_register(NULL, &tx->hw);
|
|
|
|
if (IS_ERR(clk)) {
|
|
pr_err("Failed to register clk %s: %ld\n", name, PTR_ERR(clk));
|
|
kfree(tx);
|
|
}
|
|
|
|
return clk;
|
|
}
|