lkml.org 
[lkml]   [2019]   [Mar]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v8 10/15] drm/sun4i: sun6i_mipi_dsi: Add has_mod_clk quirk
    Date
    As per the user manual, look like mod clock is not mandatory
    for all Allwinner MIPI DSI controllers, it is connected to
    CLK_DSI_SCLK for A31 and not available in A64.

    So add has_mod_clk quirk and process the clk accordingly.

    Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>
    Tested-by: Merlijn Wajer <merlijn@wizzup.org>
    ---
    drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 38 ++++++++++++++++++--------
    drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 5 ++++
    2 files changed, 32 insertions(+), 11 deletions(-)

    diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
    index f42ea806f6c8..2a63e96aaff9 100644
    --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
    +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
    @@ -10,6 +10,7 @@
    #include <linux/component.h>
    #include <linux/crc-ccitt.h>
    #include <linux/of_address.h>
    +#include <linux/of_device.h>
    #include <linux/pm_runtime.h>
    #include <linux/regmap.h>
    #include <linux/reset.h>
    @@ -1126,6 +1127,7 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
    dsi->dev = dev;
    dsi->host.ops = &sun6i_dsi_host_ops;
    dsi->host.dev = dev;
    + dsi->variant = of_device_get_match_data(dev);

    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    base = devm_ioremap_resource(dev, res);
    @@ -1153,17 +1155,20 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
    return PTR_ERR(dsi->reset);
    }

    - dsi->mod_clk = devm_clk_get(dev, "mod");
    - if (IS_ERR(dsi->mod_clk)) {
    - dev_err(dev, "Couldn't get the DSI mod clock\n");
    - return PTR_ERR(dsi->mod_clk);
    + if (dsi->variant->has_mod_clk) {
    + dsi->mod_clk = devm_clk_get(dev, "mod");
    + if (IS_ERR(dsi->mod_clk)) {
    + dev_err(dev, "Couldn't get the DSI mod clock\n");
    + return PTR_ERR(dsi->mod_clk);
    + }
    }

    /*
    * In order to operate properly, that clock seems to be always
    * set to 297MHz.
    */
    - clk_set_rate_exclusive(dsi->mod_clk, 297000000);
    + if (dsi->variant->has_mod_clk)
    + clk_set_rate_exclusive(dsi->mod_clk, 297000000);

    dsi->dphy = devm_phy_get(dev, "dphy");
    if (IS_ERR(dsi->dphy)) {
    @@ -1193,7 +1198,8 @@ static int sun6i_dsi_probe(struct platform_device *pdev)
    err_pm_disable:
    pm_runtime_disable(dev);
    err_unprotect_clk:
    - clk_rate_exclusive_put(dsi->mod_clk);
    + if (dsi->variant->has_mod_clk)
    + clk_rate_exclusive_put(dsi->mod_clk);
    return ret;
    }

    @@ -1205,7 +1211,8 @@ static int sun6i_dsi_remove(struct platform_device *pdev)
    component_del(&pdev->dev, &sun6i_dsi_ops);
    mipi_dsi_host_unregister(&dsi->host);
    pm_runtime_disable(dev);
    - clk_rate_exclusive_put(dsi->mod_clk);
    + if (dsi->variant->has_mod_clk)
    + clk_rate_exclusive_put(dsi->mod_clk);

    return 0;
    }
    @@ -1222,7 +1229,8 @@ static int __maybe_unused sun6i_dsi_runtime_resume(struct device *dev)
    }

    reset_control_deassert(dsi->reset);
    - clk_prepare_enable(dsi->mod_clk);
    + if (dsi->variant->has_mod_clk)
    + clk_prepare_enable(dsi->mod_clk);

    /*
    * Enable the DSI block.
    @@ -1250,7 +1258,8 @@ static int __maybe_unused sun6i_dsi_runtime_suspend(struct device *dev)
    {
    struct sun6i_dsi *dsi = dev_get_drvdata(dev);

    - clk_disable_unprepare(dsi->mod_clk);
    + if (dsi->variant->has_mod_clk)
    + clk_disable_unprepare(dsi->mod_clk);
    reset_control_assert(dsi->reset);
    regulator_disable(dsi->regulator);

    @@ -1263,9 +1272,16 @@ static const struct dev_pm_ops sun6i_dsi_pm_ops = {
    NULL)
    };

    +static const struct sun6i_dsi_variant sun6i_a31_mipi_dsi = {
    + .has_mod_clk = true,
    +};
    +
    static const struct of_device_id sun6i_dsi_of_table[] = {
    - { .compatible = "allwinner,sun6i-a31-mipi-dsi" },
    - { }
    + {
    + .compatible = "allwinner,sun6i-a31-mipi-dsi",
    + .data = &sun6i_a31_mipi_dsi,
    + },
    + { /* sentinel */ }
    };
    MODULE_DEVICE_TABLE(of, sun6i_dsi_of_table);

    diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
    index c570f2b3868f..5c4983212f89 100644
    --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
    +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
    @@ -15,6 +15,10 @@

    #include <linux/regulator/consumer.h>

    +struct sun6i_dsi_variant {
    + bool has_mod_clk;
    +};
    +
    struct sun6i_dsi {
    struct drm_connector connector;
    struct drm_encoder encoder;
    @@ -32,6 +36,7 @@ struct sun6i_dsi {
    struct sun4i_tcon *tcon;
    struct mipi_dsi_device *device;
    struct drm_panel *panel;
    + const struct sun6i_dsi_variant *variant;
    };

    static inline struct sun6i_dsi *host_to_sun6i_dsi(struct mipi_dsi_host *host)
    --
    2.18.0.321.gffc6fa0e3
    \
     
     \ /
      Last update: 2019-03-11 14:38    [W:5.031 / U:0.424 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site