Path: blob/master/drivers/gpu/drm/bridge/samsung-dsim.c
29281 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 or DSIM_DPHY_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)3738/* DSIM_SWRST */39#define DSIM_FUNCRST BIT(16)40#define DSIM_SWRST BIT(0)4142/* DSIM_TIMEOUT */43#define DSIM_LPDR_TIMEOUT(x) ((x) << 0)44#define DSIM_BTA_TIMEOUT(x) ((x) << 16)4546/* 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_DATA(x, offset) (((x) & 0xf) << offset)50#define DSIM_LANE_ESC_CLK_EN_DATA_MASK(offset) (0xf << offset)51#define DSIM_BYTE_CLK_SRC(x) (((x) & 0x3) << 25)52#define DSIM_BYTE_CLK_SRC_MASK (0x3 << 25)53#define DSIM_PLL_BYPASS BIT(27)5455/* DSIM_CONFIG */56#define DSIM_LANE_EN_CLK BIT(0)57#define DSIM_LANE_EN(x) (((x) & 0xf) << 1)58#define DSIM_NUM_OF_DATA_LANE(x) (((x) & 0x3) << 5)59#define DSIM_SUB_PIX_FORMAT(x) (((x) & 0x7) << 8)60#define DSIM_MAIN_PIX_FORMAT_MASK (0x7 << 12)61#define DSIM_MAIN_PIX_FORMAT_RGB888 (0x7 << 12)62#define DSIM_MAIN_PIX_FORMAT_RGB666 (0x6 << 12)63#define DSIM_MAIN_PIX_FORMAT_RGB666_P (0x5 << 12)64#define DSIM_MAIN_PIX_FORMAT_RGB565 (0x4 << 12)65#define DSIM_SUB_VC (((x) & 0x3) << 16)66#define DSIM_MAIN_VC (((x) & 0x3) << 18)67#define DSIM_HSA_DISABLE_MODE BIT(20)68#define DSIM_HBP_DISABLE_MODE BIT(21)69#define DSIM_HFP_DISABLE_MODE BIT(22)70/*71* The i.MX 8M Mini Applications Processor Reference Manual,72* Rev. 3, 11/2020 Page 409173* The i.MX 8M Nano Applications Processor Reference Manual,74* Rev. 2, 07/2022 Page 305875* The i.MX 8M Plus Applications Processor Reference Manual,76* Rev. 1, 06/2021 Page 543677* all claims this bit is 'HseDisableMode' with the definition78* 0 = Disables transfer79* 1 = Enables transfer80*81* This clearly states that HSE is not a disabled bit.82*83* The naming convention follows as per the manual and the84* driver logic is based on the MIPI_DSI_MODE_VIDEO_HSE flag.85*/86#define DSIM_HSE_DISABLE_MODE BIT(23)87#define DSIM_AUTO_MODE BIT(24)88#define DSIM_BURST_MODE BIT(26)89#define DSIM_SYNC_INFORM BIT(27)90#define DSIM_EOT_DISABLE BIT(28)91#define DSIM_MFLUSH_VS BIT(29)92/* This flag is valid only for exynos3250/3472/5260/5430 */93#define DSIM_CLKLANE_STOP BIT(30)94#define DSIM_NON_CONTINUOUS_CLKLANE BIT(31)9596/* DSIM_ESCMODE */97#define DSIM_TX_TRIGGER_RST BIT(4)98#define DSIM_TX_LPDT_LP BIT(6)99#define DSIM_CMD_LPDT_LP BIT(7)100#define DSIM_FORCE_BTA BIT(16)101#define DSIM_FORCE_STOP_STATE BIT(20)102#define DSIM_STOP_STATE_CNT(x) (((x) & 0x7ff) << 21)103#define DSIM_STOP_STATE_CNT_MASK (0x7ff << 21)104105/* DSIM_MDRESOL */106#define DSIM_MAIN_STAND_BY BIT(31)107#define DSIM_MAIN_VRESOL(x, num_bits) (((x) & ((1 << (num_bits)) - 1)) << 16)108#define DSIM_MAIN_HRESOL(x, num_bits) (((x) & ((1 << (num_bits)) - 1)) << 0)109110/* DSIM_MVPORCH */111#define DSIM_CMD_ALLOW(x) ((x) << 28)112#define DSIM_STABLE_VFP(x) ((x) << 16)113#define DSIM_MAIN_VBP(x) ((x) << 0)114#define DSIM_CMD_ALLOW_MASK (0xf << 28)115#define DSIM_STABLE_VFP_MASK (0x7ff << 16)116#define DSIM_MAIN_VBP_MASK (0x7ff << 0)117118/* DSIM_MHPORCH */119#define DSIM_MAIN_HFP(x) ((x) << 16)120#define DSIM_MAIN_HBP(x) ((x) << 0)121#define DSIM_MAIN_HFP_MASK ((0xffff) << 16)122#define DSIM_MAIN_HBP_MASK ((0xffff) << 0)123124/* DSIM_MSYNC */125#define DSIM_MAIN_VSA(x, offset) ((x) << offset)126#define DSIM_MAIN_HSA(x) ((x) << 0)127#define DSIM_MAIN_VSA_MASK(offset) ((0x3ff) << offset)128#define DSIM_MAIN_HSA_MASK ((0xffff) << 0)129130/* DSIM_SDRESOL */131#define DSIM_SUB_STANDY(x) ((x) << 31)132#define DSIM_SUB_VRESOL(x) ((x) << 16)133#define DSIM_SUB_HRESOL(x) ((x) << 0)134#define DSIM_SUB_STANDY_MASK ((0x1) << 31)135#define DSIM_SUB_VRESOL_MASK ((0x7ff) << 16)136#define DSIM_SUB_HRESOL_MASK ((0x7ff) << 0)137138/* DSIM_INTSRC */139#define DSIM_INT_PLL_STABLE BIT(31)140#define DSIM_INT_SW_RST_RELEASE BIT(30)141#define DSIM_INT_SFR_FIFO_EMPTY BIT(29)142#define DSIM_INT_SFR_HDR_FIFO_EMPTY BIT(28)143#define DSIM_INT_BTA BIT(25)144#define DSIM_INT_FRAME_DONE BIT(24)145#define DSIM_INT_RX_TIMEOUT BIT(21)146#define DSIM_INT_BTA_TIMEOUT BIT(20)147#define DSIM_INT_RX_DONE BIT(18)148#define DSIM_INT_RX_TE BIT(17)149#define DSIM_INT_RX_ACK BIT(16)150#define DSIM_INT_RX_ECC_ERR BIT(15)151#define DSIM_INT_RX_CRC_ERR BIT(14)152153/* DSIM_SFRCTRL */154#define DSIM_SFR_CTRL_STAND_BY BIT(4)155#define DSIM_SFR_CTRL_SHADOW_UPDATE BIT(1)156#define DSIM_SFR_CTRL_SHADOW_EN BIT(0)157158/* 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)182183/* DSIM_PHYACCHR */184#define DSIM_AFC_EN BIT(14)185#define DSIM_AFC_CTL(x) (((x) & 0x7) << 5)186187/* 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(x, offset) ((x) << (offset))193194/* DSIM_PHYCTRL */195#define DSIM_PHYCTRL_ULPS_EXIT(x) (((x) & 0x1ff) << 0)196#define DSIM_PHYCTRL_B_DPHYCTL_VREG_LP BIT(30)197#define DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP BIT(14)198199/* DSIM_PHYTIMING */200#define DSIM_PHYTIMING_LPX(x) ((x) << 8)201#define DSIM_PHYTIMING_HS_EXIT(x) ((x) << 0)202203/* DSIM_PHYTIMING1 */204#define DSIM_PHYTIMING1_CLK_PREPARE(x) ((x) << 24)205#define DSIM_PHYTIMING1_CLK_ZERO(x) ((x) << 16)206#define DSIM_PHYTIMING1_CLK_POST(x) ((x) << 8)207#define DSIM_PHYTIMING1_CLK_TRAIL(x) ((x) << 0)208209/* DSIM_PHYTIMING2 */210#define DSIM_PHYTIMING2_HS_PREPARE(x) ((x) << 16)211#define DSIM_PHYTIMING2_HS_ZERO(x) ((x) << 8)212#define DSIM_PHYTIMING2_HS_TRAIL(x) ((x) << 0)213214#define DSI_MAX_BUS_WIDTH 4215#define DSI_NUM_VIRTUAL_CHANNELS 4216#define DSI_TX_FIFO_SIZE 2048217#define DSI_RX_FIFO_SIZE 256218#define DSI_XFER_TIMEOUT_MS 100219#define DSI_RX_FIFO_EMPTY 0x30800002220221#define PS_TO_CYCLE(ps, hz) DIV64_U64_ROUND_CLOSEST(((ps) * (hz)), 1000000000000ULL)222223enum samsung_dsim_transfer_type {224EXYNOS_DSI_TX,225EXYNOS_DSI_RX,226};227228static struct clk_bulk_data exynos3_clk_bulk_data[] = {229{ .id = "bus_clk" },230{ .id = "pll_clk" },231};232233static struct clk_bulk_data exynos4_clk_bulk_data[] = {234{ .id = "bus_clk" },235{ .id = "sclk_mipi" },236};237238static struct clk_bulk_data exynos5433_clk_bulk_data[] = {239{ .id = "bus_clk" },240{ .id = "sclk_mipi" },241{ .id = "phyclk_mipidphy0_bitclkdiv8" },242{ .id = "phyclk_mipidphy0_rxclkesc0" },243{ .id = "sclk_rgb_vclk_to_dsim0" },244};245246static struct clk_bulk_data exynos7870_clk_bulk_data[] = {247{ .id = "bus" },248{ .id = "pll" },249{ .id = "byte" },250{ .id = "esc" },251};252253enum reg_idx {254DSIM_STATUS_REG, /* Status register (legacy) */255DSIM_LINK_STATUS_REG, /* Link status register */256DSIM_DPHY_STATUS_REG, /* D-PHY status register */257DSIM_SWRST_REG, /* Software reset register */258DSIM_CLKCTRL_REG, /* Clock control register */259DSIM_TIMEOUT_REG, /* Time out register */260DSIM_CONFIG_REG, /* Configuration register */261DSIM_ESCMODE_REG, /* Escape mode register */262DSIM_MDRESOL_REG,263DSIM_MVPORCH_REG, /* Main display Vporch register */264DSIM_MHPORCH_REG, /* Main display Hporch register */265DSIM_MSYNC_REG, /* Main display sync area register */266DSIM_INTSRC_REG, /* Interrupt source register */267DSIM_INTMSK_REG, /* Interrupt mask register */268DSIM_PKTHDR_REG, /* Packet Header FIFO register */269DSIM_PAYLOAD_REG, /* Payload FIFO register */270DSIM_RXFIFO_REG, /* Read FIFO register */271DSIM_SFRCTRL_REG, /* SFR standby and shadow control register */272DSIM_FIFOCTRL_REG, /* FIFO status and control register */273DSIM_PLLCTRL_REG, /* PLL control register */274DSIM_PHYCTRL_REG,275DSIM_PHYTIMING_REG,276DSIM_PHYTIMING1_REG,277DSIM_PHYTIMING2_REG,278NUM_REGS279};280281static const unsigned int exynos_reg_ofs[] = {282[DSIM_STATUS_REG] = 0x00,283[DSIM_SWRST_REG] = 0x04,284[DSIM_CLKCTRL_REG] = 0x08,285[DSIM_TIMEOUT_REG] = 0x0c,286[DSIM_CONFIG_REG] = 0x10,287[DSIM_ESCMODE_REG] = 0x14,288[DSIM_MDRESOL_REG] = 0x18,289[DSIM_MVPORCH_REG] = 0x1c,290[DSIM_MHPORCH_REG] = 0x20,291[DSIM_MSYNC_REG] = 0x24,292[DSIM_INTSRC_REG] = 0x2c,293[DSIM_INTMSK_REG] = 0x30,294[DSIM_PKTHDR_REG] = 0x34,295[DSIM_PAYLOAD_REG] = 0x38,296[DSIM_RXFIFO_REG] = 0x3c,297[DSIM_FIFOCTRL_REG] = 0x44,298[DSIM_PLLCTRL_REG] = 0x4c,299[DSIM_PHYCTRL_REG] = 0x5c,300[DSIM_PHYTIMING_REG] = 0x64,301[DSIM_PHYTIMING1_REG] = 0x68,302[DSIM_PHYTIMING2_REG] = 0x6c,303};304305static const unsigned int exynos5433_reg_ofs[] = {306[DSIM_STATUS_REG] = 0x04,307[DSIM_SWRST_REG] = 0x0C,308[DSIM_CLKCTRL_REG] = 0x10,309[DSIM_TIMEOUT_REG] = 0x14,310[DSIM_CONFIG_REG] = 0x18,311[DSIM_ESCMODE_REG] = 0x1C,312[DSIM_MDRESOL_REG] = 0x20,313[DSIM_MVPORCH_REG] = 0x24,314[DSIM_MHPORCH_REG] = 0x28,315[DSIM_MSYNC_REG] = 0x2C,316[DSIM_INTSRC_REG] = 0x34,317[DSIM_INTMSK_REG] = 0x38,318[DSIM_PKTHDR_REG] = 0x3C,319[DSIM_PAYLOAD_REG] = 0x40,320[DSIM_RXFIFO_REG] = 0x44,321[DSIM_FIFOCTRL_REG] = 0x4C,322[DSIM_PLLCTRL_REG] = 0x94,323[DSIM_PHYCTRL_REG] = 0xA4,324[DSIM_PHYTIMING_REG] = 0xB4,325[DSIM_PHYTIMING1_REG] = 0xB8,326[DSIM_PHYTIMING2_REG] = 0xBC,327};328329static const unsigned int exynos7870_reg_ofs[] = {330[DSIM_LINK_STATUS_REG] = 0x04,331[DSIM_DPHY_STATUS_REG] = 0x08,332[DSIM_SWRST_REG] = 0x0C,333[DSIM_CLKCTRL_REG] = 0x10,334[DSIM_TIMEOUT_REG] = 0x14,335[DSIM_ESCMODE_REG] = 0x1C,336[DSIM_MDRESOL_REG] = 0x20,337[DSIM_MVPORCH_REG] = 0x24,338[DSIM_MHPORCH_REG] = 0x28,339[DSIM_MSYNC_REG] = 0x2C,340[DSIM_CONFIG_REG] = 0x30,341[DSIM_INTSRC_REG] = 0x34,342[DSIM_INTMSK_REG] = 0x38,343[DSIM_PKTHDR_REG] = 0x3C,344[DSIM_PAYLOAD_REG] = 0x40,345[DSIM_RXFIFO_REG] = 0x44,346[DSIM_SFRCTRL_REG] = 0x48,347[DSIM_FIFOCTRL_REG] = 0x4C,348[DSIM_PLLCTRL_REG] = 0x94,349[DSIM_PHYCTRL_REG] = 0xA4,350[DSIM_PHYTIMING_REG] = 0xB4,351[DSIM_PHYTIMING1_REG] = 0xB8,352[DSIM_PHYTIMING2_REG] = 0xBC,353};354355enum reg_value_idx {356RESET_TYPE,357PLL_TIMER,358STOP_STATE_CNT,359PHYCTRL_ULPS_EXIT,360PHYCTRL_VREG_LP,361PHYCTRL_SLEW_UP,362PHYTIMING_LPX,363PHYTIMING_HS_EXIT,364PHYTIMING_CLK_PREPARE,365PHYTIMING_CLK_ZERO,366PHYTIMING_CLK_POST,367PHYTIMING_CLK_TRAIL,368PHYTIMING_HS_PREPARE,369PHYTIMING_HS_ZERO,370PHYTIMING_HS_TRAIL371};372373static const unsigned int reg_values[] = {374[RESET_TYPE] = DSIM_SWRST,375[PLL_TIMER] = 500,376[STOP_STATE_CNT] = 0xf,377[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x0af),378[PHYCTRL_VREG_LP] = 0,379[PHYCTRL_SLEW_UP] = 0,380[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),381[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),382[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),383[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x27),384[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),385[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),386[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x09),387[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),388[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),389};390391static const unsigned int exynos5422_reg_values[] = {392[RESET_TYPE] = DSIM_SWRST,393[PLL_TIMER] = 500,394[STOP_STATE_CNT] = 0xf,395[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),396[PHYCTRL_VREG_LP] = 0,397[PHYCTRL_SLEW_UP] = 0,398[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x08),399[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0d),400[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),401[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x30),402[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),403[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x0a),404[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0c),405[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x11),406[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0d),407};408409static const unsigned int exynos5433_reg_values[] = {410[RESET_TYPE] = DSIM_FUNCRST,411[PLL_TIMER] = 22200,412[STOP_STATE_CNT] = 0xa,413[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x190),414[PHYCTRL_VREG_LP] = DSIM_PHYCTRL_B_DPHYCTL_VREG_LP,415[PHYCTRL_SLEW_UP] = DSIM_PHYCTRL_B_DPHYCTL_SLEW_UP,416[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x07),417[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0c),418[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),419[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x2d),420[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),421[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x09),422[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0b),423[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x10),424[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),425};426427static const unsigned int exynos7870_reg_values[] = {428[RESET_TYPE] = DSIM_SWRST,429[PLL_TIMER] = 80000,430[STOP_STATE_CNT] = 0xa,431[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0x177),432[PHYCTRL_VREG_LP] = 0,433[PHYCTRL_SLEW_UP] = 0,434[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x07),435[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0c),436[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x08),437[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x2b),438[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),439[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x09),440[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x09),441[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0f),442[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),443};444445static const unsigned int imx8mm_dsim_reg_values[] = {446[RESET_TYPE] = DSIM_SWRST,447[PLL_TIMER] = 500,448[STOP_STATE_CNT] = 0xf,449[PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),450[PHYCTRL_VREG_LP] = 0,451[PHYCTRL_SLEW_UP] = 0,452[PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),453[PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),454[PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),455[PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x26),456[PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),457[PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),458[PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x08),459[PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),460[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),461};462463static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {464.reg_ofs = exynos_reg_ofs,465.plltmr_reg = 0x50,466.has_legacy_status_reg = 1,467.has_freqband = 1,468.has_clklane_stop = 1,469.clk_data = exynos3_clk_bulk_data,470.num_clks = ARRAY_SIZE(exynos3_clk_bulk_data),471.max_freq = 1000,472.wait_for_hdr_fifo = 1,473.wait_for_reset = 1,474.num_bits_resol = 11,475.video_mode_bit = 25,476.pll_stable_bit = 31,477.esc_clken_bit = 28,478.byte_clken_bit = 24,479.tx_req_hsclk_bit = 31,480.lane_esc_clk_bit = 19,481.lane_esc_data_offset = 20,482.pll_p_offset = 13,483.pll_m_offset = 4,484.pll_s_offset = 1,485.main_vsa_offset = 22,486.reg_values = reg_values,487.pll_fin_min = 6,488.pll_fin_max = 12,489.m_min = 41,490.m_max = 125,491.min_freq = 500,492.has_broken_fifoctrl_emptyhdr = 1,493};494495static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {496.reg_ofs = exynos_reg_ofs,497.plltmr_reg = 0x50,498.has_legacy_status_reg = 1,499.has_freqband = 1,500.has_clklane_stop = 1,501.clk_data = exynos4_clk_bulk_data,502.num_clks = ARRAY_SIZE(exynos4_clk_bulk_data),503.max_freq = 1000,504.wait_for_hdr_fifo = 1,505.wait_for_reset = 1,506.num_bits_resol = 11,507.video_mode_bit = 25,508.pll_stable_bit = 31,509.esc_clken_bit = 28,510.byte_clken_bit = 24,511.tx_req_hsclk_bit = 31,512.lane_esc_clk_bit = 19,513.lane_esc_data_offset = 20,514.pll_p_offset = 13,515.pll_m_offset = 4,516.pll_s_offset = 1,517.main_vsa_offset = 22,518.reg_values = reg_values,519.pll_fin_min = 6,520.pll_fin_max = 12,521.m_min = 41,522.m_max = 125,523.min_freq = 500,524.has_broken_fifoctrl_emptyhdr = 1,525};526527static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {528.reg_ofs = exynos_reg_ofs,529.plltmr_reg = 0x58,530.has_legacy_status_reg = 1,531.clk_data = exynos3_clk_bulk_data,532.num_clks = ARRAY_SIZE(exynos3_clk_bulk_data),533.max_freq = 1000,534.wait_for_hdr_fifo = 1,535.wait_for_reset = 1,536.num_bits_resol = 11,537.video_mode_bit = 25,538.pll_stable_bit = 31,539.esc_clken_bit = 28,540.byte_clken_bit = 24,541.tx_req_hsclk_bit = 31,542.lane_esc_clk_bit = 19,543.lane_esc_data_offset = 20,544.pll_p_offset = 13,545.pll_m_offset = 4,546.pll_s_offset = 1,547.main_vsa_offset = 22,548.reg_values = reg_values,549.pll_fin_min = 6,550.pll_fin_max = 12,551.m_min = 41,552.m_max = 125,553.min_freq = 500,554};555556static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {557.reg_ofs = exynos5433_reg_ofs,558.plltmr_reg = 0xa0,559.has_legacy_status_reg = 1,560.has_clklane_stop = 1,561.clk_data = exynos5433_clk_bulk_data,562.num_clks = ARRAY_SIZE(exynos5433_clk_bulk_data),563.max_freq = 1500,564.wait_for_hdr_fifo = 1,565.wait_for_reset = 0,566.num_bits_resol = 12,567.video_mode_bit = 25,568.pll_stable_bit = 31,569.esc_clken_bit = 28,570.byte_clken_bit = 24,571.tx_req_hsclk_bit = 31,572.lane_esc_clk_bit = 19,573.lane_esc_data_offset = 20,574.pll_p_offset = 13,575.pll_m_offset = 4,576.pll_s_offset = 1,577.main_vsa_offset = 22,578.reg_values = exynos5433_reg_values,579.pll_fin_min = 6,580.pll_fin_max = 12,581.m_min = 41,582.m_max = 125,583.min_freq = 500,584};585586static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {587.reg_ofs = exynos5433_reg_ofs,588.plltmr_reg = 0xa0,589.has_legacy_status_reg = 1,590.has_clklane_stop = 1,591.clk_data = exynos3_clk_bulk_data,592.num_clks = ARRAY_SIZE(exynos3_clk_bulk_data),593.max_freq = 1500,594.wait_for_hdr_fifo = 1,595.wait_for_reset = 1,596.num_bits_resol = 12,597.video_mode_bit = 25,598.pll_stable_bit = 31,599.esc_clken_bit = 28,600.byte_clken_bit = 24,601.tx_req_hsclk_bit = 31,602.lane_esc_clk_bit = 19,603.lane_esc_data_offset = 20,604.pll_p_offset = 13,605.pll_m_offset = 4,606.pll_s_offset = 1,607.main_vsa_offset = 22,608.reg_values = exynos5422_reg_values,609.pll_fin_min = 6,610.pll_fin_max = 12,611.m_min = 41,612.m_max = 125,613.min_freq = 500,614};615616static const struct samsung_dsim_driver_data exynos7870_dsi_driver_data = {617.reg_ofs = exynos7870_reg_ofs,618.plltmr_reg = 0xa0,619.has_clklane_stop = 1,620.has_sfrctrl = 1,621.clk_data = exynos7870_clk_bulk_data,622.num_clks = ARRAY_SIZE(exynos7870_clk_bulk_data),623.max_freq = 1500,624.wait_for_hdr_fifo = 0,625.wait_for_reset = 1,626.num_bits_resol = 12,627.video_mode_bit = 18,628.pll_stable_bit = 24,629.esc_clken_bit = 16,630.byte_clken_bit = 17,631.tx_req_hsclk_bit = 20,632.lane_esc_clk_bit = 8,633.lane_esc_data_offset = 9,634.pll_p_offset = 13,635.pll_m_offset = 3,636.pll_s_offset = 0,637.main_vsa_offset = 16,638.reg_values = exynos7870_reg_values,639.pll_fin_min = 6,640.pll_fin_max = 12,641.m_min = 41,642.m_max = 125,643.min_freq = 500,644};645646static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {647.reg_ofs = exynos5433_reg_ofs,648.plltmr_reg = 0xa0,649.has_legacy_status_reg = 1,650.has_clklane_stop = 1,651.clk_data = exynos4_clk_bulk_data,652.num_clks = ARRAY_SIZE(exynos4_clk_bulk_data),653.max_freq = 2100,654.wait_for_hdr_fifo = 1,655.wait_for_reset = 0,656.num_bits_resol = 12,657.video_mode_bit = 25,658.pll_stable_bit = 31,659.esc_clken_bit = 28,660.byte_clken_bit = 24,661.tx_req_hsclk_bit = 31,662.lane_esc_clk_bit = 19,663.lane_esc_data_offset = 20,664/*665* Unlike Exynos, PLL_P(PMS_P) offset 14 is used in i.MX8M Mini/Nano/Plus666* downstream driver - drivers/gpu/drm/bridge/sec-dsim.c667*/668.pll_p_offset = 14,669.pll_m_offset = 4,670.pll_s_offset = 1,671.main_vsa_offset = 22,672.reg_values = imx8mm_dsim_reg_values,673.pll_fin_min = 2,674.pll_fin_max = 30,675.m_min = 64,676.m_max = 1023,677.min_freq = 1050,678};679680static const struct samsung_dsim_driver_data *681samsung_dsim_types[DSIM_TYPE_COUNT] = {682[DSIM_TYPE_EXYNOS3250] = &exynos3_dsi_driver_data,683[DSIM_TYPE_EXYNOS4210] = &exynos4_dsi_driver_data,684[DSIM_TYPE_EXYNOS5410] = &exynos5_dsi_driver_data,685[DSIM_TYPE_EXYNOS5422] = &exynos5422_dsi_driver_data,686[DSIM_TYPE_EXYNOS5433] = &exynos5433_dsi_driver_data,687[DSIM_TYPE_EXYNOS7870] = &exynos7870_dsi_driver_data,688[DSIM_TYPE_IMX8MM] = &imx8mm_dsi_driver_data,689[DSIM_TYPE_IMX8MP] = &imx8mm_dsi_driver_data,690};691692static inline struct samsung_dsim *host_to_dsi(struct mipi_dsi_host *h)693{694return container_of(h, struct samsung_dsim, dsi_host);695}696697static inline struct samsung_dsim *bridge_to_dsi(struct drm_bridge *b)698{699return container_of(b, struct samsung_dsim, bridge);700}701702static inline void samsung_dsim_write(struct samsung_dsim *dsi,703enum reg_idx idx, u32 val)704{705writel(val, dsi->reg_base + dsi->driver_data->reg_ofs[idx]);706}707708static inline u32 samsung_dsim_read(struct samsung_dsim *dsi, enum reg_idx idx)709{710return readl(dsi->reg_base + dsi->driver_data->reg_ofs[idx]);711}712713static void samsung_dsim_wait_for_reset(struct samsung_dsim *dsi)714{715if (wait_for_completion_timeout(&dsi->completed, msecs_to_jiffies(300)))716return;717718dev_err(dsi->dev, "timeout waiting for reset\n");719}720721static void samsung_dsim_reset(struct samsung_dsim *dsi)722{723u32 reset_val = dsi->driver_data->reg_values[RESET_TYPE];724725reinit_completion(&dsi->completed);726samsung_dsim_write(dsi, DSIM_SWRST_REG, reset_val);727}728729static unsigned long samsung_dsim_pll_find_pms(struct samsung_dsim *dsi,730unsigned long fin,731unsigned long fout,732u8 *p, u16 *m, u8 *s)733{734const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;735unsigned long best_freq = 0;736u32 min_delta = 0xffffffff;737u8 p_min, p_max;738u8 _p, best_p;739u16 _m, best_m;740u8 _s, best_s;741742p_min = DIV_ROUND_UP(fin, (driver_data->pll_fin_max * HZ_PER_MHZ));743p_max = fin / (driver_data->pll_fin_min * HZ_PER_MHZ);744745for (_p = p_min; _p <= p_max; ++_p) {746for (_s = 0; _s <= 5; ++_s) {747u64 tmp;748u32 delta;749750tmp = (u64)fout * (_p << _s);751do_div(tmp, fin);752_m = tmp;753if (_m < driver_data->m_min || _m > driver_data->m_max)754continue;755756tmp = (u64)_m * fin;757do_div(tmp, _p);758if (tmp < driver_data->min_freq * HZ_PER_MHZ ||759tmp > driver_data->max_freq * HZ_PER_MHZ)760continue;761762tmp = (u64)_m * fin;763do_div(tmp, _p << _s);764765delta = abs(fout - tmp);766if (delta < min_delta) {767best_p = _p;768best_m = _m;769best_s = _s;770min_delta = delta;771best_freq = tmp;772}773}774}775776if (best_freq) {777*p = best_p;778*m = best_m;779*s = best_s;780}781782return best_freq;783}784785static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi,786unsigned long freq)787{788const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;789unsigned long fin, fout;790int timeout;791u8 p, s;792u16 m;793u32 reg;794795if (dsi->pll_clk) {796/*797* Ensure that the reference clock is generated with a power of798* two divider from its parent, but close to the PLLs upper799* limit.800*/801fin = clk_get_rate(clk_get_parent(dsi->pll_clk));802while (fin > driver_data->pll_fin_max * HZ_PER_MHZ)803fin /= 2;804clk_set_rate(dsi->pll_clk, fin);805806fin = clk_get_rate(dsi->pll_clk);807} else {808fin = dsi->pll_clk_rate;809}810dev_dbg(dsi->dev, "PLL ref clock freq %lu\n", fin);811812fout = samsung_dsim_pll_find_pms(dsi, fin, freq, &p, &m, &s);813if (!fout) {814dev_err(dsi->dev,815"failed to find PLL PMS for requested frequency\n");816return 0;817}818dev_dbg(dsi->dev, "PLL freq %lu, (p %d, m %d, s %d)\n", fout, p, m, s);819820writel(driver_data->reg_values[PLL_TIMER],821dsi->reg_base + driver_data->plltmr_reg);822823reg = DSIM_PLL_EN | DSIM_PLL(p, driver_data->pll_p_offset)824| DSIM_PLL(m, driver_data->pll_m_offset)825| DSIM_PLL(s, driver_data->pll_s_offset);826827if (driver_data->has_freqband) {828static const unsigned long freq_bands[] = {829100 * HZ_PER_MHZ, 120 * HZ_PER_MHZ, 160 * HZ_PER_MHZ,830200 * HZ_PER_MHZ, 270 * HZ_PER_MHZ, 320 * HZ_PER_MHZ,831390 * HZ_PER_MHZ, 450 * HZ_PER_MHZ, 510 * HZ_PER_MHZ,832560 * HZ_PER_MHZ, 640 * HZ_PER_MHZ, 690 * HZ_PER_MHZ,833770 * HZ_PER_MHZ, 870 * HZ_PER_MHZ, 950 * HZ_PER_MHZ,834};835int band;836837for (band = 0; band < ARRAY_SIZE(freq_bands); ++band)838if (fout < freq_bands[band])839break;840841dev_dbg(dsi->dev, "band %d\n", band);842843reg |= DSIM_FREQ_BAND(band);844}845846if (dsi->swap_dn_dp_clk)847reg |= DSIM_PLL_DPDNSWAP_CLK;848if (dsi->swap_dn_dp_data)849reg |= DSIM_PLL_DPDNSWAP_DAT;850851samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);852853timeout = 3000;854do {855if (timeout-- == 0) {856dev_err(dsi->dev, "PLL failed to stabilize\n");857return 0;858}859if (driver_data->has_legacy_status_reg)860reg = samsung_dsim_read(dsi, DSIM_STATUS_REG);861else862reg = samsung_dsim_read(dsi, DSIM_LINK_STATUS_REG);863} while ((reg & BIT(driver_data->pll_stable_bit)) == 0);864865dsi->hs_clock = fout;866867return fout;868}869870static int samsung_dsim_enable_clock(struct samsung_dsim *dsi)871{872const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;873unsigned long hs_clk, byte_clk, esc_clk, pix_clk;874unsigned long esc_div;875u32 reg;876struct drm_display_mode *m = &dsi->mode;877int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);878879/* m->clock is in KHz */880pix_clk = m->clock * 1000;881882/* Use burst_clk_rate if available, otherwise use the pix_clk */883if (dsi->burst_clk_rate)884hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate);885else886hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, dsi->lanes));887888if (!hs_clk) {889dev_err(dsi->dev, "failed to configure DSI PLL\n");890return -EFAULT;891}892893byte_clk = hs_clk / 8;894esc_div = DIV_ROUND_UP(byte_clk, dsi->esc_clk_rate);895esc_clk = byte_clk / esc_div;896897if (esc_clk > 20 * HZ_PER_MHZ) {898++esc_div;899esc_clk = byte_clk / esc_div;900}901902dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",903hs_clk, byte_clk, esc_clk);904905reg = samsung_dsim_read(dsi, DSIM_CLKCTRL_REG);906reg &= ~(DSIM_ESC_PRESCALER_MASK | BIT(driver_data->lane_esc_clk_bit)907| DSIM_LANE_ESC_CLK_EN_DATA_MASK(driver_data->lane_esc_data_offset)908| DSIM_PLL_BYPASS909| DSIM_BYTE_CLK_SRC_MASK);910reg |= BIT(driver_data->esc_clken_bit) | BIT(driver_data->byte_clken_bit)911| DSIM_ESC_PRESCALER(esc_div)912| BIT(driver_data->lane_esc_clk_bit)913| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1,914driver_data->lane_esc_data_offset)915| DSIM_BYTE_CLK_SRC(0)916| BIT(driver_data->tx_req_hsclk_bit);917samsung_dsim_write(dsi, DSIM_CLKCTRL_REG, reg);918919return 0;920}921922static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi)923{924const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;925const unsigned int *reg_values = driver_data->reg_values;926u32 reg;927struct phy_configure_opts_mipi_dphy cfg;928int clk_prepare, lpx, clk_zero, clk_post, clk_trail;929int hs_exit, hs_prepare, hs_zero, hs_trail;930unsigned long long byte_clock = dsi->hs_clock / 8;931932if (driver_data->has_freqband)933return;934935phy_mipi_dphy_get_default_config_for_hsclk(dsi->hs_clock,936dsi->lanes, &cfg);937938/*939* TODO:940* The tech Applications Processor manuals for i.MX8M Mini, Nano,941* and Plus don't state what the definition of the PHYTIMING942* bits are beyond their address and bit position.943* After reviewing NXP's downstream code, it appears944* that the various PHYTIMING registers take the number945* of cycles and use various dividers on them. This946* calculation does not result in an exact match to the947* downstream code, but it is very close to the values948* generated by their lookup table, and it appears949* to sync at a variety of resolutions. If someone950* can get a more accurate mathematical equation needed951* for these registers, this should be updated.952*/953954lpx = PS_TO_CYCLE(cfg.lpx, byte_clock);955hs_exit = PS_TO_CYCLE(cfg.hs_exit, byte_clock);956clk_prepare = PS_TO_CYCLE(cfg.clk_prepare, byte_clock);957clk_zero = PS_TO_CYCLE(cfg.clk_zero, byte_clock);958clk_post = PS_TO_CYCLE(cfg.clk_post, byte_clock);959clk_trail = PS_TO_CYCLE(cfg.clk_trail, byte_clock);960hs_prepare = PS_TO_CYCLE(cfg.hs_prepare, byte_clock);961hs_zero = PS_TO_CYCLE(cfg.hs_zero, byte_clock);962hs_trail = PS_TO_CYCLE(cfg.hs_trail, byte_clock);963964/* B D-PHY: D-PHY Master & Slave Analog Block control */965reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |966reg_values[PHYCTRL_SLEW_UP];967968samsung_dsim_write(dsi, DSIM_PHYCTRL_REG, reg);969970/*971* T LPX: Transmitted length of any Low-Power state period972* T HS-EXIT: Time that the transmitter drives LP-11 following a HS973* burst974*/975976reg = DSIM_PHYTIMING_LPX(lpx) | DSIM_PHYTIMING_HS_EXIT(hs_exit);977978samsung_dsim_write(dsi, DSIM_PHYTIMING_REG, reg);979980/*981* T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00982* Line state immediately before the HS-0 Line state starting the983* HS transmission984* T CLK-ZERO: Time that the transmitter drives the HS-0 state prior to985* transmitting the Clock.986* T CLK_POST: Time that the transmitter continues to send HS clock987* after the last associated Data Lane has transitioned to LP Mode988* Interval is defined as the period from the end of T HS-TRAIL to989* the beginning of T CLK-TRAIL990* T CLK-TRAIL: Time that the transmitter drives the HS-0 state after991* the last payload clock bit of a HS transmission burst992*/993994reg = DSIM_PHYTIMING1_CLK_PREPARE(clk_prepare) |995DSIM_PHYTIMING1_CLK_ZERO(clk_zero) |996DSIM_PHYTIMING1_CLK_POST(clk_post) |997DSIM_PHYTIMING1_CLK_TRAIL(clk_trail);998999samsung_dsim_write(dsi, DSIM_PHYTIMING1_REG, reg);10001001/*1002* T HS-PREPARE: Time that the transmitter drives the Data Lane LP-001003* Line state immediately before the HS-0 Line state starting the1004* HS transmission1005* T HS-ZERO: Time that the transmitter drives the HS-0 state prior to1006* transmitting the Sync sequence.1007* T HS-TRAIL: Time that the transmitter drives the flipped differential1008* state after last payload data bit of a HS transmission burst1009*/10101011reg = DSIM_PHYTIMING2_HS_PREPARE(hs_prepare) |1012DSIM_PHYTIMING2_HS_ZERO(hs_zero) |1013DSIM_PHYTIMING2_HS_TRAIL(hs_trail);10141015samsung_dsim_write(dsi, DSIM_PHYTIMING2_REG, reg);1016}10171018static void samsung_dsim_disable_clock(struct samsung_dsim *dsi)1019{1020const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;1021u32 reg;10221023reg = samsung_dsim_read(dsi, DSIM_CLKCTRL_REG);1024reg &= ~(BIT(driver_data->lane_esc_clk_bit)1025| DSIM_LANE_ESC_CLK_EN_DATA_MASK(driver_data->lane_esc_data_offset)1026| BIT(driver_data->esc_clken_bit)1027| BIT(driver_data->byte_clken_bit));1028samsung_dsim_write(dsi, DSIM_CLKCTRL_REG, reg);10291030reg = samsung_dsim_read(dsi, DSIM_PLLCTRL_REG);1031reg &= ~DSIM_PLL_EN;1032samsung_dsim_write(dsi, DSIM_PLLCTRL_REG, reg);1033}10341035static void samsung_dsim_enable_lane(struct samsung_dsim *dsi, u32 lane)1036{1037u32 reg = samsung_dsim_read(dsi, DSIM_CONFIG_REG);10381039reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |1040DSIM_LANE_EN(lane));1041samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg);1042}10431044static int samsung_dsim_init_link(struct samsung_dsim *dsi)1045{1046const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;1047int timeout;1048u32 reg;1049u32 lanes_mask;10501051/* Initialize FIFO pointers */1052reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG);1053reg &= ~0x1f;1054samsung_dsim_write(dsi, DSIM_FIFOCTRL_REG, reg);10551056usleep_range(9000, 11000);10571058reg |= 0x1f;1059samsung_dsim_write(dsi, DSIM_FIFOCTRL_REG, reg);1060usleep_range(9000, 11000);10611062/* DSI configuration */1063reg = 0;10641065/*1066* The first bit of mode_flags specifies display configuration.1067* If this bit is set[= MIPI_DSI_MODE_VIDEO], dsi will support video1068* mode, otherwise it will support command mode.1069*/1070if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {1071reg |= BIT(driver_data->video_mode_bit);10721073/*1074* The user manual describes that following bits are ignored in1075* command mode.1076*/1077if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)1078reg |= DSIM_SYNC_INFORM;1079if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)1080reg |= DSIM_BURST_MODE;1081if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_AUTO_VERT)1082reg |= DSIM_AUTO_MODE;1083if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_HSE)1084reg |= DSIM_HSE_DISABLE_MODE;1085if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HFP)1086reg |= DSIM_HFP_DISABLE_MODE;1087if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HBP)1088reg |= DSIM_HBP_DISABLE_MODE;1089if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_NO_HSA)1090reg |= DSIM_HSA_DISABLE_MODE;1091}10921093if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)1094reg |= DSIM_EOT_DISABLE;10951096switch (dsi->format) {1097case MIPI_DSI_FMT_RGB888:1098reg |= DSIM_MAIN_PIX_FORMAT_RGB888;1099break;1100case MIPI_DSI_FMT_RGB666:1101reg |= DSIM_MAIN_PIX_FORMAT_RGB666;1102break;1103case MIPI_DSI_FMT_RGB666_PACKED:1104reg |= DSIM_MAIN_PIX_FORMAT_RGB666_P;1105break;1106case MIPI_DSI_FMT_RGB565:1107reg |= DSIM_MAIN_PIX_FORMAT_RGB565;1108break;1109default:1110dev_err(dsi->dev, "invalid pixel format\n");1111return -EINVAL;1112}11131114/*1115* Use non-continuous clock mode if the periparal wants and1116* host controller supports1117*1118* In non-continous clock mode, host controller will turn off1119* the HS clock between high-speed transmissions to reduce1120* power consumption.1121*/1122if (driver_data->has_clklane_stop &&1123dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {1124if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type))1125reg |= DSIM_NON_CONTINUOUS_CLKLANE;11261127reg |= DSIM_CLKLANE_STOP;1128}1129samsung_dsim_write(dsi, DSIM_CONFIG_REG, reg);11301131lanes_mask = BIT(dsi->lanes) - 1;1132samsung_dsim_enable_lane(dsi, lanes_mask);11331134/* Check clock and data lane state are stop state */1135timeout = 100;1136do {1137if (timeout-- == 0) {1138dev_err(dsi->dev, "waiting for bus lanes timed out\n");1139return -EFAULT;1140}11411142if (driver_data->has_legacy_status_reg)1143reg = samsung_dsim_read(dsi, DSIM_STATUS_REG);1144else1145reg = samsung_dsim_read(dsi, DSIM_DPHY_STATUS_REG);1146if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))1147!= DSIM_STOP_STATE_DAT(lanes_mask))1148continue;1149} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));11501151reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);1152reg &= ~DSIM_STOP_STATE_CNT_MASK;1153reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]);1154samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg);11551156reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);1157samsung_dsim_write(dsi, DSIM_TIMEOUT_REG, reg);11581159return 0;1160}11611162static void samsung_dsim_set_display_mode(struct samsung_dsim *dsi)1163{1164struct drm_display_mode *m = &dsi->mode;1165unsigned int num_bits_resol = dsi->driver_data->num_bits_resol;1166unsigned int main_vsa_offset = dsi->driver_data->main_vsa_offset;1167u32 reg;11681169if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {1170u64 byte_clk = dsi->hs_clock / 8;1171u64 pix_clk = m->clock * 1000;11721173int hfp = DIV64_U64_ROUND_UP((m->hsync_start - m->hdisplay) * byte_clk, pix_clk);1174int hbp = DIV64_U64_ROUND_UP((m->htotal - m->hsync_end) * byte_clk, pix_clk);1175int hsa = DIV64_U64_ROUND_UP((m->hsync_end - m->hsync_start) * byte_clk, pix_clk);11761177/* remove packet overhead when possible */1178hfp = max(hfp - 6, 0);1179hbp = max(hbp - 6, 0);1180hsa = max(hsa - 6, 0);11811182dev_dbg(dsi->dev, "calculated hfp: %u, hbp: %u, hsa: %u",1183hfp, hbp, hsa);11841185reg = DSIM_CMD_ALLOW(0xf)1186| DSIM_STABLE_VFP(m->vsync_start - m->vdisplay)1187| DSIM_MAIN_VBP(m->vtotal - m->vsync_end);1188samsung_dsim_write(dsi, DSIM_MVPORCH_REG, reg);11891190reg = DSIM_MAIN_HFP(hfp) | DSIM_MAIN_HBP(hbp);1191samsung_dsim_write(dsi, DSIM_MHPORCH_REG, reg);11921193reg = DSIM_MAIN_VSA(m->vsync_end - m->vsync_start, main_vsa_offset)1194| DSIM_MAIN_HSA(hsa);1195samsung_dsim_write(dsi, DSIM_MSYNC_REG, reg);1196}1197reg = DSIM_MAIN_HRESOL(m->hdisplay, num_bits_resol) |1198DSIM_MAIN_VRESOL(m->vdisplay, num_bits_resol);11991200samsung_dsim_write(dsi, DSIM_MDRESOL_REG, reg);12011202dev_dbg(dsi->dev, "LCD size = %dx%d\n", m->hdisplay, m->vdisplay);1203}12041205static void samsung_dsim_set_display_enable(struct samsung_dsim *dsi, bool enable)1206{1207const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;1208u32 reg;12091210reg = samsung_dsim_read(dsi, DSIM_MDRESOL_REG);1211if (enable)1212reg |= DSIM_MAIN_STAND_BY;1213else1214reg &= ~DSIM_MAIN_STAND_BY;1215samsung_dsim_write(dsi, DSIM_MDRESOL_REG, reg);12161217if (driver_data->has_sfrctrl) {1218reg = samsung_dsim_read(dsi, DSIM_SFRCTRL_REG);1219if (enable)1220reg |= DSIM_SFR_CTRL_STAND_BY;1221else1222reg &= ~DSIM_SFR_CTRL_STAND_BY;1223samsung_dsim_write(dsi, DSIM_SFRCTRL_REG, reg);1224}1225}12261227static int samsung_dsim_wait_for_hdr_fifo(struct samsung_dsim *dsi)1228{1229int timeout = 2000;12301231do {1232u32 reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG);12331234if (!dsi->driver_data->has_broken_fifoctrl_emptyhdr) {1235if (reg & DSIM_SFR_HEADER_EMPTY)1236return 0;1237} else {1238if (!(reg & DSIM_SFR_HEADER_FULL)) {1239/*1240* Wait a little bit, so the pending data can1241* actually leave the FIFO to avoid overflow.1242*/1243if (!cond_resched())1244usleep_range(950, 1050);1245return 0;1246}1247}12481249if (!cond_resched())1250usleep_range(950, 1050);1251} while (--timeout);12521253return -ETIMEDOUT;1254}12551256static void samsung_dsim_set_cmd_lpm(struct samsung_dsim *dsi, bool lpm)1257{1258u32 v = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);12591260if (lpm)1261v |= DSIM_CMD_LPDT_LP;1262else1263v &= ~DSIM_CMD_LPDT_LP;12641265samsung_dsim_write(dsi, DSIM_ESCMODE_REG, v);1266}12671268static void samsung_dsim_force_bta(struct samsung_dsim *dsi)1269{1270u32 v = samsung_dsim_read(dsi, DSIM_ESCMODE_REG);12711272v |= DSIM_FORCE_BTA;1273samsung_dsim_write(dsi, DSIM_ESCMODE_REG, v);1274}12751276static void samsung_dsim_send_to_fifo(struct samsung_dsim *dsi,1277struct samsung_dsim_transfer *xfer)1278{1279struct device *dev = dsi->dev;1280struct mipi_dsi_packet *pkt = &xfer->packet;1281const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;1282const u8 *payload = pkt->payload + xfer->tx_done;1283u16 length = pkt->payload_length - xfer->tx_done;1284bool first = !xfer->tx_done;1285u32 reg;12861287dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",1288xfer, length, xfer->tx_done, xfer->rx_len, xfer->rx_done);12891290if (length > DSI_TX_FIFO_SIZE)1291length = DSI_TX_FIFO_SIZE;12921293xfer->tx_done += length;12941295/* Send payload */1296while (length >= 4) {1297reg = get_unaligned_le32(payload);1298samsung_dsim_write(dsi, DSIM_PAYLOAD_REG, reg);1299payload += 4;1300length -= 4;1301}13021303reg = 0;1304switch (length) {1305case 3:1306reg |= payload[2] << 16;1307fallthrough;1308case 2:1309reg |= payload[1] << 8;1310fallthrough;1311case 1:1312reg |= payload[0];1313samsung_dsim_write(dsi, DSIM_PAYLOAD_REG, reg);1314break;1315}13161317/* Send packet header */1318if (!first)1319return;13201321reg = get_unaligned_le32(pkt->header);1322if (driver_data->wait_for_hdr_fifo) {1323if (samsung_dsim_wait_for_hdr_fifo(dsi)) {1324dev_err(dev, "waiting for header FIFO timed out\n");1325return;1326}1327}13281329if (NEQV(xfer->flags & MIPI_DSI_MSG_USE_LPM,1330dsi->state & DSIM_STATE_CMD_LPM)) {1331samsung_dsim_set_cmd_lpm(dsi, xfer->flags & MIPI_DSI_MSG_USE_LPM);1332dsi->state ^= DSIM_STATE_CMD_LPM;1333}13341335samsung_dsim_write(dsi, DSIM_PKTHDR_REG, reg);13361337if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)1338samsung_dsim_force_bta(dsi);1339}13401341static void samsung_dsim_read_from_fifo(struct samsung_dsim *dsi,1342struct samsung_dsim_transfer *xfer)1343{1344u8 *payload = xfer->rx_payload + xfer->rx_done;1345bool first = !xfer->rx_done;1346struct device *dev = dsi->dev;1347u16 length;1348u32 reg;13491350if (first) {1351reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);13521353switch (reg & 0x3f) {1354case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:1355case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:1356if (xfer->rx_len >= 2) {1357payload[1] = reg >> 16;1358++xfer->rx_done;1359}1360fallthrough;1361case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:1362case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:1363payload[0] = reg >> 8;1364++xfer->rx_done;1365xfer->rx_len = xfer->rx_done;1366xfer->result = 0;1367goto clear_fifo;1368case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:1369dev_err(dev, "DSI Error Report: 0x%04x\n", (reg >> 8) & 0xffff);1370xfer->result = 0;1371goto clear_fifo;1372}13731374length = (reg >> 8) & 0xffff;1375if (length > xfer->rx_len) {1376dev_err(dev,1377"response too long (%u > %u bytes), stripping\n",1378xfer->rx_len, length);1379length = xfer->rx_len;1380} else if (length < xfer->rx_len) {1381xfer->rx_len = length;1382}1383}13841385length = xfer->rx_len - xfer->rx_done;1386xfer->rx_done += length;13871388/* Receive payload */1389while (length >= 4) {1390reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1391payload[0] = (reg >> 0) & 0xff;1392payload[1] = (reg >> 8) & 0xff;1393payload[2] = (reg >> 16) & 0xff;1394payload[3] = (reg >> 24) & 0xff;1395payload += 4;1396length -= 4;1397}13981399if (length) {1400reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1401switch (length) {1402case 3:1403payload[2] = (reg >> 16) & 0xff;1404fallthrough;1405case 2:1406payload[1] = (reg >> 8) & 0xff;1407fallthrough;1408case 1:1409payload[0] = reg & 0xff;1410}1411}14121413if (xfer->rx_done == xfer->rx_len)1414xfer->result = 0;14151416clear_fifo:1417length = DSI_RX_FIFO_SIZE / 4;1418do {1419reg = samsung_dsim_read(dsi, DSIM_RXFIFO_REG);1420if (reg == DSI_RX_FIFO_EMPTY)1421break;1422} while (--length);1423}14241425static void samsung_dsim_transfer_start(struct samsung_dsim *dsi)1426{1427unsigned long flags;1428struct samsung_dsim_transfer *xfer;14291430spin_lock_irqsave(&dsi->transfer_lock, flags);14311432while (!list_empty(&dsi->transfer_list)) {1433xfer = list_first_entry(&dsi->transfer_list,1434struct samsung_dsim_transfer, list);14351436spin_unlock_irqrestore(&dsi->transfer_lock, flags);14371438if (xfer->packet.payload_length &&1439xfer->tx_done == xfer->packet.payload_length)1440/* waiting for RX */1441return;14421443samsung_dsim_send_to_fifo(dsi, xfer);14441445if (xfer->packet.payload_length || xfer->rx_len)1446return;14471448xfer->result = 0;1449complete(&xfer->completed);14501451spin_lock_irqsave(&dsi->transfer_lock, flags);14521453list_del_init(&xfer->list);1454}14551456spin_unlock_irqrestore(&dsi->transfer_lock, flags);1457}14581459static bool samsung_dsim_transfer_finish(struct samsung_dsim *dsi)1460{1461struct samsung_dsim_transfer *xfer;1462unsigned long flags;1463bool start = true;14641465spin_lock_irqsave(&dsi->transfer_lock, flags);14661467if (list_empty(&dsi->transfer_list)) {1468spin_unlock_irqrestore(&dsi->transfer_lock, flags);1469return false;1470}14711472xfer = list_first_entry(&dsi->transfer_list,1473struct samsung_dsim_transfer, list);14741475spin_unlock_irqrestore(&dsi->transfer_lock, flags);14761477dev_dbg(dsi->dev,1478"> xfer %p, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",1479xfer, xfer->packet.payload_length, xfer->tx_done, xfer->rx_len,1480xfer->rx_done);14811482if (xfer->tx_done != xfer->packet.payload_length)1483return true;14841485if (xfer->rx_done != xfer->rx_len)1486samsung_dsim_read_from_fifo(dsi, xfer);14871488if (xfer->rx_done != xfer->rx_len)1489return true;14901491spin_lock_irqsave(&dsi->transfer_lock, flags);14921493list_del_init(&xfer->list);1494start = !list_empty(&dsi->transfer_list);14951496spin_unlock_irqrestore(&dsi->transfer_lock, flags);14971498if (!xfer->rx_len)1499xfer->result = 0;1500complete(&xfer->completed);15011502return start;1503}15041505static void samsung_dsim_remove_transfer(struct samsung_dsim *dsi,1506struct samsung_dsim_transfer *xfer)1507{1508unsigned long flags;1509bool start;15101511spin_lock_irqsave(&dsi->transfer_lock, flags);15121513if (!list_empty(&dsi->transfer_list) &&1514xfer == list_first_entry(&dsi->transfer_list,1515struct samsung_dsim_transfer, list)) {1516list_del_init(&xfer->list);1517start = !list_empty(&dsi->transfer_list);1518spin_unlock_irqrestore(&dsi->transfer_lock, flags);1519if (start)1520samsung_dsim_transfer_start(dsi);1521return;1522}15231524list_del_init(&xfer->list);15251526spin_unlock_irqrestore(&dsi->transfer_lock, flags);1527}15281529static int samsung_dsim_transfer(struct samsung_dsim *dsi,1530struct samsung_dsim_transfer *xfer)1531{1532unsigned long flags;1533bool stopped;15341535xfer->tx_done = 0;1536xfer->rx_done = 0;1537xfer->result = -ETIMEDOUT;1538init_completion(&xfer->completed);15391540spin_lock_irqsave(&dsi->transfer_lock, flags);15411542stopped = list_empty(&dsi->transfer_list);1543list_add_tail(&xfer->list, &dsi->transfer_list);15441545spin_unlock_irqrestore(&dsi->transfer_lock, flags);15461547if (stopped)1548samsung_dsim_transfer_start(dsi);15491550wait_for_completion_timeout(&xfer->completed,1551msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));1552if (xfer->result == -ETIMEDOUT) {1553struct mipi_dsi_packet *pkt = &xfer->packet;15541555samsung_dsim_remove_transfer(dsi, xfer);1556dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 4, pkt->header,1557(int)pkt->payload_length, pkt->payload);1558return -ETIMEDOUT;1559}15601561/* Also covers hardware timeout condition */1562return xfer->result;1563}15641565static irqreturn_t samsung_dsim_irq(int irq, void *dev_id)1566{1567struct samsung_dsim *dsi = dev_id;1568u32 status;15691570status = samsung_dsim_read(dsi, DSIM_INTSRC_REG);1571if (!status) {1572static unsigned long j;15731574if (printk_timed_ratelimit(&j, 500))1575dev_warn(dsi->dev, "spurious interrupt\n");1576return IRQ_HANDLED;1577}1578samsung_dsim_write(dsi, DSIM_INTSRC_REG, status);15791580if (status & DSIM_INT_SW_RST_RELEASE) {1581unsigned long mask = ~(DSIM_INT_RX_DONE |1582DSIM_INT_SFR_FIFO_EMPTY |1583DSIM_INT_SFR_HDR_FIFO_EMPTY |1584DSIM_INT_RX_ECC_ERR |1585DSIM_INT_SW_RST_RELEASE);1586samsung_dsim_write(dsi, DSIM_INTMSK_REG, mask);1587complete(&dsi->completed);1588return IRQ_HANDLED;1589}15901591if (!(status & (DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |1592DSIM_INT_PLL_STABLE)))1593return IRQ_HANDLED;15941595if (samsung_dsim_transfer_finish(dsi))1596samsung_dsim_transfer_start(dsi);15971598return IRQ_HANDLED;1599}16001601static void samsung_dsim_enable_irq(struct samsung_dsim *dsi)1602{1603enable_irq(dsi->irq);16041605if (dsi->te_gpio)1606enable_irq(gpiod_to_irq(dsi->te_gpio));1607}16081609static void samsung_dsim_disable_irq(struct samsung_dsim *dsi)1610{1611if (dsi->te_gpio)1612disable_irq(gpiod_to_irq(dsi->te_gpio));16131614disable_irq(dsi->irq);1615}16161617static int samsung_dsim_init(struct samsung_dsim *dsi)1618{1619const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;16201621if (dsi->state & DSIM_STATE_INITIALIZED)1622return 0;16231624samsung_dsim_reset(dsi);1625samsung_dsim_enable_irq(dsi);16261627if (driver_data->reg_values[RESET_TYPE] == DSIM_FUNCRST)1628samsung_dsim_enable_lane(dsi, BIT(dsi->lanes) - 1);16291630samsung_dsim_enable_clock(dsi);1631if (driver_data->wait_for_reset)1632samsung_dsim_wait_for_reset(dsi);1633samsung_dsim_set_phy_ctrl(dsi);1634samsung_dsim_init_link(dsi);16351636dsi->state |= DSIM_STATE_INITIALIZED;16371638return 0;1639}16401641static void samsung_dsim_atomic_pre_enable(struct drm_bridge *bridge,1642struct drm_atomic_state *state)1643{1644struct samsung_dsim *dsi = bridge_to_dsi(bridge);1645int ret;16461647if (dsi->state & DSIM_STATE_ENABLED)1648return;16491650ret = pm_runtime_resume_and_get(dsi->dev);1651if (ret < 0) {1652dev_err(dsi->dev, "failed to enable DSI device.\n");1653return;1654}16551656dsi->state |= DSIM_STATE_ENABLED;16571658/*1659* For Exynos-DSIM the downstream bridge, or panel are expecting1660* the host initialization during DSI transfer.1661*/1662if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) {1663ret = samsung_dsim_init(dsi);1664if (ret)1665return;1666}1667}16681669static void samsung_dsim_atomic_enable(struct drm_bridge *bridge,1670struct drm_atomic_state *state)1671{1672struct samsung_dsim *dsi = bridge_to_dsi(bridge);16731674samsung_dsim_set_display_mode(dsi);1675samsung_dsim_set_display_enable(dsi, true);16761677dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE;1678}16791680static void samsung_dsim_atomic_disable(struct drm_bridge *bridge,1681struct drm_atomic_state *state)1682{1683struct samsung_dsim *dsi = bridge_to_dsi(bridge);16841685if (!(dsi->state & DSIM_STATE_ENABLED))1686return;16871688samsung_dsim_set_display_enable(dsi, false);1689dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE;1690}16911692static void samsung_dsim_atomic_post_disable(struct drm_bridge *bridge,1693struct drm_atomic_state *state)1694{1695struct samsung_dsim *dsi = bridge_to_dsi(bridge);16961697dsi->state &= ~DSIM_STATE_ENABLED;1698pm_runtime_put_sync(dsi->dev);1699}17001701/*1702* This pixel output formats list referenced from,1703* AN13573 i.MX 8/RT MIPI DSI/CSI-2, Rev. 0, 21 March 20221704* 3.7.4 Pixel formats1705* Table 14. DSI pixel packing formats1706*/1707static const u32 samsung_dsim_pixel_output_fmts[] = {1708MEDIA_BUS_FMT_YUYV10_1X20,1709MEDIA_BUS_FMT_YUYV12_1X24,1710MEDIA_BUS_FMT_UYVY8_1X16,1711MEDIA_BUS_FMT_RGB101010_1X30,1712MEDIA_BUS_FMT_RGB121212_1X36,1713MEDIA_BUS_FMT_RGB565_1X16,1714MEDIA_BUS_FMT_RGB666_1X18,1715MEDIA_BUS_FMT_RGB888_1X24,1716};17171718static bool samsung_dsim_pixel_output_fmt_supported(u32 fmt)1719{1720int i;17211722if (fmt == MEDIA_BUS_FMT_FIXED)1723return false;17241725for (i = 0; i < ARRAY_SIZE(samsung_dsim_pixel_output_fmts); i++) {1726if (samsung_dsim_pixel_output_fmts[i] == fmt)1727return true;1728}17291730return false;1731}17321733static u32 *1734samsung_dsim_atomic_get_input_bus_fmts(struct drm_bridge *bridge,1735struct drm_bridge_state *bridge_state,1736struct drm_crtc_state *crtc_state,1737struct drm_connector_state *conn_state,1738u32 output_fmt,1739unsigned int *num_input_fmts)1740{1741u32 *input_fmts;17421743input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL);1744if (!input_fmts)1745return NULL;17461747if (!samsung_dsim_pixel_output_fmt_supported(output_fmt))1748/*1749* Some bridge/display drivers are still not able to pass the1750* correct format, so handle those pipelines by falling back1751* to the default format till the supported formats finalized.1752*/1753output_fmt = MEDIA_BUS_FMT_RGB888_1X24;17541755input_fmts[0] = output_fmt;1756*num_input_fmts = 1;17571758return input_fmts;1759}17601761static int samsung_dsim_atomic_check(struct drm_bridge *bridge,1762struct drm_bridge_state *bridge_state,1763struct drm_crtc_state *crtc_state,1764struct drm_connector_state *conn_state)1765{1766struct samsung_dsim *dsi = bridge_to_dsi(bridge);1767struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;17681769/*1770* The i.MX8M Mini/Nano glue logic between LCDIF and DSIM1771* inverts HS/VS/DE sync signals polarity, therefore, while1772* i.MX 8M Mini Applications Processor Reference Manual Rev. 3, 11/20201773* 13.6.3.5.2 RGB interface1774* i.MX 8M Nano Applications Processor Reference Manual Rev. 2, 07/20221775* 13.6.2.7.2 RGB interface1776* both claim "Vsync, Hsync, and VDEN are active high signals.", the1777* LCDIF must generate inverted HS/VS/DE signals, i.e. active LOW.1778*1779* The i.MX8M Plus glue logic between LCDIFv3 and DSIM does not1780* implement the same behavior, therefore LCDIFv3 must generate1781* HS/VS/DE signals active HIGH.1782*/1783if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM) {1784adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);1785adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);1786} else if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MP) {1787adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);1788adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);1789}17901791/*1792* When using video sync pulses, the HFP, HBP, and HSA are divided between1793* the available lanes if there is more than one lane. For certain1794* timings and lane configurations, the HFP may not be evenly divisible.1795* If the HFP is rounded down, it ends up being too small which can cause1796* some monitors to not sync properly. In these instances, adjust htotal1797* and hsync to round the HFP up, and recalculate the htotal. Through trial1798* and error, it appears that the HBP and HSA do not appearto need the same1799* correction that HFP does.1800*/1801if (dsi->lanes > 1) {1802int hfp = adjusted_mode->hsync_start - adjusted_mode->hdisplay;1803int remainder = hfp % dsi->lanes;18041805if (remainder) {1806adjusted_mode->hsync_start += remainder;1807adjusted_mode->hsync_end += remainder;1808adjusted_mode->htotal += remainder;1809}1810}18111812return 0;1813}18141815static void samsung_dsim_mode_set(struct drm_bridge *bridge,1816const struct drm_display_mode *mode,1817const struct drm_display_mode *adjusted_mode)1818{1819struct samsung_dsim *dsi = bridge_to_dsi(bridge);18201821drm_mode_copy(&dsi->mode, adjusted_mode);1822}18231824static int samsung_dsim_attach(struct drm_bridge *bridge,1825struct drm_encoder *encoder,1826enum drm_bridge_attach_flags flags)1827{1828struct samsung_dsim *dsi = bridge_to_dsi(bridge);18291830return drm_bridge_attach(encoder, dsi->out_bridge, bridge,1831flags);1832}18331834static const struct drm_bridge_funcs samsung_dsim_bridge_funcs = {1835.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,1836.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,1837.atomic_reset = drm_atomic_helper_bridge_reset,1838.atomic_get_input_bus_fmts = samsung_dsim_atomic_get_input_bus_fmts,1839.atomic_check = samsung_dsim_atomic_check,1840.atomic_pre_enable = samsung_dsim_atomic_pre_enable,1841.atomic_enable = samsung_dsim_atomic_enable,1842.atomic_disable = samsung_dsim_atomic_disable,1843.atomic_post_disable = samsung_dsim_atomic_post_disable,1844.mode_set = samsung_dsim_mode_set,1845.attach = samsung_dsim_attach,1846};18471848static irqreturn_t samsung_dsim_te_irq_handler(int irq, void *dev_id)1849{1850struct samsung_dsim *dsi = (struct samsung_dsim *)dev_id;1851const struct samsung_dsim_plat_data *pdata = dsi->plat_data;18521853if (pdata->host_ops && pdata->host_ops->te_irq_handler)1854return pdata->host_ops->te_irq_handler(dsi);18551856return IRQ_HANDLED;1857}18581859static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device *dev)1860{1861int te_gpio_irq;1862int ret;18631864dsi->te_gpio = devm_gpiod_get_optional(dev, "te", GPIOD_IN);1865if (!dsi->te_gpio)1866return 0;1867else if (IS_ERR(dsi->te_gpio))1868return dev_err_probe(dev, PTR_ERR(dsi->te_gpio), "failed to get te GPIO\n");18691870te_gpio_irq = gpiod_to_irq(dsi->te_gpio);18711872ret = request_threaded_irq(te_gpio_irq, samsung_dsim_te_irq_handler, NULL,1873IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN, "TE", dsi);1874if (ret) {1875dev_err(dsi->dev, "request interrupt failed with %d\n", ret);1876gpiod_put(dsi->te_gpio);1877return ret;1878}18791880return 0;1881}18821883static int samsung_dsim_host_attach(struct mipi_dsi_host *host,1884struct mipi_dsi_device *device)1885{1886struct samsung_dsim *dsi = host_to_dsi(host);1887const struct samsung_dsim_plat_data *pdata = dsi->plat_data;1888struct device *dev = dsi->dev;1889struct device_node *np = dev->of_node;1890struct device_node *remote;1891struct drm_panel *panel;1892int ret;18931894/*1895* Devices can also be child nodes when we also control that device1896* through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).1897*1898* Lookup for a child node of the given parent that isn't either port1899* or ports.1900*/1901for_each_available_child_of_node(np, remote) {1902if (of_node_name_eq(remote, "port") ||1903of_node_name_eq(remote, "ports"))1904continue;19051906goto of_find_panel_or_bridge;1907}19081909/*1910* of_graph_get_remote_node() produces a noisy error message if port1911* node isn't found and the absence of the port is a legit case here,1912* so at first we silently check whether graph presents in the1913* device-tree node.1914*/1915if (!of_graph_is_present(np))1916return -ENODEV;19171918remote = of_graph_get_remote_node(np, 1, 0);19191920of_find_panel_or_bridge:1921if (!remote)1922return -ENODEV;19231924panel = of_drm_find_panel(remote);1925if (!IS_ERR(panel)) {1926dsi->out_bridge = devm_drm_panel_bridge_add(dev, panel);1927} else {1928dsi->out_bridge = of_drm_find_bridge(remote);1929if (!dsi->out_bridge)1930dsi->out_bridge = ERR_PTR(-EINVAL);1931}19321933of_node_put(remote);19341935if (IS_ERR(dsi->out_bridge)) {1936ret = PTR_ERR(dsi->out_bridge);1937DRM_DEV_ERROR(dev, "failed to find the bridge: %d\n", ret);1938return ret;1939}19401941DRM_DEV_INFO(dev, "Attached %s device (lanes:%d bpp:%d mode-flags:0x%lx)\n",1942device->name, device->lanes,1943mipi_dsi_pixel_format_to_bpp(device->format),1944device->mode_flags);19451946drm_bridge_add(&dsi->bridge);19471948/*1949* This is a temporary solution and should be made by more generic way.1950*1951* If attached panel device is for command mode one, dsi should register1952* TE interrupt handler.1953*/1954if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) {1955ret = samsung_dsim_register_te_irq(dsi, &device->dev);1956if (ret)1957return ret;1958}19591960if (pdata->host_ops && pdata->host_ops->attach) {1961ret = pdata->host_ops->attach(dsi, device);1962if (ret)1963return ret;1964}19651966dsi->lanes = device->lanes;1967dsi->format = device->format;1968dsi->mode_flags = device->mode_flags;19691970return 0;1971}19721973static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi)1974{1975if (dsi->te_gpio) {1976free_irq(gpiod_to_irq(dsi->te_gpio), dsi);1977gpiod_put(dsi->te_gpio);1978}1979}19801981static int samsung_dsim_host_detach(struct mipi_dsi_host *host,1982struct mipi_dsi_device *device)1983{1984struct samsung_dsim *dsi = host_to_dsi(host);1985const struct samsung_dsim_plat_data *pdata = dsi->plat_data;19861987dsi->out_bridge = NULL;19881989if (pdata->host_ops && pdata->host_ops->detach)1990pdata->host_ops->detach(dsi, device);19911992samsung_dsim_unregister_te_irq(dsi);19931994drm_bridge_remove(&dsi->bridge);19951996return 0;1997}19981999static ssize_t samsung_dsim_host_transfer(struct mipi_dsi_host *host,2000const struct mipi_dsi_msg *msg)2001{2002struct samsung_dsim *dsi = host_to_dsi(host);2003struct samsung_dsim_transfer xfer;2004int ret;20052006if (!(dsi->state & DSIM_STATE_ENABLED))2007return -EINVAL;20082009ret = samsung_dsim_init(dsi);2010if (ret)2011return ret;20122013ret = mipi_dsi_create_packet(&xfer.packet, msg);2014if (ret < 0)2015return ret;20162017xfer.rx_len = msg->rx_len;2018xfer.rx_payload = msg->rx_buf;2019xfer.flags = msg->flags;20202021ret = samsung_dsim_transfer(dsi, &xfer);2022return (ret < 0) ? ret : xfer.rx_done;2023}20242025static const struct mipi_dsi_host_ops samsung_dsim_ops = {2026.attach = samsung_dsim_host_attach,2027.detach = samsung_dsim_host_detach,2028.transfer = samsung_dsim_host_transfer,2029};20302031static int samsung_dsim_of_read_u32(const struct device_node *np,2032const char *propname, u32 *out_value, bool optional)2033{2034int ret = of_property_read_u32(np, propname, out_value);20352036if (ret < 0 && !optional)2037pr_err("%pOF: failed to get '%s' property\n", np, propname);20382039return ret;2040}20412042static int samsung_dsim_parse_dt(struct samsung_dsim *dsi)2043{2044struct device *dev = dsi->dev;2045struct device_node *node = dev->of_node;2046u32 lane_polarities[5] = { 0 };2047struct device_node *endpoint;2048int i, nr_lanes, ret;20492050ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency",2051&dsi->pll_clk_rate, 1);2052/* If it doesn't exist, read it from the clock instead of failing */2053if (ret < 0) {2054dev_dbg(dev, "Using sclk_mipi for pll clock frequency\n");2055dsi->pll_clk = devm_clk_get(dev, "sclk_mipi");2056if (IS_ERR(dsi->pll_clk))2057return PTR_ERR(dsi->pll_clk);2058}20592060/* If it doesn't exist, use pixel clock instead of failing */2061ret = samsung_dsim_of_read_u32(node, "samsung,burst-clock-frequency",2062&dsi->burst_clk_rate, 1);2063if (ret < 0) {2064dev_dbg(dev, "Using pixel clock for HS clock frequency\n");2065dsi->burst_clk_rate = 0;2066}20672068ret = samsung_dsim_of_read_u32(node, "samsung,esc-clock-frequency",2069&dsi->esc_clk_rate, 0);2070if (ret < 0)2071return ret;20722073endpoint = of_graph_get_endpoint_by_regs(node, 1, -1);2074nr_lanes = of_property_count_u32_elems(endpoint, "data-lanes");2075if (nr_lanes > 0 && nr_lanes <= 4) {2076/* Polarity 0 is clock lane, 1..4 are data lanes. */2077of_property_read_u32_array(endpoint, "lane-polarities",2078lane_polarities, nr_lanes + 1);2079for (i = 1; i <= nr_lanes; i++) {2080if (lane_polarities[1] != lane_polarities[i])2081DRM_DEV_ERROR(dsi->dev, "Data lanes polarities do not match");2082}2083if (lane_polarities[0])2084dsi->swap_dn_dp_clk = true;2085if (lane_polarities[1])2086dsi->swap_dn_dp_data = true;2087}20882089return 0;2090}20912092static int generic_dsim_register_host(struct samsung_dsim *dsi)2093{2094return mipi_dsi_host_register(&dsi->dsi_host);2095}20962097static void generic_dsim_unregister_host(struct samsung_dsim *dsi)2098{2099mipi_dsi_host_unregister(&dsi->dsi_host);2100}21012102static const struct samsung_dsim_host_ops generic_dsim_host_ops = {2103.register_host = generic_dsim_register_host,2104.unregister_host = generic_dsim_unregister_host,2105};21062107static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_high = {2108.input_bus_flags = DRM_BUS_FLAG_DE_HIGH,2109};21102111static const struct drm_bridge_timings samsung_dsim_bridge_timings_de_low = {2112.input_bus_flags = DRM_BUS_FLAG_DE_LOW,2113};21142115int samsung_dsim_probe(struct platform_device *pdev)2116{2117struct device *dev = &pdev->dev;2118struct samsung_dsim *dsi;2119int ret;21202121dsi = devm_drm_bridge_alloc(dev, struct samsung_dsim, bridge, &samsung_dsim_bridge_funcs);2122if (IS_ERR(dsi))2123return PTR_ERR(dsi);21242125init_completion(&dsi->completed);2126spin_lock_init(&dsi->transfer_lock);2127INIT_LIST_HEAD(&dsi->transfer_list);21282129dsi->dsi_host.ops = &samsung_dsim_ops;2130dsi->dsi_host.dev = dev;21312132dsi->dev = dev;2133dsi->plat_data = of_device_get_match_data(dev);2134dsi->driver_data = samsung_dsim_types[dsi->plat_data->hw_type];21352136dsi->supplies[0].supply = "vddcore";2137dsi->supplies[1].supply = "vddio";2138ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies),2139dsi->supplies);2140if (ret)2141return dev_err_probe(dev, ret, "failed to get regulators\n");21422143ret = devm_clk_bulk_get(dev, dsi->driver_data->num_clks,2144dsi->driver_data->clk_data);2145if (ret) {2146dev_err(dev, "failed to get clocks in bulk (%d)\n", ret);2147return ret;2148}21492150dsi->reg_base = devm_platform_ioremap_resource(pdev, 0);2151if (IS_ERR(dsi->reg_base))2152return PTR_ERR(dsi->reg_base);21532154dsi->phy = devm_phy_optional_get(dev, "dsim");2155if (IS_ERR(dsi->phy)) {2156dev_info(dev, "failed to get dsim phy\n");2157return PTR_ERR(dsi->phy);2158}21592160dsi->irq = platform_get_irq(pdev, 0);2161if (dsi->irq < 0)2162return dsi->irq;21632164ret = devm_request_threaded_irq(dev, dsi->irq, NULL,2165samsung_dsim_irq,2166IRQF_ONESHOT | IRQF_NO_AUTOEN,2167dev_name(dev), dsi);2168if (ret) {2169dev_err(dev, "failed to request dsi irq\n");2170return ret;2171}21722173ret = samsung_dsim_parse_dt(dsi);2174if (ret)2175return ret;21762177platform_set_drvdata(pdev, dsi);21782179pm_runtime_enable(dev);21802181dsi->bridge.of_node = dev->of_node;2182dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;21832184/* DE_LOW: i.MX8M Mini/Nano LCDIF-DSIM glue logic inverts HS/VS/DE */2185if (dsi->plat_data->hw_type == DSIM_TYPE_IMX8MM)2186dsi->bridge.timings = &samsung_dsim_bridge_timings_de_low;2187else2188dsi->bridge.timings = &samsung_dsim_bridge_timings_de_high;21892190if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->register_host) {2191ret = dsi->plat_data->host_ops->register_host(dsi);2192if (ret)2193goto err_disable_runtime;2194}21952196return 0;21972198err_disable_runtime:2199pm_runtime_disable(dev);22002201return ret;2202}2203EXPORT_SYMBOL_GPL(samsung_dsim_probe);22042205void samsung_dsim_remove(struct platform_device *pdev)2206{2207struct samsung_dsim *dsi = platform_get_drvdata(pdev);22082209pm_runtime_disable(&pdev->dev);22102211if (dsi->plat_data->host_ops && dsi->plat_data->host_ops->unregister_host)2212dsi->plat_data->host_ops->unregister_host(dsi);2213}2214EXPORT_SYMBOL_GPL(samsung_dsim_remove);22152216static int samsung_dsim_suspend(struct device *dev)2217{2218struct samsung_dsim *dsi = dev_get_drvdata(dev);2219const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;2220int ret;22212222usleep_range(10000, 20000);22232224if (dsi->state & DSIM_STATE_INITIALIZED) {2225dsi->state &= ~DSIM_STATE_INITIALIZED;22262227samsung_dsim_disable_clock(dsi);22282229samsung_dsim_disable_irq(dsi);2230}22312232dsi->state &= ~DSIM_STATE_CMD_LPM;22332234phy_power_off(dsi->phy);22352236clk_bulk_disable_unprepare(driver_data->num_clks, driver_data->clk_data);22372238ret = regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);2239if (ret < 0)2240dev_err(dsi->dev, "cannot disable regulators %d\n", ret);22412242return 0;2243}22442245static int samsung_dsim_resume(struct device *dev)2246{2247struct samsung_dsim *dsi = dev_get_drvdata(dev);2248const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;2249int ret;22502251ret = regulator_bulk_enable(ARRAY_SIZE(dsi->supplies), dsi->supplies);2252if (ret < 0) {2253dev_err(dsi->dev, "cannot enable regulators %d\n", ret);2254return ret;2255}22562257ret = clk_bulk_prepare_enable(driver_data->num_clks, driver_data->clk_data);2258if (ret < 0)2259goto err_clk;22602261ret = phy_power_on(dsi->phy);2262if (ret < 0) {2263dev_err(dsi->dev, "cannot enable phy %d\n", ret);2264goto err_clk;2265}22662267return 0;22682269err_clk:2270clk_bulk_disable_unprepare(driver_data->num_clks, driver_data->clk_data);2271regulator_bulk_disable(ARRAY_SIZE(dsi->supplies), dsi->supplies);22722273return ret;2274}22752276const struct dev_pm_ops samsung_dsim_pm_ops = {2277RUNTIME_PM_OPS(samsung_dsim_suspend, samsung_dsim_resume, NULL)2278SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,2279pm_runtime_force_resume)2280};2281EXPORT_SYMBOL_GPL(samsung_dsim_pm_ops);22822283static const struct samsung_dsim_plat_data samsung_dsim_imx8mm_pdata = {2284.hw_type = DSIM_TYPE_IMX8MM,2285.host_ops = &generic_dsim_host_ops,2286};22872288static const struct samsung_dsim_plat_data samsung_dsim_imx8mp_pdata = {2289.hw_type = DSIM_TYPE_IMX8MP,2290.host_ops = &generic_dsim_host_ops,2291};22922293static const struct of_device_id samsung_dsim_of_match[] = {2294{2295.compatible = "fsl,imx8mm-mipi-dsim",2296.data = &samsung_dsim_imx8mm_pdata,2297},2298{2299.compatible = "fsl,imx8mp-mipi-dsim",2300.data = &samsung_dsim_imx8mp_pdata,2301},2302{ /* sentinel. */ }2303};2304MODULE_DEVICE_TABLE(of, samsung_dsim_of_match);23052306static struct platform_driver samsung_dsim_driver = {2307.probe = samsung_dsim_probe,2308.remove = samsung_dsim_remove,2309.driver = {2310.name = "samsung-dsim",2311.pm = pm_ptr(&samsung_dsim_pm_ops),2312.of_match_table = samsung_dsim_of_match,2313},2314};23152316module_platform_driver(samsung_dsim_driver);23172318MODULE_AUTHOR("Jagan Teki <[email protected]>");2319MODULE_DESCRIPTION("Samsung MIPI DSIM controller bridge");2320MODULE_LICENSE("GPL");232123222323