@@ -36,6 +36,7 @@ struct mtk_disp_color_data {
struct mtk_disp_color {
struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+ struct clk *clk;
const struct mtk_disp_color_data *data;
};
@@ -44,6 +45,20 @@ static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)
return container_of(comp, struct mtk_disp_color, ddp_comp);
}
+static int mtk_color_clk_enable(struct device *dev)
+{
+ struct mtk_disp_color *color = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(color->clk);
+}
+
+static void mtk_color_clk_disable(struct device *dev)
+{
+ struct mtk_disp_color *color = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(color->clk);
+}
+
static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -64,6 +79,8 @@ static void mtk_color_start(struct mtk_ddp_comp *comp)
}
static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = {
+ .clk_enable = mtk_color_clk_enable,
+ .clk_disable = mtk_color_clk_disable,
.config = mtk_color_config,
.start = mtk_color_start,
};
@@ -110,6 +127,12 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get color clk\n");
+ return PTR_ERR(priv->clk);
+ }
+
comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR);
if (comp_id < 0) {
dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
@@ -71,6 +71,7 @@ struct mtk_disp_ovl_data {
struct mtk_disp_ovl {
struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+ struct clk *clk;
const struct mtk_disp_ovl_data *data;
};
@@ -113,6 +114,20 @@ static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp)
writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN);
}
+static int mtk_ovl_clk_enable(struct device *dev)
+{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(ovl->clk);
+}
+
+static void mtk_ovl_clk_disable(struct device *dev)
+{
+ struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(ovl->clk);
+}
+
static void mtk_ovl_start(struct mtk_ddp_comp *comp)
{
writel_relaxed(0x1, comp->regs + DISP_REG_OVL_EN);
@@ -312,6 +327,8 @@ static void mtk_ovl_bgclr_in_off(struct mtk_ddp_comp *comp)
}
static const struct mtk_ddp_comp_funcs mtk_disp_ovl_funcs = {
+ .clk_enable = mtk_ovl_clk_enable,
+ .clk_disable = mtk_ovl_clk_disable,
.config = mtk_ovl_config,
.start = mtk_ovl_start,
.stop = mtk_ovl_stop,
@@ -372,6 +389,12 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get ovl clk\n");
+ return PTR_ERR(priv->clk);
+ }
+
priv->data = of_device_get_match_data(dev);
comp_id = mtk_ddp_comp_get_id(dev->of_node,
@@ -62,6 +62,7 @@ struct mtk_disp_rdma_data {
struct mtk_disp_rdma {
struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
+ struct clk *clk;
const struct mtk_disp_rdma_data *data;
};
@@ -113,6 +114,20 @@ static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp)
rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
}
+static int mtk_rdma_clk_enable(struct device *dev)
+{
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(rdma->clk);
+}
+
+static void mtk_rdma_clk_disable(struct device *dev)
+{
+ struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(rdma->clk);
+}
+
static void mtk_rdma_start(struct mtk_ddp_comp *comp)
{
rdma_update_bits(comp, DISP_REG_RDMA_GLOBAL_CON, RDMA_ENGINE_EN,
@@ -228,6 +243,8 @@ static void mtk_rdma_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
}
static const struct mtk_ddp_comp_funcs mtk_disp_rdma_funcs = {
+ .clk_enable = mtk_rdma_clk_enable,
+ .clk_disable = mtk_rdma_clk_disable,
.config = mtk_rdma_config,
.start = mtk_rdma_start,
.stop = mtk_rdma_stop,
@@ -285,6 +302,12 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(dev, "failed to get rdma clk\n");
+ return PTR_ERR(priv->clk);
+ }
+
comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_RDMA);
if (comp_id < 0) {
dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
@@ -190,7 +190,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
int i;
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
- ret = clk_prepare_enable(mtk_crtc->ddp_comp[i]->clk);
+ ret = mtk_ddp_comp_clk_enable(mtk_crtc->ddp_comp[i]);
if (ret) {
DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
goto err;
@@ -200,7 +200,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
return 0;
err:
while (--i >= 0)
- clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
+ mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
return ret;
}
@@ -209,7 +209,7 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
int i;
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
- clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
+ mtk_ddp_comp_clk_disable(mtk_crtc->ddp_comp[i]);
}
static
@@ -86,6 +86,10 @@
#define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4)
#define DITHER_ADD_RSHIFT_G(x) (((x) & 0x7) << 0)
+struct mtk_ddp_comp_dev {
+ struct clk *clk;
+};
+
void mtk_ddp_write(struct cmdq_pkt *cmdq_pkt, unsigned int value,
struct mtk_ddp_comp *comp, unsigned int offset)
{
@@ -132,6 +136,20 @@ void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt,
#endif
}
+static int mtk_ddp_clk_enable(struct device *dev)
+{
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+ return clk_prepare_enable(priv->clk);
+}
+
+static void mtk_ddp_clk_disable(struct device *dev)
+{
+ struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(priv->clk);
+}
+
void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
unsigned int CFG, struct cmdq_pkt *cmdq_pkt)
{
@@ -322,6 +340,8 @@ static void mtk_gamma_set(struct mtk_ddp_comp *comp,
}
static const struct mtk_ddp_comp_funcs ddp_aal = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.gamma_set = mtk_gamma_set,
.config = mtk_aal_config,
.start = mtk_aal_start,
@@ -329,6 +349,8 @@ static const struct mtk_ddp_comp_funcs ddp_aal = {
};
static const struct mtk_ddp_comp_funcs ddp_ccorr = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.config = mtk_ccorr_config,
.start = mtk_ccorr_start,
.stop = mtk_ccorr_stop,
@@ -336,12 +358,16 @@ static const struct mtk_ddp_comp_funcs ddp_ccorr = {
};
static const struct mtk_ddp_comp_funcs ddp_dither = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.config = mtk_dither_config,
.start = mtk_dither_start,
.stop = mtk_dither_stop,
};
static const struct mtk_ddp_comp_funcs ddp_gamma = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.gamma_set = mtk_gamma_set,
.config = mtk_gamma_config,
.start = mtk_gamma_start,
@@ -349,11 +375,15 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
};
static const struct mtk_ddp_comp_funcs ddp_od = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.config = mtk_od_config,
.start = mtk_od_start,
};
static const struct mtk_ddp_comp_funcs ddp_ufoe = {
+ .clk_enable = mtk_ddp_clk_enable,
+ .clk_disable = mtk_ddp_clk_disable,
.start = mtk_ufoe_start,
};
@@ -469,10 +499,10 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
enum mtk_ddp_comp_id comp_id, const struct mtk_ddp_comp_funcs *funcs)
{
struct platform_device *comp_pdev;
- struct device *dev;
enum mtk_ddp_comp_type type;
struct device_node *larb_node;
struct platform_device *larb_pdev;
+ struct mtk_ddp_comp_dev *priv;
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
struct resource res;
struct cmdq_client_reg cmdq_reg;
@@ -496,38 +526,54 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
comp_id == DDP_COMPONENT_DSI3 ||
comp_id == DDP_COMPONENT_PWM0) {
comp->regs = NULL;
- comp->clk = NULL;
comp->irq = 0;
return 0;
}
comp->regs = of_iomap(node, 0);
comp->irq = of_irq_get(node, 0);
- comp->clk = of_clk_get(node, 0);
- if (IS_ERR(comp->clk))
- return PTR_ERR(comp->clk);
-
comp_pdev = of_find_device_by_node(node);
if (!comp_pdev) {
DRM_INFO("Waiting for device %s\n", node->full_name);
return -EPROBE_DEFER;
}
- dev = &comp_pdev->dev;
+ comp->dev = &comp_pdev->dev;
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
if (of_address_to_resource(node, 0, &res) != 0) {
- dev_err(dev, "Missing reg in %s node\n", node->full_name);
+ dev_err(comp->dev, "Missing reg in %s node\n", node->full_name);
return -EINVAL;
}
comp->regs_pa = res.start;
- ret = cmdq_dev_get_client_reg(dev, &cmdq_reg, 0);
+ ret = cmdq_dev_get_client_reg(comp->dev, &cmdq_reg, 0);
if (ret)
- dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+ dev_dbg(comp->dev, "get mediatek,gce-client-reg fail!\n");
else
comp->subsys = cmdq_reg.subsys;
#endif
+ if (comp_id == DDP_COMPONENT_COLOR0 ||
+ comp_id == DDP_COMPONENT_COLOR1 ||
+ comp_id == DDP_COMPONENT_OVL0 ||
+ comp_id == DDP_COMPONENT_OVL1 ||
+ comp_id == DDP_COMPONENT_OVL_2L0 ||
+ comp_id == DDP_COMPONENT_OVL_2L1 ||
+ comp_id == DDP_COMPONENT_RDMA0 ||
+ comp_id == DDP_COMPONENT_RDMA1 ||
+ comp_id == DDP_COMPONENT_RDMA2)
+ return 0;
+
+ priv = devm_kzalloc(comp->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->clk = of_clk_get(node, 0);
+ if (IS_ERR(priv->clk))
+ return PTR_ERR(priv->clk);
+
+ platform_set_drvdata(comp_pdev, priv);
+
/* Only DMA capable components need the LARB property */
comp->larb_dev = NULL;
if (type != MTK_DISP_OVL &&
@@ -538,14 +584,14 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
larb_node = of_parse_phandle(node, "mediatek,larb", 0);
if (!larb_node) {
- dev_err(dev,
+ dev_err(comp->dev,
"Missing mediadek,larb phandle in %pOF node\n", node);
return -EINVAL;
}
larb_pdev = of_find_device_by_node(larb_node);
if (!larb_pdev) {
- dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
+ dev_warn(comp->dev, "Waiting for larb device %pOF\n", larb_node);
of_node_put(larb_node);
return -EPROBE_DEFER;
}
@@ -71,6 +71,8 @@ enum mtk_ddp_comp_id {
struct mtk_ddp_comp;
struct cmdq_pkt;
struct mtk_ddp_comp_funcs {
+ int (*clk_enable)(struct device *dev);
+ void (*clk_disable)(struct device *dev);
void (*config)(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
@@ -95,7 +97,7 @@ struct mtk_ddp_comp_funcs {
};
struct mtk_ddp_comp {
- struct clk *clk;
+ struct device *dev;
void __iomem *regs;
int irq;
struct device *larb_dev;
@@ -105,6 +107,20 @@ struct mtk_ddp_comp {
u8 subsys;
};
+static inline int mtk_ddp_comp_clk_enable(struct mtk_ddp_comp *comp)
+{
+ if (comp->funcs && comp->funcs->clk_enable)
+ return comp->funcs->clk_enable(comp->dev);
+
+ return 0;
+}
+
+static inline void mtk_ddp_comp_clk_disable(struct mtk_ddp_comp *comp)
+{
+ if (comp->funcs && comp->funcs->clk_disable)
+ comp->funcs->clk_disable(comp->dev);
+}
+
static inline void mtk_ddp_comp_config(struct mtk_ddp_comp *comp,
unsigned int w, unsigned int h,
unsigned int vrefresh, unsigned int bpc,