struct reset_control *rst_a;
struct reset_control *rst_h;
struct reset_control *rst_v;
+ struct reset_control *rst_niu_a;
+ struct reset_control *rst_niu_h;
#endif
struct device *dev;
(task->end.tv_usec - task->start.tv_usec) / 1000);
}
+static inline int try_reset_assert(struct reset_control *rst)
+{
+ if (rst)
+ return reset_control_assert(rst);
+ return -EINVAL;
+}
+
+static inline int try_reset_deassert(struct reset_control *rst)
+{
+ if (rst)
+ return reset_control_deassert(rst);
+ return -EINVAL;
+}
+
static inline int grf_combo_switch(const struct vpu_subdev_data *data)
{
struct vpu_service_info *pservice = data->pservice;
static void _vpu_reset(struct vpu_subdev_data *data)
{
struct vpu_service_info *pservice = data->pservice;
- enum pmu_idle_req type = IDLE_REQ_VIDEO;
-
- if (pservice->dev_id == VCODEC_DEVICE_ID_HEVC)
- type = IDLE_REQ_HEVC;
+ unsigned long rate = 0;
dev_info(pservice->dev, "resetting...\n");
WARN_ON(pservice->reg_codec != NULL);
pservice->reg_resev = NULL;
#ifdef CONFIG_RESET_CONTROLLER
- dev_info(pservice->dev, "for 3288/3368...");
- if (of_machine_is_compatible("rockchip,rk3288"))
- rockchip_pmu_idle_request(pservice->dev, true);
- if (pservice->rst_a && pservice->rst_h) {
- dev_info(pservice->dev, "vpu reset in\n");
-
- if (pservice->rst_v)
- reset_control_assert(pservice->rst_v);
- reset_control_assert(pservice->rst_a);
- reset_control_assert(pservice->rst_h);
- udelay(5);
-
- reset_control_deassert(pservice->rst_h);
- reset_control_deassert(pservice->rst_a);
- if (pservice->rst_v)
- reset_control_deassert(pservice->rst_v);
- } else if (pservice->rst_v) {
- dev_info(pservice->dev, "hevc reset in\n");
- reset_control_assert(pservice->rst_v);
- udelay(5);
-
- reset_control_deassert(pservice->rst_v);
- }
- if (of_machine_is_compatible("rockchip,rk3288"))
- rockchip_pmu_idle_request(pservice->dev, false);
+ rockchip_pmu_idle_request(pservice->dev, true);
+ rate = clk_get_rate(pservice->aclk_vcodec);
+ /*
+ * Some old platforms can't run at 300MHZ, they don't request
+ * decrease the frequency at resetting either. It is safe to
+ * keep here in 200 MHZ.
+ */
+ clk_set_rate(pservice->aclk_vcodec, 200 * MHZ);
+
+ try_reset_assert(pservice->rst_niu_a);
+ try_reset_assert(pservice->rst_niu_h);
+ try_reset_assert(pservice->rst_v);
+ try_reset_assert(pservice->rst_a);
+ try_reset_assert(pservice->rst_h);
+ udelay(5);
+
+ try_reset_deassert(pservice->rst_h);
+ try_reset_deassert(pservice->rst_a);
+ try_reset_deassert(pservice->rst_v);
+ try_reset_deassert(pservice->rst_niu_h);
+ try_reset_deassert(pservice->rst_niu_a);
+
+ rockchip_pmu_idle_request(pservice->dev, false);
+ clk_set_rate(pservice->aclk_vcodec, rate);
+ dev_info(pservice->dev, "reset done\n");
#endif
}
pservice->rst_a = devm_reset_control_get(pservice->dev, "video_a");
pservice->rst_h = devm_reset_control_get(pservice->dev, "video_h");
pservice->rst_v = devm_reset_control_get(pservice->dev, "video");
+ pservice->rst_niu_a = devm_reset_control_get(pservice->dev, "niu_a");
+ pservice->rst_niu_h = devm_reset_control_get(pservice->dev, "niu_h");
if (IS_ERR_OR_NULL(pservice->rst_a)) {
- dev_warn(pservice->dev, "No aclk reset resource define\n");
+ dev_dbg(pservice->dev, "No aclk reset resource define\n");
pservice->rst_a = NULL;
}
if (IS_ERR_OR_NULL(pservice->rst_h)) {
- dev_warn(pservice->dev, "No hclk reset resource define\n");
+ dev_dbg(pservice->dev, "No hclk reset resource define\n");
pservice->rst_h = NULL;
}
if (IS_ERR_OR_NULL(pservice->rst_v)) {
- dev_warn(pservice->dev, "No core reset resource define\n");
+ dev_dbg(pservice->dev, "No core reset resource define\n");
pservice->rst_v = NULL;
}
+
+ if (IS_ERR_OR_NULL(pservice->rst_niu_a)) {
+ dev_dbg(pservice->dev, "No NIU aclk reset resource define\n");
+ pservice->rst_niu_a = NULL;
+ }
+
+ if (IS_ERR_OR_NULL(pservice->rst_niu_h)) {
+ dev_dbg(pservice->dev, "No NIU hclk reset resource define\n");
+ pservice->rst_niu_h = NULL;
+ }
#endif
of_property_read_string(np, "name", (const char **)&pservice->name);