1074 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2020 Unisoc Inc.4 */5 6#include <linux/component.h>7#include <linux/module.h>8#include <linux/of.h>9#include <linux/platform_device.h>10#include <video/mipi_display.h>11 12#include <drm/drm_atomic_helper.h>13#include <drm/drm_bridge.h>14#include <drm/drm_of.h>15#include <drm/drm_probe_helper.h>16 17#include "sprd_drm.h"18#include "sprd_dpu.h"19#include "sprd_dsi.h"20 21#define SOFT_RESET 0x0422#define MASK_PROTOCOL_INT 0x0C23#define MASK_INTERNAL_INT 0x1424#define DSI_MODE_CFG 0x1825 26#define VIRTUAL_CHANNEL_ID 0x1C27#define GEN_RX_VCID GENMASK(1, 0)28#define VIDEO_PKT_VCID GENMASK(3, 2)29 30#define DPI_VIDEO_FORMAT 0x2031#define DPI_VIDEO_MODE_FORMAT GENMASK(5, 0)32#define LOOSELY18_EN BIT(6)33 34#define VIDEO_PKT_CONFIG 0x2435#define VIDEO_PKT_SIZE GENMASK(15, 0)36#define VIDEO_LINE_CHUNK_NUM GENMASK(31, 16)37 38#define VIDEO_LINE_HBLK_TIME 0x2839#define VIDEO_LINE_HBP_TIME GENMASK(15, 0)40#define VIDEO_LINE_HSA_TIME GENMASK(31, 16)41 42#define VIDEO_LINE_TIME 0x2C43 44#define VIDEO_VBLK_LINES 0x3045#define VFP_LINES GENMASK(9, 0)46#define VBP_LINES GENMASK(19, 10)47#define VSA_LINES GENMASK(29, 20)48 49#define VIDEO_VACTIVE_LINES 0x3450 51#define VID_MODE_CFG 0x3852#define VID_MODE_TYPE GENMASK(1, 0)53#define LP_VSA_EN BIT(8)54#define LP_VBP_EN BIT(9)55#define LP_VFP_EN BIT(10)56#define LP_VACT_EN BIT(11)57#define LP_HBP_EN BIT(12)58#define LP_HFP_EN BIT(13)59#define FRAME_BTA_ACK_EN BIT(14)60 61#define TIMEOUT_CNT_CLK_CONFIG 0x4062#define HTX_TO_CONFIG 0x4463#define LRX_H_TO_CONFIG 0x4864 65#define TX_ESC_CLK_CONFIG 0x5C66 67#define CMD_MODE_CFG 0x6868#define TEAR_FX_EN BIT(0)69 70#define GEN_HDR 0x6C71#define GEN_DT GENMASK(5, 0)72#define GEN_VC GENMASK(7, 6)73 74#define GEN_PLD_DATA 0x7075 76#define PHY_CLK_LANE_LP_CTRL 0x7477#define PHY_CLKLANE_TX_REQ_HS BIT(0)78#define AUTO_CLKLANE_CTRL_EN BIT(1)79 80#define PHY_INTERFACE_CTRL 0x7881#define RF_PHY_SHUTDOWN BIT(0)82#define RF_PHY_RESET_N BIT(1)83#define RF_PHY_CLK_EN BIT(2)84 85#define CMD_MODE_STATUS 0x9886#define GEN_CMD_RDATA_FIFO_EMPTY BIT(1)87#define GEN_CMD_WDATA_FIFO_EMPTY BIT(3)88#define GEN_CMD_CMD_FIFO_EMPTY BIT(5)89#define GEN_CMD_RDCMD_DONE BIT(7)90 91#define PHY_STATUS 0x9C92#define PHY_LOCK BIT(1)93 94#define PHY_MIN_STOP_TIME 0xA095#define PHY_LANE_NUM_CONFIG 0xA496 97#define PHY_CLKLANE_TIME_CONFIG 0xA898#define PHY_CLKLANE_LP_TO_HS_TIME GENMASK(15, 0)99#define PHY_CLKLANE_HS_TO_LP_TIME GENMASK(31, 16)100 101#define PHY_DATALANE_TIME_CONFIG 0xAC102#define PHY_DATALANE_LP_TO_HS_TIME GENMASK(15, 0)103#define PHY_DATALANE_HS_TO_LP_TIME GENMASK(31, 16)104 105#define MAX_READ_TIME 0xB0106 107#define RX_PKT_CHECK_CONFIG 0xB4108#define RX_PKT_ECC_EN BIT(0)109#define RX_PKT_CRC_EN BIT(1)110 111#define TA_EN 0xB8112 113#define EOTP_EN 0xBC114#define TX_EOTP_EN BIT(0)115#define RX_EOTP_EN BIT(1)116 117#define VIDEO_NULLPKT_SIZE 0xC0118#define DCS_WM_PKT_SIZE 0xC4119 120#define VIDEO_SIG_DELAY_CONFIG 0xD0121#define VIDEO_SIG_DELAY GENMASK(23, 0)122 123#define PHY_TST_CTRL0 0xF0124#define PHY_TESTCLR BIT(0)125#define PHY_TESTCLK BIT(1)126 127#define PHY_TST_CTRL1 0xF4128#define PHY_TESTDIN GENMASK(7, 0)129#define PHY_TESTDOUT GENMASK(15, 8)130#define PHY_TESTEN BIT(16)131 132#define host_to_dsi(host) \133 container_of(host, struct sprd_dsi, host)134 135static inline u32136dsi_reg_rd(struct dsi_context *ctx, u32 offset, u32 mask,137 u32 shift)138{139 return (readl(ctx->base + offset) & mask) >> shift;140}141 142static inline void143dsi_reg_wr(struct dsi_context *ctx, u32 offset, u32 mask,144 u32 shift, u32 val)145{146 u32 ret;147 148 ret = readl(ctx->base + offset);149 ret &= ~mask;150 ret |= (val << shift) & mask;151 writel(ret, ctx->base + offset);152}153 154static inline void155dsi_reg_up(struct dsi_context *ctx, u32 offset, u32 mask,156 u32 val)157{158 u32 ret = readl(ctx->base + offset);159 160 writel((ret & ~mask) | (val & mask), ctx->base + offset);161}162 163static int regmap_tst_io_write(void *context, u32 reg, u32 val)164{165 struct sprd_dsi *dsi = context;166 struct dsi_context *ctx = &dsi->ctx;167 168 if (val > 0xff || reg > 0xff)169 return -EINVAL;170 171 drm_dbg(dsi->drm, "reg = 0x%02x, val = 0x%02x\n", reg, val);172 173 dsi_reg_up(ctx, PHY_TST_CTRL1, PHY_TESTEN, PHY_TESTEN);174 dsi_reg_wr(ctx, PHY_TST_CTRL1, PHY_TESTDIN, 0, reg);175 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLK, PHY_TESTCLK);176 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLK, 0);177 dsi_reg_up(ctx, PHY_TST_CTRL1, PHY_TESTEN, 0);178 dsi_reg_wr(ctx, PHY_TST_CTRL1, PHY_TESTDIN, 0, val);179 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLK, PHY_TESTCLK);180 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLK, 0);181 182 return 0;183}184 185static int regmap_tst_io_read(void *context, u32 reg, u32 *val)186{187 struct sprd_dsi *dsi = context;188 struct dsi_context *ctx = &dsi->ctx;189 int ret;190 191 if (reg > 0xff)192 return -EINVAL;193 194 dsi_reg_up(ctx, PHY_TST_CTRL1, PHY_TESTEN, PHY_TESTEN);195 dsi_reg_wr(ctx, PHY_TST_CTRL1, PHY_TESTDIN, 0, reg);196 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLK, PHY_TESTCLK);197 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLK, 0);198 dsi_reg_up(ctx, PHY_TST_CTRL1, PHY_TESTEN, 0);199 200 udelay(1);201 202 ret = dsi_reg_rd(ctx, PHY_TST_CTRL1, PHY_TESTDOUT, 8);203 if (ret < 0)204 return ret;205 206 *val = ret;207 208 drm_dbg(dsi->drm, "reg = 0x%02x, val = 0x%02x\n", reg, *val);209 return 0;210}211 212static struct regmap_bus regmap_tst_io = {213 .reg_write = regmap_tst_io_write,214 .reg_read = regmap_tst_io_read,215};216 217static const struct regmap_config byte_config = {218 .reg_bits = 8,219 .val_bits = 8,220};221 222static int dphy_wait_pll_locked(struct dsi_context *ctx)223{224 struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);225 int i;226 227 for (i = 0; i < 50000; i++) {228 if (dsi_reg_rd(ctx, PHY_STATUS, PHY_LOCK, 1))229 return 0;230 udelay(3);231 }232 233 drm_err(dsi->drm, "dphy pll can not be locked\n");234 return -ETIMEDOUT;235}236 237static int dsi_wait_tx_payload_fifo_empty(struct dsi_context *ctx)238{239 int i;240 241 for (i = 0; i < 5000; i++) {242 if (dsi_reg_rd(ctx, CMD_MODE_STATUS, GEN_CMD_WDATA_FIFO_EMPTY, 3))243 return 0;244 udelay(1);245 }246 247 return -ETIMEDOUT;248}249 250static int dsi_wait_tx_cmd_fifo_empty(struct dsi_context *ctx)251{252 int i;253 254 for (i = 0; i < 5000; i++) {255 if (dsi_reg_rd(ctx, CMD_MODE_STATUS, GEN_CMD_CMD_FIFO_EMPTY, 5))256 return 0;257 udelay(1);258 }259 260 return -ETIMEDOUT;261}262 263static int dsi_wait_rd_resp_completed(struct dsi_context *ctx)264{265 int i;266 267 for (i = 0; i < 10000; i++) {268 if (dsi_reg_rd(ctx, CMD_MODE_STATUS, GEN_CMD_RDCMD_DONE, 7))269 return 0;270 udelay(10);271 }272 273 return -ETIMEDOUT;274}275 276static u16 calc_bytes_per_pixel_x100(int coding)277{278 u16 bpp_x100;279 280 switch (coding) {281 case COLOR_CODE_16BIT_CONFIG1:282 case COLOR_CODE_16BIT_CONFIG2:283 case COLOR_CODE_16BIT_CONFIG3:284 bpp_x100 = 200;285 break;286 case COLOR_CODE_18BIT_CONFIG1:287 case COLOR_CODE_18BIT_CONFIG2:288 bpp_x100 = 225;289 break;290 case COLOR_CODE_24BIT:291 bpp_x100 = 300;292 break;293 case COLOR_CODE_COMPRESSTION:294 bpp_x100 = 100;295 break;296 case COLOR_CODE_20BIT_YCC422_LOOSELY:297 bpp_x100 = 250;298 break;299 case COLOR_CODE_24BIT_YCC422:300 bpp_x100 = 300;301 break;302 case COLOR_CODE_16BIT_YCC422:303 bpp_x100 = 200;304 break;305 case COLOR_CODE_30BIT:306 bpp_x100 = 375;307 break;308 case COLOR_CODE_36BIT:309 bpp_x100 = 450;310 break;311 case COLOR_CODE_12BIT_YCC420:312 bpp_x100 = 150;313 break;314 default:315 DRM_ERROR("invalid color coding");316 bpp_x100 = 0;317 break;318 }319 320 return bpp_x100;321}322 323static u8 calc_video_size_step(int coding)324{325 u8 video_size_step;326 327 switch (coding) {328 case COLOR_CODE_16BIT_CONFIG1:329 case COLOR_CODE_16BIT_CONFIG2:330 case COLOR_CODE_16BIT_CONFIG3:331 case COLOR_CODE_18BIT_CONFIG1:332 case COLOR_CODE_18BIT_CONFIG2:333 case COLOR_CODE_24BIT:334 case COLOR_CODE_COMPRESSTION:335 return video_size_step = 1;336 case COLOR_CODE_20BIT_YCC422_LOOSELY:337 case COLOR_CODE_24BIT_YCC422:338 case COLOR_CODE_16BIT_YCC422:339 case COLOR_CODE_30BIT:340 case COLOR_CODE_36BIT:341 case COLOR_CODE_12BIT_YCC420:342 return video_size_step = 2;343 default:344 DRM_ERROR("invalid color coding");345 return 0;346 }347}348 349static u16 round_video_size(int coding, u16 video_size)350{351 switch (coding) {352 case COLOR_CODE_16BIT_YCC422:353 case COLOR_CODE_24BIT_YCC422:354 case COLOR_CODE_20BIT_YCC422_LOOSELY:355 case COLOR_CODE_12BIT_YCC420:356 /* round up active H pixels to a multiple of 2 */357 if ((video_size % 2) != 0)358 video_size += 1;359 break;360 default:361 break;362 }363 364 return video_size;365}366 367#define SPRD_MIPI_DSI_FMT_DSC 0xff368static u32 fmt_to_coding(u32 fmt)369{370 switch (fmt) {371 case MIPI_DSI_FMT_RGB565:372 return COLOR_CODE_16BIT_CONFIG1;373 case MIPI_DSI_FMT_RGB666:374 case MIPI_DSI_FMT_RGB666_PACKED:375 return COLOR_CODE_18BIT_CONFIG1;376 case MIPI_DSI_FMT_RGB888:377 return COLOR_CODE_24BIT;378 case SPRD_MIPI_DSI_FMT_DSC:379 return COLOR_CODE_COMPRESSTION;380 default:381 DRM_ERROR("Unsupported format (%d)\n", fmt);382 return COLOR_CODE_24BIT;383 }384}385 386#define ns_to_cycle(ns, byte_clk) \387 DIV_ROUND_UP((ns) * (byte_clk), 1000000)388 389static void sprd_dsi_init(struct dsi_context *ctx)390{391 struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);392 u32 byte_clk = dsi->slave->hs_rate / 8;393 u16 data_hs2lp, data_lp2hs, clk_hs2lp, clk_lp2hs;394 u16 max_rd_time;395 int div;396 397 writel(0, ctx->base + SOFT_RESET);398 writel(0xffffffff, ctx->base + MASK_PROTOCOL_INT);399 writel(0xffffffff, ctx->base + MASK_INTERNAL_INT);400 writel(1, ctx->base + DSI_MODE_CFG);401 dsi_reg_up(ctx, EOTP_EN, RX_EOTP_EN, 0);402 dsi_reg_up(ctx, EOTP_EN, TX_EOTP_EN, 0);403 dsi_reg_up(ctx, RX_PKT_CHECK_CONFIG, RX_PKT_ECC_EN, RX_PKT_ECC_EN);404 dsi_reg_up(ctx, RX_PKT_CHECK_CONFIG, RX_PKT_CRC_EN, RX_PKT_CRC_EN);405 writel(1, ctx->base + TA_EN);406 dsi_reg_up(ctx, VIRTUAL_CHANNEL_ID, VIDEO_PKT_VCID, 0);407 dsi_reg_up(ctx, VIRTUAL_CHANNEL_ID, GEN_RX_VCID, 0);408 409 div = DIV_ROUND_UP(byte_clk, dsi->slave->lp_rate);410 writel(div, ctx->base + TX_ESC_CLK_CONFIG);411 412 max_rd_time = ns_to_cycle(ctx->max_rd_time, byte_clk);413 writel(max_rd_time, ctx->base + MAX_READ_TIME);414 415 data_hs2lp = ns_to_cycle(ctx->data_hs2lp, byte_clk);416 data_lp2hs = ns_to_cycle(ctx->data_lp2hs, byte_clk);417 clk_hs2lp = ns_to_cycle(ctx->clk_hs2lp, byte_clk);418 clk_lp2hs = ns_to_cycle(ctx->clk_lp2hs, byte_clk);419 dsi_reg_wr(ctx, PHY_DATALANE_TIME_CONFIG,420 PHY_DATALANE_HS_TO_LP_TIME, 16, data_hs2lp);421 dsi_reg_wr(ctx, PHY_DATALANE_TIME_CONFIG,422 PHY_DATALANE_LP_TO_HS_TIME, 0, data_lp2hs);423 dsi_reg_wr(ctx, PHY_CLKLANE_TIME_CONFIG,424 PHY_CLKLANE_HS_TO_LP_TIME, 16, clk_hs2lp);425 dsi_reg_wr(ctx, PHY_CLKLANE_TIME_CONFIG,426 PHY_CLKLANE_LP_TO_HS_TIME, 0, clk_lp2hs);427 428 writel(1, ctx->base + SOFT_RESET);429}430 431/*432 * Free up resources and shutdown host controller and PHY433 */434static void sprd_dsi_fini(struct dsi_context *ctx)435{436 writel(0xffffffff, ctx->base + MASK_PROTOCOL_INT);437 writel(0xffffffff, ctx->base + MASK_INTERNAL_INT);438 writel(0, ctx->base + SOFT_RESET);439}440 441/*442 * If not in burst mode, it will compute the video and null packet sizes443 * according to necessity.444 * Configure timers for data lanes and/or clock lane to return to LP when445 * bandwidth is not filled by data.446 */447static int sprd_dsi_dpi_video(struct dsi_context *ctx)448{449 struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);450 struct videomode *vm = &ctx->vm;451 u32 byte_clk = dsi->slave->hs_rate / 8;452 u16 bpp_x100;453 u16 video_size;454 u32 ratio_x1000;455 u16 null_pkt_size = 0;456 u8 video_size_step;457 u32 hs_to;458 u32 total_bytes;459 u32 bytes_per_chunk;460 u32 chunks = 0;461 u32 bytes_left = 0;462 u32 chunk_overhead;463 const u8 pkt_header = 6;464 u8 coding;465 int div;466 u16 hline;467 u16 byte_cycle;468 469 coding = fmt_to_coding(dsi->slave->format);470 video_size = round_video_size(coding, vm->hactive);471 bpp_x100 = calc_bytes_per_pixel_x100(coding);472 video_size_step = calc_video_size_step(coding);473 ratio_x1000 = byte_clk * 1000 / (vm->pixelclock / 1000);474 hline = vm->hactive + vm->hsync_len + vm->hfront_porch +475 vm->hback_porch;476 477 writel(0, ctx->base + SOFT_RESET);478 dsi_reg_wr(ctx, VID_MODE_CFG, FRAME_BTA_ACK_EN, 15, ctx->frame_ack_en);479 dsi_reg_wr(ctx, DPI_VIDEO_FORMAT, DPI_VIDEO_MODE_FORMAT, 0, coding);480 dsi_reg_wr(ctx, VID_MODE_CFG, VID_MODE_TYPE, 0, ctx->burst_mode);481 byte_cycle = 95 * hline * ratio_x1000 / 100000;482 dsi_reg_wr(ctx, VIDEO_SIG_DELAY_CONFIG, VIDEO_SIG_DELAY, 0, byte_cycle);483 byte_cycle = hline * ratio_x1000 / 1000;484 writel(byte_cycle, ctx->base + VIDEO_LINE_TIME);485 byte_cycle = vm->hsync_len * ratio_x1000 / 1000;486 dsi_reg_wr(ctx, VIDEO_LINE_HBLK_TIME, VIDEO_LINE_HSA_TIME, 16, byte_cycle);487 byte_cycle = vm->hback_porch * ratio_x1000 / 1000;488 dsi_reg_wr(ctx, VIDEO_LINE_HBLK_TIME, VIDEO_LINE_HBP_TIME, 0, byte_cycle);489 writel(vm->vactive, ctx->base + VIDEO_VACTIVE_LINES);490 dsi_reg_wr(ctx, VIDEO_VBLK_LINES, VFP_LINES, 0, vm->vfront_porch);491 dsi_reg_wr(ctx, VIDEO_VBLK_LINES, VBP_LINES, 10, vm->vback_porch);492 dsi_reg_wr(ctx, VIDEO_VBLK_LINES, VSA_LINES, 20, vm->vsync_len);493 dsi_reg_up(ctx, VID_MODE_CFG, LP_HBP_EN | LP_HFP_EN | LP_VACT_EN |494 LP_VFP_EN | LP_VBP_EN | LP_VSA_EN, LP_HBP_EN | LP_HFP_EN |495 LP_VACT_EN | LP_VFP_EN | LP_VBP_EN | LP_VSA_EN);496 497 hs_to = (hline * vm->vactive) + (2 * bpp_x100) / 100;498 for (div = 0x80; (div < hs_to) && (div > 2); div--) {499 if ((hs_to % div) == 0) {500 writel(div, ctx->base + TIMEOUT_CNT_CLK_CONFIG);501 writel(hs_to / div, ctx->base + LRX_H_TO_CONFIG);502 writel(hs_to / div, ctx->base + HTX_TO_CONFIG);503 break;504 }505 }506 507 if (ctx->burst_mode == VIDEO_BURST_WITH_SYNC_PULSES) {508 dsi_reg_wr(ctx, VIDEO_PKT_CONFIG, VIDEO_PKT_SIZE, 0, video_size);509 writel(0, ctx->base + VIDEO_NULLPKT_SIZE);510 dsi_reg_up(ctx, VIDEO_PKT_CONFIG, VIDEO_LINE_CHUNK_NUM, 0);511 } else {512 /* non burst transmission */513 null_pkt_size = 0;514 515 /* bytes to be sent - first as one chunk */516 bytes_per_chunk = vm->hactive * bpp_x100 / 100 + pkt_header;517 518 /* hline total bytes from the DPI interface */519 total_bytes = (vm->hactive + vm->hfront_porch) *520 ratio_x1000 / dsi->slave->lanes / 1000;521 522 /* check if the pixels actually fit on the DSI link */523 if (total_bytes < bytes_per_chunk) {524 drm_err(dsi->drm, "current resolution can not be set\n");525 return -EINVAL;526 }527 528 chunk_overhead = total_bytes - bytes_per_chunk;529 530 /* overhead higher than 1 -> enable multi packets */531 if (chunk_overhead > 1) {532 /* multi packets */533 for (video_size = video_size_step;534 video_size < vm->hactive;535 video_size += video_size_step) {536 if (vm->hactive * 1000 / video_size % 1000)537 continue;538 539 chunks = vm->hactive / video_size;540 bytes_per_chunk = bpp_x100 * video_size / 100541 + pkt_header;542 if (total_bytes >= (bytes_per_chunk * chunks)) {543 bytes_left = total_bytes -544 bytes_per_chunk * chunks;545 break;546 }547 }548 549 /* prevent overflow (unsigned - unsigned) */550 if (bytes_left > (pkt_header * chunks)) {551 null_pkt_size = (bytes_left -552 pkt_header * chunks) / chunks;553 /* avoid register overflow */554 if (null_pkt_size > 1023)555 null_pkt_size = 1023;556 }557 558 } else {559 /* single packet */560 chunks = 1;561 562 /* must be a multiple of 4 except 18 loosely */563 for (video_size = vm->hactive;564 (video_size % video_size_step) != 0;565 video_size++)566 ;567 }568 569 dsi_reg_wr(ctx, VIDEO_PKT_CONFIG, VIDEO_PKT_SIZE, 0, video_size);570 writel(null_pkt_size, ctx->base + VIDEO_NULLPKT_SIZE);571 dsi_reg_wr(ctx, VIDEO_PKT_CONFIG, VIDEO_LINE_CHUNK_NUM, 16, chunks);572 }573 574 writel(ctx->int0_mask, ctx->base + MASK_PROTOCOL_INT);575 writel(ctx->int1_mask, ctx->base + MASK_INTERNAL_INT);576 writel(1, ctx->base + SOFT_RESET);577 578 return 0;579}580 581static void sprd_dsi_edpi_video(struct dsi_context *ctx)582{583 struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);584 const u32 fifo_depth = 1096;585 const u32 word_length = 4;586 u32 hactive = ctx->vm.hactive;587 u32 bpp_x100;588 u32 max_fifo_len;589 u8 coding;590 591 coding = fmt_to_coding(dsi->slave->format);592 bpp_x100 = calc_bytes_per_pixel_x100(coding);593 max_fifo_len = word_length * fifo_depth * 100 / bpp_x100;594 595 writel(0, ctx->base + SOFT_RESET);596 dsi_reg_wr(ctx, DPI_VIDEO_FORMAT, DPI_VIDEO_MODE_FORMAT, 0, coding);597 dsi_reg_wr(ctx, CMD_MODE_CFG, TEAR_FX_EN, 0, ctx->te_ack_en);598 599 if (max_fifo_len > hactive)600 writel(hactive, ctx->base + DCS_WM_PKT_SIZE);601 else602 writel(max_fifo_len, ctx->base + DCS_WM_PKT_SIZE);603 604 writel(ctx->int0_mask, ctx->base + MASK_PROTOCOL_INT);605 writel(ctx->int1_mask, ctx->base + MASK_INTERNAL_INT);606 writel(1, ctx->base + SOFT_RESET);607}608 609/*610 * Send a packet on the generic interface,611 * this function has an active delay to wait for the buffer to clear.612 * The delay is limited to:613 * (param_length / 4) x DSIH_FIFO_ACTIVE_WAIT x register access time614 * the controller restricts the sending of.615 *616 * This function will not be able to send Null and Blanking packets due to617 * controller restriction618 */619static int sprd_dsi_wr_pkt(struct dsi_context *ctx, u8 vc, u8 type,620 const u8 *param, u16 len)621{622 struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);623 u8 wc_lsbyte, wc_msbyte;624 u32 payload;625 int i, j, ret;626 627 if (vc > 3)628 return -EINVAL;629 630 /* 1st: for long packet, must config payload first */631 ret = dsi_wait_tx_payload_fifo_empty(ctx);632 if (ret) {633 drm_err(dsi->drm, "tx payload fifo is not empty\n");634 return ret;635 }636 637 if (len > 2) {638 for (i = 0, j = 0; i < len; i += j) {639 payload = 0;640 for (j = 0; (j < 4) && ((j + i) < (len)); j++)641 payload |= param[i + j] << (j * 8);642 643 writel(payload, ctx->base + GEN_PLD_DATA);644 }645 wc_lsbyte = len & 0xff;646 wc_msbyte = len >> 8;647 } else {648 wc_lsbyte = (len > 0) ? param[0] : 0;649 wc_msbyte = (len > 1) ? param[1] : 0;650 }651 652 /* 2nd: then set packet header */653 ret = dsi_wait_tx_cmd_fifo_empty(ctx);654 if (ret) {655 drm_err(dsi->drm, "tx cmd fifo is not empty\n");656 return ret;657 }658 659 writel(type | (vc << 6) | (wc_lsbyte << 8) | (wc_msbyte << 16),660 ctx->base + GEN_HDR);661 662 return 0;663}664 665/*666 * Send READ packet to peripheral using the generic interface,667 * this will force command mode and stop video mode (because of BTA).668 *669 * This function has an active delay to wait for the buffer to clear,670 * the delay is limited to 2 x DSIH_FIFO_ACTIVE_WAIT671 * (waiting for command buffer, and waiting for receiving)672 * @note this function will enable BTA673 */674static int sprd_dsi_rd_pkt(struct dsi_context *ctx, u8 vc, u8 type,675 u8 msb_byte, u8 lsb_byte,676 u8 *buffer, u8 bytes_to_read)677{678 struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);679 int i, ret;680 int count = 0;681 u32 temp;682 683 if (vc > 3)684 return -EINVAL;685 686 /* 1st: send read command to peripheral */687 ret = dsi_reg_rd(ctx, CMD_MODE_STATUS, GEN_CMD_CMD_FIFO_EMPTY, 5);688 if (!ret)689 return -EIO;690 691 writel(type | (vc << 6) | (lsb_byte << 8) | (msb_byte << 16),692 ctx->base + GEN_HDR);693 694 /* 2nd: wait peripheral response completed */695 ret = dsi_wait_rd_resp_completed(ctx);696 if (ret) {697 drm_err(dsi->drm, "wait read response time out\n");698 return ret;699 }700 701 /* 3rd: get data from rx payload fifo */702 ret = dsi_reg_rd(ctx, CMD_MODE_STATUS, GEN_CMD_RDATA_FIFO_EMPTY, 1);703 if (ret) {704 drm_err(dsi->drm, "rx payload fifo empty\n");705 return -EIO;706 }707 708 for (i = 0; i < 100; i++) {709 temp = readl(ctx->base + GEN_PLD_DATA);710 711 if (count < bytes_to_read)712 buffer[count++] = temp & 0xff;713 if (count < bytes_to_read)714 buffer[count++] = (temp >> 8) & 0xff;715 if (count < bytes_to_read)716 buffer[count++] = (temp >> 16) & 0xff;717 if (count < bytes_to_read)718 buffer[count++] = (temp >> 24) & 0xff;719 720 ret = dsi_reg_rd(ctx, CMD_MODE_STATUS, GEN_CMD_RDATA_FIFO_EMPTY, 1);721 if (ret)722 return count;723 }724 725 return 0;726}727 728static void sprd_dsi_set_work_mode(struct dsi_context *ctx, u8 mode)729{730 if (mode == DSI_MODE_CMD)731 writel(1, ctx->base + DSI_MODE_CFG);732 else733 writel(0, ctx->base + DSI_MODE_CFG);734}735 736static void sprd_dsi_state_reset(struct dsi_context *ctx)737{738 writel(0, ctx->base + SOFT_RESET);739 udelay(100);740 writel(1, ctx->base + SOFT_RESET);741}742 743static int sprd_dphy_init(struct dsi_context *ctx)744{745 struct sprd_dsi *dsi = container_of(ctx, struct sprd_dsi, ctx);746 int ret;747 748 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_RESET_N, 0);749 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_SHUTDOWN, 0);750 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_CLK_EN, 0);751 752 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLR, 0);753 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLR, PHY_TESTCLR);754 dsi_reg_up(ctx, PHY_TST_CTRL0, PHY_TESTCLR, 0);755 756 dphy_pll_config(ctx);757 dphy_timing_config(ctx);758 759 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_SHUTDOWN, RF_PHY_SHUTDOWN);760 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_RESET_N, RF_PHY_RESET_N);761 writel(0x1C, ctx->base + PHY_MIN_STOP_TIME);762 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_CLK_EN, RF_PHY_CLK_EN);763 writel(dsi->slave->lanes - 1, ctx->base + PHY_LANE_NUM_CONFIG);764 765 ret = dphy_wait_pll_locked(ctx);766 if (ret) {767 drm_err(dsi->drm, "dphy initial failed\n");768 return ret;769 }770 771 return 0;772}773 774static void sprd_dphy_fini(struct dsi_context *ctx)775{776 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_RESET_N, 0);777 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_SHUTDOWN, 0);778 dsi_reg_up(ctx, PHY_INTERFACE_CTRL, RF_PHY_RESET_N, RF_PHY_RESET_N);779}780 781static void sprd_dsi_encoder_mode_set(struct drm_encoder *encoder,782 struct drm_display_mode *mode,783 struct drm_display_mode *adj_mode)784{785 struct sprd_dsi *dsi = encoder_to_dsi(encoder);786 787 drm_display_mode_to_videomode(adj_mode, &dsi->ctx.vm);788}789 790static void sprd_dsi_encoder_enable(struct drm_encoder *encoder)791{792 struct sprd_dsi *dsi = encoder_to_dsi(encoder);793 struct sprd_dpu *dpu = to_sprd_crtc(encoder->crtc);794 struct dsi_context *ctx = &dsi->ctx;795 796 if (ctx->enabled) {797 drm_warn(dsi->drm, "dsi is initialized\n");798 return;799 }800 801 sprd_dsi_init(ctx);802 if (ctx->work_mode == DSI_MODE_VIDEO)803 sprd_dsi_dpi_video(ctx);804 else805 sprd_dsi_edpi_video(ctx);806 807 sprd_dphy_init(ctx);808 809 sprd_dsi_set_work_mode(ctx, ctx->work_mode);810 sprd_dsi_state_reset(ctx);811 812 if (dsi->slave->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {813 dsi_reg_up(ctx, PHY_CLK_LANE_LP_CTRL, AUTO_CLKLANE_CTRL_EN,814 AUTO_CLKLANE_CTRL_EN);815 } else {816 dsi_reg_up(ctx, PHY_CLK_LANE_LP_CTRL, RF_PHY_CLK_EN, RF_PHY_CLK_EN);817 dsi_reg_up(ctx, PHY_CLK_LANE_LP_CTRL, PHY_CLKLANE_TX_REQ_HS,818 PHY_CLKLANE_TX_REQ_HS);819 dphy_wait_pll_locked(ctx);820 }821 822 sprd_dpu_run(dpu);823 824 ctx->enabled = true;825}826 827static void sprd_dsi_encoder_disable(struct drm_encoder *encoder)828{829 struct sprd_dsi *dsi = encoder_to_dsi(encoder);830 struct sprd_dpu *dpu = to_sprd_crtc(encoder->crtc);831 struct dsi_context *ctx = &dsi->ctx;832 833 if (!ctx->enabled) {834 drm_warn(dsi->drm, "dsi isn't initialized\n");835 return;836 }837 838 sprd_dpu_stop(dpu);839 sprd_dphy_fini(ctx);840 sprd_dsi_fini(ctx);841 842 ctx->enabled = false;843}844 845static const struct drm_encoder_helper_funcs sprd_encoder_helper_funcs = {846 .mode_set = sprd_dsi_encoder_mode_set,847 .enable = sprd_dsi_encoder_enable,848 .disable = sprd_dsi_encoder_disable849};850 851static const struct drm_encoder_funcs sprd_encoder_funcs = {852 .destroy = drm_encoder_cleanup,853};854 855static int sprd_dsi_encoder_init(struct sprd_dsi *dsi,856 struct device *dev)857{858 struct drm_encoder *encoder = &dsi->encoder;859 u32 crtc_mask;860 int ret;861 862 crtc_mask = drm_of_find_possible_crtcs(dsi->drm, dev->of_node);863 if (!crtc_mask) {864 drm_err(dsi->drm, "failed to find crtc mask\n");865 return -EINVAL;866 }867 868 drm_dbg(dsi->drm, "find possible crtcs: 0x%08x\n", crtc_mask);869 870 encoder->possible_crtcs = crtc_mask;871 ret = drm_encoder_init(dsi->drm, encoder, &sprd_encoder_funcs,872 DRM_MODE_ENCODER_DSI, NULL);873 if (ret) {874 drm_err(dsi->drm, "failed to init dsi encoder\n");875 return ret;876 }877 878 drm_encoder_helper_add(encoder, &sprd_encoder_helper_funcs);879 880 return 0;881}882 883static int sprd_dsi_bridge_init(struct sprd_dsi *dsi,884 struct device *dev)885{886 int ret;887 888 dsi->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);889 if (IS_ERR(dsi->panel_bridge))890 return PTR_ERR(dsi->panel_bridge);891 892 ret = drm_bridge_attach(&dsi->encoder, dsi->panel_bridge, NULL, 0);893 if (ret)894 return ret;895 896 return 0;897}898 899static int sprd_dsi_context_init(struct sprd_dsi *dsi,900 struct device *dev)901{902 struct platform_device *pdev = to_platform_device(dev);903 struct dsi_context *ctx = &dsi->ctx;904 struct resource *res;905 906 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);907 if (!res) {908 dev_err(dev, "failed to get I/O resource\n");909 return -EINVAL;910 }911 912 ctx->base = devm_ioremap(dev, res->start, resource_size(res));913 if (!ctx->base) {914 drm_err(dsi->drm, "failed to map dsi host registers\n");915 return -ENXIO;916 }917 918 ctx->regmap = devm_regmap_init(dev, ®map_tst_io, dsi, &byte_config);919 if (IS_ERR(ctx->regmap)) {920 drm_err(dsi->drm, "dphy regmap init failed\n");921 return PTR_ERR(ctx->regmap);922 }923 924 ctx->data_hs2lp = 120;925 ctx->data_lp2hs = 500;926 ctx->clk_hs2lp = 4;927 ctx->clk_lp2hs = 15;928 ctx->max_rd_time = 6000;929 ctx->int0_mask = 0xffffffff;930 ctx->int1_mask = 0xffffffff;931 ctx->enabled = true;932 933 return 0;934}935 936static int sprd_dsi_bind(struct device *dev, struct device *master, void *data)937{938 struct drm_device *drm = data;939 struct sprd_dsi *dsi = dev_get_drvdata(dev);940 int ret;941 942 dsi->drm = drm;943 944 ret = sprd_dsi_encoder_init(dsi, dev);945 if (ret)946 return ret;947 948 ret = sprd_dsi_bridge_init(dsi, dev);949 if (ret)950 return ret;951 952 ret = sprd_dsi_context_init(dsi, dev);953 if (ret)954 return ret;955 956 return 0;957}958 959static void sprd_dsi_unbind(struct device *dev,960 struct device *master, void *data)961{962 struct sprd_dsi *dsi = dev_get_drvdata(dev);963 964 drm_of_panel_bridge_remove(dev->of_node, 1, 0);965 966 drm_encoder_cleanup(&dsi->encoder);967}968 969static const struct component_ops dsi_component_ops = {970 .bind = sprd_dsi_bind,971 .unbind = sprd_dsi_unbind,972};973 974static int sprd_dsi_host_attach(struct mipi_dsi_host *host,975 struct mipi_dsi_device *slave)976{977 struct sprd_dsi *dsi = host_to_dsi(host);978 struct dsi_context *ctx = &dsi->ctx;979 980 dsi->slave = slave;981 982 if (slave->mode_flags & MIPI_DSI_MODE_VIDEO)983 ctx->work_mode = DSI_MODE_VIDEO;984 else985 ctx->work_mode = DSI_MODE_CMD;986 987 if (slave->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)988 ctx->burst_mode = VIDEO_BURST_WITH_SYNC_PULSES;989 else if (slave->mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)990 ctx->burst_mode = VIDEO_NON_BURST_WITH_SYNC_PULSES;991 else992 ctx->burst_mode = VIDEO_NON_BURST_WITH_SYNC_EVENTS;993 994 return component_add(host->dev, &dsi_component_ops);995}996 997static int sprd_dsi_host_detach(struct mipi_dsi_host *host,998 struct mipi_dsi_device *slave)999{1000 component_del(host->dev, &dsi_component_ops);1001 1002 return 0;1003}1004 1005static ssize_t sprd_dsi_host_transfer(struct mipi_dsi_host *host,1006 const struct mipi_dsi_msg *msg)1007{1008 struct sprd_dsi *dsi = host_to_dsi(host);1009 const u8 *tx_buf = msg->tx_buf;1010 1011 if (msg->rx_buf && msg->rx_len) {1012 u8 lsb = (msg->tx_len > 0) ? tx_buf[0] : 0;1013 u8 msb = (msg->tx_len > 1) ? tx_buf[1] : 0;1014 1015 return sprd_dsi_rd_pkt(&dsi->ctx, msg->channel, msg->type,1016 msb, lsb, msg->rx_buf, msg->rx_len);1017 }1018 1019 if (msg->tx_buf && msg->tx_len)1020 return sprd_dsi_wr_pkt(&dsi->ctx, msg->channel, msg->type,1021 tx_buf, msg->tx_len);1022 1023 return 0;1024}1025 1026static const struct mipi_dsi_host_ops sprd_dsi_host_ops = {1027 .attach = sprd_dsi_host_attach,1028 .detach = sprd_dsi_host_detach,1029 .transfer = sprd_dsi_host_transfer,1030};1031 1032static const struct of_device_id dsi_match_table[] = {1033 { .compatible = "sprd,sharkl3-dsi-host" },1034 { /* sentinel */ },1035};1036 1037static int sprd_dsi_probe(struct platform_device *pdev)1038{1039 struct device *dev = &pdev->dev;1040 struct sprd_dsi *dsi;1041 1042 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);1043 if (!dsi)1044 return -ENOMEM;1045 1046 dev_set_drvdata(dev, dsi);1047 1048 dsi->host.ops = &sprd_dsi_host_ops;1049 dsi->host.dev = dev;1050 1051 return mipi_dsi_host_register(&dsi->host);1052}1053 1054static void sprd_dsi_remove(struct platform_device *pdev)1055{1056 struct sprd_dsi *dsi = dev_get_drvdata(&pdev->dev);1057 1058 mipi_dsi_host_unregister(&dsi->host);1059}1060 1061struct platform_driver sprd_dsi_driver = {1062 .probe = sprd_dsi_probe,1063 .remove_new = sprd_dsi_remove,1064 .driver = {1065 .name = "sprd-dsi-drv",1066 .of_match_table = dsi_match_table,1067 },1068};1069 1070MODULE_AUTHOR("Leon He <leon.he@unisoc.com>");1071MODULE_AUTHOR("Kevin Tang <kevin.tang@unisoc.com>");1072MODULE_DESCRIPTION("Unisoc MIPI DSI HOST Controller Driver");1073MODULE_LICENSE("GPL v2");1074