Merge branch 'CR_3051_ts_515_changhuang.liang' into 'jh7110-5.15.y-devel'
authorandy.hu <andy.hu@starfivetech.com>
Wed, 11 Jan 2023 11:06:58 +0000 (11:06 +0000)
committerandy.hu <andy.hu@starfivetech.com>
Wed, 11 Jan 2023 11:06:58 +0000 (11:06 +0000)
CR_3051_ts_515_changhuang.liang input: touchscreen: tinker_ft5406: Delete unused code.

See merge request sdk/linux!661

13 files changed:
drivers/clk/starfive/clk-starfive-jh7110-gen.c
drivers/clk/starfive/clk-starfive-jh7110.h [changed mode: 0755->0644]
drivers/media/platform/starfive/v4l2_driver/stf_video.c
drivers/media/platform/starfive/v4l2_driver/stf_video.h
drivers/media/platform/starfive/v4l2_driver/stf_vin.h
drivers/media/platform/starfive/v4l2_driver/stfcamss.c
sound/soc/starfive/pwmdac.h [changed mode: 0755->0644]
sound/soc/starfive/starfive_pwmdac.c
sound/soc/starfive/starfive_spdif.c
sound/soc/starfive/starfive_spdif.h
sound/soc/starfive/starfive_spdif_pcm.c
sound/soc/starfive/starfive_tdm.c
sound/soc/starfive/starfive_tdm.h

index d852c0a..26cbe07 100644 (file)
@@ -239,11 +239,145 @@ static void jh7110_clk_debug_init(struct clk_hw *hw, struct dentry *dentry)
 #define jh7110_clk_debug_init NULL
 #endif
 
