162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2019 NXP.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/device.h>
762306a36Sopenharmony_ci#include <linux/of.h>
862306a36Sopenharmony_ci#include <linux/slab.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "dcss-dev.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define DCSS_BLKCTL_RESET_CTRL		0x00
1362306a36Sopenharmony_ci#define   B_CLK_RESETN			BIT(0)
1462306a36Sopenharmony_ci#define   APB_CLK_RESETN		BIT(1)
1562306a36Sopenharmony_ci#define   P_CLK_RESETN			BIT(2)
1662306a36Sopenharmony_ci#define   RTR_CLK_RESETN		BIT(4)
1762306a36Sopenharmony_ci#define DCSS_BLKCTL_CONTROL0		0x10
1862306a36Sopenharmony_ci#define   HDMI_MIPI_CLK_SEL		BIT(0)
1962306a36Sopenharmony_ci#define   DISPMIX_REFCLK_SEL_POS	4
2062306a36Sopenharmony_ci#define   DISPMIX_REFCLK_SEL_MASK	GENMASK(5, 4)
2162306a36Sopenharmony_ci#define   DISPMIX_PIXCLK_SEL		BIT(8)
2262306a36Sopenharmony_ci#define   HDMI_SRC_SECURE_EN		BIT(16)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistruct dcss_blkctl {
2562306a36Sopenharmony_ci	struct dcss_dev *dcss;
2662306a36Sopenharmony_ci	void __iomem *base_reg;
2762306a36Sopenharmony_ci};
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_civoid dcss_blkctl_cfg(struct dcss_blkctl *blkctl)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	if (blkctl->dcss->hdmi_output)
3262306a36Sopenharmony_ci		dcss_writel(0, blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
3362306a36Sopenharmony_ci	else
3462306a36Sopenharmony_ci		dcss_writel(DISPMIX_PIXCLK_SEL,
3562306a36Sopenharmony_ci			    blkctl->base_reg + DCSS_BLKCTL_CONTROL0);
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci	dcss_set(B_CLK_RESETN | APB_CLK_RESETN | P_CLK_RESETN | RTR_CLK_RESETN,
3862306a36Sopenharmony_ci		 blkctl->base_reg + DCSS_BLKCTL_RESET_CTRL);
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciint dcss_blkctl_init(struct dcss_dev *dcss, unsigned long blkctl_base)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	struct dcss_blkctl *blkctl;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	blkctl = kzalloc(sizeof(*blkctl), GFP_KERNEL);
4662306a36Sopenharmony_ci	if (!blkctl)
4762306a36Sopenharmony_ci		return -ENOMEM;
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	blkctl->base_reg = ioremap(blkctl_base, SZ_4K);
5062306a36Sopenharmony_ci	if (!blkctl->base_reg) {
5162306a36Sopenharmony_ci		dev_err(dcss->dev, "unable to remap BLK CTRL base\n");
5262306a36Sopenharmony_ci		kfree(blkctl);
5362306a36Sopenharmony_ci		return -ENOMEM;
5462306a36Sopenharmony_ci	}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	dcss->blkctl = blkctl;
5762306a36Sopenharmony_ci	blkctl->dcss = dcss;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	dcss_blkctl_cfg(blkctl);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	return 0;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_civoid dcss_blkctl_exit(struct dcss_blkctl *blkctl)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	if (blkctl->base_reg)
6762306a36Sopenharmony_ci		iounmap(blkctl->base_reg);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	kfree(blkctl);
7062306a36Sopenharmony_ci}
71