cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy-mtk-hdmi.c (5167B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2018 MediaTek Inc.
      4 * Author: Jie Qiu <jie.qiu@mediatek.com>
      5 */
      6
      7#include "phy-mtk-hdmi.h"
      8
      9static int mtk_hdmi_phy_power_on(struct phy *phy);
     10static int mtk_hdmi_phy_power_off(struct phy *phy);
     11
     12static const struct phy_ops mtk_hdmi_phy_dev_ops = {
     13	.power_on = mtk_hdmi_phy_power_on,
     14	.power_off = mtk_hdmi_phy_power_off,
     15	.owner = THIS_MODULE,
     16};
     17
     18void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
     19			     u32 bits)
     20{
     21	void __iomem *reg = hdmi_phy->regs + offset;
     22	u32 tmp;
     23
     24	tmp = readl(reg);
     25	tmp &= ~bits;
     26	writel(tmp, reg);
     27}
     28
     29void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
     30			   u32 bits)
     31{
     32	void __iomem *reg = hdmi_phy->regs + offset;
     33	u32 tmp;
     34
     35	tmp = readl(reg);
     36	tmp |= bits;
     37	writel(tmp, reg);
     38}
     39
     40void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
     41		       u32 val, u32 mask)
     42{
     43	void __iomem *reg = hdmi_phy->regs + offset;
     44	u32 tmp;
     45
     46	tmp = readl(reg);
     47	tmp = (tmp & ~mask) | (val & mask);
     48	writel(tmp, reg);
     49}
     50
     51inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
     52{
     53	return container_of(hw, struct mtk_hdmi_phy, pll_hw);
     54}
     55
     56static int mtk_hdmi_phy_power_on(struct phy *phy)
     57{
     58	struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy);
     59	int ret;
     60
     61	ret = clk_prepare_enable(hdmi_phy->pll);
     62	if (ret < 0)
     63		return ret;
     64
     65	hdmi_phy->conf->hdmi_phy_enable_tmds(hdmi_phy);
     66	return 0;
     67}
     68
     69static int mtk_hdmi_phy_power_off(struct phy *phy)
     70{
     71	struct mtk_hdmi_phy *hdmi_phy = phy_get_drvdata(phy);
     72
     73	hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy);
     74	clk_disable_unprepare(hdmi_phy->pll);
     75
     76	return 0;
     77}
     78
     79static const struct phy_ops *
     80mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy)
     81{
     82	if (hdmi_phy && hdmi_phy->conf &&
     83	    hdmi_phy->conf->hdmi_phy_enable_tmds &&
     84	    hdmi_phy->conf->hdmi_phy_disable_tmds)
     85		return &mtk_hdmi_phy_dev_ops;
     86
     87	if (hdmi_phy)
     88		dev_err(hdmi_phy->dev, "Failed to get dev ops of phy\n");
     89	return NULL;
     90}
     91
     92static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,
     93				      struct clk_init_data *clk_init)
     94{
     95	clk_init->flags = hdmi_phy->conf->flags;
     96	clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops;
     97}
     98
     99static int mtk_hdmi_phy_probe(struct platform_device *pdev)
    100{
    101	struct device *dev = &pdev->dev;
    102	struct mtk_hdmi_phy *hdmi_phy;
    103	struct clk *ref_clk;
    104	const char *ref_clk_name;
    105	struct clk_init_data clk_init = {
    106		.num_parents = 1,
    107		.parent_names = (const char * const *)&ref_clk_name,
    108	};
    109
    110	struct phy *phy;
    111	struct phy_provider *phy_provider;
    112	int ret;
    113
    114	hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL);
    115	if (!hdmi_phy)
    116		return -ENOMEM;
    117
    118	hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
    119	if (IS_ERR(hdmi_phy->regs))
    120		return PTR_ERR(hdmi_phy->regs);
    121
    122	ref_clk = devm_clk_get(dev, "pll_ref");
    123	if (IS_ERR(ref_clk))
    124		return dev_err_probe(dev, PTR_ERR(ref_clk),
    125				     "Failed to get PLL reference clock\n");
    126
    127	ref_clk_name = __clk_get_name(ref_clk);
    128
    129	ret = of_property_read_string(dev->of_node, "clock-output-names",
    130				      &clk_init.name);
    131	if (ret < 0)
    132		return dev_err_probe(dev, ret, "Failed to read clock-output-names\n");
    133
    134	hdmi_phy->dev = dev;
    135	hdmi_phy->conf =
    136		(struct mtk_hdmi_phy_conf *)of_device_get_match_data(dev);
    137	mtk_hdmi_phy_clk_get_data(hdmi_phy, &clk_init);
    138	hdmi_phy->pll_hw.init = &clk_init;
    139	hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw);
    140	if (IS_ERR(hdmi_phy->pll))
    141		return dev_err_probe(dev, PTR_ERR(hdmi_phy->pll),
    142				    "Failed to register PLL\n");
    143
    144	ret = of_property_read_u32(dev->of_node, "mediatek,ibias",
    145				   &hdmi_phy->ibias);
    146	if (ret < 0)
    147		return dev_err_probe(dev, ret, "Failed to get ibias\n");
    148
    149	ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up",
    150				   &hdmi_phy->ibias_up);
    151	if (ret < 0)
    152		return dev_err_probe(dev, ret, "Failed to get ibias_up\n");
    153
    154	dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n");
    155	hdmi_phy->drv_imp_clk = 0x30;
    156	hdmi_phy->drv_imp_d2 = 0x30;
    157	hdmi_phy->drv_imp_d1 = 0x30;
    158	hdmi_phy->drv_imp_d0 = 0x30;
    159
    160	phy = devm_phy_create(dev, NULL, mtk_hdmi_phy_dev_get_ops(hdmi_phy));
    161	if (IS_ERR(phy))
    162		return dev_err_probe(dev, PTR_ERR(phy), "Cannot create HDMI PHY\n");
    163
    164	phy_set_drvdata(phy, hdmi_phy);
    165
    166	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
    167	if (IS_ERR(phy_provider))
    168		return dev_err_probe(dev, PTR_ERR(phy_provider),
    169				     "Failed to register HDMI PHY\n");
    170
    171	if (hdmi_phy->conf->pll_default_off)
    172		hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy);
    173
    174	return of_clk_add_provider(dev->of_node, of_clk_src_simple_get,
    175				   hdmi_phy->pll);
    176}
    177
    178static const struct of_device_id mtk_hdmi_phy_match[] = {
    179	{ .compatible = "mediatek,mt2701-hdmi-phy",
    180	  .data = &mtk_hdmi_phy_2701_conf,
    181	},
    182	{ .compatible = "mediatek,mt8173-hdmi-phy",
    183	  .data = &mtk_hdmi_phy_8173_conf,
    184	},
    185	{},
    186};
    187MODULE_DEVICE_TABLE(of, mtk_hdmi_phy_match);
    188
    189static struct platform_driver mtk_hdmi_phy_driver = {
    190	.probe = mtk_hdmi_phy_probe,
    191	.driver = {
    192		.name = "mediatek-hdmi-phy",
    193		.of_match_table = mtk_hdmi_phy_match,
    194	},
    195};
    196module_platform_driver(mtk_hdmi_phy_driver);
    197
    198MODULE_DESCRIPTION("MediaTek HDMI PHY Driver");
    199MODULE_LICENSE("GPL v2");