Path: blob/master/drivers/gpu/drm/bridge/samsung-dsim.c
26494 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Samsung MIPI DSIM bridge driver.3*4* Copyright (C) 2021 Amarula Solutions(India)5* Copyright (c) 2014 Samsung Electronics Co., Ltd6* Author: Jagan Teki <[email protected]>7*8* Based on exynos_drm_dsi from9* Tomasz Figa <[email protected]>10*/1112#include <linux/unaligned.h>1314#include <linux/clk.h>15#include <linux/delay.h>16#include <linux/export.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#include <linux/units.h>2324#include <video/mipi_display.h>2526#include <drm/bridge/samsung-dsim.h>27#include <drm/drm_panel.h>28#include <drm/drm_print.h>2930/* returns true iff both arguments logically differs */31#define NEQV(a, b) (!(a) ^ !(b))3233/* DSIM_STATUS */34#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)35#define DSIM_STOP_STATE_CLK BIT(8)36#define DSIM_TX_READY_HS_CLK BIT(10)37#define DSIM_PLL_STABLE BIT(31)3839/* DSIM_SWRST */40#define DSIM_FUNCRST BIT(16)41#define DSIM_SWRST BIT(0)4243/* DSIM_TIMEOUT */44#define DSIM_LPDR_TIMEOUT(x) ((x) << 0)45#define DSIM_BTA_TIMEOUT(x) ((x) << 16)4647/* DSIM_CLKCTRL */48#define DSIM_ESC_PRESCALER(x) (((x) & 0xffff) << 0)49#define DSIM_ESC_PRESCALER_MASK (0xffff << 0)50#define DSIM_LANE_ESC_CLK_EN_CLK BIT(19)51#define DSIM_LANE_ESC_CLK_EN_DATA(x) (((x) & 0xf) << 20)52#define DSIM_LANE_ESC_CLK_EN_DATA_MASK (0xf << 20)53#define DSIM_BYTE_CLKEN BIT(24)54#define DSIM_BYTE_CLK_SRC(x) (((x) & 0x3) << 25)55#define DSIM_BYTE_CLK_SRC_MASK (0x3 << 25)56#define DSIM_PLL_BYPASS BIT(27)57#define DSIM_ESC_CLKEN BIT(28)58#define DSIM_TX_REQUEST_HSCLK BIT(31)5960/* DSIM_CONFIG */61#define DSIM_LANE_EN_CLK BIT(0)62#define DSIM_LANE_EN(x) (((x) & 0xf) << 1)63#define DSIM_NUM_OF_DATA_LANE(x) (((x) & 0x3) << 5)64#define DSIM_SUB_PIX_FORMAT(x) (((x) & 0x7) << 8)65#define DSIM_MAIN_PIX_FORMAT_MASK (0x7 << 12)66#define DSIM_MAIN_PIX_FORMAT_RGB888 (0x7 << 12)67#define DSIM_MAIN_PIX_FORMAT_RGB666 (0x6 << 12)68#define DSIM_MAIN_PIX_FORMAT_RGB666_P (0x5 << 12)69#define DSIM_MAIN_PIX_FORMAT_RGB565 (0x4 << 12)70#define DSIM_SUB_VC (((x) & 0x3) << 16)71#define DSIM_MAIN_VC (((x) & 0x3) << 18)72#define DSIM_HSA_DISABLE_MODE BIT(20)73#define DSIM_HBP_DISABLE_MODE BIT(21)74#define DSIM_HFP_DISABLE_MODE BIT(22)75/*76* The i.MX 8M Mini Applications Processor Reference Manual,77* Rev. 3, 11/2020 Page 409178* The i.MX 8M Nano Applications Processor Reference Manual,79* Rev. 2, 07/2022 Page 305880* The i.MX 8M Plus Applications Processor Reference Manual,81* Rev. 1, 06/2021 Page 543682* all claims this bit is 'HseDisableMode' with the definition83* 0 = Disables transfer84* 1 = Enables transfer85*86* This clearly states that HSE is not a disabled bit.87*88* The naming convention follows as per the manual and the89* driver logic is based on the MIPI_DSI_MODE_VIDEO_HSE flag.90*/91#define DSIM_HSE_DISABLE_MODE BIT(23)92#define DSIM_AUTO_MODE BIT(24)93#define DSIM_VIDEO_MODE BIT(25)94#define DSIM_BURST_MODE BIT(26)95#define DSIM_SYNC_INFORM BIT(27)96#define DSIM_EOT_DISABLE BIT(28)97#define DSIM_MFLUSH_VS BIT(29)98/* This flag is valid only for exynos3250/3472/5260/5430 */99#define DSIM_CLKLANE_STOP BIT(30)100#define DSIM_NON_CONTINUOUS_CLKLANE BIT(31)101102/* DSIM_ESCMODE */103#define DSIM_TX_TRIGGER_RST BIT(4)104#define DSIM_TX_LPDT_LP BIT(6)105#define DSIM_CMD_LPDT_LP BIT(7)106#define DSIM_FORCE_BTA BIT(16)107#define DSIM_FORCE_STOP_STATE BIT(20)108#define DSIM_STOP_STATE_CNT(x) (((x) & 0x7ff) << 21)109#define DSIM_STOP_STATE_CNT_MASK (0x7ff << 21)110111/* DSIM_MDRESOL */112#define DSIM_MAIN_STAND_BY BIT(31)113#define DSIM_MAIN_VRESOL(x, num_bits) (((x) & ((1 << (num_bits)) - 1)) << 16)114#define DSIM_MAIN_HRESOL(x, num_bits) (((x) & ((1 << (num_bits)) - 1)) << 0)115116/* DSIM_MVPORCH */117#define DSIM_CMD_ALLOW(x) ((x) << 28)118#define DSIM_STABLE_VFP(x) ((x) << 16)119#define DSIM_MAIN_VBP(x) ((x) << 0)120#define DSIM_CMD_ALLOW_MASK (0xf << 28)121#define DSIM_STABLE_VFP_MASK (0x7ff << 16)122#define DSIM_MAIN_VBP_MASK (0x7ff << 0)123124/* DSIM_MHPORCH */125#define DSIM_MAIN_HFP(x) ((x) << 16)126#define DSIM_MAIN_HBP(x) ((x) << 0)127#define DSIM_MAIN_HFP_MASK ((0xffff) << 16)128#define DSIM_MAIN_HBP_MASK ((0xffff) << 0)129130/* DSIM_MSYNC */131#define DSIM_MAIN_VSA(x) ((x) << 22)132#define DSIM_MAIN_HSA(x) ((x) << 0)133#define DSIM_MAIN_VSA_MASK ((0x3ff) << 22)134#define DSIM_MAIN_HSA_MASK ((0xffff) << 0)135136/* DSIM_SDRESOL */137#define DSIM_SUB_STANDY(x) ((x) << 31)138#define DSIM_SUB_VRESOL(x) ((x) << 16)139#define DSIM_SUB_HRESOL(x) ((x) << 0)140#define DSIM_SUB_STANDY_MASK ((0x1) << 31)141#define DSIM_SUB_VRESOL_MASK ((0x7ff) << 16)142#define DSIM_SUB_HRESOL_MASK ((0x7ff) << 0)143144/* DSIM_INTSRC */145#define DSIM_INT_PLL_STABLE BIT(31)146#define DSIM_INT_SW_RST_RELEASE BIT(30)147#define DSIM_INT_SFR_FIFO_EMPTY BIT(29)148#define DSIM_INT_SFR_HDR_FIFO_EMPTY BIT(28)149#define DSIM_INT_BTA BIT(25)150#define DSIM_INT_FRAME_DONE BIT(24)151#define DSIM_INT_RX_TIMEOUT BIT(21)152#define DSIM_INT_BTA_TIMEOUT BIT(20)153#define DSIM_INT_RX_DONE BIT(18)154#define DSIM_INT_RX_TE BIT(17)155#define DSIM_INT_RX_ACK BIT(16)156#define DSIM_INT_RX_ECC_ERR BIT(15)157#define DSIM_INT_RX_CRC_ERR BIT(14)158159/* DSIM_FIFOCTRL */160#define DSIM_RX_DATA_FULL BIT(25)161#define DSIM_RX_DATA_EMPTY BIT(24)162#define DSIM_SFR_HEADER_FULL BIT(23)163#define DSIM_SFR_HEADER_EMPTY BIT(22)164#define DSIM_SFR_PAYLOAD_FULL BIT(21)165#define DSIM_SFR_PAYLOAD_EMPTY BIT(20)166#define DSIM_I80_HEADER_FULL BIT(19)167#define DSIM_I80_HEADER_EMPTY BIT(18)168#define DSIM_I80_PAYLOAD_FULL BIT(17)169#define DSIM_I80_PAYLOAD_EMPTY BIT(16)170#define DSIM_SD_HEADER_FULL BIT(15)171#define DSIM_SD_HEADER_EMPTY BIT(14)172#define DSIM_SD_PAYLOAD_FULL BIT(13)173#define DSIM_SD_PAYLOAD_EMPTY BIT(12)174#define DSIM_MD_HEADER_FULL BIT(11)175#define DSIM_MD_HEADER_EMPTY BIT(10)176#define DSIM_MD_PAYLOAD_FULL BIT(9)177#define DSIM_MD_PAYLOAD_EMPTY BIT(8)178#define DSIM_RX_FIFO BIT(4)179#define DSIM_SFR_FIFO BIT(3)180#define DSIM_I80_FIFO BIT(2)181#define DSIM_SD_FIFO BIT(1)182#define DSIM_MD_FIFO BIT(0)183184/* DSIM_PHYACCHR */185#define DSIM_AFC_EN BIT(14)186#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)187188/* DSIM_PLLCTRL */189#define DSIM_PLL_DPDNSWAP_CLK (1 << 25)190#define DSIM_PLL_DPDNSWAP_DAT (1 << 24)191#define DSIM_FREQ_BAND(x) ((x) << 24)192#define DSIM_PLL_EN BIT(23)193#define DSIM_PLL_P(x, offset) ((x) << (offset))194#define DSIM_PLL_M(x) ((x) << 4)195#define DSIM_PLL_S(x) ((x) << 1)196197/* DSIM_PHYCTRL */198#define DSIM_PHYCTRL_ULPS_EXIT(x) (((x) & 0x1ff) << 0)199#define DSIM_PHYCTRL_B_DPHYCTL_VREG_LP BIT(30)200#define DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP BIT(14)201202/* DSIM_PHYTIMING */203#define DSIM_PHYTIMING_LPX(x) ((x) << 8)204#define DSIM_PHYTIMING_HS_EXIT(x) ((x) << 0)205206/* DSIM_PHYTIMING1 */207#define DSIM_PHYTIMING1_CLK_PREPARE(x) ((x) << 24)208#define DSIM_PHYTIMING1_CLK_ZERO(x) ((x) << 16)209#define DSIM_PHYTIMING1_CLK_POST(x) ((x) << 8)210#define DSIM_PHYTIMING1_CLK_TRAIL(x) ((x) << 0)211212/* DSIM_PHYTIMING2 */213#define DSIM_PHYTIMING2_HS_PREPARE(x) ((x) << 16)214#define DSIM_PHYTIMING2_HS_ZERO(x) ((x) << 8)215#define DSIM_PHYTIMING2_HS_TRAIL(x) ((x) << 0)216217#define DSI_MAX_BUS_WIDTH 4218#define DSI_NUM_VIRTUAL_CHANNELS 4219#define DSI_TX_FIFO_SIZE 2048220#define DSI_RX_FIFO_SIZE 256221#define DSI_XFER_TIMEOUT_MS 100222#define DSI_RX_FIFO_EMPTY 0x30800002223224#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"225226#define PS_TO_CYCLE(ps, hz) DIV64_U64_ROUND_CLOSEST(((ps) * (hz)), 1000000000000ULL)227228static const char *const clk_names[5] = {229"bus_clk",230"sclk_mipi",231"phyclk_mipidphy0_bitclkdiv8",232"phyclk_mipidphy0_rxclkesc0",233"sclk_rgb_vclk_to_dsim0"234};235236enum samsung_dsim_transfer_type {237EXYNOS_DSI_TX,238EXYNOS_DSI_RX,239};240241enum reg_idx {242DSIM_STATUS_REG, /* Status register */243DSIM_SWRST_REG, /* Software reset register */244DSIM_CLKCTRL_REG, /* Clock control register */245DSIM_TIMEOUT_REG, /* Time out register */246DSIM_CONFIG_REG, /* Configuration register */247DSIM_ESCMODE_REG, /* Escape mode register */248DSIM_MDRESOL_REG,249DSIM_MVPORCH_REG, /* Main display Vporch register */250DSIM_MHPORCH_REG, /* Main display Hporch register */251DSIM_MSYNC_REG, /* Main display sync area register */252DSIM_INTSRC_REG, /* Interrupt source register */253DSIM_INTMSK_REG, /* Interrupt mask register */254DSIM_PKTHDR_REG, /* Packet Header FIFO register */255DSIM_PAYLOAD_REG, /* Payload FIFO register */256DSIM_RXFIFO_REG, /* Read FIFO register */257DSIM_FIFOCTRL_REG, /* FIFO status and control register */258DSIM_PLLCTRL_REG, /* PLL control register */259DSIM_PHYCTRL_REG,260DSIM_PHYTIMING_REG,261DSIM_PHYTIMING1_REG,262DSIM_PHYTIMING2_REG,263NUM_REGS264};265266static const unsigned int exynos_reg_ofs[] = {267[DSIM_STATUS_REG] = 0x00,268[DSIM_SWRST_REG] = 0x04,269[DSIM_CLKCTRL_REG] = 0x08,270[DSIM_TIMEOUT_REG] = 0x0c,271[DSIM_CONFIG_REG] = 0x10,272[DSIM_ESCMODE_REG] = 0x14,273[DSIM_MDRESOL_REG] = 0x18,274[DSIM_MVPORCH_REG] = 0x1c,275[DSIM_MHPORCH_REG] = 0x20,276[DSIM_MSYNC_REG] = 0x24,277[DSIM_INTSRC_REG] = 0x2c,278[DSIM_INTMSK_REG] = 0x30,279[DSIM_PKTHDR_REG] = 0x34,280[DSIM_PAYLOAD_REG] = 0x38,281[DSIM_RXFIFO_REG] = 0x3c,282[DSIM_FIFOCTRL_REG] = 0x44,283[DSIM_PLLCTRL_REG] = 0x4c,284[DSIM_PHYCTRL_REG] = 0x5c,285[DSIM_PHYTIMING_REG] = 0x64,286[DSIM_PHYTIMING1_REG] = 0x68,287[DSIM_PHYTIMING2_REG] = 0x6c,288};289290static const unsigned int exynos5433_reg_ofs[] = {291[DSIM_STATUS_REG] = 0x04,292[DSIM_SWRST_REG] = 0x0C,293[DSIM_CLKCTRL_REG] = 0x10,294[DSIM_TIMEOUT_REG] = 0x14,295[DSIM_CONFIG_REG] = 0x18,296[DSIM_ESCMODE_REG] = 0x1C,297[DSIM_MDRESOL_REG] = 0x20,298[DSIM_MVPORCH_REG] = 0x24,299[DSIM_MHPORCH_REG] = 0x28,300[DSIM_MSYNC_REG] = 0x2C,301[DSIM_INTSRC_REG] = 0x34,302[DSIM_INTMSK_REG] = 0x38,303[DSIM_PKTHDR_REG] = 0x3C,304[DSIM_PAYLOAD_REG] = 0x40,305[DSIM_RXFIFO_REG] = 0x44,306[DSIM_FIFOCTRL_REG] = 0x4C,307[DSIM_PLLCTRL_REG] = 0x94,308[DSIM_PHYCTRL_REG] = 0xA4,309[DSIM_PHYTIMING_REG] = 0xB4,310[DSIM_PHYTIMING1_REG] = 0xB8,311[DSIM_PHYTIMING2_REG] = 0xBC,312};313314enum reg_value_idx {315RESET_TYPE,316PLL_TIMER,317STOP_STATE_CNT,318PHYCTRL_ULPS_EXIT,319PHYCTRL_VREG_LP,320PHYCTRL_SLEW_UP,321PHYTIMING_LPX,322PHYTIMING_HS_EXIT,323PHYTIMING_CLK_PREPARE,324PHYTIMING_CLK_ZERO,325PHYTIMING_CLK_POST,326PHYTIMING_CLK_TRAIL,327PHYTIMING_HS_PREPARE,328PHYTIMING_HS_ZERO,329PHYTIMING_HS_TRAIL330};331332static const unsigned int reg_values[] = {333[RESET_TYPE] = DSIM_SWRST,334[PLL_TIMER] = 500,335[STOP_STATE_CNT] = 0xf,336[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x0af),337[PHYCTRL_VREG_LP] = 0,338[PHYCTRL_SLEW_UP] = 0,339[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),340[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),341[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),342[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x27),343[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),344[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),345[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x09),346[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),347[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),348};349350static const unsigned int exynos5422_reg_values[] = {351[RESET_TYPE] = DSIM_SWRST,352[PLL_TIMER] = 500,353[STOP_STATE_CNT] = 0xf,354[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),355[PHYCTRL_VREG_LP] = 0,356[PHYCTRL_SLEW_UP] = 0,357[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x08),358[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0d),359[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),360[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x30),361[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),362[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x0a),363[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0c),364[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x11),365[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0d),366};367368static const unsigned int exynos5433_reg_values[] = {369[RESET_TYPE] = DSIM_FUNCRST,370[PLL_TIMER] = 22200,371[STOP_STATE_CNT] = 0xa,372[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x190),373[PHYCTRL_VREG_LP] = DSIM_PHYCTRL_B_DPHYCTL_VREG_LP,374[PHYCTRL_SLEW_UP] = DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP,375[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x07),376[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0c),377[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),378[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x2d),379[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),380[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x09),381[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0b),382[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x10),383[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),384};385386static const unsigned int imx8mm_dsim_reg_values[] = {387[RESET_TYPE] = DSIM_SWRST,388[PLL_TIMER] = 500,389[STOP_STATE_CNT] = 0xf,390[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),391[PHYCTRL_VREG_LP] = 0,392[PHYCTRL_SLEW_UP] = 0,393[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),394[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),395[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),396[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x26),397[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),398[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),399[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x08),400[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),401[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),402};403404static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {405.reg_ofs = exynos_reg_ofs,406.plltmr_reg = 0x50,407.has_freqband = 1,408.has_clklane_stop = 1,409.num_clks = 2,410.max_freq = 1000,411.wait_for_reset = 1,412.num_bits_resol = 11,413.pll_p_offset = 13,414.reg_values = reg_values,415.pll_fin_min = 6,416.pll_fin_max = 12,417.m_min = 41,418.m_max = 125,419.min_freq = 500,420.has_broken_fifoctrl_emptyhdr = 1,421};422423static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {424.reg_ofs = exynos_reg_ofs,425.plltmr_reg = 0x50,426.has_freqband = 1,427.has_clklane_stop = 1,428.num_clks = 2,429.max_freq = 1000,430.wait_for_reset = 1,431.num_bits_resol = 11,432.pll_p_offset = 13,433.reg_values = reg_values,434.pll_fin_min = 6,435.pll_fin_max = 12,436.m_min = 41,437.m_max = 125,438.min_freq = 500,439.has_broken_fifoctrl_emptyhdr = 1,440};441442static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {443.reg_ofs = exynos_reg_ofs,444.plltmr_reg = 0x58,445.num_clks = 2,446.max_freq = 1000,447.wait_for_reset = 1,448.num_bits_resol = 11,449.pll_p_offset = 13,450.reg_values = reg_values,451.pll_fin_min = 6,452.pll_fin_max = 12,453.m_min = 41,454.m_max = 125,455.min_freq = 500,456};457458static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {459.reg_ofs = exynos5433_reg_ofs,460.plltmr_reg = 0xa0,461.has_clklane_stop = 1,462.num_clks = 5,463.max_freq = 1500,464.wait_for_reset = 0,465.num_bits_resol = 12,466.pll_p_offset = 13,467.reg_values = exynos5433_reg_values,468.pll_fin_min = 6,469.pll_fin_max = 12,470.m_min = 41,471.m_max = 125,472.min_freq = 500,473};474475static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {476.reg_ofs = exynos5433_reg_ofs,477.plltmr_reg = 0xa0,478.has_clklane_stop = 1,479.num_clks = 2,480.max_freq = 1500,481.wait_for_reset = 1,482.num_bits_resol = 12,483.pll_p_offset = 13,484.reg_values = exynos5422_reg_values,485.pll_fin_min = 6,486.pll_fin_max = 12,487.m_min = 41,488.m_max = 125,489.min_freq = 500,490};491492static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {493.reg_ofs = exynos5433_reg_ofs,494.plltmr_reg = 0xa0,495.has_clklane_stop = 1,496.num_clks = 2,497.max_freq = 2100,498.wait_for_reset = 0,499.num_bits_resol = 12,500/*501* Unlike Exynos, PLL_P(PMS_P) offset 14 is used in i.MX8M Mini/Nano/Plus502* downstream driver - drivers/gpu/drm/bridge/sec-dsim.c503*/504.pll_p_offset = 14,505.reg_values = imx8mm_dsim_reg_values,506.pll_fin_min = 2,507.pll_fin_max = 30,508.m_min = 64,509.m_max = 1023,510.min_freq = 1050,511};512513static const struct samsung_dsim_driver_data *514samsung_dsim_types[DSIM_TYPE_COUNT] = {515[DSIM_TYPE_EXYNOS3250] = &exynos3_dsi_driver_data,516[DSIM_TYPE_EXYNOS4210] = &exynos4_dsi_driver_data,517[DSIM_TYPE_EXYNOS5410] = &exynos5_dsi_driver_data,518[DSIM_TYPE_EXYNOS5422] = &exynos5422_dsi_driver_data,519[DSIM_TYPE_EXYNOS5433] = &exynos5433_dsi_driver_data,520[DSIM_TYPE_IMX8MM] = &imx8mm_dsi_driver_data,521[DSIM_TYPE_IMX8MP] = &imx8mm_dsi_driver_data,522};523524static inline struct samsung_dsim *host_to_dsi(struct mipi_dsi_host *h)525{526return container_of(h, struct samsung_dsim, dsi_host);527}528529static inline struct samsung_dsim *bridge_to_dsi(struct drm_bridge *b)530{531return container_of(b, struct samsung_dsim, bridge);532}533534static inline void samsung_dsim_write(struct samsung_dsim *dsi,535enum reg_idx idx, u32 val)536{537writel(val, dsi->reg_base + dsi->driver_data->reg_ofs[idx]);538}539540static inline u32 samsung_dsim_read(struct samsung_dsim *dsi, enum reg_idx idx)541{542return readl(dsi->reg_base + dsi->driver_data->reg_ofs[idx]);543}544545static void samsung_dsim_wait_for_reset(struct samsung_dsim *dsi)546{547if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300)))548return;549550dev_err(dsi->dev, "timeout waiting for reset\n");551}552553static void samsung_dsim_reset(struct samsung_dsim *dsi)554{555u32 reset_val = dsi->driver_data->reg_values[RESET_TYPE];556557reinit_completion(&dsi->completed);558samsung_dsim_write(dsi, DSIM_SWRST_REG, reset_val);559}560561static unsigned long samsung_dsim_pll_find_pms(struct samsung_dsim *dsi,562unsigned long fin,563unsigned long fout,564u8 *p, u16 *m, u8 *s)565{566const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;567unsigned long best_freq = 0;568u32 min_delta = 0xffffffff;569u8 p_min, p_max;570u8 _p, best_p;571u16 _m, best_m;572u8 _s, best_s;573574p_min = DIV_ROUND_UP(fin, (driver_data->pll_fin_max * HZ_PER_MHZ));575p_max = fin / (driver_data->pll_fin_min * HZ_PER_MHZ);576577for (_p = p_min; _p <= p_max; ++_p) {578for (_s = 0; _s <= 5; ++_s) {579u64 tmp;580u32 delta;581582tmp = (u64)fout * (_p << _s);583do_div(tmp, fin);584_m = tmp;585if (_m < driver_data->m_min || _m > driver_data->m_max)586continue;587588tmp = (u64)_m * fin;589do_div(tmp, _p);590if (tmp < driver_data->min_freq * HZ_PER_MHZ ||591tmp > driver_data->max_freq * HZ_PER_MHZ)592continue;593594tmp = (u64)_m * fin;595do_div(tmp, _p << _s);596597delta = abs(fout - tmp);598if (delta < min_delta) {599best_p = _p;600best_m = _m;601best_s = _s;602min_delta = delta;603best_freq = tmp;604}605}606}607608if (best_freq) {609*p = best_p;610*m = best_m;611*s = best_s;612}613614return best_freq;615}616617static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,618unsigned long freq)619{620const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;621unsigned long fin, fout;622int timeout;623u8 p, s;624u16 m;625u32 reg;626627if (dsi->pll_clk) {628/*629* Ensure that the reference clock is generated with a power of630* two divider from its parent, but close to the PLLs upper631* limit.632*/633fin = clk_get_rate(clk_get_parent(dsi->pll_clk));634while (fin > driver_data->pll_fin_max * HZ_PER_MHZ)635fin /= 2;636clk_set_rate(dsi->pll_clk, fin);637638fin = clk_get_rate(dsi->pll_clk);639} else {640fin = dsi->pll_clk_rate;641}642dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin);643644fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s);645if (!fout) {646dev_err(dsi->dev,647"failed to find PLL PMS for requested frequency\n");648return 0;649}650dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);651652writel(driver_data->reg_values[PLL_TIMER],653dsi->reg_base + driver_data->plltmr_reg);654655reg = DSIM_PLL_EN | DSIM_PLL_P(p, driver_data->pll_p_offset) |656DSIM_PLL_M(m) | DSIM_PLL_S(s);657658if (driver_data->has_freqband) {659static const unsigned long freq_bands[] = {660100 * HZ_PER_MHZ, 120 * HZ_PER_MHZ, 160 * HZ_PER_MHZ,661200 * HZ_PER_MHZ, 270 * HZ_PER_MHZ, 320 * HZ_PER_MHZ,662390 * HZ_PER_MHZ, 450 * HZ_PER_MHZ, 510 * HZ_PER_MHZ,663560 * HZ_PER_MHZ, 640 * HZ_PER_MHZ, 690 * HZ_PER_MHZ,664770 * HZ_PER_MHZ, 870 * HZ_PER_MHZ, 950 * HZ_PER_MHZ,665};666int band;667668for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)669if (fout < freq_bands[band])670break;671672dev_dbg(dsi->dev, "band %d\n", band);673674reg |= DSIM_FREQ_BAND(band);675}676677if (dsi->swap_dn_dp_clk)678reg |= DSIM_PLL_DPDNSWAP_CLK;679if (dsi->swap_dn_dp_data)680reg |= DSIM_PLL_DPDNSWAP_DAT;681682samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);683684timeout = 1000;685do {686if (timeout-- == 0) {687dev_err(dsi->dev, "PLL failed to stabilize\n");688return 0;689}690reg = samsung_dsim_read(dsi, DSIM_STATUS_REG);691} while ((reg & DSIM_PLL_STABLE) == 0);692693dsi->hs_clock = fout;694695return fout;696}697698static int samsung_dsim_enable_clock(struct samsung_dsim *dsi)699{700unsigned long hs_clk, byte_clk, esc_clk, pix_clk;701unsigned long esc_div;702u32 reg;703struct drm_display_mode *m = &dsi->mode;704int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);705706/* m->clock is in KHz */707pix_clk = m->clock * 1000;708709/* Use burst_clk_rate if available, otherwise use the pix_clk */710if (dsi->burst_clk_rate)711hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate);712else713hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, dsi->lanes));714715if (!hs_clk) {716dev_err(dsi->dev, "failed to configure DSI PLL\n");717return -EFAULT;718}719720byte_clk = hs_clk / 8;721esc_div = DIV_ROUND_UP(byte_clk, dsi->esc_clk_rate);722esc_clk = byte_clk / esc_div;723724if (esc_clk > 20 * HZ_PER_MHZ) {725++esc_div;726esc_clk = byte_clk / esc_div;727}728729dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",730hs_clk, byte_clk, esc_clk);731732reg = samsung_dsim_read(dsi, DSIM_CLKCTRL_REG);733reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK734| DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS735| DSIM_BYTE_CLK_SRC_MASK);736reg |= DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN737| DSIM_ESC_PRESCALER(esc_div)738| DSIM_LANE_ESC_CLK_EN_CLK739| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1)740| DSIM_BYTE_CLK_SRC(0)741| DSIM_TX_REQUEST_HSCLK;742samsung_dsim_write(dsi, DSIM_CLKCTRL_REG, reg);743744return 0;745}746747static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi)748{749const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;750const unsigned int *reg_values = driver_data->reg_values;751u32 reg;752struct phy_configure_opts_mipi_dphy cfg;753int clk_prepare, lpx, clk_zero, clk_post, clk_trail;754int hs_exit, hs_prepare, hs_zero, hs_trail;755unsigned long long byte_clock = dsi->hs_clock / 8;756757if (driver_data->has_freqband)758return;759760phy_mipi_dphy_get_default_config_for_hsclk(dsi->hs_clock,761dsi->lanes, &cfg);762763/*764* TODO:765* The tech Applications Processor manuals for i.MX8M Mini, Nano,766* and Plus don't state what the definition of the PHYTIMING767* bits are beyond their address and bit position.768* After reviewing NXP's downstream code, it appears769* that the various PHYTIMING registers take the number770* of cycles and use various dividers on them. This771* calculation does not result in an exact match to the772* downstream code, but it is very close to the values773* generated by their lookup table, and it appears774* to sync at a variety of resolutions. If someone775* can get a more accurate mathematical equation needed776* for these registers, this should be updated.777*/778779lpx = PS_TO_CYCLE(cfg.lpx, byte_clock);780hs_exit = PS_TO_CYCLE(cfg.hs_exit, byte_clock);781clk_prepare = PS_TO_CYCLE(cfg.clk_prepare, byte_clock);782clk_zero = PS_TO_CYCLE(cfg.clk_zero, byte_clock);783clk_post = PS_TO_CYCLE(cfg.clk_post, byte_clock);784clk_trail = PS_TO_CYCLE(cfg.clk_trail, byte_clock);785hs_prepare = PS_TO_CYCLE(cfg.hs_prepare, byte_clock);786hs_zero = PS_TO_CYCLE(cfg.hs_zero, byte_clock);787hs_trail = PS_TO_CYCLE(cfg.hs_trail, byte_clock);788789/* B D-PHY: D-PHY Master & Slave Analog Block control */790reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |791reg_values[PHYCTRL_SLEW_UP];792793samsung_dsim_write(dsi, DSIM_PHYCTRL_REG, reg);794795/*796* T LPX: Transmitted length of any Low-Power state period797* T HS-EXIT: Time that the transmitter drives LP-11 following a HS798* burst799*/800801reg = DSIM_PHYTIMING_LPX(lpx) | DSIM_PHYTIMING_HS_EXIT(hs_exit);802803samsung_dsim_write(dsi, DSIM_PHYTIMING_REG, reg);804805/*806* T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00807* Line state immediately before the HS-0 Line state starting the808* HS transmission809* T CLK-ZERO: Time that the transmitter drives the HS-0 state prior to810* transmitting the Clock.811* T CLK_POST: Time that the transmitter continues to send HS clock812* after the last associated Data Lane has transitioned to LP Mode813* Interval is defined as the period from the end of T HS-TRAIL to814* the beginning of T CLK-TRAIL815* T CLK-TRAIL: Time that the transmitter drives the HS-0 state after816* the last payload clock bit of a HS transmission burst817*/818819reg = DSIM_PHYTIMING1_CLK_PREPARE(clk_prepare) |820DSIM_PHYTIMING1_CLK_ZERO(clk_zero) |821DSIM_PHYTIMING1_CLK_POST(clk_post) |822DSIM_PHYTIMING1_CLK_TRAIL(clk_trail);823824samsung_dsim_write(dsi, DSIM_PHYTIMING1_REG, reg);825826/*827* T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00828* Line state immediately before the HS-0 Line state starting the829* HS transmission830* T HS-ZERO: Time that the transmitter drives the HS-0 state prior to831* transmitting the Sync sequence.832* T HS-TRAIL: Time that the transmitter drives the flipped differential833* state after last payload data bit of a HS transmission burst834*/835836reg = DSIM_PHYTIMING2_HS_PREPARE(hs_prepare) |837DSIM_PHYTIMING2_HS_ZERO(hs_zero) |838DSIM_PHYTIMING2_HS_TRAIL(hs_trail);839840samsung_dsim_write(dsi, DSIM_PHYTIMING2_REG, reg);841}842843static void samsung_dsim_disable_clock(struct samsung_dsim *dsi)844{845u32 reg;846847reg = samsung_dsim_read(dsi, DSIM_CLKCTRL_REG);848reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK849| DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);850samsung_dsim_write(dsi, DSIM_CLKCTRL_REG, reg);851852reg = samsung_dsim_read(dsi, DSIM_PLLCTRL_REG);853reg &= ~DSIM_PLL_EN;854samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);855}856857static void samsung_dsim_enable_lane(struct samsung_dsim *dsi, u32 lane)858{859u32 reg = samsung_dsim_read(dsi, DSIM_CONFIG_REG);860861reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |862DSIM_LANE_EN(lane));863samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg);864}865866static int samsung_dsim_init_link(struct samsung_dsim *dsi)867{868const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;869int timeout;870u32 reg;871u32 lanes_mask;872873/* Initialize FIFO pointers */874reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG);875reg &= ~0x1f;876samsung_dsim_write(dsi, DSIM_FIFOCTRL_REG, reg);877878usleep_range(9000, 11000);879880reg |= 0x1f;881samsung_dsim_write(dsi, DSIM_FIFOCTRL_REG, reg);882usleep_range(9000, 11000);883884/* DSI configuration */885reg = 0;886887/*888* The first bit of mode_flags specifies display configuration.889* If this bit is set[= MIPI_DSI_MODE_VIDEO], dsi will support video890* mode, otherwise it will support command mode.891*/892if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {893reg |= DSIM_VIDEO_MODE;894895/*896* The user manual describes that following bits are ignored in897* command mode.898*/899if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)900reg |= DSIM_SYNC_INFORM;901if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)902reg |= DSIM_BURST_MODE;903if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_AUTO_VERT)904reg |= DSIM_AUTO_MODE;905if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HSE)906reg |= DSIM_HSE_DISABLE_MODE;907if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)908reg |= DSIM_HFP_DISABLE_MODE;909if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)910reg |= DSIM_HBP_DISABLE_MODE;911if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA)912reg |= DSIM_HSA_DISABLE_MODE;913}914915if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)916reg |= DSIM_EOT_DISABLE;917918switch (dsi->format) {919case MIPI_DSI_FMT_RGB888:920reg |= DSIM_MAIN_PIX_FORMAT_RGB888;921break;922case MIPI_DSI_FMT_RGB666:923reg |= DSIM_MAIN_PIX_FORMAT_RGB666;924break;925case MIPI_DSI_FMT_RGB666_PACKED:926reg |= DSIM_MAIN_PIX_FORMAT_RGB666_P;927break;928case MIPI_DSI_FMT_RGB565:929reg |= DSIM_MAIN_PIX_FORMAT_RGB565;930break;931default:932dev_err(dsi->dev, "invalid pixel format\n");933return -EINVAL;934}935936/*937* Use non-continuous clock mode if the periparal wants and938* host controller supports939*940* In non-continous clock mode, host controller will turn off941* the HS clock between high-speed transmissions to reduce942* power consumption.943*/944if (driver_data->has_clklane_stop &&945dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {946if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type))947reg |= DSIM_NON_CONTINUOUS_CLKLANE;948949reg |= DSIM_CLKLANE_STOP;950}951samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg);952953lanes_mask = BIT(dsi->lanes) - 1;954samsung_dsim_enable_lane(dsi, lanes_mask);955956/* Check clock and data lane state are stop state */957timeout = 100;958do {959if (timeout-- == 0) {960dev_err(dsi->dev, "waiting for bus lanes timed out\n");961return -EFAULT;962}963964reg = samsung_dsim_read(dsi, DSIM_STATUS_REG);965if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))966!= DSIM_STOP_STATE_DAT(lanes_mask))967continue;968} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));969970reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);971reg &= ~DSIM_STOP_STATE_CNT_MASK;972reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]);973samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);974975reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);976samsung_dsim_write(dsi, DSIM_TIMEOUT_REG, reg);977978return 0;979}980981static void samsung_dsim_set_display_mode(struct samsung_dsim *dsi)982{983struct drm_display_mode *m = &dsi->mode;984unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;985u32 reg;986987if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {988u64 byte_clk = dsi->hs_clock / 8;989u64 pix_clk = m->clock * 1000;990991int hfp = DIV64_U64_ROUND_UP((m->hsync_start - m->hdisplay) * byte_clk, pix_clk);992int hbp = DIV64_U64_ROUND_UP((m->htotal - m->hsync_end) * byte_clk, pix_clk);993int hsa = DIV64_U64_ROUND_UP((m->hsync_end - m->hsync_start) * byte_clk, pix_clk);994995/* remove packet overhead when possible */996hfp = max(hfp - 6, 0);997hbp = max(hbp - 6, 0);998hsa = max(hsa - 6, 0);9991000dev_dbg(dsi->dev, "calculated hfp: %u, hbp: %u, hsa: %u",1001hfp, hbp, hsa);10021003reg = DSIM_CMD_ALLOW(0xf)1004| DSIM_STABLE_VFP(m->vsync_start - m->vdisplay)1005| DSIM_MAIN_VBP(m->vtotal - m->vsync_end);1006samsung_dsim_write(dsi, DSIM_MVPORCH_REG, reg);10071008reg = DSIM_MAIN_HFP(hfp) | DSIM_MAIN_HBP(hbp);1009samsung_dsim_write(dsi, DSIM_MHPORCH_REG, reg);10101011reg = DSIM_MAIN_VSA(m->vsync_end - m->vsync_start)1012| DSIM_MAIN_HSA(hsa);1013samsung_dsim_write(dsi, DSIM_MSYNC_REG, reg);1014}1015reg = DSIM_MAIN_HRESOL(m->hdisplay, num_bits_resol) |1016DSIM_MAIN_VRESOL(m->vdisplay, num_bits_resol);10171018samsung_dsim_write(dsi, DSIM_MDRESOL_REG, reg);10191020dev_dbg(dsi->dev, "LCD size = %dx%d\n", m->hdisplay, m->vdisplay);1021}10221023static void samsung_dsim_set_display_enable(struct samsung_dsim *dsi, bool enable)1024{1025u32 reg;10261027reg = samsung_dsim_read(dsi, DSIM_MDRESOL_REG);1028if (enable)1029reg |= DSIM_MAIN_STAND_BY;1030else1031reg &= ~DSIM_MAIN_STAND_BY;1032samsung_dsim_write(dsi, DSIM_MDRESOL_REG, reg);1033}10341035static int samsung_dsim_wait_for_hdr_fifo(struct samsung_dsim *dsi)1036{1037int timeout = 2000;10381039do {1040u32 reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG);10411042if (!dsi->driver_data->has_broken_fifoctrl_emptyhdr) {1043if (reg & DSIM_SFR_HEADER_EMPTY)1044return 0;1045} else {1046if (!(reg & DSIM_SFR_HEADER_FULL)) {1047/*1048* Wait a little bit, so the pending data can1049* actually leave the FIFO to avoid overflow.1050*/1051if (!cond_resched())1052usleep_range(950, 1050);1053return 0;1054}1055}10561057if (!cond_resched())1058usleep_range(950, 1050);1059} while (--timeout);10601061return -ETIMEDOUT;1062}10631064static void samsung_dsim_set_cmd_lpm(struct samsung_dsim *dsi, bool lpm)1065{1066u32 v = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);10671068if (lpm)1069v |= DSIM_CMD_LPDT_LP;1070else1071v &= ~DSIM_CMD_LPDT_LP;10721073samsung_dsim_write(dsi, DSIM_ESCMODE_REG, v);1074}10751076static void samsung_dsim_force_bta(struct samsung_dsim *dsi)1077{1078u32 v = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);10791080v |= DSIM_FORCE_BTA;1081samsung_dsim_write(dsi, DSIM_ESCMODE_REG, v);1082}10831084static void samsung_dsim_send_to_fifo(struct samsung_dsim *dsi,1085struct samsung_dsim_transfer *xfer)1086{1087struct device *dev = dsi->dev;1088struct mipi_dsi_packet *pkt = &xfer->packet;1089const u8 *payload = pkt->payload + xfer->tx_done;1090u16 length = pkt->payload_length - xfer->tx_done;1091bool first = !xfer->tx_done;1092u32 reg;10931094dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",1095xfer, length, xfer->tx_done, xfer->rx_len, xfer->rx_done);10961097if (length > DSI_TX_FIFO_SIZE)1098length = DSI_TX_FIFO_SIZE;10991100xfer->tx_done += length;11011102/* Send payload */1103while (length >= 4) {1104reg = get_unaligned_le32(payload);1105samsung_dsim_write(dsi, DSIM_PAYLOAD_REG, reg);1106payload += 4;1107length -= 4;1108}11091110reg = 0;1111switch (length) {1112case 3:1113reg |= payload[2] << 16;1114fallthrough;1115case 2:1116reg |= payload[1] << 8;1117fallthrough;1118case 1:1119reg |= payload[0];1120samsung_dsim_write(dsi, DSIM_PAYLOAD_REG, reg);1121break;1122}11231124/* Send packet header */1125if (!first)1126return;11271128reg = get_unaligned_le32(pkt->header);1129if (samsung_dsim_wait_for_hdr_fifo(dsi)) {1130dev_err(dev, "waiting for header FIFO timed out\n");1131return;1132}11331134if (NEQV(xfer->flags & MIPI_DSI_MSG_USE_LPM,1135dsi->state & DSIM_STATE_CMD_LPM)) {1136samsung_dsim_set_cmd_lpm(dsi, xfer->flags & MIPI_DSI_MSG_USE_LPM);1137dsi->state ^= DSIM_STATE_CMD_LPM;1138}11391140samsung_dsim_write(dsi, DSIM_PKTHDR_REG, reg);11411142if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)1143samsung_dsim_force_bta(dsi);1144}11451146static void samsung_dsim_read_from_fifo(struct samsung_dsim *dsi,1147struct samsung_dsim_transfer *xfer)1148{1149u8 *payload = xfer->rx_payload + xfer->rx_done;1150bool first = !xfer->rx_done;1151struct device *dev = dsi->dev;1152u16 length;1153u32 reg;11541155if (first) {1156reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);11571158switch (reg & 0x3f) {1159case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:1160case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:1161if (xfer->rx_len >= 2) {1162payload[1] = reg >> 16;1163++xfer->rx_done;1164}1165fallthrough;1166case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:1167case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:1168payload[0] = reg >> 8;1169++xfer->rx_done;1170xfer->rx_len = xfer->rx_done;1171xfer->result = 0;1172goto clear_fifo;1173case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:1174dev_err(dev, "DSI Error Report: 0x%04x\n", (reg >> 8) & 0xffff);1175xfer->result = 0;1176goto clear_fifo;1177}11781179length = (reg >> 8) & 0xffff;1180if (length > xfer->rx_len) {1181dev_err(dev,1182"response too long (%u > %u bytes), stripping\n",1183xfer->rx_len, length);1184length = xfer->rx_len;1185} else if (length < xfer->rx_len) {1186xfer->rx_len = length;1187}1188}11891190length = xfer->rx_len - xfer->rx_done;1191xfer->rx_done += length;11921193/* Receive payload */1194while (length >= 4) {1195reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1196payload[0] = (reg >> 0) & 0xff;1197payload[1] = (reg >> 8) & 0xff;1198payload[2] = (reg >> 16) & 0xff;1199payload[3] = (reg >> 24) & 0xff;1200payload += 4;1201length -= 4;1202}12031204if (length) {1205reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1206switch (length) {1207case 3:1208payload[2] = (reg >> 16) & 0xff;1209fallthrough;1210case 2:1211payload[1] = (reg >> 8) & 0xff;1212fallthrough;1213case 1:1214payload[0] = reg & 0xff;1215}1216}12171218if (xfer->rx_done == xfer->rx_len)1219xfer->result = 0;12201221clear_fifo:1222length = DSI_RX_FIFO_SIZE / 4;1223do {1224reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1225if (reg == DSI_RX_FIFO_EMPTY)1226break;1227} while (--length);1228}12291230static void samsung_dsim_transfer_start(struct samsung_dsim *dsi)1231{1232unsigned long flags;1233struct samsung_dsim_transfer *xfer;12341235spin_lock_irqsave(&dsi->transfer_lock, flags);12361237while (!list_empty(&dsi->transfer_list)) {1238xfer = list_first_entry(&dsi->transfer_list,1239struct samsung_dsim_transfer, list);12401241spin_unlock_irqrestore(&dsi->transfer_lock, flags);12421243if (xfer->packet.payload_length &&1244xfer->tx_done == xfer->packet.payload_length)1245/* waiting for RX */1246return;12471248samsung_dsim_send_to_fifo(dsi, xfer);12491250if (xfer->packet.payload_length || xfer->rx_len)1251return;12521253xfer->result = 0;1254complete(&xfer->completed);12551256spin_lock_irqsave(&dsi->transfer_lock, flags);12571258list_del_init(&xfer->list);1259}12601261spin_unlock_irqrestore(&dsi->transfer_lock, flags);1262}12631264static bool samsung_dsim_transfer_finish(struct samsung_dsim *dsi)1265{1266struct samsung_dsim_transfer *xfer;1267unsigned long flags;1268bool start = true;12691270spin_lock_irqsave(&dsi->transfer_lock, flags);12711272if (list_empty(&dsi->transfer_list)) {1273spin_unlock_irqrestore(&dsi->transfer_lock, flags);1274return false;1275}12761277xfer = list_first_entry(&dsi->transfer_list,1278struct samsung_dsim_transfer, list);12791280spin_unlock_irqrestore(&dsi->transfer_lock, flags);12811282dev_dbg(dsi->dev,1283"> xfer %p, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",1284xfer, xfer->packet.payload_length, xfer->tx_done, xfer->rx_len,1285xfer->rx_done);12861287if (xfer->tx_done != xfer->packet.payload_length)1288return true;12891290if (xfer->rx_done != xfer->rx_len)1291samsung_dsim_read_from_fifo(dsi, xfer);12921293if (xfer->rx_done != xfer->rx_len)1294return true;12951296spin_lock_irqsave(&dsi->transfer_lock, flags);12971298list_del_init(&xfer->list);1299start = !list_empty(&dsi->transfer_list);13001301spin_unlock_irqrestore(&dsi->transfer_lock, flags);13021303if (!xfer->rx_len)1304xfer->result = 0;1305complete(&xfer->completed);13061307return start;1308}13091310static void samsung_dsim_remove_transfer(struct samsung_dsim *dsi,1311struct samsung_dsim_transfer *xfer)1312{1313unsigned long flags;1314bool start;13151316spin_lock_irqsave(&dsi->transfer_lock, flags);13171318if (!list_empty(&dsi->transfer_list) &&1319xfer == list_first_entry(&dsi->transfer_list,1320struct samsung_dsim_transfer, list)) {1321list_del_init(&xfer->list);1322start = !list_empty(&dsi->transfer_list);1323spin_unlock_irqrestore(&dsi->transfer_lock, flags);1324if (start)1325samsung_dsim_transfer_start(dsi);1326return;1327}13281329list_del_init(&xfer->list);13301331spin_unlock_irqrestore(&dsi->transfer_lock, flags);1332}13331334static int samsung_dsim_transfer(struct samsung_dsim *dsi,1335struct samsung_dsim_transfer *xfer)1336{1337unsigned long flags;1338bool stopped;13391340xfer->tx_done = 0;1341xfer->rx_done = 0;1342xfer->result = -ETIMEDOUT;1343init_completion(&xfer->completed);13441345spin_lock_irqsave(&dsi->transfer_lock, flags);13461347stopped = list_empty(&dsi->transfer_list);1348list_add_tail(&xfer->list, &dsi->transfer_list);13491350spin_unlock_irqrestore(&dsi->transfer_lock, flags);13511352if (stopped)1353samsung_dsim_transfer_start(dsi);13541355wait_for_completion_timeout(&xfer->completed,1356msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));1357if (xfer->result == -ETIMEDOUT) {1358struct mipi_dsi_packet *pkt = &xfer->packet;13591360samsung_dsim_remove_transfer(dsi, xfer);1361dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 4, pkt->header,1362(int)pkt->payload_length, pkt->payload);1363return -ETIMEDOUT;1364}13651366/* Also covers hardware timeout condition */1367return xfer->result;1368}13691370static irqreturn_t samsung_dsim_irq(int irq, void *dev_id)1371{1372struct samsung_dsim *dsi = dev_id;1373u32 status;13741375status = samsung_dsim_read(dsi, DSIM_INTSRC_REG);1376if (!status) {1377static unsigned long j;13781379if (printk_timed_ratelimit(&j, 500))1380dev_warn(dsi->dev, "spurious interrupt\n");1381return IRQ_HANDLED;1382}1383samsung_dsim_write(dsi, DSIM_INTSRC_REG, status);13841385if (status & DSIM_INT_SW_RST_RELEASE) {1386unsigned long mask = ~(DSIM_INT_RX_DONE |1387DSIM_INT_SFR_FIFO_EMPTY |1388DSIM_INT_SFR_HDR_FIFO_EMPTY |1389DSIM_INT_RX_ECC_ERR |1390DSIM_INT_SW_RST_RELEASE);1391samsung_dsim_write(dsi, DSIM_INTMSK_REG, mask);1392complete(&dsi->completed);1393return IRQ_HANDLED;1394}13951396if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |1397DSIM_INT_PLL_STABLE)))1398return IRQ_HANDLED;13991400if (samsung_dsim_transfer_finish(dsi))1401samsung_dsim_transfer_start(dsi);14021403return IRQ_HANDLED;1404}14051406static void samsung_dsim_enable_irq(struct samsung_dsim *dsi)1407{1408enable_irq(dsi->irq);14091410if (dsi->te_gpio)1411enable_irq(gpiod_to_irq(dsi->te_gpio));1412}14131414static void samsung_dsim_disable_irq(struct samsung_dsim *dsi)1415{1416if (dsi->te_gpio)1417disable_irq(gpiod_to_irq(dsi->te_gpio));14181419disable_irq(dsi->irq);1420}14211422static int samsung_dsim_init(struct samsung_dsim *dsi)1423{1424const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;14251426if (dsi->state & DSIM_STATE_INITIALIZED)1427return 0;14281429samsung_dsim_reset(dsi);1430samsung_dsim_enable_irq(dsi);14311432if (driver_data->reg_values[RESET_TYPE] == DSIM_FUNCRST)1433samsung_dsim_enable_lane(dsi, BIT(dsi->lanes) - 1);14341435samsung_dsim_enable_clock(dsi);1436if (driver_data->wait_for_reset)1437samsung_dsim_wait_for_reset(dsi);1438samsung_dsim_set_phy_ctrl(dsi);1439samsung_dsim_init_link(dsi);14401441dsi->state |= DSIM_STATE_INITIALIZED;14421443return 0;1444}14451446static void samsung_dsim_atomic_pre_enable(struct drm_bridge *bridge,1447struct drm_atomic_state *state)1448{1449struct samsung_dsim *dsi = bridge_to_dsi(bridge);1450int ret;14511452if (dsi->state & DSIM_STATE_ENABLED)1453return;14541455ret = pm_runtime_resume_and_get(dsi->dev);1456if (ret < 0) {1457dev_err(dsi->dev, "failed to enable DSI device.\n");1458return;1459}14601461dsi->state |= DSIM_STATE_ENABLED;14621463/*1464* For Exynos-DSIM the downstream bridge, or panel are expecting1465* the host initialization during DSI transfer.1466*/1467if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {1468ret = samsung_dsim_init(dsi);1469if (ret)1470return;1471}1472}14731474static void samsung_dsim_atomic_enable(struct drm_bridge *bridge,1475struct drm_atomic_state *state)1476{1477struct samsung_dsim *dsi = bridge_to_dsi(bridge);14781479samsung_dsim_set_display_mode(dsi);1480samsung_dsim_set_display_enable(dsi, true);14811482dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;1483}14841485static void samsung_dsim_atomic_disable(struct drm_bridge *bridge,1486struct drm_atomic_state *state)1487{1488struct samsung_dsim *dsi = bridge_to_dsi(bridge);14891490if (!(dsi->state & DSIM_STATE_ENABLED))1491return;14921493samsung_dsim_set_display_enable(dsi, false);1494dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;1495}14961497static void samsung_dsim_atomic_post_disable(struct drm_bridge *bridge,1498struct drm_atomic_state *state)1499{1500struct samsung_dsim *dsi = bridge_to_dsi(bridge);15011502dsi->state &= ~DSIM_STATE_ENABLED;1503pm_runtime_put_sync(dsi->dev);1504}15051506/*1507* This pixel output formats list referenced from,1508* AN13573 i.MX 8/RT MIPI DSI/CSI-2, Rev. 0, 21 March 20221509* 3.7.4 Pixel formats1510* Table 14. DSI pixel packing formats1511*/1512static const u32 samsung_dsim_pixel_output_fmts[] = {1513MEDIA_BUS_FMT_YUYV10_1X20,1514MEDIA_BUS_FMT_YUYV12_1X24,1515MEDIA_BUS_FMT_UYVY8_1X16,1516MEDIA_BUS_FMT_RGB101010_1X30,1517MEDIA_BUS_FMT_RGB121212_1X36,1518MEDIA_BUS_FMT_RGB565_1X16,1519MEDIA_BUS_FMT_RGB666_1X18,1520MEDIA_BUS_FMT_RGB888_1X24,1521};15221523static bool samsung_dsim_pixel_output_fmt_supported(u32 fmt)1524{1525int i;15261527if (fmt == MEDIA_BUS_FMT_FIXED)1528return false;15291530for (i = 0; i < ARRAY_SIZE(samsung_dsim_pixel_output_fmts); i++) {1531if (samsung_dsim_pixel_output_fmts[i] == fmt)1532return true;1533}15341535return false;1536}15371538static u32 *1539samsung_dsim_atomic_get_input_bus_fmts(struct drm_bridge *bridge,1540struct drm_bridge_state *bridge_state,1541struct drm_crtc_state *crtc_state,1542struct drm_connector_state *conn_state,1543u32 output_fmt,1544unsigned int *num_input_fmts)1545{1546u32 *input_fmts;15471548input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);1549if (!input_fmts)1550return NULL;15511552if (!samsung_dsim_pixel_output_fmt_supported(output_fmt))1553/*1554* Some bridge/display drivers are still not able to pass the1555* correct format, so handle those pipelines by falling back1556* to the default format till the supported formats finalized.1557*/1558output_fmt = MEDIA_BUS_FMT_RGB888_1X24;15591560input_fmts[0] = output_fmt;1561*num_input_fmts = 1;15621563return input_fmts;1564}15651566static int samsung_dsim_atomic_check(struct drm_bridge *bridge,1567struct drm_bridge_state *bridge_state,1568struct drm_crtc_state *crtc_state,1569struct drm_connector_state *conn_state)1570{1571struct samsung_dsim *dsi = bridge_to_dsi(bridge);1572struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;15731574/*1575* The i.MX8M Mini/Nano glue logic between LCDIF and DSIM1576* inverts HS/VS/DE sync signals polarity, therefore, while1577* i.MX 8M Mini Applications Processor Reference Manual Rev. 3, 11/20201578* 13.6.3.5.2 RGB interface1579* i.MX 8M Nano Applications Processor Reference Manual Rev. 2, 07/20221580* 13.6.2.7.2 RGB interface1581* both claim "Vsync, Hsync, and VDEN are active high signals.", the1582* LCDIF must generate inverted HS/VS/DE signals, i.e. active LOW.1583*1584* The i.MX8M Plus glue logic between LCDIFv3 and DSIM does not1585* implement the same behavior, therefore LCDIFv3 must generate1586* HS/VS/DE signals active HIGH.1587*/1588if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM) {1589adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);1590adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);1591} else if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MP) {1592adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);1593adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);1594}15951596/*1597* When using video sync pulses, the HFP, HBP, and HSA are divided between1598* the available lanes if there is more than one lane. For certain1599* timings and lane configurations, the HFP may not be evenly divisible.1600* If the HFP is rounded down, it ends up being too small which can cause1601* some monitors to not sync properly. In these instances, adjust htotal1602* and hsync to round the HFP up, and recalculate the htotal. Through trial1603* and error, it appears that the HBP and HSA do not appearto need the same1604* correction that HFP does.1605*/1606if (dsi->lanes > 1) {1607int hfp = adjusted_mode->hsync_start - adjusted_mode->hdisplay;1608int remainder = hfp % dsi->lanes;16091610if (remainder) {1611adjusted_mode->hsync_start += remainder;1612adjusted_mode->hsync_end += remainder;1613adjusted_mode->htotal += remainder;1614}1615}16161617return 0;1618}16191620static void samsung_dsim_mode_set(struct drm_bridge *bridge,1621const struct drm_display_mode *mode,1622const struct drm_display_mode *adjusted_mode)1623{1624struct samsung_dsim *dsi = bridge_to_dsi(bridge);16251626drm_mode_copy(&dsi->mode, adjusted_mode);1627}16281629static int samsung_dsim_attach(struct drm_bridge *bridge,1630struct drm_encoder *encoder,1631enum drm_bridge_attach_flags flags)1632{1633struct samsung_dsim *dsi = bridge_to_dsi(bridge);16341635return drm_bridge_attach(encoder, dsi->out_bridge, bridge,1636flags);1637}16381639static const struct drm_bridge_funcs samsung_dsim_bridge_funcs = {1640.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,1641.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,1642.atomic_reset = drm_atomic_helper_bridge_reset,1643.atomic_get_input_bus_fmts = samsung_dsim_atomic_get_input_bus_fmts,1644.atomic_check = samsung_dsim_atomic_check,1645.atomic_pre_enable = samsung_dsim_atomic_pre_enable,1646.atomic_enable = samsung_dsim_atomic_enable,1647.atomic_disable = samsung_dsim_atomic_disable,1648.atomic_post_disable = samsung_dsim_atomic_post_disable,1649.mode_set = samsung_dsim_mode_set,1650.attach = samsung_dsim_attach,1651};16521653static irqreturn_t samsung_dsim_te_irq_handler(int irq, void *dev_id)1654{1655struct samsung_dsim *dsi = (struct samsung_dsim *)dev_id;1656const struct samsung_dsim_plat_data *pdata = dsi->plat_data;16571658if (pdata->host_ops && pdata->host_ops->te_irq_handler)1659return pdata->host_ops->te_irq_handler(dsi);16601661return IRQ_HANDLED;1662}16631664static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device *dev)1665{1666int te_gpio_irq;1667int ret;16681669dsi->te_gpio = devm_gpiod_get_optional(dev, "te", GPIOD_IN);1670if (!dsi->te_gpio)1671return 0;1672else if (IS_ERR(dsi->te_gpio))1673return dev_err_probe(dev, PTR_ERR(dsi->te_gpio), "failed to get te GPIO\n");16741675te_gpio_irq = gpiod_to_irq(dsi->te_gpio);16761677ret = request_threaded_irq(te_gpio_irq, samsung_dsim_te_irq_handler, NULL,1678IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, "TE", dsi);1679if (ret) {1680dev_err(dsi->dev, "request interrupt failed with %d\n", ret);1681gpiod_put(dsi->te_gpio);1682return ret;1683}16841685return 0;1686}16871688static int samsung_dsim_host_attach(struct mipi_dsi_host *host,1689struct mipi_dsi_device *device)1690{1691struct samsung_dsim *dsi = host_to_dsi(host);1692const struct samsung_dsim_plat_data *pdata = dsi->plat_data;1693struct device *dev = dsi->dev;1694struct device_node *np = dev->of_node;1695struct device_node *remote;1696struct drm_panel *panel;1697int ret;16981699/*1700* Devices can also be child nodes when we also control that device1701* through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).1702*1703* Lookup for a child node of the given parent that isn't either port1704* or ports.1705*/1706for_each_available_child_of_node(np, remote) {1707if (of_node_name_eq(remote, "port") ||1708of_node_name_eq(remote, "ports"))1709continue;17101711goto of_find_panel_or_bridge;1712}17131714/*1715* of_graph_get_remote_node() produces a noisy error message if port1716* node isn't found and the absence of the port is a legit case here,1717* so at first we silently check whether graph presents in the1718* device-tree node.1719*/1720if (!of_graph_is_present(np))1721return -ENODEV;17221723remote = of_graph_get_remote_node(np, 1, 0);17241725of_find_panel_or_bridge:1726if (!remote)1727return -ENODEV;17281729panel = of_drm_find_panel(remote);1730if (!IS_ERR(panel)) {1731dsi->out_bridge = devm_drm_panel_bridge_add(dev, panel);1732} else {1733dsi->out_bridge = of_drm_find_bridge(remote);1734if (!dsi->out_bridge)1735dsi->out_bridge = ERR_PTR(-EINVAL);1736}17371738of_node_put(remote);17391740if (IS_ERR(dsi->out_bridge)) {1741ret = PTR_ERR(dsi->out_bridge);1742DRM_DEV_ERROR(dev, "failed to find the bridge: %d\n", ret);1743return ret;1744}17451746DRM_DEV_INFO(dev, "Attached %s device (lanes:%d bpp:%d mode-flags:0x%lx)\n",1747device->name, device->lanes,1748mipi_dsi_pixel_format_to_bpp(device->format),1749device->mode_flags);17501751drm_bridge_add(&dsi->bridge);17521753/*1754* This is a temporary solution and should be made by more generic way.1755*1756* If attached panel device is for command mode one, dsi should register1757* TE interrupt handler.1758*/1759if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {1760ret = samsung_dsim_register_te_irq(dsi, &device->dev);1761if (ret)1762return ret;1763}17641765if (pdata->host_ops && pdata->host_ops->attach) {1766ret = pdata->host_ops->attach(dsi, device);1767if (ret)1768return ret;1769}17701771dsi->lanes = device->lanes;1772dsi->format = device->format;1773dsi->mode_flags = device->mode_flags;17741775return 0;1776}17771778static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)1779{1780if (dsi->te_gpio) {1781free_irq(gpiod_to_irq(dsi->te_gpio), dsi);1782gpiod_put(dsi->te_gpio);1783}1784}17851786static int samsung_dsim_host_detach(struct mipi_dsi_host *host,1787struct mipi_dsi_device *device)1788{1789struct samsung_dsim *dsi = host_to_dsi(host);1790const struct samsung_dsim_plat_data *pdata = dsi->plat_data;17911792dsi->out_bridge = NULL;17931794if (pdata->host_ops && pdata->host_ops->detach)1795pdata->host_ops->detach(dsi, device);17961797samsung_dsim_unregister_te_irq(dsi);17981799drm_bridge_remove(&dsi->bridge);18001801return 0;1802}18031804static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host,1805const struct mipi_dsi_msg *msg)1806{1807struct samsung_dsim *dsi = host_to_dsi(host);1808struct samsung_dsim_transfer xfer;1809int ret;18101811if (!(dsi->state & DSIM_STATE_ENABLED))1812return -EINVAL;18131814ret = samsung_dsim_init(dsi);1815if (ret)1816return ret;18171818ret = mipi_dsi_create_packet(&xfer.packet, msg);1819if (ret < 0)1820return ret;18211822xfer.rx_len = msg->rx_len;1823xfer.rx_payload = msg->rx_buf;1824xfer.flags = msg->flags;18251826ret = samsung_dsim_transfer(dsi, &xfer);1827return (ret < 0) ? ret : xfer.rx_done;1828}18291830static const struct mipi_dsi_host_ops samsung_dsim_ops = {1831.attach = samsung_dsim_host_attach,1832.detach = samsung_dsim_host_detach,1833.transfer = samsung_dsim_host_transfer,1834};18351836static int samsung_dsim_of_read_u32(const struct device_node *np,1837const char *propname, u32 *out_value, bool optional)1838{1839int ret = of_property_read_u32(np, propname, out_value);18401841if (ret < 0 && !optional)1842pr_err("%pOF: failed to get '%s' property\n", np, propname);18431844return ret;1845}18461847static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)1848{1849struct device *dev = dsi->dev;1850struct device_node *node = dev->of_node;1851u32 lane_polarities[5] = { 0 };1852struct device_node *endpoint;1853int i, nr_lanes, ret;18541855ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",1856&dsi->pll_clk_rate, 1);1857/* If it doesn't exist, read it from the clock instead of failing */1858if (ret < 0) {1859dev_dbg(dev, "Using sclk_mipi for pll clock frequency\n");1860dsi->pll_clk = devm_clk_get(dev, "sclk_mipi");1861if (IS_ERR(dsi->pll_clk))1862return PTR_ERR(dsi->pll_clk);1863}18641865/* If it doesn't exist, use pixel clock instead of failing */1866ret = samsung_dsim_of_read_u32(node, "samsung,burst-clock-frequency",1867&dsi->burst_clk_rate, 1);1868if (ret < 0) {1869dev_dbg(dev, "Using pixel clock for HS clock frequency\n");1870dsi->burst_clk_rate = 0;1871}18721873ret = samsung_dsim_of_read_u32(node, "samsung,esc-clock-frequency",1874&dsi->esc_clk_rate, 0);1875if (ret < 0)1876return ret;18771878endpoint = of_graph_get_endpoint_by_regs(node, 1, -1);1879nr_lanes = of_property_count_u32_elems(endpoint, "data-lanes");1880if (nr_lanes > 0 && nr_lanes <= 4) {1881/* Polarity 0 is clock lane, 1..4 are data lanes. */1882of_property_read_u32_array(endpoint, "lane-polarities",1883lane_polarities, nr_lanes + 1);1884for (i = 1; i <= nr_lanes; i++) {1885if (lane_polarities[1] != lane_polarities[i])1886DRM_DEV_ERROR(dsi->dev, "Data lanes polarities do not match");1887}1888if (lane_polarities[0])1889dsi->swap_dn_dp_clk = true;1890if (lane_polarities[1])1891dsi->swap_dn_dp_data = true;1892}18931894return 0;1895}18961897static int generic_dsim_register_host(struct samsung_dsim *dsi)1898{1899return mipi_dsi_host_register(&dsi->dsi_host);1900}19011902static void generic_dsim_unregister_host(struct samsung_dsim *dsi)1903{1904mipi_dsi_host_unregister(&dsi->dsi_host);1905}19061907static const struct samsung_dsim_host_ops generic_dsim_host_ops = {1908.register_host = generic_dsim_register_host,1909.unregister_host = generic_dsim_unregister_host,1910};19111912static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_high = {1913.input_bus_flags = DRM_BUS_FLAG_DE_HIGH,1914};19151916static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_low = {1917.input_bus_flags = DRM_BUS_FLAG_DE_LOW,1918};19191920int samsung_dsim_probe(struct platform_device *pdev)1921{1922struct device *dev = &pdev->dev;1923struct samsung_dsim *dsi;1924int ret, i;19251926dsi = devm_drm_bridge_alloc(dev, struct samsung_dsim, bridge, &samsung_dsim_bridge_funcs);1927if (IS_ERR(dsi))1928return PTR_ERR(dsi);19291930init_completion(&dsi->completed);1931spin_lock_init(&dsi->transfer_lock);1932INIT_LIST_HEAD(&dsi->transfer_list);19331934dsi->dsi_host.ops = &samsung_dsim_ops;1935dsi->dsi_host.dev = dev;19361937dsi->dev = dev;1938dsi->plat_data = of_device_get_match_data(dev);1939dsi->driver_data = samsung_dsim_types[dsi->plat_data->hw_type];19401941dsi->supplies[0].supply = "vddcore";1942dsi->supplies[1].supply = "vddio";1943ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies),1944dsi->supplies);1945if (ret)1946return dev_err_probe(dev, ret, "failed to get regulators\n");19471948dsi->clks = devm_kcalloc(dev, dsi->driver_data->num_clks,1949sizeof(*dsi->clks), GFP_KERNEL);1950if (!dsi->clks)1951return -ENOMEM;19521953for (i = 0; i < dsi->driver_data->num_clks; i++) {1954dsi->clks[i] = devm_clk_get(dev, clk_names[i]);1955if (IS_ERR(dsi->clks[i])) {1956if (strcmp(clk_names[i], "sclk_mipi") == 0) {1957dsi->clks[i] = devm_clk_get(dev, OLD_SCLK_MIPI_CLK_NAME);1958if (!IS_ERR(dsi->clks[i]))1959continue;1960}19611962dev_info(dev, "failed to get the clock: %s\n", clk_names[i]);1963return PTR_ERR(dsi->clks[i]);1964}1965}19661967dsi->reg_base = devm_platform_ioremap_resource(pdev, 0);1968if (IS_ERR(dsi->reg_base))1969return PTR_ERR(dsi->reg_base);19701971dsi->phy = devm_phy_optional_get(dev, "dsim");1972if (IS_ERR(dsi->phy)) {1973dev_info(dev, "failed to get dsim phy\n");1974return PTR_ERR(dsi->phy);1975}19761977dsi->irq = platform_get_irq(pdev, 0);1978if (dsi->irq < 0)1979return dsi->irq;19801981ret = devm_request_threaded_irq(dev, dsi->irq, NULL,1982samsung_dsim_irq,1983IRQF_ONESHOT | IRQF_NO_AUTOEN,1984dev_name(dev), dsi);1985if (ret) {1986dev_err(dev, "failed to request dsi irq\n");1987return ret;1988}19891990ret = samsung_dsim_parse_dt(dsi);1991if (ret)1992return ret;19931994platform_set_drvdata(pdev, dsi);19951996pm_runtime_enable(dev);19971998dsi->bridge.of_node = dev->of_node;1999dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;20002001/* DE_LOW: i.MX8M Mini/Nano LCDIF-DSIM glue logic inverts HS/VS/DE */2002if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM)2003dsi->bridge.timings = &samsung_dsim_bridge_timings_de_low;2004else2005dsi->bridge.timings = &samsung_dsim_bridge_timings_de_high;20062007if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->register_host) {2008ret = dsi->plat_data->host_ops->register_host(dsi);2009if (ret)2010goto err_disable_runtime;2011}20122013return 0;20142015err_disable_runtime:2016pm_runtime_disable(dev);20172018return ret;2019}2020EXPORT_SYMBOL_GPL(samsung_dsim_probe);20212022void samsung_dsim_remove(struct platform_device *pdev)2023{2024struct samsung_dsim *dsi = platform_get_drvdata(pdev);20252026pm_runtime_disable(&pdev->dev);20272028if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->unregister_host)2029dsi->plat_data->host_ops->unregister_host(dsi);2030}2031EXPORT_SYMBOL_GPL(samsung_dsim_remove);20322033static int samsung_dsim_suspend(struct device *dev)2034{2035struct samsung_dsim *dsi = dev_get_drvdata(dev);2036const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;2037int ret, i;20382039usleep_range(10000, 20000);20402041if (dsi->state & DSIM_STATE_INITIALIZED) {2042dsi->state &= ~DSIM_STATE_INITIALIZED;20432044samsung_dsim_disable_clock(dsi);20452046samsung_dsim_disable_irq(dsi);2047}20482049dsi->state &= ~DSIM_STATE_CMD_LPM;20502051phy_power_off(dsi->phy);20522053for (i = driver_data->num_clks - 1; i > -1; i--)2054clk_disable_unprepare(dsi->clks[i]);20552056ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);2057if (ret < 0)2058dev_err(dsi->dev, "cannot disable regulators %d\n", ret);20592060return 0;2061}20622063static int samsung_dsim_resume(struct device *dev)2064{2065struct samsung_dsim *dsi = dev_get_drvdata(dev);2066const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;2067int ret, i;20682069ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);2070if (ret < 0) {2071dev_err(dsi->dev, "cannot enable regulators %d\n", ret);2072return ret;2073}20742075for (i = 0; i < driver_data->num_clks; i++) {2076ret = clk_prepare_enable(dsi->clks[i]);2077if (ret < 0)2078goto err_clk;2079}20802081ret = phy_power_on(dsi->phy);2082if (ret < 0) {2083dev_err(dsi->dev, "cannot enable phy %d\n", ret);2084goto err_clk;2085}20862087return 0;20882089err_clk:2090while (--i > -1)2091clk_disable_unprepare(dsi->clks[i]);2092regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);20932094return ret;2095}20962097const struct dev_pm_ops samsung_dsim_pm_ops = {2098RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL)2099SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,2100pm_runtime_force_resume)2101};2102EXPORT_SYMBOL_GPL(samsung_dsim_pm_ops);21032104static const struct samsung_dsim_plat_data samsung_dsim_imx8mm_pdata = {2105.hw_type = DSIM_TYPE_IMX8MM,2106.host_ops = &generic_dsim_host_ops,2107};21082109static const struct samsung_dsim_plat_data samsung_dsim_imx8mp_pdata = {2110.hw_type = DSIM_TYPE_IMX8MP,2111.host_ops = &generic_dsim_host_ops,2112};21132114static const struct of_device_id samsung_dsim_of_match[] = {2115{2116.compatible = "fsl,imx8mm-mipi-dsim",2117.data = &samsung_dsim_imx8mm_pdata,2118},2119{2120.compatible = "fsl,imx8mp-mipi-dsim",2121.data = &samsung_dsim_imx8mp_pdata,2122},2123{ /* sentinel. */ }2124};2125MODULE_DEVICE_TABLE(of, samsung_dsim_of_match);21262127static struct platform_driver samsung_dsim_driver = {2128.probe = samsung_dsim_probe,2129.remove = samsung_dsim_remove,2130.driver = {2131.name = "samsung-dsim",2132.pm = pm_ptr(&samsung_dsim_pm_ops),2133.of_match_table = samsung_dsim_of_match,2134},2135};21362137module_platform_driver(samsung_dsim_driver);21382139MODULE_AUTHOR("Jagan Teki <[email protected]>");2140MODULE_DESCRIPTION("Samsung MIPI DSIM controller bridge");2141MODULE_LICENSE("GPL");214221432144