brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · 9b75727 Raw
218 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2021 MediaTek Inc.4 */5 6#include <linux/clk.h>7#include <linux/component.h>8#include <linux/module.h>9#include <linux/of.h>10#include <linux/platform_device.h>11#include <linux/soc/mediatek/mtk-cmdq.h>12 13#include "mtk_crtc.h"14#include "mtk_ddp_comp.h"15#include "mtk_disp_drv.h"16#include "mtk_drm_drv.h"17 18#define DISP_CCORR_EN				0x000019#define CCORR_EN					BIT(0)20#define DISP_CCORR_CFG				0x002021#define CCORR_RELAY_MODE				BIT(0)22#define CCORR_ENGINE_EN					BIT(1)23#define CCORR_GAMMA_OFF					BIT(2)24#define CCORR_WGAMUT_SRC_CLIP				BIT(3)25#define DISP_CCORR_SIZE				0x003026#define DISP_CCORR_COEF_0			0x008027#define DISP_CCORR_COEF_1			0x008428#define DISP_CCORR_COEF_2			0x008829#define DISP_CCORR_COEF_3			0x008C30#define DISP_CCORR_COEF_4			0x009031 32struct mtk_disp_ccorr_data {33	u32 matrix_bits;34};35 36struct mtk_disp_ccorr {37	struct clk *clk;38	void __iomem *regs;39	struct cmdq_client_reg cmdq_reg;40	const struct mtk_disp_ccorr_data	*data;41};42 43int mtk_ccorr_clk_enable(struct device *dev)44{45	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);46 47	return clk_prepare_enable(ccorr->clk);48}49 50void mtk_ccorr_clk_disable(struct device *dev)51{52	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);53 54	clk_disable_unprepare(ccorr->clk);55}56 57void mtk_ccorr_config(struct device *dev, unsigned int w,58			     unsigned int h, unsigned int vrefresh,59			     unsigned int bpc, struct cmdq_pkt *cmdq_pkt)60{61	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);62 63	mtk_ddp_write(cmdq_pkt, w << 16 | h, &ccorr->cmdq_reg, ccorr->regs,64		      DISP_CCORR_SIZE);65	mtk_ddp_write(cmdq_pkt, CCORR_ENGINE_EN, &ccorr->cmdq_reg, ccorr->regs,66		      DISP_CCORR_CFG);67}68 69void mtk_ccorr_start(struct device *dev)70{71	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);72 73	writel(CCORR_EN, ccorr->regs + DISP_CCORR_EN);74}75 76void mtk_ccorr_stop(struct device *dev)77{78	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);79 80	writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN);81}82 83/* Converts a DRM S31.32 value to the HW S1.n format. */84static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n)85{86	u16 r;87 88	/* Sign bit. */89	r = in & BIT_ULL(63) ? BIT(n + 1) : 0;90 91	if ((in & GENMASK_ULL(62, 33)) > 0) {92		/* identity value 0x100000000 -> 0x400(mt8183), */93		/* identity value 0x100000000 -> 0x800(mt8192), */94		/* if bigger this, set it to max 0x7ff. */95		r |= GENMASK(n, 0);96	} else {97		/* take the n+1 most important bits. */98		r |= (in >> (32 - n)) & GENMASK(n, 0);99	}100 101	return r;102}103 104void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state)105{106	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);107	struct drm_property_blob *blob = state->ctm;108	struct drm_color_ctm *ctm;109	const u64 *input;110	uint16_t coeffs[9] = { 0 };111	int i;112	struct cmdq_pkt *cmdq_pkt = NULL;113	u32 matrix_bits = ccorr->data->matrix_bits;114 115	if (!blob)116		return;117 118	ctm = (struct drm_color_ctm *)blob->data;119	input = ctm->matrix;120 121	for (i = 0; i < ARRAY_SIZE(coeffs); i++)122		coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits);123 124	mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1],125		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0);126	mtk_ddp_write(cmdq_pkt, coeffs[2] << 16 | coeffs[3],127		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_1);128	mtk_ddp_write(cmdq_pkt, coeffs[4] << 16 | coeffs[5],129		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_2);130	mtk_ddp_write(cmdq_pkt, coeffs[6] << 16 | coeffs[7],131		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_3);132	mtk_ddp_write(cmdq_pkt, coeffs[8] << 16,133		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_4);134}135 136static int mtk_disp_ccorr_bind(struct device *dev, struct device *master,137			       void *data)138{139	return 0;140}141 142static void mtk_disp_ccorr_unbind(struct device *dev, struct device *master,143				  void *data)144{145}146 147static const struct component_ops mtk_disp_ccorr_component_ops = {148	.bind	= mtk_disp_ccorr_bind,149	.unbind	= mtk_disp_ccorr_unbind,150};151 152static int mtk_disp_ccorr_probe(struct platform_device *pdev)153{154	struct device *dev = &pdev->dev;155	struct mtk_disp_ccorr *priv;156	int ret;157 158	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);159	if (!priv)160		return -ENOMEM;161 162	priv->clk = devm_clk_get(dev, NULL);163	if (IS_ERR(priv->clk))164		return dev_err_probe(dev, PTR_ERR(priv->clk),165				     "failed to get ccorr clk\n");166 167	priv->regs = devm_platform_ioremap_resource(pdev, 0);168	if (IS_ERR(priv->regs))169		return dev_err_probe(dev, PTR_ERR(priv->regs),170				     "failed to ioremap ccorr\n");171 172#if IS_REACHABLE(CONFIG_MTK_CMDQ)173	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);174	if (ret)175		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");176#endif177 178	priv->data = of_device_get_match_data(dev);179	platform_set_drvdata(pdev, priv);180 181	ret = component_add(dev, &mtk_disp_ccorr_component_ops);182	if (ret)183		return dev_err_probe(dev, ret, "Failed to add component\n");184 185	return 0;186}187 188static void mtk_disp_ccorr_remove(struct platform_device *pdev)189{190	component_del(&pdev->dev, &mtk_disp_ccorr_component_ops);191}192 193static const struct mtk_disp_ccorr_data mt8183_ccorr_driver_data = {194	.matrix_bits = 10,195};196 197static const struct mtk_disp_ccorr_data mt8192_ccorr_driver_data = {198	.matrix_bits = 11,199};200 201static const struct of_device_id mtk_disp_ccorr_driver_dt_match[] = {202	{ .compatible = "mediatek,mt8183-disp-ccorr",203	  .data = &mt8183_ccorr_driver_data},204	{ .compatible = "mediatek,mt8192-disp-ccorr",205	  .data = &mt8192_ccorr_driver_data},206	{},207};208MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match);209 210struct platform_driver mtk_disp_ccorr_driver = {211	.probe		= mtk_disp_ccorr_probe,212	.remove_new	= mtk_disp_ccorr_remove,213	.driver		= {214		.name	= "mediatek-disp-ccorr",215		.of_match_table = mtk_disp_ccorr_driver_dt_match,216	},217};218