summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/starfive/clk-starfive-jh7110-gen.c184
-rw-r--r--[-rwxr-xr-x]drivers/clk/starfive/clk-starfive-jh7110.h1
-rw-r--r--drivers/input/touchscreen/tinker_ft5406.c43
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stf_video.c88
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stf_video.h1
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stf_vin.h4
-rw-r--r--drivers/media/platform/starfive/v4l2_driver/stfcamss.c98
-rwxr-xr-xdrivers/pinctrl/starfive/pinctrl-starfive-jh7110.c37
-rw-r--r--drivers/pinctrl/starfive/pinctrl-starfive.c19
-rw-r--r--drivers/pinctrl/starfive/pinctrl-starfive.h7
-rw-r--r--drivers/usb/cdns3/cdns3-starfive.c49
11 files changed, 355 insertions, 176 deletions
diff --git a/drivers/clk/starfive/clk-starfive-jh7110-gen.c b/drivers/clk/starfive/clk-starfive-jh7110-gen.c
index d852c0a2d01f..26cbe0710b43 100644
--- a/drivers/clk/starfive/clk-starfive-jh7110-gen.c
+++ b/drivers/clk/starfive/clk-starfive-jh7110-gen.c
@@ -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,
diff --git a/drivers/clk/starfive/clk-starfive-jh7110.h b/drivers/clk/starfive/clk-starfive-jh7110.h
index 4560b75f52c9..c776ab38a7b3 100755..100644
--- a/drivers/clk/starfive/clk-starfive-jh7110.h
+++ b/drivers/clk/starfive/clk-starfive-jh7110.h
@@ -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 {
diff --git a/drivers/input/touchscreen/tinker_ft5406.c b/drivers/input/touchscreen/tinker_ft5406.c
index 256e2bac82e7..64ba05715631 100644
--- a/drivers/input/touchscreen/tinker_ft5406.c
+++ b/drivers/input/touchscreen/tinker_ft5406.c
@@ -26,10 +26,6 @@
#include <linux/module.h>
#include <linux/workqueue.h>
-#define LOG_DBG(fmt, arg...) pr_debug("tinker-ft5406: %s: "fmt, __func__, ##arg)
-#define LOG_INFO(fmt, arg...) pr_info("tinker-ft5406: %s: "fmt, __func__, ##arg)
-#define LOG_ERR(fmt, arg...) pr_err("tinker-ft5406: %s: "fmt, __func__, ##arg)
-
#define RETRY_COUNT 10
#define FT_ONE_TCH_LEN 6
@@ -38,7 +34,7 @@
#define FT_REG_FW_SUB_MIN_VER 0xB3
#define VALID_TD_STATUS_VAL 10
-#define MAX_TOUCH_POINTS 1
+#define MAX_TOUCH_POINTS 5
#define FT_PRESS 0x7F
#define FT_MAX_ID 0x0F
@@ -110,7 +106,7 @@ static int fts_i2c_read(struct i2c_client *client, char *writebuf,
};
ret = i2c_transfer(client->adapter, msgs, 2);
if (ret < 0)
- LOG_ERR("i2c read error, %d\n", ret);
+ dev_err(&client->dev, "i2c read error, %d\n", ret);
} else {
struct i2c_msg msgs[] = {
{
@@ -122,7 +118,7 @@ static int fts_i2c_read(struct i2c_client *client, char *writebuf,
};
ret = i2c_transfer(client->adapter, msgs, 1);
if (ret < 0)
- LOG_ERR("i2c read error, %d\n", ret);
+ dev_err(&client->dev, "i2c read error, %d\n", ret);
}
return ret;
@@ -153,7 +149,8 @@ static int fts_check_fw_ver(struct i2c_client *client)
if (ret < 0)
goto error;
- LOG_INFO("Firmware version = %d.%d.%d\n", fw_ver[0], fw_ver[1], fw_ver[2]);
+ dev_info(&client->dev, "Firmware version = %d.%d.%d\n",
+ fw_ver[0], fw_ver[1], fw_ver[2]);
return 0;
error:
@@ -167,7 +164,8 @@ static int fts_read_td_status(struct tinker_ft5406_data *ts_data)
ret = fts_read_reg(ts_data->client, FT_TD_STATUS_REG, &td_status);
if (ret < 0) {
- LOG_ERR("get reg td_status failed, %d\n", ret);
+ dev_err(&ts_data->client->dev,
+ "Get reg td_status failed, %d\n", ret);
return ret;
}
return (int)td_status;
@@ -184,7 +182,7 @@ static int fts_read_touchdata(struct tinker_ft5406_data *ts_data)
reg_addr = FT_TOUCH_X_H_REG + (i * FT_ONE_TCH_LEN);
ret = fts_i2c_read(ts_data->client, &reg_addr, 1, buf, FT_ONE_TCH_LEN-2);
if (ret < 0) {
- LOG_ERR("read touchdata failed.\n");
+ dev_err(&ts_data->client->dev, "Read touchdata failed.\n");
return ret;
}
@@ -226,7 +224,7 @@ static void fts_report_value(struct tinker_ft5406_data *ts_data)
event->au16_y[i]);
if (!((1 << event->au8_finger_id[i]) & ts_data->known_ids))
- LOG_DBG("Touch id-%d: x = %d, y = %d\n",
+ dev_dbg(&ts_data->client->dev, "Touch id-%d: x = %d, y = %d\n",
event->au8_finger_id[i],
event->au16_x[i],
event->au16_y[i]);
@@ -236,7 +234,7 @@ static void fts_report_value(struct tinker_ft5406_data *ts_data)
released_ids = ts_data->known_ids & ~modified_ids;
for (i = 0; released_ids && i < MAX_TOUCH_POINTS; i++) {
if (released_ids & (1<<i)) {
- LOG_DBG("Release id-%d, known = %x modified = %x\n",
+ dev_dbg(&ts_data->client->dev, "Release id-%d, known = %x modified = %x\n",
i, ts_data->known_ids, modified_ids);
input_mt_slot(ts_data->input_dev, i);
input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, false);
@@ -257,12 +255,13 @@ static void fts_retry_clear(struct tinker_ft5406_data *ts_data)
static int fts_retry_wait(struct tinker_ft5406_data *ts_data)
{
if (ts_data->retry_count < RETRY_COUNT) {
- LOG_INFO("wait and retry, count = %d\n", ts_data->retry_count);
+ dev_info(&ts_data->client->dev,
+ "Wait and retry, count = %d\n", ts_data->retry_count);
ts_data->retry_count++;
msleep(1000);
return 1;
}
- LOG_ERR("attach retry count\n");
+ dev_err(&ts_data->client->dev, "Attach retry count\n");
return 0;
}
@@ -277,7 +276,7 @@ static void tinker_ft5406_work(struct work_struct *work)
if (td_status < 0) {
ret = fts_retry_wait(g_ts_data);
if (ret == 0) {
- LOG_ERR("stop touch polling\n");
+ dev_err(&g_ts_data->client->dev, "Stop touch polling\n");
break;
}
} else if (td_status < VALID_TD_STATUS_VAL + 1 &&
@@ -312,11 +311,11 @@ static int tinker_ft5406_probe(struct i2c_client *client,
struct input_dev *input_dev;
int ret = 0;
- LOG_INFO("address = 0x%x\n", client->addr);
+ dev_info(&client->dev, "Address = 0x%x\n", client->addr);
g_ts_data = kzalloc(sizeof(struct tinker_ft5406_data), GFP_KERNEL);
if (g_ts_data == NULL) {
- LOG_ERR("no memory for device\n");
+ dev_err(&client->dev, "No memory for device\n");
return -ENOMEM;
}
@@ -327,18 +326,18 @@ static int tinker_ft5406_probe(struct i2c_client *client,
g_ts_data->screen_height = 480;
g_ts_data->xy_reverse = 1;
- LOG_INFO("width = %d, height = %d, reverse = %d\n",
+ dev_info(&client->dev, "width = %d, height = %d, reverse = %d\n",
g_ts_data->screen_width, g_ts_data->screen_height, g_ts_data->xy_reverse);
ret = fts_check_fw_ver(g_ts_data->client);
if (ret) {
- LOG_ERR("checking touch ic failed\n");
+ dev_err(&client->dev, "Checking touch ic failed\n");
goto check_fw_err;
}
input_dev = input_allocate_device();
if (!input_dev) {
- LOG_ERR("failed to allocate input device\n");
+ dev_err(&client->dev, "Failed to allocate input device\n");
goto input_allocate_failed;
}
input_dev->name = "fts_ts";
@@ -361,7 +360,7 @@ static int tinker_ft5406_probe(struct i2c_client *client,
ret = input_register_device(input_dev);
if (ret) {
- LOG_ERR("Input device registration failed\n");
+ dev_err(&client->dev, "Input device registration failed\n");
goto input_register_failed;
}
@@ -371,8 +370,6 @@ static int tinker_ft5406_probe(struct i2c_client *client,
return 0;
-check_fw_failed:
- input_unregister_device(g_ts_data->input_dev);
input_register_failed:
input_free_device(input_dev);
input_allocate_failed:
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_video.c b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
index 7a634e91fc6a..9aef386e9b54 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.c
@@ -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;
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_video.h b/drivers/media/platform/starfive/v4l2_driver/stf_video.h
index d134ee69c34e..6037d0ec7ac5 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_video.h
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_video.h
@@ -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,
diff --git a/drivers/media/platform/starfive/v4l2_driver/stf_vin.h b/drivers/media/platform/starfive/v4l2_driver/stf_vin.h
index 5625621c1544..492bffe27d17 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stf_vin.h
+++ b/drivers/media/platform/starfive/v4l2_driver/stf_vin.h
@@ -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;
diff --git a/drivers/media/platform/starfive/v4l2_driver/stfcamss.c b/drivers/media/platform/starfive/v4l2_driver/stfcamss.c
index 11dbb85c5e5e..d9213cbf64fb 100644
--- a/drivers/media/platform/starfive/v4l2_driver/stfcamss.c
+++ b/drivers/media/platform/starfive/v4l2_driver/stfcamss.c
@@ -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;
+ }
}
}
}
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
index d7adf8b3332d..091f36649512 100755
--- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c
@@ -1663,6 +1663,43 @@ static int starfive_jh7110_pinctrl_probe(struct platform_device *pdev)
return starfive_pinctrl_probe(pdev, pinctrl_info);
}
+static int __maybe_unused starfive_pinctrl_suspend(struct device *dev)
+{
+ struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
+ u8 i;
+
+ for (i = 0 ; i < SYS_IRQ_REG_SUSPENDED_NUM ; i++)
+ pctl->sys_irq_reg_suspended[i] =
+ readl_relaxed(pctl->padctl_base + GPIO_EN + OFFSET_PER_REG * i);
+
+ for (i = 0 ; i < AON_IRQ_REG_SUSPENDED_NUM ; i++)
+ pctl->aon_irq_reg_suspended[i] =
+ readl_relaxed(pctl->padctl_base + AON_GPIO_EN_REG + OFFSET_PER_REG * i);
+
+ return pinctrl_force_sleep(pctl->pctl_dev);
+}
+
+static int __maybe_unused starfive_pinctrl_resume(struct device *dev)
+{
+ struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
+ u8 i;
+
+ for (i = 0 ; i < SYS_IRQ_REG_SUSPENDED_NUM ; i++)
+ writel_relaxed(pctl->sys_irq_reg_suspended[i],
+ pctl->padctl_base + GPIO_EN + OFFSET_PER_REG * i);
+
+ for (i = 0 ; i < AON_IRQ_REG_SUSPENDED_NUM ; i++)
+ writel_relaxed(pctl->aon_irq_reg_suspended[i],
+ pctl->padctl_base + AON_GPIO_EN_REG + OFFSET_PER_REG * i);
+
+ return pinctrl_force_default(pctl->pctl_dev);
+}
+
+const struct dev_pm_ops starfive_pinctrl_pm_ops = {
+ SET_LATE_SYSTEM_SLEEP_PM_OPS(starfive_pinctrl_suspend,
+ starfive_pinctrl_resume)
+};
+
static struct platform_driver starfive_jh7110_pinctrl_driver = {
.driver = {
.name = "starfive_jh7110-pinctrl",
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive.c b/drivers/pinctrl/starfive/pinctrl-starfive.c
index 262f573bc370..127053fe096b 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive.c
+++ b/drivers/pinctrl/starfive/pinctrl-starfive.c
@@ -474,25 +474,6 @@ int starfive_pinctrl_probe(struct platform_device *pdev,
}
EXPORT_SYMBOL_GPL(starfive_pinctrl_probe);
-static int __maybe_unused starfive_pinctrl_suspend(struct device *dev)
-{
- struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
-
- return pinctrl_force_sleep(pctl->pctl_dev);
-}
-
-static int __maybe_unused starfive_pinctrl_resume(struct device *dev)
-{
- struct starfive_pinctrl *pctl = dev_get_drvdata(dev);
-
- return pinctrl_force_default(pctl->pctl_dev);
-}
-
-const struct dev_pm_ops starfive_pinctrl_pm_ops = {
- SET_LATE_SYSTEM_SLEEP_PM_OPS(starfive_pinctrl_suspend,
- starfive_pinctrl_resume)
-};
-EXPORT_SYMBOL_GPL(starfive_pinctrl_pm_ops);
MODULE_DESCRIPTION("Pinctrl driver for StarFive JH7110 SoC");
MODULE_AUTHOR("jenny.zhang <jenny.zhang@starfivetech.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/starfive/pinctrl-starfive.h b/drivers/pinctrl/starfive/pinctrl-starfive.h
index 2db9df9550af..ed79d72aaea3 100644
--- a/drivers/pinctrl/starfive/pinctrl-starfive.h
+++ b/drivers/pinctrl/starfive/pinctrl-starfive.h
@@ -17,10 +17,12 @@
#define STARFIVE_USE_SCU BIT(0)
+#define SYS_IRQ_REG_SUSPENDED_NUM 11
+#define AON_IRQ_REG_SUSPENDED_NUM 6
+
struct platform_device;
extern const struct pinmux_ops starfive_pmx_ops;
-extern const struct dev_pm_ops starfive_pinctrl_pm_ops;
struct starfive_pin_config {
unsigned long io_config;
@@ -75,6 +77,9 @@ struct starfive_pinctrl {
struct pinctrl_gpio_range gpios;
unsigned long enabled;
unsigned int trigger[MAX_GPIO];
+
+ u32 sys_irq_reg_suspended[SYS_IRQ_REG_SUSPENDED_NUM];
+ u32 aon_irq_reg_suspended[AON_IRQ_REG_SUSPENDED_NUM];
};
struct starfive_pinctrl_soc_info {
diff --git a/drivers/usb/cdns3/cdns3-starfive.c b/drivers/usb/cdns3/cdns3-starfive.c
index 9d1147b7067f..d05bf61b8052 100644
--- a/drivers/usb/cdns3/cdns3-starfive.c
+++ b/drivers/usb/cdns3/cdns3-starfive.c
@@ -74,6 +74,8 @@ struct cdns_starfive {
u32 stg_offset_500;
bool usb2_only;
enum usb_dr_mode mode;
+ void __iomem *phybase_20;
+ void __iomem *phybase_30;
};
static int cdns_mode_init(struct platform_device *pdev,
@@ -194,39 +196,44 @@ exit:
return ret;
}
+static void cdns_starfive_set_phy(struct cdns_starfive *data)
+{
+ unsigned int val;
+
+ if (data->mode != USB_DR_MODE_PERIPHERAL) {
+ /* Enable the LS speed keep-alive signal */
+ val = readl(data->phybase_20 + USB_LS_KEEPALIVE_OFF);
+ val |= BIT(USB_LS_KEEPALIVE_ENABLE);
+ writel(val, data->phybase_20 + USB_LS_KEEPALIVE_OFF);
+ }
+
+ if (!data->usb2_only) {
+ /* Configuare spread-spectrum mode: down-spread-spectrum */
+ writel(BIT(4), data->phybase_30 + PCIE_USB3_PHY_PLL_CTL_OFF);
+ }
+}
+
static int cdns_starfive_phy_init(struct platform_device *pdev,
struct cdns_starfive *data)
{
struct device *dev = &pdev->dev;
- void __iomem *phybase_20, *phybase_30;
- unsigned int val;
int ret = 0;
- phybase_20 = devm_platform_ioremap_resource(pdev, USB2_PHY_RES_INDEX);
- if (IS_ERR(phybase_20)) {
+ data->phybase_20 = devm_platform_ioremap_resource(pdev, USB2_PHY_RES_INDEX);
+ if (IS_ERR(data->phybase_20)) {
dev_err(dev, "Can't map phybase_20 IOMEM resource\n");
- ret = PTR_ERR(phybase_20);
+ ret = PTR_ERR(data->phybase_20);
goto get_res_err;
}
- phybase_30 = devm_platform_ioremap_resource(pdev, USB3_PHY_RES_INDEX);
- if (IS_ERR(phybase_30)) {
+ data->phybase_30 = devm_platform_ioremap_resource(pdev, USB3_PHY_RES_INDEX);
+ if (IS_ERR(data->phybase_30)) {
dev_err(dev, "Can't map phybase_30 IOMEM resource\n");
- ret = PTR_ERR(phybase_30);
+ ret = PTR_ERR(data->phybase_30);
goto get_res_err;
}
- if (data->mode != USB_DR_MODE_PERIPHERAL) {
- /* Enable the LS speed keep-alive signal */
- val = readl(phybase_20 + USB_LS_KEEPALIVE_OFF);
- val |= BIT(USB_LS_KEEPALIVE_ENABLE);
- writel(val, phybase_20 + USB_LS_KEEPALIVE_OFF);
- }
-
- if (!data->usb2_only) {
- /* Configuare spread-spectrum mode: down-spread-spectrum */
- writel(BIT(4), (phybase_30 + PCIE_USB3_PHY_PLL_CTL_OFF));
- }
+ cdns_starfive_set_phy(data);
get_res_err:
return ret;
@@ -351,6 +358,10 @@ static int cdns_starfive_resume(struct device *dev)
goto err;
ret = reset_control_deassert(data->resets);
+ if (ret)
+ goto err;
+
+ cdns_starfive_set_phy(data);
err:
return ret;
}