+#ifdef CONFIG_PM_SLEEP
+static int jh7110_clk_save_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+       void __iomem *reg = jh7110_clk_reg_addr_get(clk);
+       struct jh7110_clk_priv *priv = jh7110_priv_from(clk);
+
+       if (!clk || !priv)
+               return 0;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return 0;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return 0;
+
+       spin_lock(&priv->rmw_lock);
+       clk->saved_reg_value = readl_relaxed(reg);
+       spin_unlock(&priv->rmw_lock);
+
+       return 0;
+}
+
+static void jh7110_clk_gate_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_ENABLE, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_div_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_DIV_MASK, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_mux_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_MUX_MASK, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_inv_restore_context(struct clk_hw *hw)
+{
+       struct jh7110_clk *clk = jh7110_clk_from(hw);
+
+       if (!clk)
+               return;
+
+       if ((clk->reg_flags == JH7110_CLK_ISP_FLAG) || (clk->reg_flags == JH7110_CLK_VOUT_FLAG))
+               return;
+
+       if (clk->idx >= JH7110_CLK_REG_END)
+               return;
+
+       jh7110_clk_reg_rmw(clk, JH7110_CLK_INVERT, clk->saved_reg_value);
+
+       return;
+}
+
+static void jh7110_clk_gdiv_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_div_restore_context(hw);
+       jh7110_clk_gate_restore_context(hw);
+
+       return;
+}
+
+static void jh7110_clk_gmux_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_mux_restore_context(hw);
+       jh7110_clk_gate_restore_context(hw);
+
+       return;
+}
+
+static void jh7110_clk_mdiv_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_mux_restore_context(hw);
+       jh7110_clk_div_restore_context(hw);
+
+       return;
+}
+
+static void jh7110_clk_gmd_restore_context(struct clk_hw *hw)
+{
+       jh7110_clk_mux_restore_context(hw);
+       jh7110_clk_div_restore_context(hw);
+       jh7110_clk_gate_restore_context(hw);
+
+       return;
+}
+
+#endif
+
 static const struct clk_ops jh7110_clk_gate_ops = {
        .enable = jh7110_clk_enable,
        .disable = jh7110_clk_disable,
        .is_enabled = jh7110_clk_is_enabled,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gate_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_div_ops = {
@@ -251,6 +385,10 @@ static const struct clk_ops jh7110_clk_div_ops = {
        .determine_rate = jh7110_clk_determine_rate,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_div_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_gdiv_ops = {
@@ -261,6 +399,10 @@ static const struct clk_ops jh7110_clk_gdiv_ops = {
        .determine_rate = jh7110_clk_determine_rate,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gdiv_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_mux_ops = {
@@ -268,6 +410,10 @@ static const struct clk_ops jh7110_clk_mux_ops = {
        .set_parent = jh7110_clk_set_parent,
        .get_parent = jh7110_clk_get_parent,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_mux_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_gmux_ops = {
@@ -278,6 +424,10 @@ static const struct clk_ops jh7110_clk_gmux_ops = {
        .set_parent = jh7110_clk_set_parent,
        .get_parent = jh7110_clk_get_parent,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gmux_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_mdiv_ops = {
@@ -287,6 +437,10 @@ static const struct clk_ops jh7110_clk_mdiv_ops = {
        .set_parent = jh7110_clk_set_parent,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_mdiv_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_gmd_ops = {
@@ -299,12 +453,20 @@ static const struct clk_ops jh7110_clk_gmd_ops = {
        .set_parent = jh7110_clk_set_parent,
        .set_rate = jh7110_clk_set_rate,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_gmd_restore_context,
+#endif
 };
 
 static const struct clk_ops jh7110_clk_inv_ops = {
        .get_phase = jh7110_clk_get_phase,
        .set_phase = jh7110_clk_set_phase,
        .debug_init = jh7110_clk_debug_init,
+#ifdef CONFIG_PM_SLEEP
+       .save_context = jh7110_clk_save_context,
+       .restore_context = jh7110_clk_inv_restore_context,
+#endif
 };
 
 const struct clk_ops *starfive_jh7110_clk_ops(u32 max)
@@ -335,6 +497,25 @@ const struct clk_ops *starfive_jh7110_clk_ops(u32 max)
 }
 EXPORT_SYMBOL_GPL(starfive_jh7110_clk_ops);
 
+#ifdef CONFIG_PM_SLEEP
+static int clk_starfive_jh7110_gen_system_suspend(struct device *dev)
+{
+       return clk_save_context();
+}
+
+static int clk_starfive_jh7110_gen_system_resume(struct device *dev)
+{
+       clk_restore_context();
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops clk_starfive_jh7110_gen_pm_ops = {
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(clk_starfive_jh7110_gen_system_suspend,
+                                    clk_starfive_jh7110_gen_system_resume)
+};
+
 static struct clk_hw *jh7110_clk_get(struct of_phandle_args *clkspec,
                                                void *data)
 {
@@ -369,6 +550,8 @@ static int __init clk_starfive_jh7110_probe(struct platform_device *pdev)
        spin_lock_init(&priv->rmw_lock);
        priv->dev = &pdev->dev;
 
+       pm_runtime_enable(priv->dev);
+
 #ifdef CONFIG_CLK_STARFIVE_JH7110_PLL
        ret = clk_starfive_jh7110_pll_init(pdev, priv->pll_priv);
        if (ret)
@@ -439,6 +622,7 @@ static struct platform_driver clk_starfive_jh7110_driver = {
        .driver = {
                .name = "clk-starfive-jh7110",
                .of_match_table = clk_starfive_jh7110_match,
+               .pm = &clk_starfive_jh7110_gen_pm_ops,
        },
 };
 builtin_platform_driver_probe(clk_starfive_jh7110_driver,
old mode 100755 (executable)
new mode 100644 (file)
index 4560b75..c776ab3
@@ -59,6 +59,7 @@ struct jh7110_clk {
        unsigned int idx;
        unsigned int max_div;
        unsigned int reg_flags;
+       u32 saved_reg_value;
 };
 
 struct jh7110_clk_priv {
index 7a634e9..9aef386 100644 (file)
@@ -11,8 +11,6 @@
 #include <media/videobuf2-vmalloc.h>
 #include <media/videobuf2-dma-contig.h>
 
-#define USE_MEDIA_PIPELINE
-
 static const struct stfcamss_format_info formats_pix_st7110_wr[] = {
        { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_PIX_FMT_YUYV, 1,
          { { 1, 1 } }, { { 1, 1 } }, { 16 } },
@@ -552,15 +550,13 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
        struct v4l2_subdev *subdev;
        int ret;
 
-#ifdef USE_MEDIA_PIPELINE
-       // ret = media_pipeline_start(&vdev->entity, &video->pipe);
        ret = media_pipeline_start(&vdev->entity, &video->stfcamss->pipe);
        if (ret < 0) {
                st_err(ST_VIDEO,
                        "Failed to media_pipeline_start: %d\n", ret);
                return ret;
        }
-#endif
+
        ret = video_check_format(video);
        if (ret < 0)
                goto error;
@@ -584,9 +580,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
        return 0;
 
 error:
-#ifdef USE_MEDIA_PIPELINE
        media_pipeline_stop(&vdev->entity);
-#endif
        video->ops->flush_buffers(video, VB2_BUF_STATE_QUEUED);
        return ret;
 }
@@ -615,9 +609,7 @@ static void video_stop_streaming(struct vb2_queue *q)
                v4l2_subdev_call(subdev, video, s_stream, 0);
        }
 
-#ifdef USE_MEDIA_PIPELINE
        media_pipeline_stop(&vdev->entity);
-#endif
        video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
 }
 
@@ -1619,59 +1611,21 @@ static int video_open(struct file *file)
 
        file->private_data = vfh;
 
-#ifdef USE_MEDIA_PIPELINE
-       ret = v4l2_pipeline_pm_get(&vdev->entity);
-       if (ret < 0) {
-               st_err(ST_VIDEO,
-                       "Failed to power up pipeline: %d\n", ret);
-               goto error_pm_use;
+       if (!video->pm_count) {
+               ret = v4l2_pipeline_pm_get(&vdev->entity);
+               if (ret < 0) {
+                       st_err(ST_VIDEO,
+                               "Failed to power up pipeline: %d\n", ret);
+                       goto error_pm_use;
+               }
        }
-#else
-       struct media_entity *entity;
-       struct media_pad *pad;
-       struct v4l2_subdev *subdev;
-       int i = 0;
-
-       entity = &vdev->entity;
-       while (1) {
-               pad = &entity->pads[0];
-               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                       break;
 
-               pad = media_entity_remote_pad(pad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
+       video->pm_count++;
 
-               entity = pad->entity;
-               subdev = media_entity_to_v4l2_subdev(entity);
-
-               ret = v4l2_subdev_call(subdev, core, s_power, 1);
-               if (ret < 0 && ret != -ENOIOCTLCMD)
-                       goto error_power;
-               i++;
-       }
-#endif
        mutex_unlock(&video->lock);
 
        return 0;
-#ifndef USE_MEDIA_PIPELINE
-error_power:
-       entity = &vdev->entity;
-       while (i--) {
-               pad = &entity->pads[0];
-               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                       break;
 
-               pad = media_entity_remote_pad(pad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
-
-               entity = pad->entity;
-               subdev = media_entity_to_v4l2_subdev(entity);
-
-               v4l2_subdev_call(subdev, core, s_power, 0);
-       }
-#endif
 error_pm_use:
        v4l2_fh_release(file);
 error_alloc:
@@ -1682,31 +1636,15 @@ error_alloc:
 static int video_release(struct file *file)
 {
        struct video_device *vdev = video_devdata(file);
+       struct stfcamss_video *video = video_drvdata(file);
 
        vb2_fop_release(file);
-#ifdef USE_MEDIA_PIPELINE
-       v4l2_pipeline_pm_put(&vdev->entity);
-#else
-       struct media_entity *entity;
-       struct media_pad *pad;
-       struct v4l2_subdev *subdev;
 
-       entity = &vdev->entity;
-       while (1) {
-               pad = &entity->pads[0];
-               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                       break;
-
-               pad = media_entity_remote_pad(pad);
-               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                       break;
+       video->pm_count--;
 
-               entity = pad->entity;
-               subdev = media_entity_to_v4l2_subdev(entity);
+       if (!video->pm_count)
+               v4l2_pipeline_pm_put(&vdev->entity);
 
-               v4l2_subdev_call(subdev, core, s_power, 0);
-       }
-#endif
        file->private_data = NULL;
 
        return 0;
index d134ee6..6037d0e 100644 (file)
@@ -69,6 +69,7 @@ struct stfcamss_video {
        const struct stfcamss_format_info *formats;
        unsigned int nformats;
        unsigned int is_mp;
+       unsigned int pm_count;
 };
 
 int stf_video_register(struct stfcamss_video *video,
index 5625621..492bffe 100644 (file)
@@ -82,6 +82,10 @@ struct vin_line {
        spinlock_t output_lock;
        const struct vin2_format *formats;
        unsigned int nformats;
+#ifdef CONFIG_PM_SLEEP
+       int pm_stream_count;
+       int pm_power_count;
+#endif
 };
 
 struct stf_vin2_dev;
index 11dbb85..d9213cb 100644 (file)
@@ -1201,31 +1201,43 @@ static int stfcamss_suspend(struct device *dev)
        struct stfcamss_video *video;
        struct video_device *vdev;
        int i = 0;
+       int pm_power_count;
+       int pm_stream_count;
 
        for (i = 0; i < VIN_LINE_MAX; i++) {
-               if (vin_dev->line[i].stream_count) {
-                       vin_dev->line[i].stream_count ++;
-                       video = &vin_dev->line[i].video_out;
-                       vdev = &vin_dev->line[i].video_out.vdev;
-                       entity = &vdev->entity;
-                       while (1) {
-                               pad = &entity->pads[0];
-                               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                                       break;
-
-                               pad = media_entity_remote_pad(pad);
-                               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                                       break;
-
-                               entity = pad->entity;
-                               subdev = media_entity_to_v4l2_subdev(entity);
-
-                               v4l2_subdev_call(subdev, video, s_stream, 0);
+               video = &vin_dev->line[i].video_out;
+               vdev = &vin_dev->line[i].video_out.vdev;
+               vin_dev->line[i].pm_power_count = vin_dev->line[i].power_count;
+               vin_dev->line[i].pm_stream_count = vin_dev->line[i].stream_count;
+               pm_power_count = vin_dev->line[i].pm_power_count;
+               pm_stream_count = vin_dev->line[i].pm_stream_count;
+
+               if (pm_stream_count) {
+                       while (pm_stream_count--) {
+                               entity = &vdev->entity;
+                               while (1) {
+                                       pad = &entity->pads[0];
+                                       if (!(pad->flags & MEDIA_PAD_FL_SINK))
+                                               break;
+
+                                       pad = media_entity_remote_pad(pad);
+                                       if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+                                               break;
+
+                                       entity = pad->entity;
+                                       subdev = media_entity_to_v4l2_subdev(entity);
+
+                                       v4l2_subdev_call(subdev, video, s_stream, 0);
+                               }
                        }
                        media_pipeline_stop(&vdev->entity);
                        video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
-                       v4l2_pipeline_pm_put(&vdev->entity);
                }
+
+               if (!pm_power_count)
+                       continue;
+
+               v4l2_pipeline_pm_put(&vdev->entity);
        }
 
        return pm_runtime_force_suspend(dev);
@@ -1241,40 +1253,48 @@ static int stfcamss_resume(struct device *dev)
        struct stfcamss_video *video;
        struct video_device *vdev;
        int i = 0;
+       int pm_power_count;
+       int pm_stream_count;
        int ret = 0;
 
        pm_runtime_force_resume(dev);
 
        for (i = 0; i < VIN_LINE_MAX; i++) {
-               if (vin_dev->line[i].stream_count) {
-                       vin_dev->line[i].stream_count--;
-                       video = &vin_dev->line[i].video_out;
-                       vdev = &vin_dev->line[i].video_out.vdev;
+               video = &vin_dev->line[i].video_out;
+               vdev = &vin_dev->line[i].video_out.vdev;
+               pm_power_count = vin_dev->line[i].pm_power_count;
+               pm_stream_count = vin_dev->line[i].pm_stream_count;
 
-                       ret = v4l2_pipeline_pm_get(&vdev->entity);
-                       if (ret < 0)
-                               goto err;
+               if (!pm_power_count)
+                       continue;
 
+               ret = v4l2_pipeline_pm_get(&vdev->entity);
+               if (ret < 0)
+                       goto err;
+
+               if (pm_stream_count) {
                        ret = media_pipeline_start(&vdev->entity, &video->stfcamss->pipe);
                        if (ret < 0)
                                goto err_pm_put;
 
-                       entity = &vdev->entity;
-                       while (1) {
-                               pad = &entity->pads[0];
-                               if (!(pad->flags & MEDIA_PAD_FL_SINK))
-                                       break;
+                       while (pm_stream_count--) {
+                               entity = &vdev->entity;
+                               while (1) {
+                                       pad = &entity->pads[0];
+                                       if (!(pad->flags & MEDIA_PAD_FL_SINK))
+                                               break;
 
-                               pad = media_entity_remote_pad(pad);
-                               if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
-                                       break;
+                                       pad = media_entity_remote_pad(pad);
+                                       if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
+                                               break;
 
-                               entity = pad->entity;
-                               subdev = media_entity_to_v4l2_subdev(entity);
+                                       entity = pad->entity;
+                                       subdev = media_entity_to_v4l2_subdev(entity);
 
-                               ret = v4l2_subdev_call(subdev, video, s_stream, 1);
-                               if (ret < 0 && ret != -ENOIOCTLCMD)
-                                       goto err_pipeline_stop;
+                                       ret = v4l2_subdev_call(subdev, video, s_stream, 1);
+                                       if (ret < 0 && ret != -ENOIOCTLCMD)
+                                               goto err_pipeline_stop;
+                               }
                        }
                }
        }
old mode 100755 (executable)
new mode 100644 (file)
index 8b93d7d..d4742f9
@@ -34,9 +34,6 @@
 #define PWMDAC_DUTY_CYCLE_LOW  2
 #define PWMDAC_DUTY_CYCLE_HIGH 3
 
-
-
-
 #define PWMDAC_MCLK    4096000
 
 enum pwmdac_lr_change{
@@ -86,7 +83,6 @@ enum pwmdac_sample_count{
        PWMDAC_SAMPLE_CNT_511 = 511,
 };
 
-
 enum data_shift{
        PWMDAC_DATA_LEFT_SHIFT_BIT_0 = 0,
        PWMDAC_DATA_LEFT_SHIFT_BIT_1,
@@ -144,11 +140,10 @@ struct sf_pwmdac_dev {
        struct clk *audio_src;
        struct clk *pwmdac_apb;
        struct clk *pwmdac_mclk;
+       unsigned int pwmdac_ctrl_data;
 };
 
-
-
-#if IS_ENABLED(CONFIG_SND_STARFIVE_PWMDAC_PCM)
+#if IS_ENABLED(CONFIG_SND_SOC_STARFIVE_PWMDAC_PCM)
 void sf_pwmdac_pcm_push_tx(struct sf_pwmdac_dev *dev);
 void sf_pwmdac_pcm_pop_rx(struct sf_pwmdac_dev *dev);
 int sf_pwmdac_pcm_register(struct platform_device *pdev);
index 1e7a438..fba58e2 100644 (file)
@@ -761,12 +761,25 @@ static int sf_pwmdac_dai_probe(struct snd_soc_dai *dai)
 #ifdef CONFIG_PM_SLEEP
 static int starfive_pwmdac_system_suspend(struct device *dev)
 {
+       struct sf_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
+
+       /* save the register value */
+       pwmdac->pwmdac_ctrl_data = pwmdc_read_reg(pwmdac->pwmdac_base, PWMDAC_CTRL);
        return pm_runtime_force_suspend(dev);
 }
 
 static int starfive_pwmdac_system_resume(struct device *dev)
 {
-       return pm_runtime_force_resume(dev);
+       struct sf_pwmdac_dev *pwmdac = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pm_runtime_force_resume(dev);
+       if (ret)
+               return ret;
+
+       /* restore the register value */
+       pwmdc_write_reg(pwmdac->pwmdac_base, PWMDAC_CTRL, pwmdac->pwmdac_ctrl_data);
+       return 0;
 }
 #endif
 
index ee97627..d7886d3 100644 (file)
@@ -423,12 +423,34 @@ static const struct snd_soc_dai_ops sf_spdif_dai_ops = {
 #ifdef CONFIG_PM_SLEEP
 static int spdif_system_suspend(struct device *dev)
 {
+       struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
+
+       /* save the register value */
+       regmap_read(spdif->regmap, SPDIF_CTRL, &spdif->reg_spdif_ctrl);
+       regmap_read(spdif->regmap, SPDIF_INT_REG, &spdif->reg_spdif_int);
+       regmap_read(spdif->regmap, SPDIF_FIFO_CTRL, &spdif->reg_spdif_fifo_ctrl);
+
        return pm_runtime_force_suspend(dev);
 }
 
 static int spdif_system_resume(struct device *dev)
 {
-       return pm_runtime_force_resume(dev);
+       struct sf_spdif_dev *spdif = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pm_runtime_force_resume(dev);
+       if (ret)
+               return ret;
+
+       /* restore the register value */
+       regmap_update_bits(spdif->regmap, SPDIF_CTRL,
+                          ALLBITMASK, spdif->reg_spdif_ctrl);
+       regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
+                          ALLBITMASK, spdif->reg_spdif_int);
+       regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
+                          ALLBITMASK, spdif->reg_spdif_fifo_ctrl);
+
+       return 0;
 }
 #endif
 
@@ -453,7 +475,6 @@ static const struct dev_pm_ops spdif_pm_ops = {
        SET_SYSTEM_SLEEP_PM_OPS(spdif_system_suspend, spdif_system_resume)
 };
 
-
 #define SF_PCM_RATE_44100_192000  (SNDRV_PCM_RATE_44100 | \
                                   SNDRV_PCM_RATE_48000 | \
                                   SNDRV_PCM_RATE_96000 | \
index bc1cc96..a0c91ae 100644 (file)
@@ -156,6 +156,9 @@ struct sf_spdif_dev {
        struct clk *mclk;
        struct clk *mclk_ext;
        struct reset_control *rst_apb;
+       unsigned int reg_spdif_ctrl;
+       unsigned int reg_spdif_int;
+       unsigned int reg_spdif_fifo_ctrl;
 
        struct snd_dmaengine_dai_dma_data dma_data;
 };
@@ -173,5 +176,4 @@ int sf_spdif_pcm_register(struct platform_device *pdev)
 }
 #endif
 
-
 #endif /* __SND_SOC_STARFIVE_SPDIF_H */
index 5823837..78ed55a 100644 (file)
@@ -149,7 +149,9 @@ static const struct snd_pcm_hardware sf_pcm_hardware = {
        .info = SNDRV_PCM_INFO_INTERLEAVED |
                SNDRV_PCM_INFO_MMAP |
                SNDRV_PCM_INFO_MMAP_VALID |
-               SNDRV_PCM_INFO_BLOCK_TRANSFER,
+               SNDRV_PCM_INFO_BLOCK_TRANSFER |
+               SNDRV_PCM_INFO_PAUSE |
+               SNDRV_PCM_INFO_RESUME,
        .rates = SNDRV_PCM_RATE_8000 |
                SNDRV_PCM_RATE_11025 |
                SNDRV_PCM_RATE_16000 |
index bd7372e..a3506e7 100644 (file)
@@ -30,6 +30,22 @@ static inline void sf_tdm_writel(struct sf_tdm_dev *dev, u16 reg, u32 val)
        writel_relaxed(val, dev->tdm_base + reg);
 }
 
+static void sf_tdm_save_context(struct sf_tdm_dev *dev)
+{
+       dev->saved_reg_value[0] = sf_tdm_readl(dev, TDM_PCMGBCR);
+       dev->saved_reg_value[1] = sf_tdm_readl(dev, TDM_PCMTXCR);
+       dev->saved_reg_value[2] = sf_tdm_readl(dev, TDM_PCMRXCR);
+       dev->saved_reg_value[3] = sf_tdm_readl(dev, TDM_PCMDIV);
+}
+
+static void sf_tdm_restore_context(struct sf_tdm_dev *dev)
+{
+       sf_tdm_writel(dev, TDM_PCMGBCR, dev->saved_reg_value[0]);
+       sf_tdm_writel(dev, TDM_PCMTXCR, dev->saved_reg_value[1]);
+       sf_tdm_writel(dev, TDM_PCMRXCR, dev->saved_reg_value[2]);
+       sf_tdm_writel(dev, TDM_PCMDIV, dev->saved_reg_value[3]);
+}
+
 static void sf_tdm_start(struct sf_tdm_dev *dev, struct snd_pcm_substream *substream)
 {
        u32 data;
@@ -60,6 +76,10 @@ static void sf_tdm_stop(struct sf_tdm_dev *dev, struct snd_pcm_substream *substr
                val &= ~PCMRXCR_RXEN;
                sf_tdm_writel(dev, TDM_PCMRXCR, val);
        }
+
+       val = sf_tdm_readl(dev, TDM_PCMGBCR);
+       val &= ~PCMGBCR_ENABLE;
+       sf_tdm_writel(dev, TDM_PCMGBCR, val);
 }
 
 static int sf_tdm_syncdiv(struct sf_tdm_dev *dev)
@@ -129,7 +149,9 @@ static void sf_tdm_clk_disable(struct sf_tdm_dev *priv)
        clk_disable_unprepare(priv->clk_tdm_ext);
        clk_disable_unprepare(priv->clk_tdm_internal);
        clk_disable_unprepare(priv->clk_tdm_apb);
+       clk_disable_unprepare(priv->clk_apb0);
        clk_disable_unprepare(priv->clk_tdm_ahb);
+       clk_disable_unprepare(priv->clk_ahb0);
        clk_disable_unprepare(priv->clk_mclk_inner);
 }
 
@@ -153,12 +175,24 @@ static int sf_tdm_runtime_resume(struct device *dev)
                return ret;
        }
 
+       ret = clk_prepare_enable(priv->clk_ahb0);
+       if (ret) {
+               dev_err(dev, "Failed to prepare enable clk_ahb0\n");
+               return ret;
+       }
+
        ret = clk_prepare_enable(priv->clk_tdm_ahb);
        if (ret) {
                dev_err(dev, "Failed to prepare enable clk_tdm_ahb\n");
                goto dis_mclk_inner;
        }
 
+       ret = clk_prepare_enable(priv->clk_apb0);
+       if (ret) {
+               dev_err(dev, "Failed to prepare enable clk_apb0\n");
+               return ret;
+       }
+       
        ret = clk_prepare_enable(priv->clk_tdm_apb);
        if (ret) {
                dev_err(dev, "Failed to prepare enable clk_tdm_apb\n");
@@ -183,8 +217,16 @@ static int sf_tdm_runtime_resume(struct device *dev)
                goto dis_tdm_ext;
        }
 
+       ret = reset_control_deassert(priv->resets);
+       if (ret) {
+               dev_err(dev, "Failed to deassert tdm resets\n");
+               goto err_reset;
+       }
+
        return 0;
 
+err_reset:
+       clk_disable_unprepare(priv->clk_tdm);   
 dis_tdm_ext:
        clk_disable_unprepare(priv->clk_tdm_ext);
 dis_tdm_internal:
@@ -385,6 +427,7 @@ static int sf_tdm_hw_params(struct snd_pcm_substream *substream,
        }
 
        sf_tdm_config(dev, substream);
+       sf_tdm_save_context(dev);
 
        return 0;
 }
@@ -400,6 +443,7 @@ static int sf_tdm_trigger(struct snd_pcm_substream *substream,
        case SNDRV_PCM_TRIGGER_RESUME:
        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
                dev->active++;
+               sf_tdm_restore_context(dev);
                sf_tdm_start(dev, substream);
                break;
 
@@ -485,6 +529,8 @@ static struct snd_soc_dai_driver sf_tdm_dai = {
 static const struct snd_pcm_hardware jh71xx_pcm_hardware = {
        .info                   = (SNDRV_PCM_INFO_MMAP          |
                                   SNDRV_PCM_INFO_MMAP_VALID    |
+                                  SNDRV_PCM_INFO_PAUSE         |
+                                  SNDRV_PCM_INFO_RESUME        |
                                   SNDRV_PCM_INFO_INTERLEAVED   |
                                   SNDRV_PCM_INFO_BLOCK_TRANSFER),
        .buffer_bytes_max       = 192512,
@@ -628,7 +674,7 @@ static int sf_tdm_clk_reset_init(struct platform_device *pdev, struct sf_tdm_dev
                dev_err(&pdev->dev, "Failed to deassert tdm resets\n");
                goto dis_tdm_clk;
        }
-
+       
        return 0;
 
 dis_tdm_clk:
index dfba82f..e435e1e 100644 (file)
@@ -149,6 +149,7 @@ struct sf_tdm_dev {
        /* data related to DMA transfers b/w tdm and DMAC */
        struct snd_dmaengine_dai_dma_data play_dma_data;
        struct snd_dmaengine_dai_dma_data capture_dma_data;
+       u32 saved_reg_value[4];
 };
 
 #endif /* __SND_SOC_STARFIVE_TDM_H */