18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2019 NXP.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/device.h>
78c2ecf20Sopenharmony_ci#include <linux/of.h>
88c2ecf20Sopenharmony_ci#include <linux/slab.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "dcss-dev.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define DCSS_BLKCTL_RESET_CTRL		0x00
138c2ecf20Sopenharmony_ci#define   B_CLK_RESETN			BIT(0)
148c2ecf20Sopenharmony_ci#define   APB_CLK_RESETN		BIT(1)
158c2ecf20Sopenharmony_ci#define   P_CLK_RESETN			BIT(2)
168c2ecf20Sopenharmony_ci#define   RTR_CLK_RESETN		BIT(4)
178c2ecf20Sopenharmony_ci#define DCSS_BLKCTL_CONTROL0		0x10
188c2ecf20Sopenharmony_ci#define   HDMI_MIPI_CLK_SEL		BIT(0)
198c2ecf20Sopenharmony_ci#define   DISPMIX_REFCLK_SEL_POS	4
208c2ecf20Sopenharmony_ci#define   DISPMIX_REFCLK_SEL_MASK	GENMASK(5, 4)
218c2ecf20Sopenharmony_ci#define   DISPMIX_PIXCLK_SEL		BIT(8)
228c2ecf20Sopenharmony_ci#define   HDMI_SRC_SECURE_EN		BIT(16)
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_cistruct dcss_blkctl {
258c2ecf20Sopenharmony_ci	struct dcss_dev *dcss;
268c2ecf20Sopenharmony_ci	void __iomem *base_reg;
278c2ecf20Sopenharmony_ci};
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_civoid dcss_blkctl_cfg(struct dcss_blkctl *blkctl)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	if (blkctl->dcss->hdmi_output)
328c2ecf20Sopenharmony_ci		dcss_writel(0, blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
338c2ecf20Sopenharmony_ci	else
348c2ecf20Sopenharmony_ci		dcss_writel(DISPMIX_PIXCLK_SEL,
358c2ecf20Sopenharmony_ci			    blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	dcss_set(B_CLK_RESETN | APB_CLK_RESETN | P_CLK_RESETN | RTR_CLK_RESETN,
388c2ecf20Sopenharmony_ci		 blkctl->base_reg + DCSS_BLKCTL_RESET_CTRL);
398c2ecf20Sopenharmony_ci}
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciint dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	struct dcss_blkctl *blkctl;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	blkctl = kzalloc(sizeof(*blkctl), GFP_KERNEL);
468c2ecf20Sopenharmony_ci	if (!blkctl)
478c2ecf20Sopenharmony_ci		return -ENOMEM;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	blkctl->base_reg = ioremap(blkctl_base, SZ_4K);
508c2ecf20Sopenharmony_ci	if (!blkctl->base_reg) {
518c2ecf20Sopenharmony_ci		dev_err(dcss->dev, "unable to remap BLK CTRL base\n");
528c2ecf20Sopenharmony_ci		kfree(blkctl);
538c2ecf20Sopenharmony_ci		return -ENOMEM;
548c2ecf20Sopenharmony_ci	}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	dcss->blkctl = blkctl;
578c2ecf20Sopenharmony_ci	blkctl->dcss = dcss;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	dcss_blkctl_cfg(blkctl);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	return 0;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_civoid dcss_blkctl_exit(struct dcss_blkctl *blkctl)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	if (blkctl->base_reg)
678c2ecf20Sopenharmony_ci		iounmap(blkctl->base_reg);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	kfree(blkctl);
708c2ecf20Sopenharmony_ci}
71