brintos

brintos / linux-shallow public Read only

0
0
Text · 58.7 KiB · 430f8ad Raw
2155 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Samsung MIPI DSIM bridge driver.4 *5 * Copyright (C) 2021 Amarula Solutions(India)6 * Copyright (c) 2014 Samsung Electronics Co., Ltd7 * Author: Jagan Teki <jagan@amarulasolutions.com>8 *9 * Based on exynos_drm_dsi from10 * Tomasz Figa <t.figa@samsung.com>11 */12 13#include <linux/unaligned.h>14 15#include <linux/clk.h>16#include <linux/delay.h>17#include <linux/irq.h>18#include <linux/media-bus-format.h>19#include <linux/of.h>20#include <linux/phy/phy.h>21#include <linux/platform_device.h>22 23#include <video/mipi_display.h>24 25#include <drm/bridge/samsung-dsim.h>26#include <drm/drm_panel.h>27#include <drm/drm_print.h>28 29/* returns true iff both arguments logically differs */30#define NEQV(a, b) (!(a) ^ !(b))31 32/* DSIM_STATUS */33#define DSIM_STOP_STATE_DAT(x)		(((x) & 0xf) << 0)34#define DSIM_STOP_STATE_CLK		BIT(8)35#define DSIM_TX_READY_HS_CLK		BIT(10)36#define DSIM_PLL_STABLE			BIT(31)37 38/* DSIM_SWRST */39#define DSIM_FUNCRST			BIT(16)40#define DSIM_SWRST			BIT(0)41 42/* DSIM_TIMEOUT */43#define DSIM_LPDR_TIMEOUT(x)		((x) << 0)44#define DSIM_BTA_TIMEOUT(x)		((x) << 16)45 46/* DSIM_CLKCTRL */47#define DSIM_ESC_PRESCALER(x)		(((x) & 0xffff) << 0)48#define DSIM_ESC_PRESCALER_MASK		(0xffff << 0)49#define DSIM_LANE_ESC_CLK_EN_CLK	BIT(19)50#define DSIM_LANE_ESC_CLK_EN_DATA(x)	(((x) & 0xf) << 20)51#define DSIM_LANE_ESC_CLK_EN_DATA_MASK	(0xf << 20)52#define DSIM_BYTE_CLKEN			BIT(24)53#define DSIM_BYTE_CLK_SRC(x)		(((x) & 0x3) << 25)54#define DSIM_BYTE_CLK_SRC_MASK		(0x3 << 25)55#define DSIM_PLL_BYPASS			BIT(27)56#define DSIM_ESC_CLKEN			BIT(28)57#define DSIM_TX_REQUEST_HSCLK		BIT(31)58 59/* DSIM_CONFIG */60#define DSIM_LANE_EN_CLK		BIT(0)61#define DSIM_LANE_EN(x)			(((x) & 0xf) << 1)62#define DSIM_NUM_OF_DATA_LANE(x)	(((x) & 0x3) << 5)63#define DSIM_SUB_PIX_FORMAT(x)		(((x) & 0x7) << 8)64#define DSIM_MAIN_PIX_FORMAT_MASK	(0x7 << 12)65#define DSIM_MAIN_PIX_FORMAT_RGB888	(0x7 << 12)66#define DSIM_MAIN_PIX_FORMAT_RGB666	(0x6 << 12)67#define DSIM_MAIN_PIX_FORMAT_RGB666_P	(0x5 << 12)68#define DSIM_MAIN_PIX_FORMAT_RGB565	(0x4 << 12)69#define DSIM_SUB_VC			(((x) & 0x3) << 16)70#define DSIM_MAIN_VC			(((x) & 0x3) << 18)71#define DSIM_HSA_DISABLE_MODE		BIT(20)72#define DSIM_HBP_DISABLE_MODE		BIT(21)73#define DSIM_HFP_DISABLE_MODE		BIT(22)74/*75 * The i.MX 8M Mini Applications Processor Reference Manual,76 * Rev. 3, 11/2020 Page 409177 * The i.MX 8M Nano Applications Processor Reference Manual,78 * Rev. 2, 07/2022 Page 305879 * The i.MX 8M Plus Applications Processor Reference Manual,80 * Rev. 1, 06/2021 Page 543681 * all claims this bit is 'HseDisableMode' with the definition82 * 0 = Disables transfer83 * 1 = Enables transfer84 *85 * This clearly states that HSE is not a disabled bit.86 *87 * The naming convention follows as per the manual and the88 * driver logic is based on the MIPI_DSI_MODE_VIDEO_HSE flag.89 */90#define DSIM_HSE_DISABLE_MODE		BIT(23)91#define DSIM_AUTO_MODE			BIT(24)92#define DSIM_VIDEO_MODE			BIT(25)93#define DSIM_BURST_MODE			BIT(26)94#define DSIM_SYNC_INFORM		BIT(27)95#define DSIM_EOT_DISABLE		BIT(28)96#define DSIM_MFLUSH_VS			BIT(29)97/* This flag is valid only for exynos3250/3472/5260/5430 */98#define DSIM_CLKLANE_STOP		BIT(30)99#define DSIM_NON_CONTINUOUS_CLKLANE	BIT(31)100 101/* DSIM_ESCMODE */102#define DSIM_TX_TRIGGER_RST		BIT(4)103#define DSIM_TX_LPDT_LP			BIT(6)104#define DSIM_CMD_LPDT_LP		BIT(7)105#define DSIM_FORCE_BTA			BIT(16)106#define DSIM_FORCE_STOP_STATE		BIT(20)107#define DSIM_STOP_STATE_CNT(x)		(((x) & 0x7ff) << 21)108#define DSIM_STOP_STATE_CNT_MASK	(0x7ff << 21)109 110/* DSIM_MDRESOL */111#define DSIM_MAIN_STAND_BY		BIT(31)112#define DSIM_MAIN_VRESOL(x, num_bits)	(((x) & ((1 << (num_bits)) - 1)) << 16)113#define DSIM_MAIN_HRESOL(x, num_bits)	(((x) & ((1 << (num_bits)) - 1)) << 0)114 115/* DSIM_MVPORCH */116#define DSIM_CMD_ALLOW(x)		((x) << 28)117#define DSIM_STABLE_VFP(x)		((x) << 16)118#define DSIM_MAIN_VBP(x)		((x) << 0)119#define DSIM_CMD_ALLOW_MASK		(0xf << 28)120#define DSIM_STABLE_VFP_MASK		(0x7ff << 16)121#define DSIM_MAIN_VBP_MASK		(0x7ff << 0)122 123/* DSIM_MHPORCH */124#define DSIM_MAIN_HFP(x)		((x) << 16)125#define DSIM_MAIN_HBP(x)		((x) << 0)126#define DSIM_MAIN_HFP_MASK		((0xffff) << 16)127#define DSIM_MAIN_HBP_MASK		((0xffff) << 0)128 129/* DSIM_MSYNC */130#define DSIM_MAIN_VSA(x)		((x) << 22)131#define DSIM_MAIN_HSA(x)		((x) << 0)132#define DSIM_MAIN_VSA_MASK		((0x3ff) << 22)133#define DSIM_MAIN_HSA_MASK		((0xffff) << 0)134 135/* DSIM_SDRESOL */136#define DSIM_SUB_STANDY(x)		((x) << 31)137#define DSIM_SUB_VRESOL(x)		((x) << 16)138#define DSIM_SUB_HRESOL(x)		((x) << 0)139#define DSIM_SUB_STANDY_MASK		((0x1) << 31)140#define DSIM_SUB_VRESOL_MASK		((0x7ff) << 16)141#define DSIM_SUB_HRESOL_MASK		((0x7ff) << 0)142 143/* DSIM_INTSRC */144#define DSIM_INT_PLL_STABLE		BIT(31)145#define DSIM_INT_SW_RST_RELEASE		BIT(30)146#define DSIM_INT_SFR_FIFO_EMPTY		BIT(29)147#define DSIM_INT_SFR_HDR_FIFO_EMPTY	BIT(28)148#define DSIM_INT_BTA			BIT(25)149#define DSIM_INT_FRAME_DONE		BIT(24)150#define DSIM_INT_RX_TIMEOUT		BIT(21)151#define DSIM_INT_BTA_TIMEOUT		BIT(20)152#define DSIM_INT_RX_DONE		BIT(18)153#define DSIM_INT_RX_TE			BIT(17)154#define DSIM_INT_RX_ACK			BIT(16)155#define DSIM_INT_RX_ECC_ERR		BIT(15)156#define DSIM_INT_RX_CRC_ERR		BIT(14)157 158/* DSIM_FIFOCTRL */159#define DSIM_RX_DATA_FULL		BIT(25)160#define DSIM_RX_DATA_EMPTY		BIT(24)161#define DSIM_SFR_HEADER_FULL		BIT(23)162#define DSIM_SFR_HEADER_EMPTY		BIT(22)163#define DSIM_SFR_PAYLOAD_FULL		BIT(21)164#define DSIM_SFR_PAYLOAD_EMPTY		BIT(20)165#define DSIM_I80_HEADER_FULL		BIT(19)166#define DSIM_I80_HEADER_EMPTY		BIT(18)167#define DSIM_I80_PAYLOAD_FULL		BIT(17)168#define DSIM_I80_PAYLOAD_EMPTY		BIT(16)169#define DSIM_SD_HEADER_FULL		BIT(15)170#define DSIM_SD_HEADER_EMPTY		BIT(14)171#define DSIM_SD_PAYLOAD_FULL		BIT(13)172#define DSIM_SD_PAYLOAD_EMPTY		BIT(12)173#define DSIM_MD_HEADER_FULL		BIT(11)174#define DSIM_MD_HEADER_EMPTY		BIT(10)175#define DSIM_MD_PAYLOAD_FULL		BIT(9)176#define DSIM_MD_PAYLOAD_EMPTY		BIT(8)177#define DSIM_RX_FIFO			BIT(4)178#define DSIM_SFR_FIFO			BIT(3)179#define DSIM_I80_FIFO			BIT(2)180#define DSIM_SD_FIFO			BIT(1)181#define DSIM_MD_FIFO			BIT(0)182 183/* DSIM_PHYACCHR */184#define DSIM_AFC_EN			BIT(14)185#define DSIM_AFC_CTL(x)			(((x) & 0x7) << 5)186 187/* DSIM_PLLCTRL */188#define DSIM_PLL_DPDNSWAP_CLK		(1 << 25)189#define DSIM_PLL_DPDNSWAP_DAT		(1 << 24)190#define DSIM_FREQ_BAND(x)		((x) << 24)191#define DSIM_PLL_EN			BIT(23)192#define DSIM_PLL_P(x, offset)		((x) << (offset))193#define DSIM_PLL_M(x)			((x) << 4)194#define DSIM_PLL_S(x)			((x) << 1)195 196/* DSIM_PHYCTRL */197#define DSIM_PHYCTRL_ULPS_EXIT(x)	(((x) & 0x1ff) << 0)198#define DSIM_PHYCTRL_B_DPHYCTL_VREG_LP	BIT(30)199#define DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP	BIT(14)200 201/* DSIM_PHYTIMING */202#define DSIM_PHYTIMING_LPX(x)		((x) << 8)203#define DSIM_PHYTIMING_HS_EXIT(x)	((x) << 0)204 205/* DSIM_PHYTIMING1 */206#define DSIM_PHYTIMING1_CLK_PREPARE(x)	((x) << 24)207#define DSIM_PHYTIMING1_CLK_ZERO(x)	((x) << 16)208#define DSIM_PHYTIMING1_CLK_POST(x)	((x) << 8)209#define DSIM_PHYTIMING1_CLK_TRAIL(x)	((x) << 0)210 211/* DSIM_PHYTIMING2 */212#define DSIM_PHYTIMING2_HS_PREPARE(x)	((x) << 16)213#define DSIM_PHYTIMING2_HS_ZERO(x)	((x) << 8)214#define DSIM_PHYTIMING2_HS_TRAIL(x)	((x) << 0)215 216#define DSI_MAX_BUS_WIDTH		4217#define DSI_NUM_VIRTUAL_CHANNELS	4218#define DSI_TX_FIFO_SIZE		2048219#define DSI_RX_FIFO_SIZE		256220#define DSI_XFER_TIMEOUT_MS		100221#define DSI_RX_FIFO_EMPTY		0x30800002222 223#define OLD_SCLK_MIPI_CLK_NAME		"pll_clk"224 225#define PS_TO_CYCLE(ps, hz) DIV64_U64_ROUND_CLOSEST(((ps) * (hz)), 1000000000000ULL)226 227static const char *const clk_names[5] = {228	"bus_clk",229	"sclk_mipi",230	"phyclk_mipidphy0_bitclkdiv8",231	"phyclk_mipidphy0_rxclkesc0",232	"sclk_rgb_vclk_to_dsim0"233};234 235enum samsung_dsim_transfer_type {236	EXYNOS_DSI_TX,237	EXYNOS_DSI_RX,238};239 240enum reg_idx {241	DSIM_STATUS_REG,	/* Status register */242	DSIM_SWRST_REG,		/* Software reset register */243	DSIM_CLKCTRL_REG,	/* Clock control register */244	DSIM_TIMEOUT_REG,	/* Time out register */245	DSIM_CONFIG_REG,	/* Configuration register */246	DSIM_ESCMODE_REG,	/* Escape mode register */247	DSIM_MDRESOL_REG,248	DSIM_MVPORCH_REG,	/* Main display Vporch register */249	DSIM_MHPORCH_REG,	/* Main display Hporch register */250	DSIM_MSYNC_REG,		/* Main display sync area register */251	DSIM_INTSRC_REG,	/* Interrupt source register */252	DSIM_INTMSK_REG,	/* Interrupt mask register */253	DSIM_PKTHDR_REG,	/* Packet Header FIFO register */254	DSIM_PAYLOAD_REG,	/* Payload FIFO register */255	DSIM_RXFIFO_REG,	/* Read FIFO register */256	DSIM_FIFOCTRL_REG,	/* FIFO status and control register */257	DSIM_PLLCTRL_REG,	/* PLL control register */258	DSIM_PHYCTRL_REG,259	DSIM_PHYTIMING_REG,260	DSIM_PHYTIMING1_REG,261	DSIM_PHYTIMING2_REG,262	NUM_REGS263};264 265static const unsigned int exynos_reg_ofs[] = {266	[DSIM_STATUS_REG] =  0x00,267	[DSIM_SWRST_REG] =  0x04,268	[DSIM_CLKCTRL_REG] =  0x08,269	[DSIM_TIMEOUT_REG] =  0x0c,270	[DSIM_CONFIG_REG] =  0x10,271	[DSIM_ESCMODE_REG] =  0x14,272	[DSIM_MDRESOL_REG] =  0x18,273	[DSIM_MVPORCH_REG] =  0x1c,274	[DSIM_MHPORCH_REG] =  0x20,275	[DSIM_MSYNC_REG] =  0x24,276	[DSIM_INTSRC_REG] =  0x2c,277	[DSIM_INTMSK_REG] =  0x30,278	[DSIM_PKTHDR_REG] =  0x34,279	[DSIM_PAYLOAD_REG] =  0x38,280	[DSIM_RXFIFO_REG] =  0x3c,281	[DSIM_FIFOCTRL_REG] =  0x44,282	[DSIM_PLLCTRL_REG] =  0x4c,283	[DSIM_PHYCTRL_REG] =  0x5c,284	[DSIM_PHYTIMING_REG] =  0x64,285	[DSIM_PHYTIMING1_REG] =  0x68,286	[DSIM_PHYTIMING2_REG] =  0x6c,287};288 289static const unsigned int exynos5433_reg_ofs[] = {290	[DSIM_STATUS_REG] = 0x04,291	[DSIM_SWRST_REG] = 0x0C,292	[DSIM_CLKCTRL_REG] = 0x10,293	[DSIM_TIMEOUT_REG] = 0x14,294	[DSIM_CONFIG_REG] = 0x18,295	[DSIM_ESCMODE_REG] = 0x1C,296	[DSIM_MDRESOL_REG] = 0x20,297	[DSIM_MVPORCH_REG] = 0x24,298	[DSIM_MHPORCH_REG] = 0x28,299	[DSIM_MSYNC_REG] = 0x2C,300	[DSIM_INTSRC_REG] = 0x34,301	[DSIM_INTMSK_REG] = 0x38,302	[DSIM_PKTHDR_REG] = 0x3C,303	[DSIM_PAYLOAD_REG] = 0x40,304	[DSIM_RXFIFO_REG] = 0x44,305	[DSIM_FIFOCTRL_REG] = 0x4C,306	[DSIM_PLLCTRL_REG] = 0x94,307	[DSIM_PHYCTRL_REG] = 0xA4,308	[DSIM_PHYTIMING_REG] = 0xB4,309	[DSIM_PHYTIMING1_REG] = 0xB8,310	[DSIM_PHYTIMING2_REG] = 0xBC,311};312 313enum reg_value_idx {314	RESET_TYPE,315	PLL_TIMER,316	STOP_STATE_CNT,317	PHYCTRL_ULPS_EXIT,318	PHYCTRL_VREG_LP,319	PHYCTRL_SLEW_UP,320	PHYTIMING_LPX,321	PHYTIMING_HS_EXIT,322	PHYTIMING_CLK_PREPARE,323	PHYTIMING_CLK_ZERO,324	PHYTIMING_CLK_POST,325	PHYTIMING_CLK_TRAIL,326	PHYTIMING_HS_PREPARE,327	PHYTIMING_HS_ZERO,328	PHYTIMING_HS_TRAIL329};330 331static const unsigned int reg_values[] = {332	[RESET_TYPE] = DSIM_SWRST,333	[PLL_TIMER] = 500,334	[STOP_STATE_CNT] = 0xf,335	[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x0af),336	[PHYCTRL_VREG_LP] = 0,337	[PHYCTRL_SLEW_UP] = 0,338	[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),339	[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),340	[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),341	[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x27),342	[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),343	[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),344	[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x09),345	[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),346	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),347};348 349static const unsigned int exynos5422_reg_values[] = {350	[RESET_TYPE] = DSIM_SWRST,351	[PLL_TIMER] = 500,352	[STOP_STATE_CNT] = 0xf,353	[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),354	[PHYCTRL_VREG_LP] = 0,355	[PHYCTRL_SLEW_UP] = 0,356	[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x08),357	[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0d),358	[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),359	[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x30),360	[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),361	[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x0a),362	[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0c),363	[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x11),364	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0d),365};366 367static const unsigned int exynos5433_reg_values[] = {368	[RESET_TYPE] = DSIM_FUNCRST,369	[PLL_TIMER] = 22200,370	[STOP_STATE_CNT] = 0xa,371	[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x190),372	[PHYCTRL_VREG_LP] = DSIM_PHYCTRL_B_DPHYCTL_VREG_LP,373	[PHYCTRL_SLEW_UP] = DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP,374	[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x07),375	[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0c),376	[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),377	[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x2d),378	[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),379	[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x09),380	[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0b),381	[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x10),382	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),383};384 385static const unsigned int imx8mm_dsim_reg_values[] = {386	[RESET_TYPE] = DSIM_SWRST,387	[PLL_TIMER] = 500,388	[STOP_STATE_CNT] = 0xf,389	[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),390	[PHYCTRL_VREG_LP] = 0,391	[PHYCTRL_SLEW_UP] = 0,392	[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),393	[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),394	[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),395	[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x26),396	[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),397	[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),398	[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x08),399	[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),400	[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),401};402 403static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {404	.reg_ofs = exynos_reg_ofs,405	.plltmr_reg = 0x50,406	.has_freqband = 1,407	.has_clklane_stop = 1,408	.num_clks = 2,409	.max_freq = 1000,410	.wait_for_reset = 1,411	.num_bits_resol = 11,412	.pll_p_offset = 13,413	.reg_values = reg_values,414	.pll_fin_min = 6,415	.pll_fin_max = 12,416	.m_min = 41,417	.m_max = 125,418	.min_freq = 500,419	.has_broken_fifoctrl_emptyhdr = 1,420};421 422static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {423	.reg_ofs = exynos_reg_ofs,424	.plltmr_reg = 0x50,425	.has_freqband = 1,426	.has_clklane_stop = 1,427	.num_clks = 2,428	.max_freq = 1000,429	.wait_for_reset = 1,430	.num_bits_resol = 11,431	.pll_p_offset = 13,432	.reg_values = reg_values,433	.pll_fin_min = 6,434	.pll_fin_max = 12,435	.m_min = 41,436	.m_max = 125,437	.min_freq = 500,438	.has_broken_fifoctrl_emptyhdr = 1,439};440 441static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {442	.reg_ofs = exynos_reg_ofs,443	.plltmr_reg = 0x58,444	.num_clks = 2,445	.max_freq = 1000,446	.wait_for_reset = 1,447	.num_bits_resol = 11,448	.pll_p_offset = 13,449	.reg_values = reg_values,450	.pll_fin_min = 6,451	.pll_fin_max = 12,452	.m_min = 41,453	.m_max = 125,454	.min_freq = 500,455};456 457static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {458	.reg_ofs = exynos5433_reg_ofs,459	.plltmr_reg = 0xa0,460	.has_clklane_stop = 1,461	.num_clks = 5,462	.max_freq = 1500,463	.wait_for_reset = 0,464	.num_bits_resol = 12,465	.pll_p_offset = 13,466	.reg_values = exynos5433_reg_values,467	.pll_fin_min = 6,468	.pll_fin_max = 12,469	.m_min = 41,470	.m_max = 125,471	.min_freq = 500,472};473 474static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {475	.reg_ofs = exynos5433_reg_ofs,476	.plltmr_reg = 0xa0,477	.has_clklane_stop = 1,478	.num_clks = 2,479	.max_freq = 1500,480	.wait_for_reset = 1,481	.num_bits_resol = 12,482	.pll_p_offset = 13,483	.reg_values = exynos5422_reg_values,484	.pll_fin_min = 6,485	.pll_fin_max = 12,486	.m_min = 41,487	.m_max = 125,488	.min_freq = 500,489};490 491static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {492	.reg_ofs = exynos5433_reg_ofs,493	.plltmr_reg = 0xa0,494	.has_clklane_stop = 1,495	.num_clks = 2,496	.max_freq = 2100,497	.wait_for_reset = 0,498	.num_bits_resol = 12,499	/*500	 * Unlike Exynos, PLL_P(PMS_P) offset 14 is used in i.MX8M Mini/Nano/Plus501	 * downstream driver - drivers/gpu/drm/bridge/sec-dsim.c502	 */503	.pll_p_offset = 14,504	.reg_values = imx8mm_dsim_reg_values,505	.pll_fin_min = 2,506	.pll_fin_max = 30,507	.m_min = 64,508	.m_max = 1023,509	.min_freq = 1050,510};511 512static const struct samsung_dsim_driver_data *513samsung_dsim_types[DSIM_TYPE_COUNT] = {514	[DSIM_TYPE_EXYNOS3250] = &exynos3_dsi_driver_data,515	[DSIM_TYPE_EXYNOS4210] = &exynos4_dsi_driver_data,516	[DSIM_TYPE_EXYNOS5410] = &exynos5_dsi_driver_data,517	[DSIM_TYPE_EXYNOS5422] = &exynos5422_dsi_driver_data,518	[DSIM_TYPE_EXYNOS5433] = &exynos5433_dsi_driver_data,519	[DSIM_TYPE_IMX8MM] = &imx8mm_dsi_driver_data,520	[DSIM_TYPE_IMX8MP] = &imx8mm_dsi_driver_data,521};522 523static inline struct samsung_dsim *host_to_dsi(struct mipi_dsi_host *h)524{525	return container_of(h, struct samsung_dsim, dsi_host);526}527 528static inline struct samsung_dsim *bridge_to_dsi(struct drm_bridge *b)529{530	return container_of(b, struct samsung_dsim, bridge);531}532 533static inline void samsung_dsim_write(struct samsung_dsim *dsi,534				      enum reg_idx idx, u32 val)535{536	writel(val, dsi->reg_base + dsi->driver_data->reg_ofs[idx]);537}538 539static inline u32 samsung_dsim_read(struct samsung_dsim *dsi, enum reg_idx idx)540{541	return readl(dsi->reg_base + dsi->driver_data->reg_ofs[idx]);542}543 544static void samsung_dsim_wait_for_reset(struct samsung_dsim *dsi)545{546	if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300)))547		return;548 549	dev_err(dsi->dev, "timeout waiting for reset\n");550}551 552static void samsung_dsim_reset(struct samsung_dsim *dsi)553{554	u32 reset_val = dsi->driver_data->reg_values[RESET_TYPE];555 556	reinit_completion(&dsi->completed);557	samsung_dsim_write(dsi, DSIM_SWRST_REG, reset_val);558}559 560#ifndef MHZ561#define MHZ	(1000 * 1000)562#endif563 564static unsigned long samsung_dsim_pll_find_pms(struct samsung_dsim *dsi,565					       unsigned long fin,566					       unsigned long fout,567					       u8 *p, u16 *m, u8 *s)568{569	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;570	unsigned long best_freq = 0;571	u32 min_delta = 0xffffffff;572	u8 p_min, p_max;573	u8 _p, best_p;574	u16 _m, best_m;575	u8 _s, best_s;576 577	p_min = DIV_ROUND_UP(fin, (driver_data->pll_fin_max * MHZ));578	p_max = fin / (driver_data->pll_fin_min * MHZ);579 580	for (_p = p_min; _p <= p_max; ++_p) {581		for (_s = 0; _s <= 5; ++_s) {582			u64 tmp;583			u32 delta;584 585			tmp = (u64)fout * (_p << _s);586			do_div(tmp, fin);587			_m = tmp;588			if (_m < driver_data->m_min || _m > driver_data->m_max)589				continue;590 591			tmp = (u64)_m * fin;592			do_div(tmp, _p);593			if (tmp < driver_data->min_freq  * MHZ ||594			    tmp > driver_data->max_freq * MHZ)595				continue;596 597			tmp = (u64)_m * fin;598			do_div(tmp, _p << _s);599 600			delta = abs(fout - tmp);601			if (delta < min_delta) {602				best_p = _p;603				best_m = _m;604				best_s = _s;605				min_delta = delta;606				best_freq = tmp;607			}608		}609	}610 611	if (best_freq) {612		*p = best_p;613		*m = best_m;614		*s = best_s;615	}616 617	return best_freq;618}619 620static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,621					  unsigned long freq)622{623	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;624	unsigned long fin, fout;625	int timeout;626	u8 p, s;627	u16 m;628	u32 reg;629 630	if (dsi->pll_clk) {631		/*632		 * Ensure that the reference clock is generated with a power of633		 * two divider from its parent, but close to the PLLs upper634		 * limit.635		 */636		fin = clk_get_rate(clk_get_parent(dsi->pll_clk));637		while (fin > driver_data->pll_fin_max * MHZ)638			fin /= 2;639		clk_set_rate(dsi->pll_clk, fin);640 641		fin = clk_get_rate(dsi->pll_clk);642	} else {643		fin = dsi->pll_clk_rate;644	}645	dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin);646 647	fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s);648	if (!fout) {649		dev_err(dsi->dev,650			"failed to find PLL PMS for requested frequency\n");651		return 0;652	}653	dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);654 655	writel(driver_data->reg_values[PLL_TIMER],656	       dsi->reg_base + driver_data->plltmr_reg);657 658	reg = DSIM_PLL_EN | DSIM_PLL_P(p, driver_data->pll_p_offset) |659	      DSIM_PLL_M(m) | DSIM_PLL_S(s);660 661	if (driver_data->has_freqband) {662		static const unsigned long freq_bands[] = {663			100 * MHZ, 120 * MHZ, 160 * MHZ, 200 * MHZ,664			270 * MHZ, 320 * MHZ, 390 * MHZ, 450 * MHZ,665			510 * MHZ, 560 * MHZ, 640 * MHZ, 690 * MHZ,666			770 * MHZ, 870 * MHZ, 950 * MHZ,667		};668		int band;669 670		for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)671			if (fout < freq_bands[band])672				break;673 674		dev_dbg(dsi->dev, "band %d\n", band);675 676		reg |= DSIM_FREQ_BAND(band);677	}678 679	if (dsi->swap_dn_dp_clk)680		reg |= DSIM_PLL_DPDNSWAP_CLK;681	if (dsi->swap_dn_dp_data)682		reg |= DSIM_PLL_DPDNSWAP_DAT;683 684	samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);685 686	timeout = 1000;687	do {688		if (timeout-- == 0) {689			dev_err(dsi->dev, "PLL failed to stabilize\n");690			return 0;691		}692		reg = samsung_dsim_read(dsi, DSIM_STATUS_REG);693	} while ((reg & DSIM_PLL_STABLE) == 0);694 695	dsi->hs_clock = fout;696 697	return fout;698}699 700static int samsung_dsim_enable_clock(struct samsung_dsim *dsi)701{702	unsigned long hs_clk, byte_clk, esc_clk, pix_clk;703	unsigned long esc_div;704	u32 reg;705	struct drm_display_mode *m = &dsi->mode;706	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);707 708	/* m->clock is in KHz */709	pix_clk = m->clock * 1000;710 711	/* Use burst_clk_rate if available, otherwise use the pix_clk */712	if (dsi->burst_clk_rate)713		hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate);714	else715		hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, dsi->lanes));716 717	if (!hs_clk) {718		dev_err(dsi->dev, "failed to configure DSI PLL\n");719		return -EFAULT;720	}721 722	byte_clk = hs_clk / 8;723	esc_div = DIV_ROUND_UP(byte_clk, dsi->esc_clk_rate);724	esc_clk = byte_clk / esc_div;725 726	if (esc_clk > 20 * MHZ) {727		++esc_div;728		esc_clk = byte_clk / esc_div;729	}730 731	dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",732		hs_clk, byte_clk, esc_clk);733 734	reg = samsung_dsim_read(dsi, DSIM_CLKCTRL_REG);735	reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK736			| DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS737			| DSIM_BYTE_CLK_SRC_MASK);738	reg |= DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN739			| DSIM_ESC_PRESCALER(esc_div)740			| DSIM_LANE_ESC_CLK_EN_CLK741			| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1)742			| DSIM_BYTE_CLK_SRC(0)743			| DSIM_TX_REQUEST_HSCLK;744	samsung_dsim_write(dsi, DSIM_CLKCTRL_REG, reg);745 746	return 0;747}748 749static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi)750{751	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;752	const unsigned int *reg_values = driver_data->reg_values;753	u32 reg;754	struct phy_configure_opts_mipi_dphy cfg;755	int clk_prepare, lpx, clk_zero, clk_post, clk_trail;756	int hs_exit, hs_prepare, hs_zero, hs_trail;757	unsigned long long byte_clock = dsi->hs_clock / 8;758 759	if (driver_data->has_freqband)760		return;761 762	phy_mipi_dphy_get_default_config_for_hsclk(dsi->hs_clock,763						   dsi->lanes, &cfg);764 765	/*766	 * TODO:767	 * The tech Applications Processor manuals for i.MX8M Mini, Nano,768	 * and Plus don't state what the definition of the PHYTIMING769	 * bits are beyond their address and bit position.770	 * After reviewing NXP's downstream code, it appears771	 * that the various PHYTIMING registers take the number772	 * of cycles and use various dividers on them.  This773	 * calculation does not result in an exact match to the774	 * downstream code, but it is very close to the values775	 * generated by their lookup table, and it appears776	 * to sync at a variety of resolutions. If someone777	 * can get a more accurate mathematical equation needed778	 * for these registers, this should be updated.779	 */780 781	lpx = PS_TO_CYCLE(cfg.lpx, byte_clock);782	hs_exit = PS_TO_CYCLE(cfg.hs_exit, byte_clock);783	clk_prepare = PS_TO_CYCLE(cfg.clk_prepare, byte_clock);784	clk_zero = PS_TO_CYCLE(cfg.clk_zero, byte_clock);785	clk_post = PS_TO_CYCLE(cfg.clk_post, byte_clock);786	clk_trail = PS_TO_CYCLE(cfg.clk_trail, byte_clock);787	hs_prepare = PS_TO_CYCLE(cfg.hs_prepare, byte_clock);788	hs_zero = PS_TO_CYCLE(cfg.hs_zero, byte_clock);789	hs_trail = PS_TO_CYCLE(cfg.hs_trail, byte_clock);790 791	/* B D-PHY: D-PHY Master & Slave Analog Block control */792	reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |793		reg_values[PHYCTRL_SLEW_UP];794 795	samsung_dsim_write(dsi, DSIM_PHYCTRL_REG, reg);796 797	/*798	 * T LPX: Transmitted length of any Low-Power state period799	 * T HS-EXIT: Time that the transmitter drives LP-11 following a HS800	 *	burst801	 */802 803	reg  = DSIM_PHYTIMING_LPX(lpx) | DSIM_PHYTIMING_HS_EXIT(hs_exit);804 805	samsung_dsim_write(dsi, DSIM_PHYTIMING_REG, reg);806 807	/*808	 * T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00809	 *	Line state immediately before the HS-0 Line state starting the810	 *	HS transmission811	 * T CLK-ZERO: Time that the transmitter drives the HS-0 state prior to812	 *	transmitting the Clock.813	 * T CLK_POST: Time that the transmitter continues to send HS clock814	 *	after the last associated Data Lane has transitioned to LP Mode815	 *	Interval is defined as the period from the end of T HS-TRAIL to816	 *	the beginning of T CLK-TRAIL817	 * T CLK-TRAIL: Time that the transmitter drives the HS-0 state after818	 *	the last payload clock bit of a HS transmission burst819	 */820 821	reg = DSIM_PHYTIMING1_CLK_PREPARE(clk_prepare)	|822	      DSIM_PHYTIMING1_CLK_ZERO(clk_zero)	|823	      DSIM_PHYTIMING1_CLK_POST(clk_post)	|824	      DSIM_PHYTIMING1_CLK_TRAIL(clk_trail);825 826	samsung_dsim_write(dsi, DSIM_PHYTIMING1_REG, reg);827 828	/*829	 * T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00830	 *	Line state immediately before the HS-0 Line state starting the831	 *	HS transmission832	 * T HS-ZERO: Time that the transmitter drives the HS-0 state prior to833	 *	transmitting the Sync sequence.834	 * T HS-TRAIL: Time that the transmitter drives the flipped differential835	 *	state after last payload data bit of a HS transmission burst836	 */837 838	reg = DSIM_PHYTIMING2_HS_PREPARE(hs_prepare) |839	      DSIM_PHYTIMING2_HS_ZERO(hs_zero) |840	      DSIM_PHYTIMING2_HS_TRAIL(hs_trail);841 842	samsung_dsim_write(dsi, DSIM_PHYTIMING2_REG, reg);843}844 845static void samsung_dsim_disable_clock(struct samsung_dsim *dsi)846{847	u32 reg;848 849	reg = samsung_dsim_read(dsi, DSIM_CLKCTRL_REG);850	reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK851			| DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);852	samsung_dsim_write(dsi, DSIM_CLKCTRL_REG, reg);853 854	reg = samsung_dsim_read(dsi, DSIM_PLLCTRL_REG);855	reg &= ~DSIM_PLL_EN;856	samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);857}858 859static void samsung_dsim_enable_lane(struct samsung_dsim *dsi, u32 lane)860{861	u32 reg = samsung_dsim_read(dsi, DSIM_CONFIG_REG);862 863	reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |864			DSIM_LANE_EN(lane));865	samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg);866}867 868static int samsung_dsim_init_link(struct samsung_dsim *dsi)869{870	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;871	int timeout;872	u32 reg;873	u32 lanes_mask;874 875	/* Initialize FIFO pointers */876	reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG);877	reg &= ~0x1f;878	samsung_dsim_write(dsi, DSIM_FIFOCTRL_REG, reg);879 880	usleep_range(9000, 11000);881 882	reg |= 0x1f;883	samsung_dsim_write(dsi, DSIM_FIFOCTRL_REG, reg);884	usleep_range(9000, 11000);885 886	/* DSI configuration */887	reg = 0;888 889	/*890	 * The first bit of mode_flags specifies display configuration.891	 * If this bit is set[= MIPI_DSI_MODE_VIDEO], dsi will support video892	 * mode, otherwise it will support command mode.893	 */894	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {895		reg |= DSIM_VIDEO_MODE;896 897		/*898		 * The user manual describes that following bits are ignored in899		 * command mode.900		 */901		if (!(dsi->mode_flags & MIPI_DSI_MODE_VSYNC_FLUSH))902			reg |= DSIM_MFLUSH_VS;903		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)904			reg |= DSIM_SYNC_INFORM;905		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)906			reg |= DSIM_BURST_MODE;907		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_AUTO_VERT)908			reg |= DSIM_AUTO_MODE;909		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HSE)910			reg |= DSIM_HSE_DISABLE_MODE;911		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)912			reg |= DSIM_HFP_DISABLE_MODE;913		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)914			reg |= DSIM_HBP_DISABLE_MODE;915		if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA)916			reg |= DSIM_HSA_DISABLE_MODE;917	}918 919	if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)920		reg |= DSIM_EOT_DISABLE;921 922	switch (dsi->format) {923	case MIPI_DSI_FMT_RGB888:924		reg |= DSIM_MAIN_PIX_FORMAT_RGB888;925		break;926	case MIPI_DSI_FMT_RGB666:927		reg |= DSIM_MAIN_PIX_FORMAT_RGB666;928		break;929	case MIPI_DSI_FMT_RGB666_PACKED:930		reg |= DSIM_MAIN_PIX_FORMAT_RGB666_P;931		break;932	case MIPI_DSI_FMT_RGB565:933		reg |= DSIM_MAIN_PIX_FORMAT_RGB565;934		break;935	default:936		dev_err(dsi->dev, "invalid pixel format\n");937		return -EINVAL;938	}939 940	/*941	 * Use non-continuous clock mode if the periparal wants and942	 * host controller supports943	 *944	 * In non-continous clock mode, host controller will turn off945	 * the HS clock between high-speed transmissions to reduce946	 * power consumption.947	 */948	if (driver_data->has_clklane_stop &&949	    dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {950		if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type))951			reg |= DSIM_NON_CONTINUOUS_CLKLANE;952 953		reg |= DSIM_CLKLANE_STOP;954	}955	samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg);956 957	lanes_mask = BIT(dsi->lanes) - 1;958	samsung_dsim_enable_lane(dsi, lanes_mask);959 960	/* Check clock and data lane state are stop state */961	timeout = 100;962	do {963		if (timeout-- == 0) {964			dev_err(dsi->dev, "waiting for bus lanes timed out\n");965			return -EFAULT;966		}967 968		reg = samsung_dsim_read(dsi, DSIM_STATUS_REG);969		if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))970		    != DSIM_STOP_STATE_DAT(lanes_mask))971			continue;972	} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));973 974	reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);975	reg &= ~DSIM_STOP_STATE_CNT_MASK;976	reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]);977	samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);978 979	reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);980	samsung_dsim_write(dsi, DSIM_TIMEOUT_REG, reg);981 982	return 0;983}984 985static void samsung_dsim_set_display_mode(struct samsung_dsim *dsi)986{987	struct drm_display_mode *m = &dsi->mode;988	unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;989	u32 reg;990 991	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {992		u64 byte_clk = dsi->hs_clock / 8;993		u64 pix_clk = m->clock * 1000;994 995		int hfp = DIV64_U64_ROUND_UP((m->hsync_start - m->hdisplay) * byte_clk, pix_clk);996		int hbp = DIV64_U64_ROUND_UP((m->htotal - m->hsync_end) * byte_clk, pix_clk);997		int hsa = DIV64_U64_ROUND_UP((m->hsync_end - m->hsync_start) * byte_clk, pix_clk);998 999		/* remove packet overhead when possible */1000		hfp = max(hfp - 6, 0);1001		hbp = max(hbp - 6, 0);1002		hsa = max(hsa - 6, 0);1003 1004		dev_dbg(dsi->dev, "calculated hfp: %u, hbp: %u, hsa: %u",1005			hfp, hbp, hsa);1006 1007		reg = DSIM_CMD_ALLOW(0xf)1008			| DSIM_STABLE_VFP(m->vsync_start - m->vdisplay)1009			| DSIM_MAIN_VBP(m->vtotal - m->vsync_end);1010		samsung_dsim_write(dsi, DSIM_MVPORCH_REG, reg);1011 1012		reg = DSIM_MAIN_HFP(hfp) | DSIM_MAIN_HBP(hbp);1013		samsung_dsim_write(dsi, DSIM_MHPORCH_REG, reg);1014 1015		reg = DSIM_MAIN_VSA(m->vsync_end - m->vsync_start)1016			| DSIM_MAIN_HSA(hsa);1017		samsung_dsim_write(dsi, DSIM_MSYNC_REG, reg);1018	}1019	reg =  DSIM_MAIN_HRESOL(m->hdisplay, num_bits_resol) |1020		DSIM_MAIN_VRESOL(m->vdisplay, num_bits_resol);1021 1022	samsung_dsim_write(dsi, DSIM_MDRESOL_REG, reg);1023 1024	dev_dbg(dsi->dev, "LCD size = %dx%d\n", m->hdisplay, m->vdisplay);1025}1026 1027static void samsung_dsim_set_display_enable(struct samsung_dsim *dsi, bool enable)1028{1029	u32 reg;1030 1031	reg = samsung_dsim_read(dsi, DSIM_MDRESOL_REG);1032	if (enable)1033		reg |= DSIM_MAIN_STAND_BY;1034	else1035		reg &= ~DSIM_MAIN_STAND_BY;1036	samsung_dsim_write(dsi, DSIM_MDRESOL_REG, reg);1037}1038 1039static int samsung_dsim_wait_for_hdr_fifo(struct samsung_dsim *dsi)1040{1041	int timeout = 2000;1042 1043	do {1044		u32 reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG);1045 1046		if (!dsi->driver_data->has_broken_fifoctrl_emptyhdr) {1047			if (reg & DSIM_SFR_HEADER_EMPTY)1048				return 0;1049		} else {1050			if (!(reg & DSIM_SFR_HEADER_FULL)) {1051				/*1052				 * Wait a little bit, so the pending data can1053				 * actually leave the FIFO to avoid overflow.1054				 */1055				if (!cond_resched())1056					usleep_range(950, 1050);1057				return 0;1058			}1059		}1060 1061		if (!cond_resched())1062			usleep_range(950, 1050);1063	} while (--timeout);1064 1065	return -ETIMEDOUT;1066}1067 1068static void samsung_dsim_set_cmd_lpm(struct samsung_dsim *dsi, bool lpm)1069{1070	u32 v = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);1071 1072	if (lpm)1073		v |= DSIM_CMD_LPDT_LP;1074	else1075		v &= ~DSIM_CMD_LPDT_LP;1076 1077	samsung_dsim_write(dsi, DSIM_ESCMODE_REG, v);1078}1079 1080static void samsung_dsim_force_bta(struct samsung_dsim *dsi)1081{1082	u32 v = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);1083 1084	v |= DSIM_FORCE_BTA;1085	samsung_dsim_write(dsi, DSIM_ESCMODE_REG, v);1086}1087 1088static void samsung_dsim_send_to_fifo(struct samsung_dsim *dsi,1089				      struct samsung_dsim_transfer *xfer)1090{1091	struct device *dev = dsi->dev;1092	struct mipi_dsi_packet *pkt = &xfer->packet;1093	const u8 *payload = pkt->payload + xfer->tx_done;1094	u16 length = pkt->payload_length - xfer->tx_done;1095	bool first = !xfer->tx_done;1096	u32 reg;1097 1098	dev_dbg(dev, "< xfer %pK: tx len %u, done %u, rx len %u, done %u\n",1099		xfer, length, xfer->tx_done, xfer->rx_len, xfer->rx_done);1100 1101	if (length > DSI_TX_FIFO_SIZE)1102		length = DSI_TX_FIFO_SIZE;1103 1104	xfer->tx_done += length;1105 1106	/* Send payload */1107	while (length >= 4) {1108		reg = get_unaligned_le32(payload);1109		samsung_dsim_write(dsi, DSIM_PAYLOAD_REG, reg);1110		payload += 4;1111		length -= 4;1112	}1113 1114	reg = 0;1115	switch (length) {1116	case 3:1117		reg |= payload[2] << 16;1118		fallthrough;1119	case 2:1120		reg |= payload[1] << 8;1121		fallthrough;1122	case 1:1123		reg |= payload[0];1124		samsung_dsim_write(dsi, DSIM_PAYLOAD_REG, reg);1125		break;1126	}1127 1128	/* Send packet header */1129	if (!first)1130		return;1131 1132	reg = get_unaligned_le32(pkt->header);1133	if (samsung_dsim_wait_for_hdr_fifo(dsi)) {1134		dev_err(dev, "waiting for header FIFO timed out\n");1135		return;1136	}1137 1138	if (NEQV(xfer->flags & MIPI_DSI_MSG_USE_LPM,1139		 dsi->state & DSIM_STATE_CMD_LPM)) {1140		samsung_dsim_set_cmd_lpm(dsi, xfer->flags & MIPI_DSI_MSG_USE_LPM);1141		dsi->state ^= DSIM_STATE_CMD_LPM;1142	}1143 1144	samsung_dsim_write(dsi, DSIM_PKTHDR_REG, reg);1145 1146	if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)1147		samsung_dsim_force_bta(dsi);1148}1149 1150static void samsung_dsim_read_from_fifo(struct samsung_dsim *dsi,1151					struct samsung_dsim_transfer *xfer)1152{1153	u8 *payload = xfer->rx_payload + xfer->rx_done;1154	bool first = !xfer->rx_done;1155	struct device *dev = dsi->dev;1156	u16 length;1157	u32 reg;1158 1159	if (first) {1160		reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1161 1162		switch (reg & 0x3f) {1163		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:1164		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:1165			if (xfer->rx_len >= 2) {1166				payload[1] = reg >> 16;1167				++xfer->rx_done;1168			}1169			fallthrough;1170		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:1171		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:1172			payload[0] = reg >> 8;1173			++xfer->rx_done;1174			xfer->rx_len = xfer->rx_done;1175			xfer->result = 0;1176			goto clear_fifo;1177		case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:1178			dev_err(dev, "DSI Error Report: 0x%04x\n", (reg >> 8) & 0xffff);1179			xfer->result = 0;1180			goto clear_fifo;1181		}1182 1183		length = (reg >> 8) & 0xffff;1184		if (length > xfer->rx_len) {1185			dev_err(dev,1186				"response too long (%u > %u bytes), stripping\n",1187				xfer->rx_len, length);1188			length = xfer->rx_len;1189		} else if (length < xfer->rx_len) {1190			xfer->rx_len = length;1191		}1192	}1193 1194	length = xfer->rx_len - xfer->rx_done;1195	xfer->rx_done += length;1196 1197	/* Receive payload */1198	while (length >= 4) {1199		reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1200		payload[0] = (reg >>  0) & 0xff;1201		payload[1] = (reg >>  8) & 0xff;1202		payload[2] = (reg >> 16) & 0xff;1203		payload[3] = (reg >> 24) & 0xff;1204		payload += 4;1205		length -= 4;1206	}1207 1208	if (length) {1209		reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1210		switch (length) {1211		case 3:1212			payload[2] = (reg >> 16) & 0xff;1213			fallthrough;1214		case 2:1215			payload[1] = (reg >> 8) & 0xff;1216			fallthrough;1217		case 1:1218			payload[0] = reg & 0xff;1219		}1220	}1221 1222	if (xfer->rx_done == xfer->rx_len)1223		xfer->result = 0;1224 1225clear_fifo:1226	length = DSI_RX_FIFO_SIZE / 4;1227	do {1228		reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1229		if (reg == DSI_RX_FIFO_EMPTY)1230			break;1231	} while (--length);1232}1233 1234static void samsung_dsim_transfer_start(struct samsung_dsim *dsi)1235{1236	unsigned long flags;1237	struct samsung_dsim_transfer *xfer;1238	bool start = false;1239 1240again:1241	spin_lock_irqsave(&dsi->transfer_lock, flags);1242 1243	if (list_empty(&dsi->transfer_list)) {1244		spin_unlock_irqrestore(&dsi->transfer_lock, flags);1245		return;1246	}1247 1248	xfer = list_first_entry(&dsi->transfer_list,1249				struct samsung_dsim_transfer, list);1250 1251	spin_unlock_irqrestore(&dsi->transfer_lock, flags);1252 1253	if (xfer->packet.payload_length &&1254	    xfer->tx_done == xfer->packet.payload_length)1255		/* waiting for RX */1256		return;1257 1258	samsung_dsim_send_to_fifo(dsi, xfer);1259 1260	if (xfer->packet.payload_length || xfer->rx_len)1261		return;1262 1263	xfer->result = 0;1264	complete(&xfer->completed);1265 1266	spin_lock_irqsave(&dsi->transfer_lock, flags);1267 1268	list_del_init(&xfer->list);1269	start = !list_empty(&dsi->transfer_list);1270 1271	spin_unlock_irqrestore(&dsi->transfer_lock, flags);1272 1273	if (start)1274		goto again;1275}1276 1277static bool samsung_dsim_transfer_finish(struct samsung_dsim *dsi)1278{1279	struct samsung_dsim_transfer *xfer;1280	unsigned long flags;1281	bool start = true;1282 1283	spin_lock_irqsave(&dsi->transfer_lock, flags);1284 1285	if (list_empty(&dsi->transfer_list)) {1286		spin_unlock_irqrestore(&dsi->transfer_lock, flags);1287		return false;1288	}1289 1290	xfer = list_first_entry(&dsi->transfer_list,1291				struct samsung_dsim_transfer, list);1292 1293	spin_unlock_irqrestore(&dsi->transfer_lock, flags);1294 1295	dev_dbg(dsi->dev,1296		"> xfer %pK, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",1297		xfer, xfer->packet.payload_length, xfer->tx_done, xfer->rx_len,1298		xfer->rx_done);1299 1300	if (xfer->tx_done != xfer->packet.payload_length)1301		return true;1302 1303	if (xfer->rx_done != xfer->rx_len)1304		samsung_dsim_read_from_fifo(dsi, xfer);1305 1306	if (xfer->rx_done != xfer->rx_len)1307		return true;1308 1309	spin_lock_irqsave(&dsi->transfer_lock, flags);1310 1311	list_del_init(&xfer->list);1312	start = !list_empty(&dsi->transfer_list);1313 1314	spin_unlock_irqrestore(&dsi->transfer_lock, flags);1315 1316	if (!xfer->rx_len)1317		xfer->result = 0;1318	complete(&xfer->completed);1319 1320	return start;1321}1322 1323static void samsung_dsim_remove_transfer(struct samsung_dsim *dsi,1324					 struct samsung_dsim_transfer *xfer)1325{1326	unsigned long flags;1327	bool start;1328 1329	spin_lock_irqsave(&dsi->transfer_lock, flags);1330 1331	if (!list_empty(&dsi->transfer_list) &&1332	    xfer == list_first_entry(&dsi->transfer_list,1333				     struct samsung_dsim_transfer, list)) {1334		list_del_init(&xfer->list);1335		start = !list_empty(&dsi->transfer_list);1336		spin_unlock_irqrestore(&dsi->transfer_lock, flags);1337		if (start)1338			samsung_dsim_transfer_start(dsi);1339		return;1340	}1341 1342	list_del_init(&xfer->list);1343 1344	spin_unlock_irqrestore(&dsi->transfer_lock, flags);1345}1346 1347static int samsung_dsim_transfer(struct samsung_dsim *dsi,1348				 struct samsung_dsim_transfer *xfer)1349{1350	unsigned long flags;1351	bool stopped;1352 1353	xfer->tx_done = 0;1354	xfer->rx_done = 0;1355	xfer->result = -ETIMEDOUT;1356	init_completion(&xfer->completed);1357 1358	spin_lock_irqsave(&dsi->transfer_lock, flags);1359 1360	stopped = list_empty(&dsi->transfer_list);1361	list_add_tail(&xfer->list, &dsi->transfer_list);1362 1363	spin_unlock_irqrestore(&dsi->transfer_lock, flags);1364 1365	if (stopped)1366		samsung_dsim_transfer_start(dsi);1367 1368	wait_for_completion_timeout(&xfer->completed,1369				    msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));1370	if (xfer->result == -ETIMEDOUT) {1371		struct mipi_dsi_packet *pkt = &xfer->packet;1372 1373		samsung_dsim_remove_transfer(dsi, xfer);1374		dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 4, pkt->header,1375			(int)pkt->payload_length, pkt->payload);1376		return -ETIMEDOUT;1377	}1378 1379	/* Also covers hardware timeout condition */1380	return xfer->result;1381}1382 1383static irqreturn_t samsung_dsim_irq(int irq, void *dev_id)1384{1385	struct samsung_dsim *dsi = dev_id;1386	u32 status;1387 1388	status = samsung_dsim_read(dsi, DSIM_INTSRC_REG);1389	if (!status) {1390		static unsigned long j;1391 1392		if (printk_timed_ratelimit(&j, 500))1393			dev_warn(dsi->dev, "spurious interrupt\n");1394		return IRQ_HANDLED;1395	}1396	samsung_dsim_write(dsi, DSIM_INTSRC_REG, status);1397 1398	if (status & DSIM_INT_SW_RST_RELEASE) {1399		unsigned long mask = ~(DSIM_INT_RX_DONE |1400				       DSIM_INT_SFR_FIFO_EMPTY |1401				       DSIM_INT_SFR_HDR_FIFO_EMPTY |1402				       DSIM_INT_RX_ECC_ERR |1403				       DSIM_INT_SW_RST_RELEASE);1404		samsung_dsim_write(dsi, DSIM_INTMSK_REG, mask);1405		complete(&dsi->completed);1406		return IRQ_HANDLED;1407	}1408 1409	if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |1410			DSIM_INT_PLL_STABLE)))1411		return IRQ_HANDLED;1412 1413	if (samsung_dsim_transfer_finish(dsi))1414		samsung_dsim_transfer_start(dsi);1415 1416	return IRQ_HANDLED;1417}1418 1419static void samsung_dsim_enable_irq(struct samsung_dsim *dsi)1420{1421	enable_irq(dsi->irq);1422 1423	if (dsi->te_gpio)1424		enable_irq(gpiod_to_irq(dsi->te_gpio));1425}1426 1427static void samsung_dsim_disable_irq(struct samsung_dsim *dsi)1428{1429	if (dsi->te_gpio)1430		disable_irq(gpiod_to_irq(dsi->te_gpio));1431 1432	disable_irq(dsi->irq);1433}1434 1435static int samsung_dsim_init(struct samsung_dsim *dsi)1436{1437	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;1438 1439	if (dsi->state & DSIM_STATE_INITIALIZED)1440		return 0;1441 1442	samsung_dsim_reset(dsi);1443	samsung_dsim_enable_irq(dsi);1444 1445	if (driver_data->reg_values[RESET_TYPE] == DSIM_FUNCRST)1446		samsung_dsim_enable_lane(dsi, BIT(dsi->lanes) - 1);1447 1448	samsung_dsim_enable_clock(dsi);1449	if (driver_data->wait_for_reset)1450		samsung_dsim_wait_for_reset(dsi);1451	samsung_dsim_set_phy_ctrl(dsi);1452	samsung_dsim_init_link(dsi);1453 1454	dsi->state |= DSIM_STATE_INITIALIZED;1455 1456	return 0;1457}1458 1459static void samsung_dsim_atomic_pre_enable(struct drm_bridge *bridge,1460					   struct drm_bridge_state *old_bridge_state)1461{1462	struct samsung_dsim *dsi = bridge_to_dsi(bridge);1463	int ret;1464 1465	if (dsi->state & DSIM_STATE_ENABLED)1466		return;1467 1468	ret = pm_runtime_resume_and_get(dsi->dev);1469	if (ret < 0) {1470		dev_err(dsi->dev, "failed to enable DSI device.\n");1471		return;1472	}1473 1474	dsi->state |= DSIM_STATE_ENABLED;1475 1476	/*1477	 * For Exynos-DSIM the downstream bridge, or panel are expecting1478	 * the host initialization during DSI transfer.1479	 */1480	if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {1481		ret = samsung_dsim_init(dsi);1482		if (ret)1483			return;1484	}1485}1486 1487static void samsung_dsim_atomic_enable(struct drm_bridge *bridge,1488				       struct drm_bridge_state *old_bridge_state)1489{1490	struct samsung_dsim *dsi = bridge_to_dsi(bridge);1491 1492	samsung_dsim_set_display_mode(dsi);1493	samsung_dsim_set_display_enable(dsi, true);1494 1495	dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;1496}1497 1498static void samsung_dsim_atomic_disable(struct drm_bridge *bridge,1499					struct drm_bridge_state *old_bridge_state)1500{1501	struct samsung_dsim *dsi = bridge_to_dsi(bridge);1502 1503	if (!(dsi->state & DSIM_STATE_ENABLED))1504		return;1505 1506	samsung_dsim_set_display_enable(dsi, false);1507	dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;1508}1509 1510static void samsung_dsim_atomic_post_disable(struct drm_bridge *bridge,1511					     struct drm_bridge_state *old_bridge_state)1512{1513	struct samsung_dsim *dsi = bridge_to_dsi(bridge);1514 1515	dsi->state &= ~DSIM_STATE_ENABLED;1516	pm_runtime_put_sync(dsi->dev);1517}1518 1519/*1520 * This pixel output formats list referenced from,1521 * AN13573 i.MX 8/RT MIPI DSI/CSI-2, Rev. 0, 21 March 20221522 * 3.7.4 Pixel formats1523 * Table 14. DSI pixel packing formats1524 */1525static const u32 samsung_dsim_pixel_output_fmts[] = {1526	MEDIA_BUS_FMT_YUYV10_1X20,1527	MEDIA_BUS_FMT_YUYV12_1X24,1528	MEDIA_BUS_FMT_UYVY8_1X16,1529	MEDIA_BUS_FMT_RGB101010_1X30,1530	MEDIA_BUS_FMT_RGB121212_1X36,1531	MEDIA_BUS_FMT_RGB565_1X16,1532	MEDIA_BUS_FMT_RGB666_1X18,1533	MEDIA_BUS_FMT_RGB888_1X24,1534};1535 1536static bool samsung_dsim_pixel_output_fmt_supported(u32 fmt)1537{1538	int i;1539 1540	if (fmt == MEDIA_BUS_FMT_FIXED)1541		return false;1542 1543	for (i = 0; i < ARRAY_SIZE(samsung_dsim_pixel_output_fmts); i++) {1544		if (samsung_dsim_pixel_output_fmts[i] == fmt)1545			return true;1546	}1547 1548	return false;1549}1550 1551static u32 *1552samsung_dsim_atomic_get_input_bus_fmts(struct drm_bridge *bridge,1553				       struct drm_bridge_state *bridge_state,1554				       struct drm_crtc_state *crtc_state,1555				       struct drm_connector_state *conn_state,1556				       u32 output_fmt,1557				       unsigned int *num_input_fmts)1558{1559	u32 *input_fmts;1560 1561	input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);1562	if (!input_fmts)1563		return NULL;1564 1565	if (!samsung_dsim_pixel_output_fmt_supported(output_fmt))1566		/*1567		 * Some bridge/display drivers are still not able to pass the1568		 * correct format, so handle those pipelines by falling back1569		 * to the default format till the supported formats finalized.1570		 */1571		output_fmt = MEDIA_BUS_FMT_RGB888_1X24;1572 1573	input_fmts[0] = output_fmt;1574	*num_input_fmts = 1;1575 1576	return input_fmts;1577}1578 1579static int samsung_dsim_atomic_check(struct drm_bridge *bridge,1580				     struct drm_bridge_state *bridge_state,1581				     struct drm_crtc_state *crtc_state,1582				     struct drm_connector_state *conn_state)1583{1584	struct samsung_dsim *dsi = bridge_to_dsi(bridge);1585	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;1586 1587	/*1588	 * The i.MX8M Mini/Nano glue logic between LCDIF and DSIM1589	 * inverts HS/VS/DE sync signals polarity, therefore, while1590	 * i.MX 8M Mini Applications Processor Reference Manual Rev. 3, 11/20201591	 * 13.6.3.5.2 RGB interface1592	 * i.MX 8M Nano Applications Processor Reference Manual Rev. 2, 07/20221593	 * 13.6.2.7.2 RGB interface1594	 * both claim "Vsync, Hsync, and VDEN are active high signals.", the1595	 * LCDIF must generate inverted HS/VS/DE signals, i.e. active LOW.1596	 *1597	 * The i.MX8M Plus glue logic between LCDIFv3 and DSIM does not1598	 * implement the same behavior, therefore LCDIFv3 must generate1599	 * HS/VS/DE signals active HIGH.1600	 */1601	if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM) {1602		adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);1603		adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);1604	} else if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MP) {1605		adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);1606		adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);1607	}1608 1609	/*1610	 * When using video sync pulses, the HFP, HBP, and HSA are divided between1611	 * the available lanes if there is more than one lane.  For certain1612	 * timings and lane configurations, the HFP may not be evenly divisible.1613	 * If the HFP is rounded down, it ends up being too small which can cause1614	 * some monitors to not sync properly. In these instances, adjust htotal1615	 * and hsync to round the HFP up, and recalculate the htotal. Through trial1616	 * and error, it appears that the HBP and HSA do not appearto need the same1617	 * correction that HFP does.1618	 */1619	if (dsi->lanes > 1) {1620		int hfp = adjusted_mode->hsync_start - adjusted_mode->hdisplay;1621		int remainder = hfp % dsi->lanes;1622 1623		if (remainder) {1624			adjusted_mode->hsync_start += remainder;1625			adjusted_mode->hsync_end   += remainder;1626			adjusted_mode->htotal      += remainder;1627		}1628	}1629 1630	return 0;1631}1632 1633static void samsung_dsim_mode_set(struct drm_bridge *bridge,1634				  const struct drm_display_mode *mode,1635				  const struct drm_display_mode *adjusted_mode)1636{1637	struct samsung_dsim *dsi = bridge_to_dsi(bridge);1638 1639	drm_mode_copy(&dsi->mode, adjusted_mode);1640}1641 1642static int samsung_dsim_attach(struct drm_bridge *bridge,1643			       enum drm_bridge_attach_flags flags)1644{1645	struct samsung_dsim *dsi = bridge_to_dsi(bridge);1646 1647	return drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge,1648				 flags);1649}1650 1651static const struct drm_bridge_funcs samsung_dsim_bridge_funcs = {1652	.atomic_duplicate_state		= drm_atomic_helper_bridge_duplicate_state,1653	.atomic_destroy_state		= drm_atomic_helper_bridge_destroy_state,1654	.atomic_reset			= drm_atomic_helper_bridge_reset,1655	.atomic_get_input_bus_fmts	= samsung_dsim_atomic_get_input_bus_fmts,1656	.atomic_check			= samsung_dsim_atomic_check,1657	.atomic_pre_enable		= samsung_dsim_atomic_pre_enable,1658	.atomic_enable			= samsung_dsim_atomic_enable,1659	.atomic_disable			= samsung_dsim_atomic_disable,1660	.atomic_post_disable		= samsung_dsim_atomic_post_disable,1661	.mode_set			= samsung_dsim_mode_set,1662	.attach				= samsung_dsim_attach,1663};1664 1665static irqreturn_t samsung_dsim_te_irq_handler(int irq, void *dev_id)1666{1667	struct samsung_dsim *dsi = (struct samsung_dsim *)dev_id;1668	const struct samsung_dsim_plat_data *pdata = dsi->plat_data;1669 1670	if (pdata->host_ops && pdata->host_ops->te_irq_handler)1671		return pdata->host_ops->te_irq_handler(dsi);1672 1673	return IRQ_HANDLED;1674}1675 1676static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device *dev)1677{1678	int te_gpio_irq;1679	int ret;1680 1681	dsi->te_gpio = devm_gpiod_get_optional(dev, "te", GPIOD_IN);1682	if (!dsi->te_gpio)1683		return 0;1684	else if (IS_ERR(dsi->te_gpio))1685		return dev_err_probe(dev, PTR_ERR(dsi->te_gpio), "failed to get te GPIO\n");1686 1687	te_gpio_irq = gpiod_to_irq(dsi->te_gpio);1688 1689	ret = request_threaded_irq(te_gpio_irq, samsung_dsim_te_irq_handler, NULL,1690				   IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, "TE", dsi);1691	if (ret) {1692		dev_err(dsi->dev, "request interrupt failed with %d\n", ret);1693		gpiod_put(dsi->te_gpio);1694		return ret;1695	}1696 1697	return 0;1698}1699 1700static int samsung_dsim_host_attach(struct mipi_dsi_host *host,1701				    struct mipi_dsi_device *device)1702{1703	struct samsung_dsim *dsi = host_to_dsi(host);1704	const struct samsung_dsim_plat_data *pdata = dsi->plat_data;1705	struct device *dev = dsi->dev;1706	struct device_node *np = dev->of_node;1707	struct device_node *remote;1708	struct drm_panel *panel;1709	int ret;1710 1711	/*1712	 * Devices can also be child nodes when we also control that device1713	 * through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).1714	 *1715	 * Lookup for a child node of the given parent that isn't either port1716	 * or ports.1717	 */1718	for_each_available_child_of_node(np, remote) {1719		if (of_node_name_eq(remote, "port") ||1720		    of_node_name_eq(remote, "ports"))1721			continue;1722 1723		goto of_find_panel_or_bridge;1724	}1725 1726	/*1727	 * of_graph_get_remote_node() produces a noisy error message if port1728	 * node isn't found and the absence of the port is a legit case here,1729	 * so at first we silently check whether graph presents in the1730	 * device-tree node.1731	 */1732	if (!of_graph_is_present(np))1733		return -ENODEV;1734 1735	remote = of_graph_get_remote_node(np, 1, 0);1736 1737of_find_panel_or_bridge:1738	if (!remote)1739		return -ENODEV;1740 1741	panel = of_drm_find_panel(remote);1742	if (!IS_ERR(panel)) {1743		dsi->out_bridge = devm_drm_panel_bridge_add(dev, panel);1744	} else {1745		dsi->out_bridge = of_drm_find_bridge(remote);1746		if (!dsi->out_bridge)1747			dsi->out_bridge = ERR_PTR(-EINVAL);1748	}1749 1750	of_node_put(remote);1751 1752	if (IS_ERR(dsi->out_bridge)) {1753		ret = PTR_ERR(dsi->out_bridge);1754		DRM_DEV_ERROR(dev, "failed to find the bridge: %d\n", ret);1755		return ret;1756	}1757 1758	DRM_DEV_INFO(dev, "Attached %s device (lanes:%d bpp:%d mode-flags:0x%lx)\n",1759		     device->name, device->lanes,1760		     mipi_dsi_pixel_format_to_bpp(device->format),1761		     device->mode_flags);1762 1763	drm_bridge_add(&dsi->bridge);1764 1765	/*1766	 * This is a temporary solution and should be made by more generic way.1767	 *1768	 * If attached panel device is for command mode one, dsi should register1769	 * TE interrupt handler.1770	 */1771	if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {1772		ret = samsung_dsim_register_te_irq(dsi, &device->dev);1773		if (ret)1774			return ret;1775	}1776 1777	if (pdata->host_ops && pdata->host_ops->attach) {1778		ret = pdata->host_ops->attach(dsi, device);1779		if (ret)1780			return ret;1781	}1782 1783	dsi->lanes = device->lanes;1784	dsi->format = device->format;1785	dsi->mode_flags = device->mode_flags;1786 1787	return 0;1788}1789 1790static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)1791{1792	if (dsi->te_gpio) {1793		free_irq(gpiod_to_irq(dsi->te_gpio), dsi);1794		gpiod_put(dsi->te_gpio);1795	}1796}1797 1798static int samsung_dsim_host_detach(struct mipi_dsi_host *host,1799				    struct mipi_dsi_device *device)1800{1801	struct samsung_dsim *dsi = host_to_dsi(host);1802	const struct samsung_dsim_plat_data *pdata = dsi->plat_data;1803 1804	dsi->out_bridge = NULL;1805 1806	if (pdata->host_ops && pdata->host_ops->detach)1807		pdata->host_ops->detach(dsi, device);1808 1809	samsung_dsim_unregister_te_irq(dsi);1810 1811	drm_bridge_remove(&dsi->bridge);1812 1813	return 0;1814}1815 1816static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host,1817					  const struct mipi_dsi_msg *msg)1818{1819	struct samsung_dsim *dsi = host_to_dsi(host);1820	struct samsung_dsim_transfer xfer;1821	int ret;1822 1823	if (!(dsi->state & DSIM_STATE_ENABLED))1824		return -EINVAL;1825 1826	ret = samsung_dsim_init(dsi);1827	if (ret)1828		return ret;1829 1830	ret = mipi_dsi_create_packet(&xfer.packet, msg);1831	if (ret < 0)1832		return ret;1833 1834	xfer.rx_len = msg->rx_len;1835	xfer.rx_payload = msg->rx_buf;1836	xfer.flags = msg->flags;1837 1838	ret = samsung_dsim_transfer(dsi, &xfer);1839	return (ret < 0) ? ret : xfer.rx_done;1840}1841 1842static const struct mipi_dsi_host_ops samsung_dsim_ops = {1843	.attach = samsung_dsim_host_attach,1844	.detach = samsung_dsim_host_detach,1845	.transfer = samsung_dsim_host_transfer,1846};1847 1848static int samsung_dsim_of_read_u32(const struct device_node *np,1849				    const char *propname, u32 *out_value, bool optional)1850{1851	int ret = of_property_read_u32(np, propname, out_value);1852 1853	if (ret < 0 && !optional)1854		pr_err("%pOF: failed to get '%s' property\n", np, propname);1855 1856	return ret;1857}1858 1859static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)1860{1861	struct device *dev = dsi->dev;1862	struct device_node *node = dev->of_node;1863	u32 lane_polarities[5] = { 0 };1864	struct device_node *endpoint;1865	int i, nr_lanes, ret;1866 1867	ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",1868				       &dsi->pll_clk_rate, 1);1869	/* If it doesn't exist, read it from the clock instead of failing */1870	if (ret < 0) {1871		dev_dbg(dev, "Using sclk_mipi for pll clock frequency\n");1872		dsi->pll_clk = devm_clk_get(dev, "sclk_mipi");1873		if (IS_ERR(dsi->pll_clk))1874			return PTR_ERR(dsi->pll_clk);1875	}1876 1877	/* If it doesn't exist, use pixel clock instead of failing */1878	ret = samsung_dsim_of_read_u32(node, "samsung,burst-clock-frequency",1879				       &dsi->burst_clk_rate, 1);1880	if (ret < 0) {1881		dev_dbg(dev, "Using pixel clock for HS clock frequency\n");1882		dsi->burst_clk_rate = 0;1883	}1884 1885	ret = samsung_dsim_of_read_u32(node, "samsung,esc-clock-frequency",1886				       &dsi->esc_clk_rate, 0);1887	if (ret < 0)1888		return ret;1889 1890	endpoint = of_graph_get_endpoint_by_regs(node, 1, -1);1891	nr_lanes = of_property_count_u32_elems(endpoint, "data-lanes");1892	if (nr_lanes > 0 && nr_lanes <= 4) {1893		/* Polarity 0 is clock lane, 1..4 are data lanes. */1894		of_property_read_u32_array(endpoint, "lane-polarities",1895					   lane_polarities, nr_lanes + 1);1896		for (i = 1; i <= nr_lanes; i++) {1897			if (lane_polarities[1] != lane_polarities[i])1898				DRM_DEV_ERROR(dsi->dev, "Data lanes polarities do not match");1899		}1900		if (lane_polarities[0])1901			dsi->swap_dn_dp_clk = true;1902		if (lane_polarities[1])1903			dsi->swap_dn_dp_data = true;1904	}1905 1906	return 0;1907}1908 1909static int generic_dsim_register_host(struct samsung_dsim *dsi)1910{1911	return mipi_dsi_host_register(&dsi->dsi_host);1912}1913 1914static void generic_dsim_unregister_host(struct samsung_dsim *dsi)1915{1916	mipi_dsi_host_unregister(&dsi->dsi_host);1917}1918 1919static const struct samsung_dsim_host_ops generic_dsim_host_ops = {1920	.register_host = generic_dsim_register_host,1921	.unregister_host = generic_dsim_unregister_host,1922};1923 1924static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_high = {1925	.input_bus_flags = DRM_BUS_FLAG_DE_HIGH,1926};1927 1928static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_low = {1929	.input_bus_flags = DRM_BUS_FLAG_DE_LOW,1930};1931 1932int samsung_dsim_probe(struct platform_device *pdev)1933{1934	struct device *dev = &pdev->dev;1935	struct samsung_dsim *dsi;1936	int ret, i;1937 1938	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);1939	if (!dsi)1940		return -ENOMEM;1941 1942	init_completion(&dsi->completed);1943	spin_lock_init(&dsi->transfer_lock);1944	INIT_LIST_HEAD(&dsi->transfer_list);1945 1946	dsi->dsi_host.ops = &samsung_dsim_ops;1947	dsi->dsi_host.dev = dev;1948 1949	dsi->dev = dev;1950	dsi->plat_data = of_device_get_match_data(dev);1951	dsi->driver_data = samsung_dsim_types[dsi->plat_data->hw_type];1952 1953	dsi->supplies[0].supply = "vddcore";1954	dsi->supplies[1].supply = "vddio";1955	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies),1956				      dsi->supplies);1957	if (ret)1958		return dev_err_probe(dev, ret, "failed to get regulators\n");1959 1960	dsi->clks = devm_kcalloc(dev, dsi->driver_data->num_clks,1961				 sizeof(*dsi->clks), GFP_KERNEL);1962	if (!dsi->clks)1963		return -ENOMEM;1964 1965	for (i = 0; i < dsi->driver_data->num_clks; i++) {1966		dsi->clks[i] = devm_clk_get(dev, clk_names[i]);1967		if (IS_ERR(dsi->clks[i])) {1968			if (strcmp(clk_names[i], "sclk_mipi") == 0) {1969				dsi->clks[i] = devm_clk_get(dev, OLD_SCLK_MIPI_CLK_NAME);1970				if (!IS_ERR(dsi->clks[i]))1971					continue;1972			}1973 1974			dev_info(dev, "failed to get the clock: %s\n", clk_names[i]);1975			return PTR_ERR(dsi->clks[i]);1976		}1977	}1978 1979	dsi->reg_base = devm_platform_ioremap_resource(pdev, 0);1980	if (IS_ERR(dsi->reg_base))1981		return PTR_ERR(dsi->reg_base);1982 1983	dsi->phy = devm_phy_optional_get(dev, "dsim");1984	if (IS_ERR(dsi->phy)) {1985		dev_info(dev, "failed to get dsim phy\n");1986		return PTR_ERR(dsi->phy);1987	}1988 1989	dsi->irq = platform_get_irq(pdev, 0);1990	if (dsi->irq < 0)1991		return dsi->irq;1992 1993	ret = devm_request_threaded_irq(dev, dsi->irq, NULL,1994					samsung_dsim_irq,1995					IRQF_ONESHOT | IRQF_NO_AUTOEN,1996					dev_name(dev), dsi);1997	if (ret) {1998		dev_err(dev, "failed to request dsi irq\n");1999		return ret;2000	}2001 2002	ret = samsung_dsim_parse_dt(dsi);2003	if (ret)2004		return ret;2005 2006	platform_set_drvdata(pdev, dsi);2007 2008	pm_runtime_enable(dev);2009 2010	dsi->bridge.funcs = &samsung_dsim_bridge_funcs;2011	dsi->bridge.of_node = dev->of_node;2012	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;2013 2014	/* DE_LOW: i.MX8M Mini/Nano LCDIF-DSIM glue logic inverts HS/VS/DE */2015	if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM)2016		dsi->bridge.timings = &samsung_dsim_bridge_timings_de_low;2017	else2018		dsi->bridge.timings = &samsung_dsim_bridge_timings_de_high;2019 2020	if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->register_host) {2021		ret = dsi->plat_data->host_ops->register_host(dsi);2022		if (ret)2023			goto err_disable_runtime;2024	}2025 2026	return 0;2027 2028err_disable_runtime:2029	pm_runtime_disable(dev);2030 2031	return ret;2032}2033EXPORT_SYMBOL_GPL(samsung_dsim_probe);2034 2035void samsung_dsim_remove(struct platform_device *pdev)2036{2037	struct samsung_dsim *dsi = platform_get_drvdata(pdev);2038 2039	pm_runtime_disable(&pdev->dev);2040 2041	if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->unregister_host)2042		dsi->plat_data->host_ops->unregister_host(dsi);2043}2044EXPORT_SYMBOL_GPL(samsung_dsim_remove);2045 2046static int __maybe_unused samsung_dsim_suspend(struct device *dev)2047{2048	struct samsung_dsim *dsi = dev_get_drvdata(dev);2049	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;2050	int ret, i;2051 2052	usleep_range(10000, 20000);2053 2054	if (dsi->state & DSIM_STATE_INITIALIZED) {2055		dsi->state &= ~DSIM_STATE_INITIALIZED;2056 2057		samsung_dsim_disable_clock(dsi);2058 2059		samsung_dsim_disable_irq(dsi);2060	}2061 2062	dsi->state &= ~DSIM_STATE_CMD_LPM;2063 2064	phy_power_off(dsi->phy);2065 2066	for (i = driver_data->num_clks - 1; i > -1; i--)2067		clk_disable_unprepare(dsi->clks[i]);2068 2069	ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);2070	if (ret < 0)2071		dev_err(dsi->dev, "cannot disable regulators %d\n", ret);2072 2073	return 0;2074}2075 2076static int __maybe_unused samsung_dsim_resume(struct device *dev)2077{2078	struct samsung_dsim *dsi = dev_get_drvdata(dev);2079	const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;2080	int ret, i;2081 2082	ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);2083	if (ret < 0) {2084		dev_err(dsi->dev, "cannot enable regulators %d\n", ret);2085		return ret;2086	}2087 2088	for (i = 0; i < driver_data->num_clks; i++) {2089		ret = clk_prepare_enable(dsi->clks[i]);2090		if (ret < 0)2091			goto err_clk;2092	}2093 2094	ret = phy_power_on(dsi->phy);2095	if (ret < 0) {2096		dev_err(dsi->dev, "cannot enable phy %d\n", ret);2097		goto err_clk;2098	}2099 2100	return 0;2101 2102err_clk:2103	while (--i > -1)2104		clk_disable_unprepare(dsi->clks[i]);2105	regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);2106 2107	return ret;2108}2109 2110const struct dev_pm_ops samsung_dsim_pm_ops = {2111	SET_RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL)2112	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,2113				pm_runtime_force_resume)2114};2115EXPORT_SYMBOL_GPL(samsung_dsim_pm_ops);2116 2117static const struct samsung_dsim_plat_data samsung_dsim_imx8mm_pdata = {2118	.hw_type = DSIM_TYPE_IMX8MM,2119	.host_ops = &generic_dsim_host_ops,2120};2121 2122static const struct samsung_dsim_plat_data samsung_dsim_imx8mp_pdata = {2123	.hw_type = DSIM_TYPE_IMX8MP,2124	.host_ops = &generic_dsim_host_ops,2125};2126 2127static const struct of_device_id samsung_dsim_of_match[] = {2128	{2129		.compatible = "fsl,imx8mm-mipi-dsim",2130		.data = &samsung_dsim_imx8mm_pdata,2131	},2132	{2133		.compatible = "fsl,imx8mp-mipi-dsim",2134		.data = &samsung_dsim_imx8mp_pdata,2135	},2136	{ /* sentinel. */ }2137};2138MODULE_DEVICE_TABLE(of, samsung_dsim_of_match);2139 2140static struct platform_driver samsung_dsim_driver = {2141	.probe = samsung_dsim_probe,2142	.remove_new = samsung_dsim_remove,2143	.driver = {2144		   .name = "samsung-dsim",2145		   .pm = &samsung_dsim_pm_ops,2146		   .of_match_table = samsung_dsim_of_match,2147	},2148};2149 2150module_platform_driver(samsung_dsim_driver);2151 2152MODULE_AUTHOR("Jagan Teki <jagan@amarulasolutions.com>");2153MODULE_DESCRIPTION("Samsung MIPI DSIM controller bridge");2154MODULE_LICENSE("GPL");2155