{
struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
+ /* for powerdown the innohdmi, syspm can use*/
+ inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
}
static void inno_hdmi_encoder_disable(struct drm_encoder *encoder)
{
- struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
-
- inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+ return;
+ /*mention: if enable, sys pm test will be crashed*/
+ //struct inno_hdmi *hdmi = to_inno_hdmi(encoder);
+ //inno_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
}
static bool inno_hdmi_encoder_mode_fixup(struct drm_encoder *encoder,
DRM_DEV_ERROR(dev, "Unable to get HDMI bclk clk\n");
return PTR_ERR(hdmi->bclk);
}
- hdmi->tx_rst = reset_control_get_exclusive(dev, "hdmi_tx");
+ hdmi->tx_rst = reset_control_get_shared(dev, "hdmi_tx");
if (IS_ERR(hdmi->tx_rst)) {
DRM_DEV_ERROR(dev, "Unable to get HDMI tx rst\n");
return PTR_ERR(hdmi->tx_rst);
return 0;
}
-static int inno_hdmi_en_clk_deas_rst(struct device *dev, struct inno_hdmi *hdmi)
+static int inno_hdmi_enable_clk_deassert_rst(struct device *dev, struct inno_hdmi *hdmi)
{
int ret;
"Cannot enable HDMI sys clock: %d\n", ret);
return ret;
}
+
ret = clk_prepare_enable(hdmi->mclk);
if (ret) {
DRM_DEV_ERROR(dev,
"Cannot enable HDMI bclk clock: %d\n", ret);
return ret;
}
-
ret = reset_control_deassert(hdmi->tx_rst);
if (ret < 0) {
dev_err(dev, "failed to deassert tx_rst\n");
return ret;
}
- return ret;
+ return 0;
+}
+
+static void inno_hdmi_disable_clk_assert_rst(struct device *dev, struct inno_hdmi *hdmi)
+{
+ int ret;
+
+ ret = reset_control_assert(hdmi->tx_rst);
+ if (ret < 0)
+ dev_err(dev, "failed to assert tx_rst\n");
+
+ clk_disable_unprepare(hdmi->sys_clk);
+ clk_disable_unprepare(hdmi->mclk);
+ clk_disable_unprepare(hdmi->bclk);
}
int irq;
int ret;
+ dev_info(dev, "inno hdmi bind begin\n");
+
hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi)
return -ENOMEM;
udelay(100);
ret = inno_hdmi_get_clk_rst(dev, hdmi);
- ret = inno_hdmi_en_clk_deas_rst(dev, hdmi);
+ ret = inno_hdmi_enable_clk_deassert_rst(dev, hdmi);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
if (ret)
dev_err(dev, "failed to audio init\n");
+ inno_hdmi_disable_clk_assert_rst(dev, hdmi);
+
+ dev_info(dev, "inno hdmi bind end\n");
+
return 0;
err_cleanup_hdmi:
hdmi->connector.funcs->destroy(&hdmi->connector);
void *data)
{
struct inno_hdmi *hdmi = dev_get_drvdata(dev);
- int ret;
hdmi->connector.funcs->destroy(&hdmi->connector);
hdmi->encoder.funcs->destroy(&hdmi->encoder);
i2c_put_adapter(hdmi->ddc);
- ret = reset_control_assert(hdmi->tx_rst);
- if (ret < 0)
- dev_err(dev, "failed to assert tx_rst\n");
-
- clk_disable_unprepare(hdmi->sys_clk);
- clk_disable_unprepare(hdmi->mclk);
- clk_disable_unprepare(hdmi->bclk);
+ inno_hdmi_disable_clk_assert_rst(dev, hdmi);
regulator_disable(hdmi->hdmi_1p8);
udelay(100);
struct reset_control *sys_rst;
struct reset_control *txbytehs_rst;
struct reset_control *txesc_rst;
+ int irq;
};
+static int cdns_check_register_access(struct cdns_dsi *dsi);
+
//clk op func----------//
static int cdns_dsi_clock_enable(struct cdns_dsi *dsi, struct device *dev)
{
struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
struct cdns_dsi *dsi = input_to_dsi(input);
u32 val;
- int ret;
dsi->link_initialized = false;
val = readl(dsi->regs + MCTL_MAIN_DATA_CTL);
phy_power_off(dsi->dphy);
phy_exit(dsi->dphy);
- ret = cdns_dsi_resets_assert(dsi, dsi->base.dev);
- if (ret < 0)
- dev_err(dsi->base.dev, "failed to assert reset\n");
- cdns_dsi_clock_disable(dsi);
}
static void cdns_dsi_hs_init(struct cdns_dsi *dsi)
int nlanes;
int vrefresh;
u32 div;
- int ret;
-
- ret = cdns_dsi_clock_enable(dsi, dsi->base.dev);
- if (ret) {
- dev_err(dsi->base.dev, "failed to enable clock\n");
- return;
- }
- ret = cdns_dsi_resets_deassert(dsi, dsi->base.dev);
- if (ret < 0) {
- dev_err(dsi->base.dev, "failed to deassert reset\n");
- return;
- }
if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0))
return;
.transfer = cdns_dsi_transfer,
};
-static int __maybe_unused cdns_dsi_resume(struct device *dev)
-{
- struct cdns_dsi *dsi = dev_get_drvdata(dev);
- reset_control_deassert(dsi->dsi_p_rst);
- clk_prepare_enable(dsi->dsi_p_clk);
- clk_prepare_enable(dsi->dsi_sys_clk);
- return 0;
+#ifdef CONFIG_PM_SLEEP
+static int cdns_dsi_system_pm_suspend(struct device *dev)
+{
+ return pm_runtime_force_suspend(dev);
+}
+
+static int cdns_dsi_system_pm_resume(struct device *dev)
+{
+ return pm_runtime_force_resume(dev);
}
+#endif
-static int __maybe_unused cdns_dsi_suspend(struct device *dev)
+static int cdns_dsi_runtime_resume(struct device *dev)
{
struct cdns_dsi *dsi = dev_get_drvdata(dev);
+ int ret;
+
+ ret = cdns_dsi_clock_enable(dsi, dsi->base.dev);
+ if (ret) {
+ dev_err(dsi->base.dev, "failed to enable clock\n");
+ return ret;
+ }
+ enable_irq(dsi->irq);
+
+ ret = cdns_dsi_resets_deassert(dsi, dsi->base.dev);
+ if (ret < 0) {
+ dev_err(dsi->base.dev, "failed to deassert reset\n");
+ return ret;
+ }
- clk_disable_unprepare(dsi->dsi_sys_clk);
- clk_disable_unprepare(dsi->dsi_p_clk);
- reset_control_assert(dsi->dsi_p_rst);
- dsi->link_initialized = false;
return 0;
}
-static UNIVERSAL_DEV_PM_OPS(cdns_dsi_pm_ops, cdns_dsi_suspend, cdns_dsi_resume,
- NULL);
-
-#if 0
-static int cdns_dsi_drm_remove(struct platform_device *pdev)
+static int cdns_dsi_runtime_suspend(struct device *dev)
{
- struct cdns_dsi *dsi = platform_get_drvdata(pdev);
+ struct cdns_dsi *dsi = dev_get_drvdata(dev);
+ int ret;
- mipi_dsi_host_unregister(&dsi->base);
- pm_runtime_disable(&pdev->dev);
+ ret = cdns_dsi_resets_assert(dsi, dsi->base.dev);
+ if (ret < 0)
+ dev_err(dsi->base.dev, "failed to assert reset\n");
+
+ cdns_dsi_clock_disable(dsi);
+
+ dsi->link_initialized = false;
+ disable_irq(dsi->irq);
return 0;
}
-#endif
-static const struct of_device_id cdns_dsi_of_match[] = {
- { .compatible = "cdns,dsi" },
- { },
+static const struct dev_pm_ops cdns_dsi_pm_ops = {
+ SET_RUNTIME_PM_OPS(cdns_dsi_runtime_suspend, cdns_dsi_runtime_resume, NULL)
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(cdns_dsi_system_pm_suspend, cdns_dsi_system_pm_resume)
};
static int cdns_check_register_access(struct cdns_dsi* dsi)
return 0;
}
-static int starfive_dsi_bind(struct device *dev, struct device *master, void *data)
+static int cdns_dsi_drm_probe(struct platform_device *pdev)
{
struct cdns_dsi *dsi;
struct cdns_dsi_input *input;
struct resource *res;
- struct platform_device *pdev = to_platform_device(dev);
- //struct drm_device *drm_dev = data;
- //struct starfive_drm_private *private = drm_dev->dev_private;
int ret;
- int irq;
u32 val;
dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
return -ENOMEM;
platform_set_drvdata(pdev, dsi);
+
input = &dsi->input;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (IS_ERR(dsi->regs))
return PTR_ERR(dsi->regs);
- ret = cdns_dsi_get_clock(dev, dsi);//get clock res
+ ret = cdns_dsi_get_clock(&pdev->dev, dsi);//get clock res
- dev_info(dev, "dsi_sys_clk = %ld\n",clk_get_rate(dsi->dsi_sys_clk));
+ dev_info(&pdev->dev, "dsi_sys_clk = %ld\n", clk_get_rate(dsi->dsi_sys_clk));
- ret = cdns_dsi_get_reset(dev, dsi);//get reset res
+ ret = cdns_dsi_get_reset(&pdev->dev, dsi);//get reset res
- ret = cdns_dsi_clock_enable(dsi, dev);
+ ret = cdns_dsi_clock_enable(dsi, &pdev->dev);
if (ret) {
- dev_err(dev, "failed to enable clock\n");
+ dev_err(&pdev->dev, "failed to enable clock\n");
return ret;
}
- ret = cdns_dsi_resets_deassert(dsi, dev);
+ ret = cdns_dsi_resets_deassert(dsi, &pdev->dev);
if (ret < 0) {
- dev_err(dev, "failed to deassert reset\n");
+ dev_err(&pdev->dev, "failed to deassert reset\n");
return ret;
}
- irq = platform_get_irq(pdev, 0);
- if (irq < 0){
- dev_err(dev, "---get irq error\n");
- return irq;
+ dsi->irq = platform_get_irq(pdev, 0);
+ if (dsi->irq < 0) {
+ dev_err(&pdev->dev, "---get irq error\n");
+ return dsi->irq;
}
dsi->dphy = devm_phy_get(&pdev->dev, "dphy");
}
ret = cdns_check_register_access(dsi);
- if (ret) {
- dev_err(dev, "error: r/w test generic reg failed\n");
- goto ERROR;
+ if (ret) {
+ dev_err(&pdev->dev, "rw test generic reg failed\n");
+ goto ERROR;
}
val = readl(dsi->regs + IP_CONF);
writel(0, dsi->regs + TVG_STS_CTL);
writel(0, dsi->regs + DPI_IRQ_EN);
- ret = devm_request_irq(&pdev->dev, irq, cdns_dsi_interrupt, 0,
+ ret = devm_request_irq(&pdev->dev, dsi->irq, cdns_dsi_interrupt, 0,
dev_name(&pdev->dev), dsi);
- if (ret){
- dev_err(dev, "---devm_request_irq error\n");
- goto err_disable_pclk;
- }
+
+ if (ret)
+ goto err_disable_pclk;
+
+ disable_irq(dsi->irq);
pm_runtime_enable(&pdev->dev);
dsi->base.dev = &pdev->dev;
if (ret)
goto err_disable_runtime_pm;
- init_seeed_panel();
- dev_err(dev, "====starfive_dsi_bind end\n");
+ ret = cdns_dsi_resets_assert(dsi, dsi->base.dev);
+ if (ret < 0)
+ dev_err(dsi->base.dev, "failed to assert reset\n");
+ cdns_dsi_clock_disable(dsi);
+
+ dev_err(&pdev->dev, "starfive dsi bind end\n");
return 0;
err_disable_runtime_pm:
return ret;
}
-static void starfive_dsi_unbind(struct device *dev, struct device *master, void *data)
+static int cdns_dsi_drm_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct cdns_dsi *dsi = platform_get_drvdata(pdev);
int ret;
- ret = cdns_dsi_resets_assert(dsi, dev);
+ ret = cdns_dsi_resets_assert(dsi, &pdev->dev);
if (ret < 0)
- dev_err(dev, "failed to assert reset\n");
+ dev_err(&pdev->dev, "failed to assert reset\n");
cdns_dsi_clock_disable(dsi);
- exit_seeed_panel();
+ //exit_seeed_panel();
mipi_dsi_host_unregister(&dsi->base);
- pm_runtime_disable(dev);
-}
-
-static const struct component_ops starfive_dsi_component_ops = {
- .bind = starfive_dsi_bind,
- .unbind = starfive_dsi_unbind,
-};
-
-static int starfive_dsi_probe(struct platform_device *pdev)
-{
- return component_add(&pdev->dev, &starfive_dsi_component_ops);
-}
+ pm_runtime_disable(&pdev->dev);
-static int starfive_dsi_remove(struct platform_device *pdev)
-{
- component_del(&pdev->dev, &starfive_dsi_component_ops);
return 0;
}
-struct platform_driver starfive_dsi_platform_driver = {
- .probe = starfive_dsi_probe,
- .remove = starfive_dsi_remove,
+static const struct of_device_id cdns_dsi_of_match[] = {
+ { .compatible = "cdns,dsi" },
+ { },
+};
+
+static struct platform_driver cdns_dsi_platform_driver = {
+ .probe = cdns_dsi_drm_probe,
+ .remove = cdns_dsi_drm_remove,
.driver = {
.name = "cdns-dsi",
.of_match_table = cdns_dsi_of_match,
.pm = &cdns_dsi_pm_ops,
},
};
+module_platform_driver(cdns_dsi_platform_driver);
+
MODULE_AUTHOR("Boris Brezillon <boris.brezillon@bootlin.com>");
MODULE_DESCRIPTION("Cadence DSI driver");
connector->display_info.height_mm = 86;
drm_display_info_set_bus_formats(&connector->display_info,
&bus_format, 1);
-
return num;
}
.channel = 0, //0,
.node = NULL,
};
-
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_warn(&client->dev,
"I2C adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
.probe = seeed_dsi_probe,
};
-int init_seeed_panel(void)
+static int __init init_seeed_panel(void)
{
int err;
err = i2c_add_driver(&seeed_panel_driver);
return err;
}
-EXPORT_SYMBOL(init_seeed_panel);
+module_init(init_seeed_panel);
-void exit_seeed_panel(void)
+static void __exit exit_seeed_panel(void)
{
i2c_del_driver(&seeed_panel_driver);
mipi_dsi_driver_unregister(&seeed_dsi_driver);
}
-EXPORT_SYMBOL(exit_seeed_panel);
+module_exit(exit_seeed_panel);
+
+MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
+MODULE_DESCRIPTION("Raspberry Pi 7-inch touchscreen driver");
+MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("A driver for seeed_panel");
-MODULE_LICENSE("GPL");
static int vs_crtc_enable_vblank(struct drm_crtc *crtc)
{
struct vs_crtc *vs_crtc = to_vs_crtc(crtc);
- struct vs_crtc_state *vs_crtc_state = to_vs_crtc_state(crtc->state);
vs_crtc->funcs->enable_vblank(vs_crtc->dev, true);
struct device *dev = vs_crtc->dev;
struct drm_property_blob *blob = crtc->state->gamma_lut;
struct drm_color_lut *lut;
- struct vs_crtc_state *vs_crtc_state = to_vs_crtc_state(crtc->state);
if (crtc_state->color_mgmt_changed) {
if ((blob) && (blob->length)) {
}
#endif
-
static int vs_dc_get_clock(struct device *dev, struct vs_dc *dc)
{
- dc->cpu_axi = devm_clk_get(dev, "noc_cpu");
- if (IS_ERR(dc->cpu_axi)) {
- dev_err(dev, "---cpu_axi get error\n");
- return PTR_ERR(dc->cpu_axi);
- }
-
- dc->axicfg0_axi = devm_clk_get(dev, "noc_cfg0");
- if (IS_ERR(dc->axicfg0_axi)) {
- dev_err(dev, "---axicfg0_axi get error\n");
- return PTR_ERR(dc->axicfg0_axi);
- }
-
dc->disp_axi = devm_clk_get(dev, "noc_disp");
if (IS_ERR(dc->disp_axi)) {
dev_err(dev, "---disp_axi get error\n");
return PTR_ERR(dc->disp_axi);
}
- dc->stg_axi = devm_clk_get(dev, "noc_stg");
- if (IS_ERR(dc->stg_axi)) {
- dev_err(dev, "---stg_axi get error\n");
- return PTR_ERR(dc->stg_axi);
- }
return 0;
}
static int vs_dc_clock_enable(struct device *dev, struct vs_dc *dc)
{
int ret;
- /*clk_prepare_enable(dc->sys_clk);*/
- ret = clk_prepare_enable(dc->cpu_axi);
- if (ret) {
- dev_err(dev, "failed to prepare/enable cpu_axi\n");
- return ret;
- }
- ret = clk_prepare_enable(dc->axicfg0_axi);
- if (ret) {
- dev_err(dev, "failed to prepare/enable axicfg0_axi\n");
- return ret;
- }
ret = clk_prepare_enable(dc->disp_axi);
if (ret) {
dev_err(dev, "failed to prepare/enable disp_axi\n");
return ret;
}
- ret = clk_prepare_enable(dc->stg_axi);
- if (ret) {
- dev_err(dev, "failed to prepare/enable stg_axi\n");
- return ret;
- }
-
- return ret;
+ return 0;
}
static void vs_dc_clock_disable(struct vs_dc *dc)
{
- clk_disable_unprepare(dc->cpu_axi);
- clk_disable_unprepare(dc->axicfg0_axi);
clk_disable_unprepare(dc->disp_axi);
- clk_disable_unprepare(dc->stg_axi);
}
static int vs_dc_vouttop_get_clock(struct device *dev, struct vs_dc *dc)
dev_err(dev, "failed to get vout_axi\n");
return PTR_ERR(dc->vout_axi);
}
-
- dc->ahb1 = devm_clk_get(dev, "ahb1");
- if (IS_ERR(dc->ahb1)) {
- dev_err(dev, "failed to get ahb1\n");
- return PTR_ERR(dc->ahb1);
- }
-
dc->vout_ahb = devm_clk_get(dev, "top_vout_ahb");
if (IS_ERR(dc->vout_ahb)) {
dev_err(dev, "failed to get vout_ahb\n");
return PTR_ERR(dc->vout_ahb);
}
-
- dc->hdmitx0_mclk = devm_clk_get(dev, "top_vout_hdmiTX0");
- if (IS_ERR(dc->hdmitx0_mclk)) {
- dev_err(dev, "failed to get hdmitx0_mclk\n");
- return PTR_ERR(dc->hdmitx0_mclk);
- }
-
- dc->bclk_mst = devm_clk_get(dev, "i2stx");
- if (IS_ERR(dc->bclk_mst)) {
- dev_err(dev, "failed to get bclk_mst\n");
- return PTR_ERR(dc->bclk_mst);
- }
-
return 0;
}
dev_err(dev, "failed to prepare/enable vout_axi\n");
return ret;
}
- ret = clk_prepare_enable(dc->ahb1);
- if (ret) {
- dev_err(dev, "failed to prepare/enable ahb1\n");
- return ret;
- }
- ret = clk_prepare_enable(dc->hdmitx0_mclk);
- if (ret) {
- dev_err(dev, "failed to prepare/enable hdmitx0_mclk\n");
- return ret;
- }
- ret = clk_prepare_enable(dc->bclk_mst);
- if (ret) {
- dev_err(dev, "failed to prepare/enable bclk_mst\n");
- return ret;
- }
return ret;
}
{
clk_disable_unprepare(dc->vout_src);
clk_disable_unprepare(dc->vout_axi);
- clk_disable_unprepare(dc->ahb1);
- clk_disable_unprepare(dc->hdmitx0_mclk);
- clk_disable_unprepare(dc->bclk_mst);
}
static int vs_dc_dc8200_get_clock(struct device *dev, struct vs_dc *dc)
clk_disable_unprepare(dc->dc8200_ahb);
}
-static int dc_vout_clk_rst_init(struct device *dev, struct vs_dc *dc)
+static void vs_vout_reset_get(struct device *dev, struct vs_dc *dc)
+{
+ //dc->rst_vout_src=reset_control_get_shared(dev, "rst_vout_src");
+ dc->rst_vout_src = reset_control_get_shared(dev, "rst_vout_src");
+ if (IS_ERR(dc->rst_vout_src))
+ dev_err(dev, "failed to get rst_vout_src\n");
+ dc->noc_disp = reset_control_get_shared(dev, "rst_noc_disp");
+ if (IS_ERR(dc->noc_disp))
+ dev_err(dev, "failed to get rst_noc_disp\n");
+}
+
+static void vs_vout_reset_deassert(struct vs_dc *dc)
+{
+ reset_control_deassert(dc->rst_vout_src);//no!
+ reset_control_deassert(dc->noc_disp);//ok
+}
+
+/*
+static void vs_vout_reset_assert(struct vs_dc *dc)
+{
+ reset_control_assert(dc->rst_vout_src);//no!
+ reset_control_assert(dc->noc_disp);//ok
+}
+*/
+
+static void vs_dc8200_reset_get(struct device *dev, struct vs_dc *dc)
+{
+ dc->dc8200_rst_axi = reset_control_get_shared(dev, "rst_axi");
+ if (IS_ERR(dc->dc8200_rst_axi))
+ dev_err(dev, "failed to get dc8200_rst_axi\n");
+ dc->dc8200_rst_core = reset_control_get_shared(dev, "rst_ahb");
+ if (IS_ERR(dc->dc8200_rst_core))
+ dev_err(dev, "failed to get dc8200_rst_core\n");
+ dc->dc8200_rst_ahb = reset_control_get_shared(dev, "rst_core");
+ if (IS_ERR(dc->dc8200_rst_core))
+ dev_err(dev, "failed to get dc8200_rst_core\n");
+}
+
+static void vs_dc8200_reset_deassert(struct vs_dc *dc)
+{
+ reset_control_deassert(dc->dc8200_rst_axi);
+ reset_control_deassert(dc->dc8200_rst_core);//ok
+ reset_control_deassert(dc->dc8200_rst_ahb);
+}
+
+static void vs_dc8200_reset_assert(struct vs_dc *dc)
+{
+ reset_control_assert(dc->dc8200_rst_axi);
+ reset_control_assert(dc->dc8200_rst_core);//ok
+ reset_control_assert(dc->dc8200_rst_ahb);
+}
+
+static int dc_vout_clk_get(struct device *dev, struct vs_dc *dc)
{
int ret;
ret = vs_dc_get_clock(dev, dc);
dev_err(dev, "failed to get clock\n");
return ret;
}
-
- ret = vs_dc_clock_enable(dev, dc);
+ ret = vs_dc_vouttop_get_clock(dev, dc);
if (ret) {
- dev_err(dev, "failed to enable clock\n");
+ dev_err(dev, "failed to get clock\n");
return ret;
}
-
- ret = vs_dc_vouttop_get_clock(dev, dc);
+ ret = vs_dc_dc8200_get_clock(dev, dc);
if (ret) {
dev_err(dev, "failed to get clock\n");
return ret;
}
- ret = vs_dc_vouttop_clock_enable(dev, dc);
+ return 0;
+}
+
+static int dc_vout_clk_enable(struct device *dev, struct vs_dc *dc)
+{
+ int ret;
+
+ ret = vs_dc_clock_enable(dev, dc);
if (ret) {
dev_err(dev, "failed to enable clock\n");
return ret;
}
- ret = vs_dc_dc8200_get_clock(dev, dc);
+ ret = vs_dc_vouttop_clock_enable(dev, dc);
if (ret) {
- dev_err(dev, "failed to get clock\n");
+ dev_err(dev, "failed to enable clock\n");
return ret;
}
return ret;
}
- dc->vout_resets = devm_reset_control_array_get_exclusive(dev);
- if (IS_ERR(dc->vout_resets)) {
- ret = PTR_ERR(dc->vout_resets);
- dev_err(dev, "faied to get vout resets controls\n");
- }
-
- ret = reset_control_deassert(dc->vout_resets);
- if (ret){
- dev_err(dev, "deassert error.\n");
- return ret;
- }
-
- return ret;
+ return 0;
}
-
static int syscon_panel_parse_dt(struct device *dev)
{
struct vs_dc *dc = dev_get_drvdata(dev);
static void dc_deinit(struct device *dev)
{
struct vs_dc *dc = dev_get_drvdata(dev);
- struct platform_device *pdev = to_platform_device(dev);
int ret;
dc_hw_enable_interrupt(&dc->hw, 0);
dc_hw_deinit(&dc->hw);
ret = reset_control_assert(dc->vout_resets);
if (ret)
dev_err(dev, "assert vout resets error.\n");
-
- pm_runtime_put_sync(&pdev->dev);
- pm_runtime_disable(&pdev->dev);
}
static int dc_init(struct device *dev)
{
struct vs_dc *dc = dev_get_drvdata(dev);
- struct platform_device *pdev = to_platform_device(dev);
int ret;
dc->first_frame = true;
return ret;
}
- pm_runtime_enable(&pdev->dev);
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0) {
- dev_err(&pdev->dev, "dc_init: failed to get pm runtime: %d\n", ret);
+ ret = dc_vout_clk_get(dev, dc);
+ if (ret) {
+ dev_err(dev, "failed to get clock\n");
return ret;
}
-
- ret = dc_vout_clk_rst_init(dev, dc);
+ vs_vout_reset_get(dev, dc);
+ vs_dc8200_reset_get(dev, dc);
ret = sys_dispctrl_clk_standard(dc, dev);
+ ret = dc_vout_clk_enable(dev, dc);
+ if (ret) {
+ dev_err(dev, "failed to enable clock\n");
+ //return ret;
+ }
+ //vs_vout_reset_deassert(dc);
+ vs_dc8200_reset_deassert(dc);
+ ret = clk_prepare_enable(dc->vout_top_lcd);
+ if (ret)
+ dev_err(dev, "failed to prepare/enable vout_top_lcd\n");
+
+ ret = dc_hw_init(&dc->hw);
+ if (ret) {
+ dev_err(dev, "failed to init DC HW\n");
+ //return ret;
+ }
+
+ vs_vout_reset_deassert(dc);
#ifdef CONFIG_DRM_I2C_NXP_TDA998X//tda998x-rgb2hdmi
regmap_update_bits(dc->dss_regmap, 0x4, BIT(20), 1<<20);
#endif
return PTR_ERR(dc->vout_top_lcd);
}
- ret = clk_set_parent(dc->vout_top_lcd, dc->dc8200_clk_pix1_out);
+ ret = clk_set_parent(dc->vout_top_lcd, dc->dc8200_clk_pix1_out);
+/*
ret = clk_prepare_enable(dc->vout_top_lcd);
if (ret) {
dev_err(dev, "failed to prepare/enable vout_top_lcd\n");
return ret;
}
-
+*/
ret = dc_hw_init(&dc->hw);
if (ret) {
dev_err(dev, "failed to init DC HW\n");
struct vs_crtc_state *crtc_state = to_vs_crtc_state(crtc->state);
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
struct dc_hw_display display;
+ int ret;
+
+ ret = dc_vout_clk_enable(dev, dc);
+ if (ret)
+ dev_err(dev, "failed to enable clock\n");
+
+ vs_dc8200_reset_deassert(dc);
+ ret = clk_prepare_enable(dc->vout_top_lcd);
+ if (ret)
+ dev_err(dev, "failed to prepare/enable vout_top_lcd\n");
+
+ //regmap_update_bits(dc->dss_regmap, 0x4, BIT(20), 1<<20);
+
+ //regmap_update_bits(dc->dss_regmap, 0x8, BIT(3), 1<<3);
+
+ ret = dc_hw_init(&dc->hw);
+ if (ret)
+ dev_err(dev, "failed to init DC HW\n");
display.bus_format = crtc_state->output_fmt;
display.h_active = mode->hdisplay;
display.enable = true;
+ clk_set_rate(dc->dc8200_pix0, mode->clock * 1000);
+ dc->pix_clk_rate = mode->clock;
+
if (crtc_state->encoder_type == DRM_MODE_ENCODER_DSI){
+ /*
if (dc->pix_clk_rate != mode->clock) {
clk_set_rate(dc->dc8200_pix0, mode->clock * 1000);
dc->pix_clk_rate = mode->clock;
}
+ */
clk_set_parent(dc->dc8200_clk_pix1, dc->dc8200_pix0);
udelay(1000);
dc_hw_set_out(&dc->hw, OUT_DPI, display.id);
} else {
+ /*
if (dc->pix_clk_rate != mode->clock) {
clk_set_rate(dc->dc8200_pix0, mode->clock * 1000);
dc->pix_clk_rate = mode->clock;
}
+ */
clk_set_parent(dc->dc8200_clk_pix1, dc->dc8200_pix0);
clk_set_parent(dc->dc8200_clk_pix0, dc->hdmitx0_pixelclk);
dc_hw_enable_mmu_prefetch(&dc->hw, false);
#endif
+ regmap_update_bits(dc->dss_regmap, 0x4, BIT(20), 1 << 20);
+
+ regmap_update_bits(dc->dss_regmap, 0x8, BIT(3), 1 << 3);
+
dc_hw_setup_display(&dc->hw, &display);
}
display.enable = false;
dc_hw_setup_display(&dc->hw, &display);
+
+ clk_disable_unprepare(dc->vout_top_lcd);
+/*dc8200 asrt*/
+ vs_dc8200_reset_assert(dc);
+
+/*dc8200 clk disable*/
+ vs_dc_dc8200_clock_disable(dc);
+
+/*vouttop clk disable*/
+ vs_dc_vouttop_clock_disable(dc);
+
+/*vout clk disable*/
+ vs_dc_clock_disable(dc);
}
static bool vs_dc_mode_fixup(struct device *dev,
vs_drm_update_pitch_alignment(drm_dev, dc_info->pitch_alignment);
+ clk_disable_unprepare(dc->vout_top_lcd);
+/*dc8200 asrt*/
+ vs_dc8200_reset_assert(dc);
+
+/*dc8200 clk disable*/
+ vs_dc_dc8200_clock_disable(dc);
+
+/*vouttop clk disable*/
+ vs_dc_vouttop_clock_disable(dc);
+
+/*vout clk disable*/
+ vs_dc_clock_disable(dc);
+
return 0;
err_cleanup_planes:
struct reset_control *vout_resets;
+//20221014
+ struct reset_control *dc8200_rst_axi;
+ struct reset_control *dc8200_rst_core;
+ struct reset_control *dc8200_rst_ahb;
+
+ struct reset_control *rst_vout_src;
+ struct reset_control *noc_disp;
+
+//20221014
+
struct regmap *dss_regmap;
};
#include <linux/component.h>
#include <linux/iommu.h>
#include <linux/version.h>
+#include <linux/delay.h>
#include <drm/drm_of.h>
#include <drm/drm_crtc.h>
#include "vs_virtual.h"
#include "dw_mipi_dsi.h"
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+
extern struct platform_driver starfive_encoder_driver;
#define DRV_NAME "starfive"
static bool has_iommu = true;
static struct platform_driver vs_drm_platform_driver;
+struct drm_minor *drm_minor_acquire(unsigned int minor_id);
+
+static int vs_hdmi_get_clk_rst(struct device *dev, struct vs_drm_private *priv)
+{
+ priv->vs_hdmi_sys_clk = devm_clk_get(dev, "hdmi_sysclk");
+ if (IS_ERR(priv->vs_hdmi_sys_clk)) {
+ DRM_DEV_ERROR(dev, "Unable to get HDMI sysclk clk\n");
+ return PTR_ERR(priv->vs_hdmi_sys_clk);
+ }
+
+ priv->vs_hdmi_mclk = devm_clk_get(dev, "hdmi_mclk");
+ if (IS_ERR(priv->vs_hdmi_mclk)) {
+ DRM_DEV_ERROR(dev, "Unable to get HDMI mclk clk\n");
+ return PTR_ERR(priv->vs_hdmi_mclk);
+ }
+ priv->vs_hdmi_bclk = devm_clk_get(dev, "hdmi_bclk");
+ if (IS_ERR(priv->vs_hdmi_bclk)) {
+ DRM_DEV_ERROR(dev, "Unable to get HDMI bclk clk\n");
+ return PTR_ERR(priv->vs_hdmi_bclk);
+ }
+
+ priv->vs_hdmi_tx_rst = reset_control_get_shared(dev, "hdmi_txrst");
+ if (IS_ERR(priv->vs_hdmi_tx_rst)) {
+ DRM_DEV_ERROR(dev, "Unable to get HDMI tx rst in vs_drm\n");
+ return PTR_ERR(priv->vs_hdmi_tx_rst);
+ }
+
+ return 0;
+}
+
+static int vs_hdmi_enable_clk_deassert_rst(struct device *dev, struct vs_drm_private *priv)
+{
+ int ret;
+
+ ret = clk_prepare_enable(priv->vs_hdmi_sys_clk);
+ if (ret) {
+ DRM_DEV_ERROR(dev,
+ "Cannot enable HDMI sys clock: %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(priv->vs_hdmi_mclk);
+ if (ret) {
+ DRM_DEV_ERROR(dev,
+ "Cannot enable HDMI mclk clock: %d\n", ret);
+ return ret;
+ }
+ ret = clk_prepare_enable(priv->vs_hdmi_bclk);
+ if (ret) {
+ DRM_DEV_ERROR(dev,
+ "Cannot enable HDMI bclk clock: %d\n", ret);
+ return ret;
+ }
+ ret = reset_control_deassert(priv->vs_hdmi_tx_rst);
+ if (ret < 0) {
+ dev_err(dev, "failed to deassert tx_rst\n");
+ return ret;
+ }
+ return 0;
+}
+
+static void vs_hdmi_disable_clk_assert_rst(struct device *dev, struct vs_drm_private *priv)
+{
+ int ret;
+
+ ret = reset_control_assert(priv->vs_hdmi_tx_rst);
+ if (ret < 0)
+ dev_err(dev, "failed to assert tx_rst in vs_drm\n");
+
+ clk_disable_unprepare(priv->vs_hdmi_sys_clk);
+ clk_disable_unprepare(priv->vs_hdmi_mclk);
+ clk_disable_unprepare(priv->vs_hdmi_bclk);
+}
+
+static int vs_drm_open(struct inode *inode, struct file *filp)
+{
+ struct drm_minor *minor; //= file_priv->minor;
+ struct drm_device *drm_dev; //= minor->dev;
+ struct device *dev;
+ int ret;
+ struct vs_drm_private *priv;
+
+ minor = drm_minor_acquire(iminor(inode));
+ if (IS_ERR(minor))
+ return PTR_ERR(minor);
+
+ dev = minor->dev->dev;
+ dev_info(dev, "vs drm open\n");
+
+ drm_dev = dev_get_drvdata(dev);
+ priv = drm_dev->dev_private;
+
+ ret = vs_hdmi_enable_clk_deassert_rst(dev, priv);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable clk or deassert rst in %s\n", __func__);
+ return ret;
+ }
+ return drm_open(inode, filp);
+}
+
+static int vs_drm_release(struct inode *inode, struct file *filp)
+{
+ struct drm_file *file_priv = filp->private_data;
+ struct drm_minor *minor = file_priv->minor;
+ struct device *dev;
+
+ dev = minor->dev->dev;
+ dev_info(dev, "vs drm release\n");
+
+ return drm_release(inode, filp);
+}
+
+static void vs_drm_lastclose(struct drm_device *dev)
+{
+ struct vs_drm_private *priv;
+
+ dev_info(dev->dev, "vs drm lastclose\n");
+ drm_fb_helper_lastclose(dev);
+ priv = dev->dev_private;
+ vs_hdmi_disable_clk_assert_rst(dev->dev, priv);
+}
+
static const struct file_operations fops = {
.owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
+ .open = vs_drm_open,//drm_open,
+ .release = vs_drm_release,//drm_release,
.unlocked_ioctl = drm_ioctl,
.compat_ioctl = drm_compat_ioctl,
.poll = drm_poll,
static struct drm_driver vs_drm_driver = {
.driver_features = DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_GEM,
- .lastclose = drm_fb_helper_lastclose,
+ .lastclose = vs_drm_lastclose,//drm_fb_helper_lastclose,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = vs_gem_prime_import,
goto err_put_dev;
}
+ ret = vs_hdmi_get_clk_rst(dev, priv);
+ if (ret) {
+ dev_err(dev, "vs_hdmi_get_clk_rst failed\n");
+ goto err_put_dev;
+ }
+
priv->pitch_alignment = 64;
priv->dma_dev = drm_dev->dev;
priv->dma_dev->coherent_dma_mask = dma_mask;
#ifdef CONFIG_STARFIVE_INNO_HDMI
&inno_hdmi_driver,
#endif
-#ifdef CONFIG_STARFIVE_DSI
- &starfive_dsi_platform_driver,
-#endif
&simple_encoder_driver,
static int vs_drm_suspend(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
+ dev_info(dev, "vs_drm_suspend\n");
return drm_mode_config_helper_suspend(drm);
}
static int vs_drm_resume(struct device *dev)
{
struct drm_device *drm = dev_get_drvdata(dev);
+ dev_info(dev, "vs_drm_resume\n");
return drm_mode_config_helper_resume(drm);
}
static SIMPLE_DEV_PM_OPS(vs_drm_pm_ops, vs_drm_suspend, vs_drm_resume);
-
static const struct of_device_id vs_drm_dt_ids[] = {
{ .compatible = "verisilicon,display-subsystem", },
#endif
unsigned int pitch_alignment;
+ struct clk *vs_hdmi_sys_clk;
+ struct clk *vs_hdmi_mclk;
+ struct clk *vs_hdmi_bclk;
+ struct reset_control *vs_hdmi_tx_rst;
};
int vs_drm_iommu_attach_device(struct drm_device *drm_dev,
extern struct platform_driver inno_hdmi_driver;
#endif
-#ifdef CONFIG_STARFIVE_DSI
-extern int init_seeed_panel(void);
-extern void exit_seeed_panel(void);
-extern struct platform_driver starfive_dsi_platform_driver;
-#endif
-
#endif /* __VS_DRV_H__ */