xref: /openbmc/linux/drivers/gpu/drm/msm/msm_mdss.c (revision 26d0dfbb16fcb17d128a79dc70f3020ea6992af0)
187729e2aSDmitry Baryshkov /*
287729e2aSDmitry Baryshkov  * SPDX-License-Identifier: GPL-2.0
387729e2aSDmitry Baryshkov  * Copyright (c) 2018, The Linux Foundation
487729e2aSDmitry Baryshkov  */
587729e2aSDmitry Baryshkov 
6e1072257SDmitry Baryshkov #include <linux/clk.h>
73e9c146fSBjorn Andersson #include <linux/delay.h>
8b9364eedSDouglas Anderson #include <linux/interconnect.h>
987729e2aSDmitry Baryshkov #include <linux/irq.h>
1087729e2aSDmitry Baryshkov #include <linux/irqchip.h>
1187729e2aSDmitry Baryshkov #include <linux/irqdesc.h>
1287729e2aSDmitry Baryshkov #include <linux/irqchip/chained_irq.h>
13722d4f06SRob Herring #include <linux/of_platform.h>
14722d4f06SRob Herring #include <linux/platform_device.h>
15e1072257SDmitry Baryshkov #include <linux/pm_runtime.h>
163e9c146fSBjorn Andersson #include <linux/reset.h>
1787729e2aSDmitry Baryshkov 
1871e00fc0SDmitry Baryshkov #include "msm_mdss.h"
19ecb23f2eSDmitry Baryshkov #include "msm_kms.h"
20ecb23f2eSDmitry Baryshkov 
2187729e2aSDmitry Baryshkov #define HW_REV				0x0
2287729e2aSDmitry Baryshkov #define HW_INTR_STATUS			0x0010
2387729e2aSDmitry Baryshkov 
2492bab914SDmitry Baryshkov #define UBWC_DEC_HW_VERSION		0x58
2587729e2aSDmitry Baryshkov #define UBWC_STATIC			0x144
2687729e2aSDmitry Baryshkov #define UBWC_CTRL_2			0x150
2787729e2aSDmitry Baryshkov #define UBWC_PREDICTION_MODE		0x154
2887729e2aSDmitry Baryshkov 
29b9364eedSDouglas Anderson #define MIN_IB_BW	400000000UL /* Min ib vote 400MB */
30b9364eedSDouglas Anderson 
31aba75693SDmitry Baryshkov #define DEFAULT_REG_BW	153600 /* Used in mdss fbdev driver */
32aba75693SDmitry Baryshkov 
33e1072257SDmitry Baryshkov struct msm_mdss {
34e1072257SDmitry Baryshkov 	struct device *dev;
35e1072257SDmitry Baryshkov 
3687729e2aSDmitry Baryshkov 	void __iomem *mmio;
3787729e2aSDmitry Baryshkov 	struct clk_bulk_data *clocks;
3887729e2aSDmitry Baryshkov 	size_t num_clocks;
3987729e2aSDmitry Baryshkov 	bool is_mdp5;
4087729e2aSDmitry Baryshkov 	struct {
4187729e2aSDmitry Baryshkov 		unsigned long enabled_mask;
4287729e2aSDmitry Baryshkov 		struct irq_domain *domain;
4387729e2aSDmitry Baryshkov 	} irq_controller;
44d68db606SDmitry Baryshkov 	const struct msm_mdss_data *mdss_data;
45707601fcSKonrad Dybcio 	struct icc_path *mdp_path[2];
46707601fcSKonrad Dybcio 	u32 num_mdp_paths;
47aba75693SDmitry Baryshkov 	struct icc_path *reg_bus_path;
4887729e2aSDmitry Baryshkov };
4987729e2aSDmitry Baryshkov 
msm_mdss_parse_data_bus_icc_path(struct device * dev,struct msm_mdss * msm_mdss)50b9364eedSDouglas Anderson static int msm_mdss_parse_data_bus_icc_path(struct device *dev,
51b9364eedSDouglas Anderson 					    struct msm_mdss *msm_mdss)
52b9364eedSDouglas Anderson {
5345dac135SMiaoqian Lin 	struct icc_path *path0;
5445dac135SMiaoqian Lin 	struct icc_path *path1;
55aba75693SDmitry Baryshkov 	struct icc_path *reg_bus_path;
56b9364eedSDouglas Anderson 
579611899fSDmitry Baryshkov 	path0 = devm_of_icc_get(dev, "mdp0-mem");
58b9364eedSDouglas Anderson 	if (IS_ERR_OR_NULL(path0))
59b9364eedSDouglas Anderson 		return PTR_ERR_OR_ZERO(path0);
60b9364eedSDouglas Anderson 
61707601fcSKonrad Dybcio 	msm_mdss->mdp_path[0] = path0;
62707601fcSKonrad Dybcio 	msm_mdss->num_mdp_paths = 1;
63b9364eedSDouglas Anderson 
649611899fSDmitry Baryshkov 	path1 = devm_of_icc_get(dev, "mdp1-mem");
65b9364eedSDouglas Anderson 	if (!IS_ERR_OR_NULL(path1)) {
66707601fcSKonrad Dybcio 		msm_mdss->mdp_path[1] = path1;
67707601fcSKonrad Dybcio 		msm_mdss->num_mdp_paths++;
68b9364eedSDouglas Anderson 	}
69b9364eedSDouglas Anderson 
70aba75693SDmitry Baryshkov 	reg_bus_path = of_icc_get(dev, "cpu-cfg");
71aba75693SDmitry Baryshkov 	if (!IS_ERR_OR_NULL(reg_bus_path))
72aba75693SDmitry Baryshkov 		msm_mdss->reg_bus_path = reg_bus_path;
73aba75693SDmitry Baryshkov 
74b9364eedSDouglas Anderson 	return 0;
75b9364eedSDouglas Anderson }
76b9364eedSDouglas Anderson 
msm_mdss_icc_request_bw(struct msm_mdss * msm_mdss,unsigned long bw)77b9364eedSDouglas Anderson static void msm_mdss_icc_request_bw(struct msm_mdss *msm_mdss, unsigned long bw)
78b9364eedSDouglas Anderson {
79b9364eedSDouglas Anderson 	int i;
80b9364eedSDouglas Anderson 
81707601fcSKonrad Dybcio 	for (i = 0; i < msm_mdss->num_mdp_paths; i++)
82707601fcSKonrad Dybcio 		icc_set_bw(msm_mdss->mdp_path[i], 0, Bps_to_icc(bw));
83b9364eedSDouglas Anderson }
84b9364eedSDouglas Anderson 
msm_mdss_irq(struct irq_desc * desc)8587729e2aSDmitry Baryshkov static void msm_mdss_irq(struct irq_desc *desc)
8687729e2aSDmitry Baryshkov {
87e1072257SDmitry Baryshkov 	struct msm_mdss *msm_mdss = irq_desc_get_handler_data(desc);
8887729e2aSDmitry Baryshkov 	struct irq_chip *chip = irq_desc_get_chip(desc);
8987729e2aSDmitry Baryshkov 	u32 interrupts;
9087729e2aSDmitry Baryshkov 
9187729e2aSDmitry Baryshkov 	chained_irq_enter(chip, desc);
9287729e2aSDmitry Baryshkov 
93e1072257SDmitry Baryshkov 	interrupts = readl_relaxed(msm_mdss->mmio + HW_INTR_STATUS);
9487729e2aSDmitry Baryshkov 
9587729e2aSDmitry Baryshkov 	while (interrupts) {
9687729e2aSDmitry Baryshkov 		irq_hw_number_t hwirq = fls(interrupts) - 1;
9787729e2aSDmitry Baryshkov 		int rc;
9887729e2aSDmitry Baryshkov 
99e1072257SDmitry Baryshkov 		rc = generic_handle_domain_irq(msm_mdss->irq_controller.domain,
10087729e2aSDmitry Baryshkov 					       hwirq);
10187729e2aSDmitry Baryshkov 		if (rc < 0) {
102e1072257SDmitry Baryshkov 			dev_err(msm_mdss->dev, "handle irq fail: irq=%lu rc=%d\n",
10387729e2aSDmitry Baryshkov 				  hwirq, rc);
10487729e2aSDmitry Baryshkov 			break;
10587729e2aSDmitry Baryshkov 		}
10687729e2aSDmitry Baryshkov 
10787729e2aSDmitry Baryshkov 		interrupts &= ~(1 << hwirq);
10887729e2aSDmitry Baryshkov 	}
10987729e2aSDmitry Baryshkov 
11087729e2aSDmitry Baryshkov 	chained_irq_exit(chip, desc);
11187729e2aSDmitry Baryshkov }
11287729e2aSDmitry Baryshkov 
msm_mdss_irq_mask(struct irq_data * irqd)11387729e2aSDmitry Baryshkov static void msm_mdss_irq_mask(struct irq_data *irqd)
11487729e2aSDmitry Baryshkov {
115e1072257SDmitry Baryshkov 	struct msm_mdss *msm_mdss = irq_data_get_irq_chip_data(irqd);
11687729e2aSDmitry Baryshkov 
11787729e2aSDmitry Baryshkov 	/* memory barrier */
11887729e2aSDmitry Baryshkov 	smp_mb__before_atomic();
119e1072257SDmitry Baryshkov 	clear_bit(irqd->hwirq, &msm_mdss->irq_controller.enabled_mask);
12087729e2aSDmitry Baryshkov 	/* memory barrier */
12187729e2aSDmitry Baryshkov 	smp_mb__after_atomic();
12287729e2aSDmitry Baryshkov }
12387729e2aSDmitry Baryshkov 
msm_mdss_irq_unmask(struct irq_data * irqd)12487729e2aSDmitry Baryshkov static void msm_mdss_irq_unmask(struct irq_data *irqd)
12587729e2aSDmitry Baryshkov {
126e1072257SDmitry Baryshkov 	struct msm_mdss *msm_mdss = irq_data_get_irq_chip_data(irqd);
12787729e2aSDmitry Baryshkov 
12887729e2aSDmitry Baryshkov 	/* memory barrier */
12987729e2aSDmitry Baryshkov 	smp_mb__before_atomic();
130e1072257SDmitry Baryshkov 	set_bit(irqd->hwirq, &msm_mdss->irq_controller.enabled_mask);
13187729e2aSDmitry Baryshkov 	/* memory barrier */
13287729e2aSDmitry Baryshkov 	smp_mb__after_atomic();
13387729e2aSDmitry Baryshkov }
13487729e2aSDmitry Baryshkov 
13587729e2aSDmitry Baryshkov static struct irq_chip msm_mdss_irq_chip = {
136e1072257SDmitry Baryshkov 	.name = "msm_mdss",
13787729e2aSDmitry Baryshkov 	.irq_mask = msm_mdss_irq_mask,
13887729e2aSDmitry Baryshkov 	.irq_unmask = msm_mdss_irq_unmask,
13987729e2aSDmitry Baryshkov };
14087729e2aSDmitry Baryshkov 
14187729e2aSDmitry Baryshkov static struct lock_class_key msm_mdss_lock_key, msm_mdss_request_key;
14287729e2aSDmitry Baryshkov 
msm_mdss_irqdomain_map(struct irq_domain * domain,unsigned int irq,irq_hw_number_t hwirq)14387729e2aSDmitry Baryshkov static int msm_mdss_irqdomain_map(struct irq_domain *domain,
14487729e2aSDmitry Baryshkov 		unsigned int irq, irq_hw_number_t hwirq)
14587729e2aSDmitry Baryshkov {
146e1072257SDmitry Baryshkov 	struct msm_mdss *msm_mdss = domain->host_data;
14787729e2aSDmitry Baryshkov 
14887729e2aSDmitry Baryshkov 	irq_set_lockdep_class(irq, &msm_mdss_lock_key, &msm_mdss_request_key);
14987729e2aSDmitry Baryshkov 	irq_set_chip_and_handler(irq, &msm_mdss_irq_chip, handle_level_irq);
15087729e2aSDmitry Baryshkov 
151e1072257SDmitry Baryshkov 	return irq_set_chip_data(irq, msm_mdss);
15287729e2aSDmitry Baryshkov }
15387729e2aSDmitry Baryshkov 
15487729e2aSDmitry Baryshkov static const struct irq_domain_ops msm_mdss_irqdomain_ops = {
15587729e2aSDmitry Baryshkov 	.map = msm_mdss_irqdomain_map,
15687729e2aSDmitry Baryshkov 	.xlate = irq_domain_xlate_onecell,
15787729e2aSDmitry Baryshkov };
15887729e2aSDmitry Baryshkov 
_msm_mdss_irq_domain_add(struct msm_mdss * msm_mdss)159e1072257SDmitry Baryshkov static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss)
16087729e2aSDmitry Baryshkov {
16187729e2aSDmitry Baryshkov 	struct device *dev;
16287729e2aSDmitry Baryshkov 	struct irq_domain *domain;
16387729e2aSDmitry Baryshkov 
164e1072257SDmitry Baryshkov 	dev = msm_mdss->dev;
16587729e2aSDmitry Baryshkov 
16687729e2aSDmitry Baryshkov 	domain = irq_domain_add_linear(dev->of_node, 32,
167e1072257SDmitry Baryshkov 			&msm_mdss_irqdomain_ops, msm_mdss);
16887729e2aSDmitry Baryshkov 	if (!domain) {
169e1072257SDmitry Baryshkov 		dev_err(dev, "failed to add irq_domain\n");
17087729e2aSDmitry Baryshkov 		return -EINVAL;
17187729e2aSDmitry Baryshkov 	}
17287729e2aSDmitry Baryshkov 
173e1072257SDmitry Baryshkov 	msm_mdss->irq_controller.enabled_mask = 0;
174e1072257SDmitry Baryshkov 	msm_mdss->irq_controller.domain = domain;
17587729e2aSDmitry Baryshkov 
17687729e2aSDmitry Baryshkov 	return 0;
17787729e2aSDmitry Baryshkov }
17887729e2aSDmitry Baryshkov 
msm_mdss_setup_ubwc_dec_20(struct msm_mdss * msm_mdss)179d68db606SDmitry Baryshkov static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss)
18092bab914SDmitry Baryshkov {
181d68db606SDmitry Baryshkov 	const struct msm_mdss_data *data = msm_mdss->mdss_data;
182d68db606SDmitry Baryshkov 
183d68db606SDmitry Baryshkov 	writel_relaxed(data->ubwc_static, msm_mdss->mmio + UBWC_STATIC);
18492bab914SDmitry Baryshkov }
18592bab914SDmitry Baryshkov 
msm_mdss_setup_ubwc_dec_30(struct msm_mdss * msm_mdss)186d68db606SDmitry Baryshkov static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss)
18792bab914SDmitry Baryshkov {
188d68db606SDmitry Baryshkov 	const struct msm_mdss_data *data = msm_mdss->mdss_data;
189d68db606SDmitry Baryshkov 	u32 value = (data->ubwc_swizzle & 0x1) |
190d68db606SDmitry Baryshkov 		    (data->highest_bank_bit & 0x3) << 4 |
191d68db606SDmitry Baryshkov 		    (data->macrotile_mode & 0x1) << 12;
19292bab914SDmitry Baryshkov 
193cab5b406SDmitry Baryshkov 	if (data->ubwc_enc_version == UBWC_3_0)
19492bab914SDmitry Baryshkov 		value |= BIT(10);
19592bab914SDmitry Baryshkov 
196cab5b406SDmitry Baryshkov 	if (data->ubwc_enc_version == UBWC_1_0)
19792bab914SDmitry Baryshkov 		value |= BIT(8);
19892bab914SDmitry Baryshkov 
19992bab914SDmitry Baryshkov 	writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);
20092bab914SDmitry Baryshkov }
20192bab914SDmitry Baryshkov 
msm_mdss_setup_ubwc_dec_40(struct msm_mdss * msm_mdss)202d68db606SDmitry Baryshkov static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)
20392bab914SDmitry Baryshkov {
204d68db606SDmitry Baryshkov 	const struct msm_mdss_data *data = msm_mdss->mdss_data;
205d68db606SDmitry Baryshkov 	u32 value = (data->ubwc_swizzle & 0x7) |
206d68db606SDmitry Baryshkov 		    (data->ubwc_static & 0x1) << 3 |
207d68db606SDmitry Baryshkov 		    (data->highest_bank_bit & 0x7) << 4 |
208d68db606SDmitry Baryshkov 		    (data->macrotile_mode & 0x1) << 12;
20992bab914SDmitry Baryshkov 
21092bab914SDmitry Baryshkov 	writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);
21192bab914SDmitry Baryshkov 
212cab5b406SDmitry Baryshkov 	if (data->ubwc_enc_version == UBWC_3_0) {
21392bab914SDmitry Baryshkov 		writel_relaxed(1, msm_mdss->mmio + UBWC_CTRL_2);
21492bab914SDmitry Baryshkov 		writel_relaxed(0, msm_mdss->mmio + UBWC_PREDICTION_MODE);
21592bab914SDmitry Baryshkov 	} else {
216a85c238cSDmitry Baryshkov 		if (data->ubwc_dec_version == UBWC_4_3)
217a85c238cSDmitry Baryshkov 			writel_relaxed(3, msm_mdss->mmio + UBWC_CTRL_2);
218a85c238cSDmitry Baryshkov 		else
21992bab914SDmitry Baryshkov 			writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2);
22092bab914SDmitry Baryshkov 		writel_relaxed(1, msm_mdss->mmio + UBWC_PREDICTION_MODE);
22192bab914SDmitry Baryshkov 	}
22292bab914SDmitry Baryshkov }
22392bab914SDmitry Baryshkov 
msm_mdss_get_mdss_data(struct device * dev)22471e00fc0SDmitry Baryshkov const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev)
22571e00fc0SDmitry Baryshkov {
22671e00fc0SDmitry Baryshkov 	struct msm_mdss *mdss;
22771e00fc0SDmitry Baryshkov 
22871e00fc0SDmitry Baryshkov 	if (!dev)
22971e00fc0SDmitry Baryshkov 		return ERR_PTR(-EINVAL);
23071e00fc0SDmitry Baryshkov 
23171e00fc0SDmitry Baryshkov 	mdss = dev_get_drvdata(dev);
23271e00fc0SDmitry Baryshkov 
23371e00fc0SDmitry Baryshkov 	return mdss->mdss_data;
23471e00fc0SDmitry Baryshkov }
23571e00fc0SDmitry Baryshkov 
msm_mdss_enable(struct msm_mdss * msm_mdss)236ecb23f2eSDmitry Baryshkov static int msm_mdss_enable(struct msm_mdss *msm_mdss)
23787729e2aSDmitry Baryshkov {
23887729e2aSDmitry Baryshkov 	int ret;
23987729e2aSDmitry Baryshkov 
240b9364eedSDouglas Anderson 	/*
241b9364eedSDouglas Anderson 	 * Several components have AXI clocks that can only be turned on if
242b9364eedSDouglas Anderson 	 * the interconnect is enabled (non-zero bandwidth). Let's make sure
243b9364eedSDouglas Anderson 	 * that the interconnects are at least at a minimum amount.
244b9364eedSDouglas Anderson 	 */
245b9364eedSDouglas Anderson 	msm_mdss_icc_request_bw(msm_mdss, MIN_IB_BW);
246b9364eedSDouglas Anderson 
247aba75693SDmitry Baryshkov 	if (msm_mdss->mdss_data && msm_mdss->mdss_data->reg_bus_bw)
248aba75693SDmitry Baryshkov 		icc_set_bw(msm_mdss->reg_bus_path, 0,
249aba75693SDmitry Baryshkov 			   msm_mdss->mdss_data->reg_bus_bw);
250aba75693SDmitry Baryshkov 	else
251aba75693SDmitry Baryshkov 		icc_set_bw(msm_mdss->reg_bus_path, 0,
252aba75693SDmitry Baryshkov 			   DEFAULT_REG_BW);
253aba75693SDmitry Baryshkov 
254e1072257SDmitry Baryshkov 	ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks);
25587729e2aSDmitry Baryshkov 	if (ret) {
256e1072257SDmitry Baryshkov 		dev_err(msm_mdss->dev, "clock enable failed, ret:%d\n", ret);
25787729e2aSDmitry Baryshkov 		return ret;
25887729e2aSDmitry Baryshkov 	}
25987729e2aSDmitry Baryshkov 
26087729e2aSDmitry Baryshkov 	/*
261d68db606SDmitry Baryshkov 	 * Register access requires MDSS_MDP_CLK, which is not enabled by the
262d68db606SDmitry Baryshkov 	 * mdss on mdp5 hardware. Skip it for now.
26387729e2aSDmitry Baryshkov 	 */
264d68db606SDmitry Baryshkov 	if (msm_mdss->is_mdp5 || !msm_mdss->mdss_data)
26587729e2aSDmitry Baryshkov 		return 0;
26687729e2aSDmitry Baryshkov 
26787729e2aSDmitry Baryshkov 	/*
26887729e2aSDmitry Baryshkov 	 * ubwc config is part of the "mdss" region which is not accessible
26987729e2aSDmitry Baryshkov 	 * from the rest of the driver. hardcode known configurations here
27092bab914SDmitry Baryshkov 	 *
27192bab914SDmitry Baryshkov 	 * Decoder version can be read from the UBWC_DEC_HW_VERSION reg,
272d68db606SDmitry Baryshkov 	 * UBWC_n and the rest of params comes from hw data.
27387729e2aSDmitry Baryshkov 	 */
274d68db606SDmitry Baryshkov 	switch (msm_mdss->mdss_data->ubwc_dec_version) {
2756f410b24SDmitry Baryshkov 	case 0: /* no UBWC */
2766f410b24SDmitry Baryshkov 	case UBWC_1_0:
2776f410b24SDmitry Baryshkov 		/* do nothing */
2786f410b24SDmitry Baryshkov 		break;
279d68db606SDmitry Baryshkov 	case UBWC_2_0:
280d68db606SDmitry Baryshkov 		msm_mdss_setup_ubwc_dec_20(msm_mdss);
28187729e2aSDmitry Baryshkov 		break;
282d68db606SDmitry Baryshkov 	case UBWC_3_0:
283d68db606SDmitry Baryshkov 		msm_mdss_setup_ubwc_dec_30(msm_mdss);
28487729e2aSDmitry Baryshkov 		break;
285d68db606SDmitry Baryshkov 	case UBWC_4_0:
286a85c238cSDmitry Baryshkov 	case UBWC_4_3:
287d68db606SDmitry Baryshkov 		msm_mdss_setup_ubwc_dec_40(msm_mdss);
28887729e2aSDmitry Baryshkov 		break;
289d68db606SDmitry Baryshkov 	default:
2906ec59381SColin Ian King 		dev_err(msm_mdss->dev, "Unsupported UBWC decoder version %x\n",
291d68db606SDmitry Baryshkov 			msm_mdss->mdss_data->ubwc_dec_version);
292d68db606SDmitry Baryshkov 		dev_err(msm_mdss->dev, "HW_REV: 0x%x\n",
293d68db606SDmitry Baryshkov 			readl_relaxed(msm_mdss->mmio + HW_REV));
294d68db606SDmitry Baryshkov 		dev_err(msm_mdss->dev, "UBWC_DEC_HW_VERSION: 0x%x\n",
295d68db606SDmitry Baryshkov 			readl_relaxed(msm_mdss->mmio + UBWC_DEC_HW_VERSION));
29680056d9aSDmitry Baryshkov 		break;
29787729e2aSDmitry Baryshkov 	}
29887729e2aSDmitry Baryshkov 
29987729e2aSDmitry Baryshkov 	return ret;
30087729e2aSDmitry Baryshkov }
30187729e2aSDmitry Baryshkov 
msm_mdss_disable(struct msm_mdss * msm_mdss)302ecb23f2eSDmitry Baryshkov static int msm_mdss_disable(struct msm_mdss *msm_mdss)
30387729e2aSDmitry Baryshkov {
304e1072257SDmitry Baryshkov 	clk_bulk_disable_unprepare(msm_mdss->num_clocks, msm_mdss->clocks);
305b9364eedSDouglas Anderson 	msm_mdss_icc_request_bw(msm_mdss, 0);
30687729e2aSDmitry Baryshkov 
307aba75693SDmitry Baryshkov 	if (msm_mdss->reg_bus_path)
308aba75693SDmitry Baryshkov 		icc_set_bw(msm_mdss->reg_bus_path, 0, 0);
309aba75693SDmitry Baryshkov 
31087729e2aSDmitry Baryshkov 	return 0;
31187729e2aSDmitry Baryshkov }
31287729e2aSDmitry Baryshkov 
msm_mdss_destroy(struct msm_mdss * msm_mdss)313ecb23f2eSDmitry Baryshkov static void msm_mdss_destroy(struct msm_mdss *msm_mdss)
31487729e2aSDmitry Baryshkov {
315e1072257SDmitry Baryshkov 	struct platform_device *pdev = to_platform_device(msm_mdss->dev);
31687729e2aSDmitry Baryshkov 	int irq;
31787729e2aSDmitry Baryshkov 
318e1072257SDmitry Baryshkov 	pm_runtime_suspend(msm_mdss->dev);
319e1072257SDmitry Baryshkov 	pm_runtime_disable(msm_mdss->dev);
320e1072257SDmitry Baryshkov 	irq_domain_remove(msm_mdss->irq_controller.domain);
321e1072257SDmitry Baryshkov 	msm_mdss->irq_controller.domain = NULL;
32287729e2aSDmitry Baryshkov 	irq = platform_get_irq(pdev, 0);
32387729e2aSDmitry Baryshkov 	irq_set_chained_handler_and_data(irq, NULL, NULL);
32487729e2aSDmitry Baryshkov }
32587729e2aSDmitry Baryshkov 
msm_mdss_reset(struct device * dev)3263e9c146fSBjorn Andersson static int msm_mdss_reset(struct device *dev)
3273e9c146fSBjorn Andersson {
3283e9c146fSBjorn Andersson 	struct reset_control *reset;
3293e9c146fSBjorn Andersson 
3303e9c146fSBjorn Andersson 	reset = reset_control_get_optional_exclusive(dev, NULL);
3313e9c146fSBjorn Andersson 	if (!reset) {
3323e9c146fSBjorn Andersson 		/* Optional reset not specified */
3333e9c146fSBjorn Andersson 		return 0;
3343e9c146fSBjorn Andersson 	} else if (IS_ERR(reset)) {
3353e9c146fSBjorn Andersson 		return dev_err_probe(dev, PTR_ERR(reset),
3363e9c146fSBjorn Andersson 				     "failed to acquire mdss reset\n");
3373e9c146fSBjorn Andersson 	}
3383e9c146fSBjorn Andersson 
3393e9c146fSBjorn Andersson 	reset_control_assert(reset);
3403e9c146fSBjorn Andersson 	/*
3413e9c146fSBjorn Andersson 	 * Tests indicate that reset has to be held for some period of time,
3423e9c146fSBjorn Andersson 	 * make it one frame in a typical system
3433e9c146fSBjorn Andersson 	 */
3443e9c146fSBjorn Andersson 	msleep(20);
3453e9c146fSBjorn Andersson 	reset_control_deassert(reset);
3463e9c146fSBjorn Andersson 
3473e9c146fSBjorn Andersson 	reset_control_put(reset);
3483e9c146fSBjorn Andersson 
3493e9c146fSBjorn Andersson 	return 0;
3503e9c146fSBjorn Andersson }
3513e9c146fSBjorn Andersson 
35287729e2aSDmitry Baryshkov /*
35387729e2aSDmitry Baryshkov  * MDP5 MDSS uses at most three specified clocks.
35487729e2aSDmitry Baryshkov  */
35587729e2aSDmitry Baryshkov #define MDP5_MDSS_NUM_CLOCKS 3
mdp5_mdss_parse_clock(struct platform_device * pdev,struct clk_bulk_data ** clocks)35687729e2aSDmitry Baryshkov static int mdp5_mdss_parse_clock(struct platform_device *pdev, struct clk_bulk_data **clocks)
35787729e2aSDmitry Baryshkov {
35887729e2aSDmitry Baryshkov 	struct clk_bulk_data *bulk;
35987729e2aSDmitry Baryshkov 	int num_clocks = 0;
36087729e2aSDmitry Baryshkov 	int ret;
36187729e2aSDmitry Baryshkov 
36287729e2aSDmitry Baryshkov 	if (!pdev)
36387729e2aSDmitry Baryshkov 		return -EINVAL;
36487729e2aSDmitry Baryshkov 
36587729e2aSDmitry Baryshkov 	bulk = devm_kcalloc(&pdev->dev, MDP5_MDSS_NUM_CLOCKS, sizeof(struct clk_bulk_data), GFP_KERNEL);
36687729e2aSDmitry Baryshkov 	if (!bulk)
36787729e2aSDmitry Baryshkov 		return -ENOMEM;
36887729e2aSDmitry Baryshkov 
36987729e2aSDmitry Baryshkov 	bulk[num_clocks++].id = "iface";
37087729e2aSDmitry Baryshkov 	bulk[num_clocks++].id = "bus";
37187729e2aSDmitry Baryshkov 	bulk[num_clocks++].id = "vsync";
37287729e2aSDmitry Baryshkov 
37387729e2aSDmitry Baryshkov 	ret = devm_clk_bulk_get_optional(&pdev->dev, num_clocks, bulk);
37487729e2aSDmitry Baryshkov 	if (ret)
37587729e2aSDmitry Baryshkov 		return ret;
37687729e2aSDmitry Baryshkov 
37787729e2aSDmitry Baryshkov 	*clocks = bulk;
37887729e2aSDmitry Baryshkov 
37987729e2aSDmitry Baryshkov 	return num_clocks;
38087729e2aSDmitry Baryshkov }
38187729e2aSDmitry Baryshkov 
msm_mdss_init(struct platform_device * pdev,bool is_mdp5)382ecb23f2eSDmitry Baryshkov static struct msm_mdss *msm_mdss_init(struct platform_device *pdev, bool is_mdp5)
38387729e2aSDmitry Baryshkov {
384e1072257SDmitry Baryshkov 	struct msm_mdss *msm_mdss;
38587729e2aSDmitry Baryshkov 	int ret;
38687729e2aSDmitry Baryshkov 	int irq;
38787729e2aSDmitry Baryshkov 
3883e9c146fSBjorn Andersson 	ret = msm_mdss_reset(&pdev->dev);
3893e9c146fSBjorn Andersson 	if (ret)
3903e9c146fSBjorn Andersson 		return ERR_PTR(ret);
3913e9c146fSBjorn Andersson 
392e1072257SDmitry Baryshkov 	msm_mdss = devm_kzalloc(&pdev->dev, sizeof(*msm_mdss), GFP_KERNEL);
393e1072257SDmitry Baryshkov 	if (!msm_mdss)
394e1072257SDmitry Baryshkov 		return ERR_PTR(-ENOMEM);
39587729e2aSDmitry Baryshkov 
396aba75693SDmitry Baryshkov 	msm_mdss->mdss_data = of_device_get_match_data(&pdev->dev);
397aba75693SDmitry Baryshkov 
398e1072257SDmitry Baryshkov 	msm_mdss->mmio = devm_platform_ioremap_resource_byname(pdev, is_mdp5 ? "mdss_phys" : "mdss");
399e1072257SDmitry Baryshkov 	if (IS_ERR(msm_mdss->mmio))
400e1072257SDmitry Baryshkov 		return ERR_CAST(msm_mdss->mmio);
40187729e2aSDmitry Baryshkov 
402e1072257SDmitry Baryshkov 	dev_dbg(&pdev->dev, "mapped mdss address space @%pK\n", msm_mdss->mmio);
40387729e2aSDmitry Baryshkov 
404b9364eedSDouglas Anderson 	ret = msm_mdss_parse_data_bus_icc_path(&pdev->dev, msm_mdss);
405b9364eedSDouglas Anderson 	if (ret)
406b9364eedSDouglas Anderson 		return ERR_PTR(ret);
407b9364eedSDouglas Anderson 
40887729e2aSDmitry Baryshkov 	if (is_mdp5)
409e1072257SDmitry Baryshkov 		ret = mdp5_mdss_parse_clock(pdev, &msm_mdss->clocks);
41087729e2aSDmitry Baryshkov 	else
411e1072257SDmitry Baryshkov 		ret = devm_clk_bulk_get_all(&pdev->dev, &msm_mdss->clocks);
41287729e2aSDmitry Baryshkov 	if (ret < 0) {
413e1072257SDmitry Baryshkov 		dev_err(&pdev->dev, "failed to parse clocks, ret=%d\n", ret);
414e1072257SDmitry Baryshkov 		return ERR_PTR(ret);
41587729e2aSDmitry Baryshkov 	}
416e1072257SDmitry Baryshkov 	msm_mdss->num_clocks = ret;
417e1072257SDmitry Baryshkov 	msm_mdss->is_mdp5 = is_mdp5;
41887729e2aSDmitry Baryshkov 
419e1072257SDmitry Baryshkov 	msm_mdss->dev = &pdev->dev;
42087729e2aSDmitry Baryshkov 
42187729e2aSDmitry Baryshkov 	irq = platform_get_irq(pdev, 0);
42287729e2aSDmitry Baryshkov 	if (irq < 0)
423e1072257SDmitry Baryshkov 		return ERR_PTR(irq);
42487729e2aSDmitry Baryshkov 
425e1072257SDmitry Baryshkov 	ret = _msm_mdss_irq_domain_add(msm_mdss);
42687729e2aSDmitry Baryshkov 	if (ret)
427e1072257SDmitry Baryshkov 		return ERR_PTR(ret);
42887729e2aSDmitry Baryshkov 
42987729e2aSDmitry Baryshkov 	irq_set_chained_handler_and_data(irq, msm_mdss_irq,
430e1072257SDmitry Baryshkov 					 msm_mdss);
43187729e2aSDmitry Baryshkov 
43287729e2aSDmitry Baryshkov 	pm_runtime_enable(&pdev->dev);
43387729e2aSDmitry Baryshkov 
434e1072257SDmitry Baryshkov 	return msm_mdss;
43587729e2aSDmitry Baryshkov }
436ecb23f2eSDmitry Baryshkov 
mdss_runtime_suspend(struct device * dev)437ecb23f2eSDmitry Baryshkov static int __maybe_unused mdss_runtime_suspend(struct device *dev)
438ecb23f2eSDmitry Baryshkov {
4396874f48bSDmitry Baryshkov 	struct msm_mdss *mdss = dev_get_drvdata(dev);
440ecb23f2eSDmitry Baryshkov 
441ecb23f2eSDmitry Baryshkov 	DBG("");
442ecb23f2eSDmitry Baryshkov 
4436874f48bSDmitry Baryshkov 	return msm_mdss_disable(mdss);
444ecb23f2eSDmitry Baryshkov }
445ecb23f2eSDmitry Baryshkov 
mdss_runtime_resume(struct device * dev)446ecb23f2eSDmitry Baryshkov static int __maybe_unused mdss_runtime_resume(struct device *dev)
447ecb23f2eSDmitry Baryshkov {
4486874f48bSDmitry Baryshkov 	struct msm_mdss *mdss = dev_get_drvdata(dev);
449ecb23f2eSDmitry Baryshkov 
450ecb23f2eSDmitry Baryshkov 	DBG("");
451ecb23f2eSDmitry Baryshkov 
4526874f48bSDmitry Baryshkov 	return msm_mdss_enable(mdss);
453ecb23f2eSDmitry Baryshkov }
454ecb23f2eSDmitry Baryshkov 
mdss_pm_suspend(struct device * dev)455ecb23f2eSDmitry Baryshkov static int __maybe_unused mdss_pm_suspend(struct device *dev)
456ecb23f2eSDmitry Baryshkov {
457ecb23f2eSDmitry Baryshkov 
458ecb23f2eSDmitry Baryshkov 	if (pm_runtime_suspended(dev))
459ecb23f2eSDmitry Baryshkov 		return 0;
460ecb23f2eSDmitry Baryshkov 
461ecb23f2eSDmitry Baryshkov 	return mdss_runtime_suspend(dev);
462ecb23f2eSDmitry Baryshkov }
463ecb23f2eSDmitry Baryshkov 
mdss_pm_resume(struct device * dev)464ecb23f2eSDmitry Baryshkov static int __maybe_unused mdss_pm_resume(struct device *dev)
465ecb23f2eSDmitry Baryshkov {
466ecb23f2eSDmitry Baryshkov 	if (pm_runtime_suspended(dev))
467ecb23f2eSDmitry Baryshkov 		return 0;
468ecb23f2eSDmitry Baryshkov 
469ecb23f2eSDmitry Baryshkov 	return mdss_runtime_resume(dev);
470ecb23f2eSDmitry Baryshkov }
471ecb23f2eSDmitry Baryshkov 
472ecb23f2eSDmitry Baryshkov static const struct dev_pm_ops mdss_pm_ops = {
473ecb23f2eSDmitry Baryshkov 	SET_SYSTEM_SLEEP_PM_OPS(mdss_pm_suspend, mdss_pm_resume)
474ecb23f2eSDmitry Baryshkov 	SET_RUNTIME_PM_OPS(mdss_runtime_suspend, mdss_runtime_resume, NULL)
475ecb23f2eSDmitry Baryshkov };
476ecb23f2eSDmitry Baryshkov 
mdss_probe(struct platform_device * pdev)477ecb23f2eSDmitry Baryshkov static int mdss_probe(struct platform_device *pdev)
478ecb23f2eSDmitry Baryshkov {
479ecb23f2eSDmitry Baryshkov 	struct msm_mdss *mdss;
4805d44531bSDmitry Baryshkov 	bool is_mdp5 = of_device_is_compatible(pdev->dev.of_node, "qcom,mdss");
481ecb23f2eSDmitry Baryshkov 	struct device *dev = &pdev->dev;
482ecb23f2eSDmitry Baryshkov 	int ret;
483ecb23f2eSDmitry Baryshkov 
4845d44531bSDmitry Baryshkov 	mdss = msm_mdss_init(pdev, is_mdp5);
485ecb23f2eSDmitry Baryshkov 	if (IS_ERR(mdss))
486ecb23f2eSDmitry Baryshkov 		return PTR_ERR(mdss);
487ecb23f2eSDmitry Baryshkov 
4886874f48bSDmitry Baryshkov 	platform_set_drvdata(pdev, mdss);
489ecb23f2eSDmitry Baryshkov 
490ecb23f2eSDmitry Baryshkov 	/*
491ecb23f2eSDmitry Baryshkov 	 * MDP5/DPU based devices don't have a flat hierarchy. There is a top
492ecb23f2eSDmitry Baryshkov 	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
493ecb23f2eSDmitry Baryshkov 	 * Populate the children devices, find the MDP5/DPU node, and then add
494ecb23f2eSDmitry Baryshkov 	 * the interfaces to our components list.
495ecb23f2eSDmitry Baryshkov 	 */
496ecb23f2eSDmitry Baryshkov 	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
497ecb23f2eSDmitry Baryshkov 	if (ret) {
498ecb23f2eSDmitry Baryshkov 		DRM_DEV_ERROR(dev, "failed to populate children devices\n");
4996874f48bSDmitry Baryshkov 		msm_mdss_destroy(mdss);
5006874f48bSDmitry Baryshkov 		return ret;
501ecb23f2eSDmitry Baryshkov 	}
502ecb23f2eSDmitry Baryshkov 
503ecb23f2eSDmitry Baryshkov 	return 0;
504ecb23f2eSDmitry Baryshkov }
505ecb23f2eSDmitry Baryshkov 
mdss_remove(struct platform_device * pdev)506ecb23f2eSDmitry Baryshkov static int mdss_remove(struct platform_device *pdev)
507ecb23f2eSDmitry Baryshkov {
5086874f48bSDmitry Baryshkov 	struct msm_mdss *mdss = platform_get_drvdata(pdev);
509ecb23f2eSDmitry Baryshkov 
510ecb23f2eSDmitry Baryshkov 	of_platform_depopulate(&pdev->dev);
511ecb23f2eSDmitry Baryshkov 
512ecb23f2eSDmitry Baryshkov 	msm_mdss_destroy(mdss);
513ecb23f2eSDmitry Baryshkov 
514ecb23f2eSDmitry Baryshkov 	return 0;
515ecb23f2eSDmitry Baryshkov }
516ecb23f2eSDmitry Baryshkov 
5176f410b24SDmitry Baryshkov static const struct msm_mdss_data msm8998_data = {
5186f410b24SDmitry Baryshkov 	.ubwc_enc_version = UBWC_1_0,
5196f410b24SDmitry Baryshkov 	.ubwc_dec_version = UBWC_1_0,
520c0666d1dSDmitry Baryshkov 	.highest_bank_bit = 2,
521aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
5226f410b24SDmitry Baryshkov };
5236f410b24SDmitry Baryshkov 
5246f410b24SDmitry Baryshkov static const struct msm_mdss_data qcm2290_data = {
5256f410b24SDmitry Baryshkov 	/* no UBWC */
5266f410b24SDmitry Baryshkov 	.highest_bank_bit = 0x2,
527aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
5286f410b24SDmitry Baryshkov };
5296f410b24SDmitry Baryshkov 
530d68db606SDmitry Baryshkov static const struct msm_mdss_data sc7180_data = {
531cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_2_0,
532d68db606SDmitry Baryshkov 	.ubwc_dec_version = UBWC_2_0,
533d68db606SDmitry Baryshkov 	.ubwc_static = 0x1e,
53488c232fdSAbhinav Kumar 	.highest_bank_bit = 0x1,
535aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
536d68db606SDmitry Baryshkov };
537d68db606SDmitry Baryshkov 
538d68db606SDmitry Baryshkov static const struct msm_mdss_data sc7280_data = {
539cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_3_0,
540d68db606SDmitry Baryshkov 	.ubwc_dec_version = UBWC_4_0,
541d68db606SDmitry Baryshkov 	.ubwc_swizzle = 6,
542d68db606SDmitry Baryshkov 	.ubwc_static = 1,
543d68db606SDmitry Baryshkov 	.highest_bank_bit = 1,
544d68db606SDmitry Baryshkov 	.macrotile_mode = 1,
545aba75693SDmitry Baryshkov 	.reg_bus_bw = 74000,
546d68db606SDmitry Baryshkov };
547d68db606SDmitry Baryshkov 
548aeff6bb5SDmitry Baryshkov static const struct msm_mdss_data sc8180x_data = {
549cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_3_0,
550aeff6bb5SDmitry Baryshkov 	.ubwc_dec_version = UBWC_3_0,
551aeff6bb5SDmitry Baryshkov 	.highest_bank_bit = 3,
552aeff6bb5SDmitry Baryshkov 	.macrotile_mode = 1,
553aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
554aeff6bb5SDmitry Baryshkov };
555aeff6bb5SDmitry Baryshkov 
556d68db606SDmitry Baryshkov static const struct msm_mdss_data sc8280xp_data = {
557cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_4_0,
558d68db606SDmitry Baryshkov 	.ubwc_dec_version = UBWC_4_0,
559d68db606SDmitry Baryshkov 	.ubwc_swizzle = 6,
560d68db606SDmitry Baryshkov 	.ubwc_static = 1,
561d68db606SDmitry Baryshkov 	.highest_bank_bit = 2,
562d68db606SDmitry Baryshkov 	.macrotile_mode = 1,
563aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
564d68db606SDmitry Baryshkov };
565d68db606SDmitry Baryshkov 
5669cffae4aSDmitry Baryshkov static const struct msm_mdss_data sdm845_data = {
567cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_2_0,
5689cffae4aSDmitry Baryshkov 	.ubwc_dec_version = UBWC_2_0,
5699cffae4aSDmitry Baryshkov 	.highest_bank_bit = 2,
570aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
5719cffae4aSDmitry Baryshkov };
5729cffae4aSDmitry Baryshkov 
573c2c1217eSKonrad Dybcio static const struct msm_mdss_data sm6350_data = {
574cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_2_0,
575c2c1217eSKonrad Dybcio 	.ubwc_dec_version = UBWC_2_0,
576c2c1217eSKonrad Dybcio 	.ubwc_swizzle = 6,
577c2c1217eSKonrad Dybcio 	.ubwc_static = 0x1e,
578c2c1217eSKonrad Dybcio 	.highest_bank_bit = 1,
579aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
580c2c1217eSKonrad Dybcio };
581c2c1217eSKonrad Dybcio 
582d68db606SDmitry Baryshkov static const struct msm_mdss_data sm8150_data = {
583cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_3_0,
584d68db606SDmitry Baryshkov 	.ubwc_dec_version = UBWC_3_0,
585d68db606SDmitry Baryshkov 	.highest_bank_bit = 2,
586aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
587d68db606SDmitry Baryshkov };
588d68db606SDmitry Baryshkov 
589d68db606SDmitry Baryshkov static const struct msm_mdss_data sm6115_data = {
590cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_1_0,
591d68db606SDmitry Baryshkov 	.ubwc_dec_version = UBWC_2_0,
592d68db606SDmitry Baryshkov 	.ubwc_swizzle = 7,
593d68db606SDmitry Baryshkov 	.ubwc_static = 0x11f,
5946f410b24SDmitry Baryshkov 	.highest_bank_bit = 0x1,
595aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
596d68db606SDmitry Baryshkov };
597d68db606SDmitry Baryshkov 
59887aa3c9bSMarijn Suijten static const struct msm_mdss_data sm6125_data = {
599cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_1_0,
60087aa3c9bSMarijn Suijten 	.ubwc_dec_version = UBWC_3_0,
60187aa3c9bSMarijn Suijten 	.ubwc_swizzle = 1,
60287aa3c9bSMarijn Suijten 	.highest_bank_bit = 1,
603*ab7554fbSDmitry Baryshkov 	.reg_bus_bw = 76800,
604d68db606SDmitry Baryshkov };
605d68db606SDmitry Baryshkov 
606d68db606SDmitry Baryshkov static const struct msm_mdss_data sm8250_data = {
607cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_4_0,
608d68db606SDmitry Baryshkov 	.ubwc_dec_version = UBWC_4_0,
609d68db606SDmitry Baryshkov 	.ubwc_swizzle = 6,
610d68db606SDmitry Baryshkov 	.ubwc_static = 1,
611d68db606SDmitry Baryshkov 	/* TODO: highest_bank_bit = 2 for LP_DDR4 */
612d68db606SDmitry Baryshkov 	.highest_bank_bit = 3,
613d68db606SDmitry Baryshkov 	.macrotile_mode = 1,
614aba75693SDmitry Baryshkov 	.reg_bus_bw = 76800,
615aba75693SDmitry Baryshkov };
616aba75693SDmitry Baryshkov 
617aba75693SDmitry Baryshkov static const struct msm_mdss_data sm8350_data = {
618aba75693SDmitry Baryshkov 	.ubwc_enc_version = UBWC_4_0,
619aba75693SDmitry Baryshkov 	.ubwc_dec_version = UBWC_4_0,
620aba75693SDmitry Baryshkov 	.ubwc_swizzle = 6,
621aba75693SDmitry Baryshkov 	.ubwc_static = 1,
622aba75693SDmitry Baryshkov 	/* TODO: highest_bank_bit = 2 for LP_DDR4 */
623aba75693SDmitry Baryshkov 	.highest_bank_bit = 3,
624aba75693SDmitry Baryshkov 	.macrotile_mode = 1,
625aba75693SDmitry Baryshkov 	.reg_bus_bw = 74000,
626d68db606SDmitry Baryshkov };
627d68db606SDmitry Baryshkov 
628a85c238cSDmitry Baryshkov static const struct msm_mdss_data sm8550_data = {
629cab5b406SDmitry Baryshkov 	.ubwc_enc_version = UBWC_4_0,
630a85c238cSDmitry Baryshkov 	.ubwc_dec_version = UBWC_4_3,
631a85c238cSDmitry Baryshkov 	.ubwc_swizzle = 6,
632a85c238cSDmitry Baryshkov 	.ubwc_static = 1,
633a85c238cSDmitry Baryshkov 	/* TODO: highest_bank_bit = 2 for LP_DDR4 */
634a85c238cSDmitry Baryshkov 	.highest_bank_bit = 3,
635a85c238cSDmitry Baryshkov 	.macrotile_mode = 1,
636aba75693SDmitry Baryshkov 	.reg_bus_bw = 57000,
637a85c238cSDmitry Baryshkov };
638ecb23f2eSDmitry Baryshkov static const struct of_device_id mdss_dt_match[] = {
6395d44531bSDmitry Baryshkov 	{ .compatible = "qcom,mdss" },
6406f410b24SDmitry Baryshkov 	{ .compatible = "qcom,msm8998-mdss", .data = &msm8998_data },
6416f410b24SDmitry Baryshkov 	{ .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data },
6429cffae4aSDmitry Baryshkov 	{ .compatible = "qcom,sdm845-mdss", .data = &sdm845_data },
643d68db606SDmitry Baryshkov 	{ .compatible = "qcom,sc7180-mdss", .data = &sc7180_data },
644d68db606SDmitry Baryshkov 	{ .compatible = "qcom,sc7280-mdss", .data = &sc7280_data },
645aeff6bb5SDmitry Baryshkov 	{ .compatible = "qcom,sc8180x-mdss", .data = &sc8180x_data },
646d68db606SDmitry Baryshkov 	{ .compatible = "qcom,sc8280xp-mdss", .data = &sc8280xp_data },
647d68db606SDmitry Baryshkov 	{ .compatible = "qcom,sm6115-mdss", .data = &sm6115_data },
64887aa3c9bSMarijn Suijten 	{ .compatible = "qcom,sm6125-mdss", .data = &sm6125_data },
649c2c1217eSKonrad Dybcio 	{ .compatible = "qcom,sm6350-mdss", .data = &sm6350_data },
6505ff3d3a0SKonrad Dybcio 	{ .compatible = "qcom,sm6375-mdss", .data = &sm6350_data },
651d68db606SDmitry Baryshkov 	{ .compatible = "qcom,sm8150-mdss", .data = &sm8150_data },
652d68db606SDmitry Baryshkov 	{ .compatible = "qcom,sm8250-mdss", .data = &sm8250_data },
653aba75693SDmitry Baryshkov 	{ .compatible = "qcom,sm8350-mdss", .data = &sm8350_data },
654aba75693SDmitry Baryshkov 	{ .compatible = "qcom,sm8450-mdss", .data = &sm8350_data },
655a85c238cSDmitry Baryshkov 	{ .compatible = "qcom,sm8550-mdss", .data = &sm8550_data },
656ecb23f2eSDmitry Baryshkov 	{}
657ecb23f2eSDmitry Baryshkov };
658ecb23f2eSDmitry Baryshkov MODULE_DEVICE_TABLE(of, mdss_dt_match);
659ecb23f2eSDmitry Baryshkov 
660ecb23f2eSDmitry Baryshkov static struct platform_driver mdss_platform_driver = {
661ecb23f2eSDmitry Baryshkov 	.probe      = mdss_probe,
662ecb23f2eSDmitry Baryshkov 	.remove     = mdss_remove,
663ecb23f2eSDmitry Baryshkov 	.driver     = {
664ecb23f2eSDmitry Baryshkov 		.name   = "msm-mdss",
665ecb23f2eSDmitry Baryshkov 		.of_match_table = mdss_dt_match,
666ecb23f2eSDmitry Baryshkov 		.pm     = &mdss_pm_ops,
667ecb23f2eSDmitry Baryshkov 	},
668ecb23f2eSDmitry Baryshkov };
669ecb23f2eSDmitry Baryshkov 
msm_mdss_register(void)670ecb23f2eSDmitry Baryshkov void __init msm_mdss_register(void)
671ecb23f2eSDmitry Baryshkov {
672ecb23f2eSDmitry Baryshkov 	platform_driver_register(&mdss_platform_driver);
673ecb23f2eSDmitry Baryshkov }
674ecb23f2eSDmitry Baryshkov 
msm_mdss_unregister(void)675ecb23f2eSDmitry Baryshkov void __exit msm_mdss_unregister(void)
676ecb23f2eSDmitry Baryshkov {
677ecb23f2eSDmitry Baryshkov 	platform_driver_unregister(&mdss_platform_driver);
678ecb23f2eSDmitry Baryshkov }
679