1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2019 NXP.
4  */
5 
6 #include <linux/device.h>
7 #include <linux/of.h>
8 #include <linux/slab.h>
9 
10 #include "dcss-dev.h"
11 
12 #define DCSS_BLKCTL_RESET_CTRL		0x00
13 #define   B_CLK_RESETN			BIT(0)
14 #define   APB_CLK_RESETN		BIT(1)
15 #define   P_CLK_RESETN			BIT(2)
16 #define   RTR_CLK_RESETN		BIT(4)
17 #define DCSS_BLKCTL_CONTROL0		0x10
18 #define   HDMI_MIPI_CLK_SEL		BIT(0)
19 #define   DISPMIX_REFCLK_SEL_POS	4
20 #define   DISPMIX_REFCLK_SEL_MASK	GENMASK(5, 4)
21 #define   DISPMIX_PIXCLK_SEL		BIT(8)
22 #define   HDMI_SRC_SECURE_EN		BIT(16)
23 
24 struct dcss_blkctl {
25 	struct dcss_dev *dcss;
26 	void __iomem *base_reg;
27 };
28 
29 void dcss_blkctl_cfg(struct dcss_blkctl *blkctl)
30 {
31 	if (blkctl->dcss->hdmi_output)
32 		dcss_writel(0, blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
33 	else
34 		dcss_writel(DISPMIX_PIXCLK_SEL,
35 			    blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
36 
37 	dcss_set(B_CLK_RESETN | APB_CLK_RESETN | P_CLK_RESETN | RTR_CLK_RESETN,
38 		 blkctl->base_reg + DCSS_BLKCTL_RESET_CTRL);
39 }
40 
41 int dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base)
42 {
43 	struct dcss_blkctl *blkctl;
44 
45 	blkctl = kzalloc(sizeof(*blkctl), GFP_KERNEL);
46 	if (!blkctl)
47 		return -ENOMEM;
48 
49 	blkctl->base_reg = ioremap(blkctl_base, SZ_4K);
50 	if (!blkctl->base_reg) {
51 		dev_err(dcss->dev, "unable to remap BLK CTRL base\n");
52 		kfree(blkctl);
53 		return -ENOMEM;
54 	}
55 
56 	dcss->blkctl = blkctl;
57 	blkctl->dcss = dcss;
58 
59 	dcss_blkctl_cfg(blkctl);
60 
61 	return 0;
62 }
63 
64 void dcss_blkctl_exit(struct dcss_blkctl *blkctl)
65 {
66 	if (blkctl->base_reg)
67 		iounmap(blkctl->base_reg);
68 
69 	kfree(blkctl);
70 }
71