Commit cdf5316b authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next-4.12' of https://github.com/ckhu-mediatek/linux.git-tags into drm-next

This series is MT2701 DRM support.

* 'drm-next-4.12' of https://github.com/ckhu-mediatek/linux.git-tags:
  drm/mediatek: add support for Mediatek SoC MT2701
  drm/mediatek: update DSI sub driver flow for sending commands to panel
  drm/mediatek: add non-continuous clock mode and EOT packet control
  drm/mediatek: add dsi transfer function
  drm/mediatek: add dsi interrupt control
  drm/mediatek: cleaning up and refine
  drm/mediatek: update display module connections
  drm/mediatek: add BLS component
  drm/mediatek: add shadow register support
  drm/mediatek: add *driver_data for different hardware settings
  drm/mediatek: add helpers for coverting from the generic components
  dt-bindings: display: mediatek: update supported chips
parents 01687781 84a5ead1
...@@ -40,6 +40,7 @@ Required properties (all function blocks): ...@@ -40,6 +40,7 @@ Required properties (all function blocks):
"mediatek,<chip>-dpi" - DPI controller, see mediatek,dpi.txt "mediatek,<chip>-dpi" - DPI controller, see mediatek,dpi.txt
"mediatek,<chip>-disp-mutex" - display mutex "mediatek,<chip>-disp-mutex" - display mutex
"mediatek,<chip>-disp-od" - overdrive "mediatek,<chip>-disp-od" - overdrive
the supported chips are mt2701 and mt8173.
- reg: Physical base address and length of the function block register space - reg: Physical base address and length of the function block register space
- interrupts: The interrupt signal from the function block (required, except for - interrupts: The interrupt signal from the function block (required, except for
merge and split function blocks). merge and split function blocks).
...@@ -54,6 +55,7 @@ Required properties (DMA function blocks): ...@@ -54,6 +55,7 @@ Required properties (DMA function blocks):
"mediatek,<chip>-disp-ovl" "mediatek,<chip>-disp-ovl"
"mediatek,<chip>-disp-rdma" "mediatek,<chip>-disp-rdma"
"mediatek,<chip>-disp-wdma" "mediatek,<chip>-disp-wdma"
the supported chips are mt2701 and mt8173.
- larb: Should contain a phandle pointing to the local arbiter device as defined - larb: Should contain a phandle pointing to the local arbiter device as defined
in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
- iommus: Should point to the respective IOMMU block with master port as - iommus: Should point to the respective IOMMU block with master port as
......
...@@ -7,6 +7,7 @@ channel output. ...@@ -7,6 +7,7 @@ channel output.
Required properties: Required properties:
- compatible: "mediatek,<chip>-dsi" - compatible: "mediatek,<chip>-dsi"
the supported chips are mt2701 and mt8173.
- reg: Physical base address and length of the controller's registers - reg: Physical base address and length of the controller's registers
- interrupts: The interrupt signal from the function block. - interrupts: The interrupt signal from the function block.
- clocks: device clocks - clocks: device clocks
...@@ -25,6 +26,7 @@ The MIPI TX configuration module controls the MIPI D-PHY. ...@@ -25,6 +26,7 @@ The MIPI TX configuration module controls the MIPI D-PHY.
Required properties: Required properties:
- compatible: "mediatek,<chip>-mipi-tx" - compatible: "mediatek,<chip>-mipi-tx"
the supported chips are mt2701 and mt8173.
- reg: Physical base address and length of the controller's registers - reg: Physical base address and length of the controller's registers
- clocks: PLL reference clock - clocks: PLL reference clock
- clock-output-names: name of the output clock line to the DSI encoder - clock-output-names: name of the output clock line to the DSI encoder
......
...@@ -35,18 +35,28 @@ ...@@ -35,18 +35,28 @@
#define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n)) #define DISP_REG_OVL_PITCH(n) (0x0044 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_CTRL(n) (0x00c0 + 0x20 * (n))
#define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n)) #define DISP_REG_OVL_RDMA_GMC(n) (0x00c8 + 0x20 * (n))
#define DISP_REG_OVL_ADDR(n) (0x0f40 + 0x20 * (n)) #define DISP_REG_OVL_ADDR_MT2701 0x0040
#define DISP_REG_OVL_ADDR_MT8173 0x0f40
#define DISP_REG_OVL_ADDR(ovl, n) ((ovl)->data->addr + 0x20 * (n))
#define OVL_RDMA_MEM_GMC 0x40402020 #define OVL_RDMA_MEM_GMC 0x40402020
#define OVL_CON_BYTE_SWAP BIT(24) #define OVL_CON_BYTE_SWAP BIT(24)
#define OVL_CON_CLRFMT_RGB565 (0 << 12) #define OVL_CON_CLRFMT_RGB (1 << 12)
#define OVL_CON_CLRFMT_RGB888 (1 << 12)
#define OVL_CON_CLRFMT_RGBA8888 (2 << 12) #define OVL_CON_CLRFMT_RGBA8888 (2 << 12)
#define OVL_CON_CLRFMT_ARGB8888 (3 << 12) #define OVL_CON_CLRFMT_ARGB8888 (3 << 12)
#define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
0 : OVL_CON_CLRFMT_RGB)
#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
OVL_CON_CLRFMT_RGB : 0)
#define OVL_CON_AEN BIT(8) #define OVL_CON_AEN BIT(8)
#define OVL_CON_ALPHA 0xff #define OVL_CON_ALPHA 0xff
struct mtk_disp_ovl_data {
unsigned int addr;
bool fmt_rgb565_is_0;
};
/** /**
* struct mtk_disp_ovl - DISP_OVL driver structure * struct mtk_disp_ovl - DISP_OVL driver structure
* @ddp_comp - structure containing type enum and hardware resources * @ddp_comp - structure containing type enum and hardware resources
...@@ -55,8 +65,14 @@ ...@@ -55,8 +65,14 @@
struct mtk_disp_ovl { struct mtk_disp_ovl {
struct mtk_ddp_comp ddp_comp; struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc; struct drm_crtc *crtc;
const struct mtk_disp_ovl_data *data;
}; };
static inline struct mtk_disp_ovl *comp_to_ovl(struct mtk_ddp_comp *comp)
{
return container_of(comp, struct mtk_disp_ovl, ddp_comp);
}
static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
{ {
struct mtk_disp_ovl *priv = dev_id; struct mtk_disp_ovl *priv = dev_id;
...@@ -76,20 +92,18 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id) ...@@ -76,20 +92,18 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp, static void mtk_ovl_enable_vblank(struct mtk_ddp_comp *comp,
struct drm_crtc *crtc) struct drm_crtc *crtc)
{ {
struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl, struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
ddp_comp);
priv->crtc = crtc; ovl->crtc = crtc;
writel(0x0, comp->regs + DISP_REG_OVL_INTSTA); writel(0x0, comp->regs + DISP_REG_OVL_INTSTA);
writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN); writel_relaxed(OVL_FME_CPL_INT, comp->regs + DISP_REG_OVL_INTEN);
} }
static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp) static void mtk_ovl_disable_vblank(struct mtk_ddp_comp *comp)
{ {
struct mtk_disp_ovl *priv = container_of(comp, struct mtk_disp_ovl, struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
ddp_comp);
priv->crtc = NULL; ovl->crtc = NULL;
writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN); writel_relaxed(0x0, comp->regs + DISP_REG_OVL_INTEN);
} }
...@@ -138,18 +152,18 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx) ...@@ -138,18 +152,18 @@ static void mtk_ovl_layer_off(struct mtk_ddp_comp *comp, unsigned int idx)
writel(0x0, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx)); writel(0x0, comp->regs + DISP_REG_OVL_RDMA_CTRL(idx));
} }
static unsigned int ovl_fmt_convert(unsigned int fmt) static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
{ {
switch (fmt) { switch (fmt) {
default: default:
case DRM_FORMAT_RGB565: case DRM_FORMAT_RGB565:
return OVL_CON_CLRFMT_RGB565; return OVL_CON_CLRFMT_RGB565(ovl);
case DRM_FORMAT_BGR565: case DRM_FORMAT_BGR565:
return OVL_CON_CLRFMT_RGB565 | OVL_CON_BYTE_SWAP; return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_RGB888: case DRM_FORMAT_RGB888:
return OVL_CON_CLRFMT_RGB888; return OVL_CON_CLRFMT_RGB888(ovl);
case DRM_FORMAT_BGR888: case DRM_FORMAT_BGR888:
return OVL_CON_CLRFMT_RGB888 | OVL_CON_BYTE_SWAP; return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_RGBX8888: case DRM_FORMAT_RGBX8888:
case DRM_FORMAT_RGBA8888: case DRM_FORMAT_RGBA8888:
return OVL_CON_CLRFMT_ARGB8888; return OVL_CON_CLRFMT_ARGB8888;
...@@ -168,6 +182,7 @@ static unsigned int ovl_fmt_convert(unsigned int fmt) ...@@ -168,6 +182,7 @@ static unsigned int ovl_fmt_convert(unsigned int fmt)
static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx, static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
struct mtk_plane_state *state) struct mtk_plane_state *state)
{ {
struct mtk_disp_ovl *ovl = comp_to_ovl(comp);
struct mtk_plane_pending_state *pending = &state->pending; struct mtk_plane_pending_state *pending = &state->pending;
unsigned int addr = pending->addr; unsigned int addr = pending->addr;
unsigned int pitch = pending->pitch & 0xffff; unsigned int pitch = pending->pitch & 0xffff;
...@@ -179,7 +194,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx, ...@@ -179,7 +194,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
if (!pending->enable) if (!pending->enable)
mtk_ovl_layer_off(comp, idx); mtk_ovl_layer_off(comp, idx);
con = ovl_fmt_convert(fmt); con = ovl_fmt_convert(ovl, fmt);
if (idx != 0) if (idx != 0)
con |= OVL_CON_AEN | OVL_CON_ALPHA; con |= OVL_CON_AEN | OVL_CON_ALPHA;
...@@ -187,7 +202,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx, ...@@ -187,7 +202,7 @@ static void mtk_ovl_layer_config(struct mtk_ddp_comp *comp, unsigned int idx,
writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx)); writel_relaxed(pitch, comp->regs + DISP_REG_OVL_PITCH(idx));
writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx)); writel_relaxed(src_size, comp->regs + DISP_REG_OVL_SRC_SIZE(idx));
writel_relaxed(offset, comp->regs + DISP_REG_OVL_OFFSET(idx)); writel_relaxed(offset, comp->regs + DISP_REG_OVL_OFFSET(idx));
writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(idx)); writel_relaxed(addr, comp->regs + DISP_REG_OVL_ADDR(ovl, idx));
if (pending->enable) if (pending->enable)
mtk_ovl_layer_on(comp, idx); mtk_ovl_layer_on(comp, idx);
...@@ -264,6 +279,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev) ...@@ -264,6 +279,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
return ret; return ret;
} }
priv->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler, ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
...@@ -287,8 +304,21 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev) ...@@ -287,8 +304,21 @@ static int mtk_disp_ovl_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
.addr = DISP_REG_OVL_ADDR_MT2701,
.fmt_rgb565_is_0 = false,
};
static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
.addr = DISP_REG_OVL_ADDR_MT8173,
.fmt_rgb565_is_0 = true,
};
static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = { static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
{ .compatible = "mediatek,mt8173-disp-ovl", }, { .compatible = "mediatek,mt2701-disp-ovl",
.data = &mt2701_ovl_driver_data},
{ .compatible = "mediatek,mt8173-disp-ovl",
.data = &mt8173_ovl_driver_data},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match); MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);
......
...@@ -38,6 +38,11 @@ ...@@ -38,6 +38,11 @@
#define RDMA_FIFO_UNDERFLOW_EN BIT(31) #define RDMA_FIFO_UNDERFLOW_EN BIT(31)
#define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16) #define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16)
#define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16) #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16)
#define RDMA_FIFO_SIZE(rdma) ((rdma)->data->fifo_size)
struct mtk_disp_rdma_data {
unsigned int fifo_size;
};
/** /**
* struct mtk_disp_rdma - DISP_RDMA driver structure * struct mtk_disp_rdma - DISP_RDMA driver structure
...@@ -47,8 +52,14 @@ ...@@ -47,8 +52,14 @@
struct mtk_disp_rdma { struct mtk_disp_rdma {
struct mtk_ddp_comp ddp_comp; struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc; struct drm_crtc *crtc;
const struct mtk_disp_rdma_data *data;
}; };
static inline struct mtk_disp_rdma *comp_to_rdma(struct mtk_ddp_comp *comp)
{
return container_of(comp, struct mtk_disp_rdma, ddp_comp);
}
static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id) static irqreturn_t mtk_disp_rdma_irq_handler(int irq, void *dev_id)
{ {
struct mtk_disp_rdma *priv = dev_id; struct mtk_disp_rdma *priv = dev_id;
...@@ -77,20 +88,18 @@ static void rdma_update_bits(struct mtk_ddp_comp *comp, unsigned int reg, ...@@ -77,20 +88,18 @@ static void rdma_update_bits(struct mtk_ddp_comp *comp, unsigned int reg,
static void mtk_rdma_enable_vblank(struct mtk_ddp_comp *comp, static void mtk_rdma_enable_vblank(struct mtk_ddp_comp *comp,
struct drm_crtc *crtc) struct drm_crtc *crtc)
{ {
struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma, struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
ddp_comp);
priv->crtc = crtc; rdma->crtc = crtc;
rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
RDMA_FRAME_END_INT); RDMA_FRAME_END_INT);
} }
static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp) static void mtk_rdma_disable_vblank(struct mtk_ddp_comp *comp)
{ {
struct mtk_disp_rdma *priv = container_of(comp, struct mtk_disp_rdma, struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
ddp_comp);
priv->crtc = NULL; rdma->crtc = NULL;
rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0); rdma_update_bits(comp, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
} }
...@@ -111,6 +120,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width, ...@@ -111,6 +120,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
{ {
unsigned int threshold; unsigned int threshold;
unsigned int reg; unsigned int reg;
struct mtk_disp_rdma *rdma = comp_to_rdma(comp);
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xfff, width); rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_0, 0xfff, width);
rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_1, 0xfffff, height); rdma_update_bits(comp, DISP_REG_RDMA_SIZE_CON_1, 0xfffff, height);
...@@ -123,7 +133,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width, ...@@ -123,7 +133,7 @@ static void mtk_rdma_config(struct mtk_ddp_comp *comp, unsigned int width,
*/ */
threshold = width * height * vrefresh * 4 * 7 / 1000000; threshold = width * height * vrefresh * 4 * 7 / 1000000;
reg = RDMA_FIFO_UNDERFLOW_EN | reg = RDMA_FIFO_UNDERFLOW_EN |
RDMA_FIFO_PSEUDO_SIZE(SZ_8K) | RDMA_FIFO_PSEUDO_SIZE(RDMA_FIFO_SIZE(rdma)) |
RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold); RDMA_OUTPUT_VALID_FIFO_THRESHOLD(threshold);
writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON); writel(reg, comp->regs + DISP_REG_RDMA_FIFO_CON);
} }
...@@ -208,6 +218,8 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev) ...@@ -208,6 +218,8 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
return ret; return ret;
} }
priv->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
ret = component_add(dev, &mtk_disp_rdma_component_ops); ret = component_add(dev, &mtk_disp_rdma_component_ops);
...@@ -224,8 +236,19 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev) ...@@ -224,8 +236,19 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
.fifo_size = SZ_4K,
};
static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
.fifo_size = SZ_8K,
};
static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = { static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
{ .compatible = "mediatek,mt8173-disp-rdma", }, { .compatible = "mediatek,mt2701-disp-rdma",
.data = &mt2701_rdma_driver_data},
{ .compatible = "mediatek,mt8173-disp-rdma",
.data = &mt8173_rdma_driver_data},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match); MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
......
...@@ -327,6 +327,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc) ...@@ -327,6 +327,42 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
pm_runtime_put(drm->dev); pm_runtime_put(drm->dev);
} }
static void mtk_crtc_ddp_config(struct drm_crtc *crtc)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state);
struct mtk_ddp_comp *ovl = mtk_crtc->ddp_comp[0];
unsigned int i;
/*
* TODO: instead of updating the registers here, we should prepare
* working registers in atomic_commit and let the hardware command
* queue update module registers on vblank.
*/
if (state->pending_config) {
mtk_ddp_comp_config(ovl, state->pending_width,
state->pending_height,
state->pending_vrefresh, 0);
state->pending_config = false;
}
if (mtk_crtc->pending_planes) {
for (i = 0; i < OVL_LAYER_NR; i++) {
struct drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state;
plane_state = to_mtk_plane_state(plane->state);
if (plane_state->pending.config) {
mtk_ddp_comp_layer_config(ovl, i, plane_state);
plane_state->pending.config = false;
}
}
mtk_crtc->pending_planes = false;
}
}
static void mtk_drm_crtc_enable(struct drm_crtc *crtc) static void mtk_drm_crtc_enable(struct drm_crtc *crtc)
{ {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
...@@ -403,6 +439,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc, ...@@ -403,6 +439,7 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state) struct drm_crtc_state *old_crtc_state)
{ {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_drm_private *priv = crtc->dev->dev_private;
unsigned int pending_planes = 0; unsigned int pending_planes = 0;
int i; int i;
...@@ -424,6 +461,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc, ...@@ -424,6 +461,12 @@ static void mtk_drm_crtc_atomic_flush(struct drm_crtc *crtc,
if (crtc->state->color_mgmt_changed) if (crtc->state->color_mgmt_changed)
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state); mtk_ddp_gamma_set(mtk_crtc->ddp_comp[i], crtc->state);
if (priv->data->shadow_register) {
mtk_disp_mutex_acquire(mtk_crtc->mutex);
mtk_crtc_ddp_config(crtc);
mtk_disp_mutex_release(mtk_crtc->mutex);
}
} }
static const struct drm_crtc_funcs mtk_crtc_funcs = { static const struct drm_crtc_funcs mtk_crtc_funcs = {
...@@ -471,36 +514,10 @@ static int mtk_drm_crtc_init(struct drm_device *drm, ...@@ -471,36 +514,10 @@ static int mtk_drm_crtc_init(struct drm_device *drm,
void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl) void mtk_crtc_ddp_irq(struct drm_crtc *crtc, struct mtk_ddp_comp *ovl)
{ {
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc); struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
struct mtk_crtc_state *state = to_mtk_crtc_state(mtk_crtc->base.state); struct mtk_drm_private *priv = crtc->dev->dev_private;
unsigned int i;
/* if (!priv->data->shadow_register)
* TODO: instead of updating the registers here, we should prepare mtk_crtc_ddp_config(crtc);
* working registers in atomic_commit and let the hardware command
* queue update module registers on vblank.
*/
if (state->pending_config) {
mtk_ddp_comp_config(ovl, state->pending_width,
state->pending_height,
state->pending_vrefresh, 0);
state->pending_config = false;
}
if (mtk_crtc->pending_planes) {
for (i = 0; i < OVL_LAYER_NR; i++) {
struct drm_plane *plane = &mtk_crtc->planes[i];
struct mtk_plane_state *plane_state;
plane_state = to_mtk_plane_state(plane->state);
if (plane_state->pending.config) {
mtk_ddp_comp_layer_config(ovl, i, plane_state);
plane_state->pending.config = false;
}
}
mtk_crtc->pending_planes = false;
}
mtk_drm_finish_page_flip(mtk_crtc); mtk_drm_finish_page_flip(mtk_crtc);
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
*/ */
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/iopoll.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -31,26 +32,40 @@ ...@@ -31,26 +32,40 @@
#define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN 0x0c8 #define DISP_REG_CONFIG_DISP_RDMA1_MOUT_EN 0x0c8
#define DISP_REG_CONFIG_MMSYS_CG_CON0 0x100 #define DISP_REG_CONFIG_MMSYS_CG_CON0 0x100
#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN 0x030
#define DISP_REG_CONFIG_OUT_SEL 0x04c
#define DISP_REG_CONFIG_DSI_SEL 0x050
#define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n)) #define DISP_REG_MUTEX_EN(n) (0x20 + 0x20 * (n))
#define DISP_REG_MUTEX(n) (0x24 + 0x20 * (n))
#define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n)) #define DISP_REG_MUTEX_RST(n) (0x28 + 0x20 * (n))
#define DISP_REG_MUTEX_MOD(n) (0x2c + 0x20 * (n)) #define DISP_REG_MUTEX_MOD(n) (0x2c + 0x20 * (n))
#define DISP_REG_MUTEX_SOF(n) (0x30 + 0x20 * (n)) #define DISP_REG_MUTEX_SOF(n) (0x30 + 0x20 * (n))
#define MUTEX_MOD_DISP_OVL0 BIT(11) #define INT_MUTEX BIT(1)
#define MUTEX_MOD_DISP_OVL1 BIT(12)
#define MUTEX_MOD_DISP_RDMA0 BIT(13) #define MT8173_MUTEX_MOD_DISP_OVL0 BIT(11)
#define MUTEX_MOD_DISP_RDMA1 BIT(14) #define MT8173_MUTEX_MOD_DISP_OVL1 BIT(12)
#define MUTEX_MOD_DISP_RDMA2 BIT(15) #define MT8173_MUTEX_MOD_DISP_RDMA0 BIT(13)
#define MUTEX_MOD_DISP_WDMA0 BIT(16) #define MT8173_MUTEX_MOD_DISP_RDMA1 BIT(14)
#define MUTEX_MOD_DISP_WDMA1 BIT(17) #define MT8173_MUTEX_MOD_DISP_RDMA2 BIT(15)
#define MUTEX_MOD_DISP_COLOR0 BIT(18) #define MT8173_MUTEX_MOD_DISP_WDMA0 BIT(16)
#define MUTEX_MOD_DISP_COLOR1 BIT(19) #define MT8173_MUTEX_MOD_DISP_WDMA1 BIT(17)
#define MUTEX_MOD_DISP_AAL BIT(20) #define MT8173_MUTEX_MOD_DISP_COLOR0 BIT(18)
#define MUTEX_MOD_DISP_GAMMA BIT(21) #define MT8173_MUTEX_MOD_DISP_COLOR1 BIT(19)
#define MUTEX_MOD_DISP_UFOE BIT(22) #define MT8173_MUTEX_MOD_DISP_AAL BIT(20)
#define MUTEX_MOD_DISP_PWM0 BIT(23) #define MT8173_MUTEX_MOD_DISP_GAMMA BIT(21)
#define MUTEX_MOD_DISP_PWM1 BIT(24) #define MT8173_MUTEX_MOD_DISP_UFOE BIT(22)
#define MUTEX_MOD_DISP_OD BIT(25) #define MT8173_MUTEX_MOD_DISP_PWM0 BIT(23)
#define MT8173_MUTEX_MOD_DISP_PWM1 BIT(24)
#define MT8173_MUTEX_MOD_DISP_OD BIT(25)
#define MT2701_MUTEX_MOD_DISP_OVL BIT(3)
#define MT2701_MUTEX_MOD_DISP_WDMA BIT(6)
#define MT2701_MUTEX_MOD_DISP_COLOR BIT(7)
#define MT2701_MUTEX_MOD_DISP_BLS BIT(9)
#define MT2701_MUTEX_MOD_DISP_RDMA0 BIT(10)
#define MT2701_MUTEX_MOD_DISP_RDMA1 BIT(12)
#define MUTEX_SOF_SINGLE_MODE 0 #define MUTEX_SOF_SINGLE_MODE 0
#define MUTEX_SOF_DSI0 1 #define MUTEX_SOF_DSI0 1
...@@ -67,6 +82,10 @@ ...@@ -67,6 +82,10 @@
#define DPI0_SEL_IN_RDMA1 0x1 #define DPI0_SEL_IN_RDMA1 0x1
#define COLOR1_SEL_IN_OVL1 0x1 #define COLOR1_SEL_IN_OVL1 0x1
#define OVL_MOUT_EN_RDMA 0x1
#define BLS_TO_DSI_RDMA1_TO_DPI1 0x8
#define DSI_SEL_IN_BLS 0x0
struct mtk_disp_mutex { struct mtk_disp_mutex {
int id; int id;
bool claimed; bool claimed;
...@@ -77,24 +96,34 @@ struct mtk_ddp { ...@@ -77,24 +96,34 @@ struct mtk_ddp {
struct clk *clk; struct clk *clk;
void __iomem *regs; void __iomem *regs;
struct mtk_disp_mutex mutex[10]; struct mtk_disp_mutex mutex[10];
const unsigned int *mutex_mod;
};
static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
[DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
[DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
[DDP_COMPONENT_RDMA0] = MT2701_MUTEX_MOD_DISP_RDMA0,
[DDP_COMPONENT_RDMA1] = MT2701_MUTEX_MOD_DISP_RDMA1,
[DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
}; };
static const unsigned int mutex_mod[DDP_COMPONENT_ID_MAX] = { static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL] = MUTEX_MOD_DISP_AAL, [DDP_COMPONENT_AAL] = MT8173_MUTEX_MOD_DISP_AAL,
[DDP_COMPONENT_COLOR0] = MUTEX_MOD_DISP_COLOR0, [DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
[DDP_COMPONENT_COLOR1] = MUTEX_MOD_DISP_COLOR1, [DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
[DDP_COMPONENT_GAMMA] = MUTEX_MOD_DISP_GAMMA, [DDP_COMPONENT_GAMMA] = MT8173_MUTEX_MOD_DISP_GAMMA,
[DDP_COMPONENT_OD] = MUTEX_MOD_DISP_OD, [DDP_COMPONENT_OD] = MT8173_MUTEX_MOD_DISP_OD,
[DDP_COMPONENT_OVL0] = MUTEX_MOD_DISP_OVL0, [DDP_COMPONENT_OVL0] = MT8173_MUTEX_MOD_DISP_OVL0,
[DDP_COMPONENT_OVL1] = MUTEX_MOD_DISP_OVL1, [DDP_COMPONENT_OVL1] = MT8173_MUTEX_MOD_DISP_OVL1,
[DDP_COMPONENT_PWM0] = MUTEX_MOD_DISP_PWM0, [DDP_COMPONENT_PWM0] = MT8173_MUTEX_MOD_DISP_PWM0,
[DDP_COMPONENT_PWM1] = MUTEX_MOD_DISP_PWM1, [DDP_COMPONENT_PWM1] = MT8173_MUTEX_MOD_DISP_PWM1,
[DDP_COMPONENT_RDMA0] = MUTEX_MOD_DISP_RDMA0, [DDP_COMPONENT_RDMA0] = MT8173_MUTEX_MOD_DISP_RDMA0,
[DDP_COMPONENT_RDMA1] = MUTEX_MOD_DISP_RDMA1, [DDP_COMPONENT_RDMA1] = MT8173_MUTEX_MOD_DISP_RDMA1,
[DDP_COMPONENT_RDMA2] = MUTEX_MOD_DISP_RDMA2, [DDP_COMPONENT_RDMA2] = MT8173_MUTEX_MOD_DISP_RDMA2,
[DDP_COMPONENT_UFOE] = MUTEX_MOD_DISP_UFOE, [DDP_COMPONENT_UFOE] = MT8173_MUTEX_MOD_DISP_UFOE,
[DDP_COMPONENT_WDMA0] = MUTEX_MOD_DISP_WDMA0, [DDP_COMPONENT_WDMA0] = MT8173_MUTEX_MOD_DISP_WDMA0,
[DDP_COMPONENT_WDMA1] = MUTEX_MOD_DISP_WDMA1, [DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
}; };
static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur, static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
...@@ -106,6 +135,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur, ...@@ -106,6 +135,9 @@ static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) { if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
*addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN; *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
value = OVL0_MOUT_EN_COLOR0; value = OVL0_MOUT_EN_COLOR0;
} else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
*addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
value = OVL_MOUT_EN_RDMA;
} else if (cur == DDP_COMPONENT_OD && next == DDP_COMPONENT_RDMA0) { } else if (cur == DDP_COMPONENT_OD && next == DDP_COMPONENT_RDMA0) {
*addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN; *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
value = OD_MOUT_EN_RDMA0; value = OD_MOUT_EN_RDMA0;
...@@ -143,6 +175,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur, ...@@ -143,6 +175,9 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
} else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) { } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
*addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN; *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
value = COLOR1_SEL_IN_OVL1; value = COLOR1_SEL_IN_OVL1;
} else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
*addr = DISP_REG_CONFIG_DSI_SEL;
value = DSI_SEL_IN_BLS;
} else { } else {
value = 0; value = 0;
} }
...@@ -150,6 +185,15 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur, ...@@ -150,6 +185,15 @@ static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
return value; return value;
} }
static void mtk_ddp_sout_sel(void __iomem *config_regs,
enum mtk_ddp_comp_id cur,
enum mtk_ddp_comp_id next)
{
if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0)
writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
config_regs + DISP_REG_CONFIG_OUT_SEL);
}
void mtk_ddp_add_comp_to_path(void __iomem *config_regs, void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
enum mtk_ddp_comp_id cur, enum mtk_ddp_comp_id cur,
enum mtk_ddp_comp_id next) enum mtk_ddp_comp_id next)
...@@ -162,6 +206,8 @@ void mtk_ddp_add_comp_to_path(void __iomem *config_regs, ...@@ -162,6 +206,8 @@ void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
writel_relaxed(reg, config_regs + addr); writel_relaxed(reg, config_regs + addr);
} }
mtk_ddp_sout_sel(config_regs, cur, next);
value = mtk_ddp_sel_in(cur, next, &addr); value = mtk_ddp_sel_in(cur, next, &addr);
if (value) { if (value) {
reg = readl_relaxed(config_regs + addr) | value; reg = readl_relaxed(config_regs + addr) | value;
...@@ -247,7 +293,7 @@ void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex, ...@@ -247,7 +293,7 @@ void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
break; break;
default: default:
reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id)); reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
reg |= mutex_mod[id]; reg |= ddp->mutex_mod[id];
writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id)); writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
return; return;
} }
...@@ -273,7 +319,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex, ...@@ -273,7 +319,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
break; break;
default: default:
reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id)); reg = readl_relaxed(ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
reg &= ~mutex_mod[id]; reg &= ~(ddp->mutex_mod[id]);
writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id)); writel_relaxed(reg, ddp->regs + DISP_REG_MUTEX_MOD(mutex->id));
break; break;
} }
...@@ -299,6 +345,27 @@ void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex) ...@@ -299,6 +345,27 @@ void mtk_disp_mutex_disable(struct mtk_disp_mutex *mutex)
writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id)); writel(0, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
} }
void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex)
{
struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
mutex[mutex->id]);
u32 tmp;
writel(1, ddp->regs + DISP_REG_MUTEX_EN(mutex->id));
writel(1, ddp->regs + DISP_REG_MUTEX(mutex->id));
if (readl_poll_timeout_atomic(ddp->regs + DISP_REG_MUTEX(mutex->id),
tmp, tmp & INT_MUTEX, 1, 10000))
pr_err("could not acquire mutex %d\n", mutex->id);
}
void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex)
{
struct mtk_ddp *ddp = container_of(mutex, struct mtk_ddp,
mutex[mutex->id]);
writel(0, ddp->regs + DISP_REG_MUTEX(mutex->id));
}
static int mtk_ddp_probe(struct platform_device *pdev) static int mtk_ddp_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -326,6 +393,8 @@ static int mtk_ddp_probe(struct platform_device *pdev) ...@@ -326,6 +393,8 @@ static int mtk_ddp_probe(struct platform_device *pdev)
return PTR_ERR(ddp->regs); return PTR_ERR(ddp->regs);
} }
ddp->mutex_mod = of_device_get_match_data(dev);
platform_set_drvdata(pdev, ddp); platform_set_drvdata(pdev, ddp);
return 0; return 0;
...@@ -337,7 +406,8 @@ static int mtk_ddp_remove(struct platform_device *pdev) ...@@ -337,7 +406,8 @@ static int mtk_ddp_remove(struct platform_device *pdev)
} }
static const struct of_device_id ddp_driver_dt_match[] = { static const struct of_device_id ddp_driver_dt_match[] = {
{ .compatible = "mediatek,mt8173-disp-mutex" }, { .compatible = "mediatek,mt2701-disp-mutex", .data = mt2701_mutex_mod},
{ .compatible = "mediatek,mt8173-disp-mutex", .data = mt8173_mutex_mod},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, ddp_driver_dt_match); MODULE_DEVICE_TABLE(of, ddp_driver_dt_match);
......
...@@ -37,5 +37,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex, ...@@ -37,5 +37,7 @@ void mtk_disp_mutex_remove_comp(struct mtk_disp_mutex *mutex,
enum mtk_ddp_comp_id id); enum mtk_ddp_comp_id id);
void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex); void mtk_disp_mutex_unprepare(struct mtk_disp_mutex *mutex);
void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex); void mtk_disp_mutex_put(struct mtk_disp_mutex *mutex);
void mtk_disp_mutex_acquire(struct mtk_disp_mutex *mutex);
void mtk_disp_mutex_release(struct mtk_disp_mutex *mutex);
#endif /* MTK_DRM_DDP_H */ #endif /* MTK_DRM_DDP_H */
...@@ -39,9 +39,11 @@ ...@@ -39,9 +39,11 @@
#define DISP_REG_UFO_START 0x0000 #define DISP_REG_UFO_START 0x0000
#define DISP_COLOR_CFG_MAIN 0x0400 #define DISP_COLOR_CFG_MAIN 0x0400
#define DISP_COLOR_START 0x0c00 #define DISP_COLOR_START_MT2701 0x0f00
#define DISP_COLOR_WIDTH 0x0c50 #define DISP_COLOR_START_MT8173 0x0c00
#define DISP_COLOR_HEIGHT 0x0c54 #define DISP_COLOR_START(comp) ((comp)->data->color_offset)
#define DISP_COLOR_WIDTH(comp) (DISP_COLOR_START(comp) + 0x50)
#define DISP_COLOR_HEIGHT(comp) (DISP_COLOR_START(comp) + 0x54)
#define DISP_AAL_EN 0x0000 #define DISP_AAL_EN 0x0000
#define DISP_AAL_SIZE 0x0030 #define DISP_AAL_SIZE 0x0030
...@@ -80,6 +82,20 @@ ...@@ -80,6 +82,20 @@
#define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4) #define DITHER_ADD_LSHIFT_G(x) (((x) & 0x7) << 4)
#define DITHER_ADD_RSHIFT_G(x) (((x) & 0x7) << 0) #define DITHER_ADD_RSHIFT_G(x) (((x) & 0x7) << 0)
struct mtk_disp_color_data {
unsigned int color_offset;
};
struct mtk_disp_color {
struct mtk_ddp_comp ddp_comp;
const struct mtk_disp_color_data *data;
};
static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)
{
return container_of(comp, struct mtk_disp_color, ddp_comp);
}
void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc, void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
unsigned int CFG) unsigned int CFG)
{ {
...@@ -107,15 +123,19 @@ static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w, ...@@ -107,15 +123,19 @@ static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh, unsigned int h, unsigned int vrefresh,
unsigned int bpc) unsigned int bpc)
{ {
writel(w, comp->regs + DISP_COLOR_WIDTH); struct mtk_disp_color *color = comp_to_color(comp);
writel(h, comp->regs + DISP_COLOR_HEIGHT);
writel(w, comp->regs + DISP_COLOR_WIDTH(color));
writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
} }
static void mtk_color_start(struct mtk_ddp_comp *comp) static void mtk_color_start(struct mtk_ddp_comp *comp)
{ {
struct mtk_disp_color *color = comp_to_color(comp);
writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL, writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
comp->regs + DISP_COLOR_CFG_MAIN); comp->regs + DISP_COLOR_CFG_MAIN);
writel(0x1, comp->regs + DISP_COLOR_START); writel(0x1, comp->regs + DISP_COLOR_START(color));
} }
static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w, static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
...@@ -236,6 +256,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = { ...@@ -236,6 +256,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
[MTK_DISP_PWM] = "pwm", [MTK_DISP_PWM] = "pwm",
[MTK_DISP_MUTEX] = "mutex", [MTK_DISP_MUTEX] = "mutex",
[MTK_DISP_OD] = "od", [MTK_DISP_OD] = "od",
[MTK_DISP_BLS] = "bls",
}; };
struct mtk_ddp_comp_match { struct mtk_ddp_comp_match {
...@@ -246,6 +267,7 @@ struct mtk_ddp_comp_match { ...@@ -246,6 +267,7 @@ struct mtk_ddp_comp_match {
static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_AAL] = { MTK_DISP_AAL, 0, &ddp_aal }, [DDP_COMPONENT_AAL] = { MTK_DISP_AAL, 0, &ddp_aal },
[DDP_COMPONENT_BLS] = { MTK_DISP_BLS, 0, NULL },
[DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, &ddp_color }, [DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, &ddp_color },
[DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, &ddp_color }, [DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, &ddp_color },
[DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL }, [DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL },
...@@ -264,6 +286,22 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { ...@@ -264,6 +286,22 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
[DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL }, [DDP_COMPONENT_WDMA1] = { MTK_DISP_WDMA, 1, NULL },
}; };
static const struct mtk_disp_color_data mt2701_color_driver_data = {
.color_offset = DISP_COLOR_START_MT2701,
};
static const struct mtk_disp_color_data mt8173_color_driver_data = {
.color_offset = DISP_COLOR_START_MT8173,
};
static const struct of_device_id mtk_disp_color_driver_dt_match[] = {
{ .compatible = "mediatek,mt2701-disp-color",
.data = &mt2701_color_driver_data},
{ .compatible = "mediatek,mt8173-disp-color",
.data = &mt8173_color_driver_data},
{},
};
int mtk_ddp_comp_get_id(struct device_node *node, int mtk_ddp_comp_get_id(struct device_node *node,
enum mtk_ddp_comp_type comp_type) enum mtk_ddp_comp_type comp_type)
{ {
...@@ -286,14 +324,29 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, ...@@ -286,14 +324,29 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
enum mtk_ddp_comp_type type; enum mtk_ddp_comp_type type;
struct device_node *larb_node; struct device_node *larb_node;
struct platform_device *larb_pdev; struct platform_device *larb_pdev;
const struct of_device_id *match;
struct mtk_disp_color *color;
if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX) if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
return -EINVAL; return -EINVAL;
type = mtk_ddp_matches[comp_id].type;
if (type == MTK_DISP_COLOR) {
devm_kfree(dev, comp);
color = devm_kzalloc(dev, sizeof(*color), GFP_KERNEL);
if (!color)
return -ENOMEM;
match = of_match_node(mtk_disp_color_driver_dt_match, node);
color->data = match->data;
comp = &color->ddp_comp;
}
comp->id = comp_id; comp->id = comp_id;
comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs; comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
if (comp_id == DDP_COMPONENT_DPI0 || if (comp_id == DDP_COMPONENT_BLS ||
comp_id == DDP_COMPONENT_DPI0 ||
comp_id == DDP_COMPONENT_DSI0 || comp_id == DDP_COMPONENT_DSI0 ||
comp_id == DDP_COMPONENT_PWM0) { comp_id == DDP_COMPONENT_PWM0) {
comp->regs = NULL; comp->regs = NULL;
...@@ -308,8 +361,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, ...@@ -308,8 +361,6 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
if (IS_ERR(comp->clk)) if (IS_ERR(comp->clk))
comp->clk = NULL; comp->clk = NULL;
type = mtk_ddp_matches[comp_id].type;
/* Only DMA capable components need the LARB property */ /* Only DMA capable components need the LARB property */
comp->larb_dev = NULL; comp->larb_dev = NULL;
if (type != MTK_DISP_OVL && if (type != MTK_DISP_OVL &&
......
...@@ -36,11 +36,13 @@ enum mtk_ddp_comp_type { ...@@ -36,11 +36,13 @@ enum mtk_ddp_comp_type {
MTK_DISP_PWM, MTK_DISP_PWM,
MTK_DISP_MUTEX, MTK_DISP_MUTEX,
MTK_DISP_OD, MTK_DISP_OD,
MTK_DISP_BLS,
MTK_DDP_COMP_TYPE_MAX, MTK_DDP_COMP_TYPE_MAX,
}; };
enum mtk_ddp_comp_id { enum mtk_ddp_comp_id {
DDP_COMPONENT_AAL, DDP_COMPONENT_AAL,
DDP_COMPONENT_BLS,
DDP_COMPONENT_COLOR0, DDP_COMPONENT_COLOR0,
DDP_COMPONENT_COLOR1, DDP_COMPONENT_COLOR1,
DDP_COMPONENT_DPI0, DDP_COMPONENT_DPI0,
......
...@@ -128,7 +128,20 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = { ...@@ -128,7 +128,20 @@ static const struct drm_mode_config_funcs mtk_drm_mode_config_funcs = {
.atomic_commit = mtk_atomic_commit, .atomic_commit = mtk_atomic_commit,
}; };
static const enum mtk_ddp_comp_id mtk_ddp_main[] = { static const enum mtk_ddp_comp_id mt2701_mtk_ddp_main[] = {
DDP_COMPONENT_OVL0,
DDP_COMPONENT_RDMA0,
DDP_COMPONENT_COLOR0,
DDP_COMPONENT_BLS,
DDP_COMPONENT_DSI0,
};
static const enum mtk_ddp_comp_id mt2701_mtk_ddp_ext[] = {
DDP_COMPONENT_RDMA1,
DDP_COMPONENT_DPI0,
};
static const enum mtk_ddp_comp_id mt8173_mtk_ddp_main[] = {
DDP_COMPONENT_OVL0, DDP_COMPONENT_OVL0,
DDP_COMPONENT_COLOR0, DDP_COMPONENT_COLOR0,
DDP_COMPONENT_AAL, DDP_COMPONENT_AAL,
...@@ -139,7 +152,7 @@ static const enum mtk_ddp_comp_id mtk_ddp_main[] = { ...@@ -139,7 +152,7 @@ static const enum mtk_ddp_comp_id mtk_ddp_main[] = {
DDP_COMPONENT_PWM0, DDP_COMPONENT_PWM0,
}; };
static const enum mtk_ddp_comp_id mtk_ddp_ext[] = { static const enum mtk_ddp_comp_id mt8173_mtk_ddp_ext[] = {
DDP_COMPONENT_OVL1, DDP_COMPONENT_OVL1,
DDP_COMPONENT_COLOR1, DDP_COMPONENT_COLOR1,
DDP_COMPONENT_GAMMA, DDP_COMPONENT_GAMMA,
...@@ -147,6 +160,21 @@ static const enum mtk_ddp_comp_id mtk_ddp_ext[] = { ...@@ -147,6 +160,21 @@ static const enum mtk_ddp_comp_id mtk_ddp_ext[] = {
DDP_COMPONENT_DPI0, DDP_COMPONENT_DPI0,
}; };
static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
.main_path = mt2701_mtk_ddp_main,
.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
.ext_path = mt2701_mtk_ddp_ext,
.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
.shadow_register = true,
};
static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
.main_path = mt8173_mtk_ddp_main,
.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
.ext_path = mt8173_mtk_ddp_ext,
.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
};
static int mtk_drm_kms_init(struct drm_device *drm) static int mtk_drm_kms_init(struct drm_device *drm)
{ {
struct mtk_drm_private *private = drm->dev_private; struct mtk_drm_private *private = drm->dev_private;
...@@ -189,17 +217,19 @@ static int mtk_drm_kms_init(struct drm_device *drm) ...@@ -189,17 +217,19 @@ static int mtk_drm_kms_init(struct drm_device *drm)
* and each statically assigned to a crtc: * and each statically assigned to a crtc:
* OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ... * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
*/ */
ret = mtk_drm_crtc_create(drm, mtk_ddp_main, ARRAY_SIZE(mtk_ddp_main)); ret = mtk_drm_crtc_create(drm, private->data->main_path,
private->data->main_len);
if (ret < 0) if (ret < 0)
goto err_component_unbind; goto err_component_unbind;
/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */ /* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
ret = mtk_drm_crtc_create(drm, mtk_ddp_ext, ARRAY_SIZE(mtk_ddp_ext)); ret = mtk_drm_crtc_create(drm, private->data->ext_path,
private->data->ext_len);
if (ret < 0) if (ret < 0)
goto err_component_unbind; goto err_component_unbind;
/* Use OVL device for all DMA memory allocations */ /* Use OVL device for all DMA memory allocations */
np = private->comp_node[mtk_ddp_main[0]] ?: np = private->comp_node[private->data->main_path[0]] ?:
private->comp_node[mtk_ddp_ext[0]]; private->comp_node[private->data->ext_path[0]];
pdev = of_find_device_by_node(np); pdev = of_find_device_by_node(np);
if (!pdev) { if (!pdev) {
ret = -ENODEV; ret = -ENODEV;
...@@ -328,16 +358,22 @@ static const struct component_master_ops mtk_drm_ops = { ...@@ -328,16 +358,22 @@ static const struct component_master_ops mtk_drm_ops = {
}; };
static const struct of_device_id mtk_ddp_comp_dt_ids[] = { static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
{ .compatible = "mediatek,mt2701-disp-ovl", .data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt8173-disp-ovl", .data = (void *)MTK_DISP_OVL }, { .compatible = "mediatek,mt8173-disp-ovl", .data = (void *)MTK_DISP_OVL },
{ .compatible = "mediatek,mt2701-disp-rdma", .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-rdma", .data = (void *)MTK_DISP_RDMA }, { .compatible = "mediatek,mt8173-disp-rdma", .data = (void *)MTK_DISP_RDMA },
{ .compatible = "mediatek,mt8173-disp-wdma", .data = (void *)MTK_DISP_WDMA }, { .compatible = "mediatek,mt8173-disp-wdma", .data = (void *)MTK_DISP_WDMA },
{ .compatible = "mediatek,mt2701-disp-color", .data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8173-disp-color", .data = (void *)MTK_DISP_COLOR }, { .compatible = "mediatek,mt8173-disp-color", .data = (void *)MTK_DISP_COLOR },
{ .compatible = "mediatek,mt8173-disp-aal", .data = (void *)MTK_DISP_AAL}, { .compatible = "mediatek,mt8173-disp-aal", .data = (void *)MTK_DISP_AAL},
{ .compatible = "mediatek,mt8173-disp-gamma", .data = (void *)MTK_DISP_GAMMA, }, { .compatible = "mediatek,mt8173-disp-gamma", .data = (void *)MTK_DISP_GAMMA, },
{ .compatible = "mediatek,mt8173-disp-ufoe", .data = (void *)MTK_DISP_UFOE }, { .compatible = "mediatek,mt8173-disp-ufoe", .data = (void *)MTK_DISP_UFOE },
{ .compatible = "mediatek,mt2701-dsi", .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8173-dsi", .data = (void *)MTK_DSI }, { .compatible = "mediatek,mt8173-dsi", .data = (void *)MTK_DSI },
{ .compatible = "mediatek,mt8173-dpi", .data = (void *)MTK_DPI }, { .compatible = "mediatek,mt8173-dpi", .data = (void *)MTK_DPI },
{ .compatible = "mediatek,mt2701-disp-mutex", .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt8173-disp-mutex", .data = (void *)MTK_DISP_MUTEX }, { .compatible = "mediatek,mt8173-disp-mutex", .data = (void *)MTK_DISP_MUTEX },
{ .compatible = "mediatek,mt2701-disp-pwm", .data = (void *)MTK_DISP_BLS },
{ .compatible = "mediatek,mt8173-disp-pwm", .data = (void *)MTK_DISP_PWM }, { .compatible = "mediatek,mt8173-disp-pwm", .data = (void *)MTK_DISP_PWM },
{ .compatible = "mediatek,mt8173-disp-od", .data = (void *)MTK_DISP_OD }, { .compatible = "mediatek,mt8173-disp-od", .data = (void *)MTK_DISP_OD },
{ } { }
...@@ -359,6 +395,7 @@ static int mtk_drm_probe(struct platform_device *pdev) ...@@ -359,6 +395,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
mutex_init(&private->commit.lock); mutex_init(&private->commit.lock);
INIT_WORK(&private->commit.work, mtk_atomic_work); INIT_WORK(&private->commit.work, mtk_atomic_work);
private->data = of_device_get_match_data(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
private->config_regs = devm_ioremap_resource(dev, mem); private->config_regs = devm_ioremap_resource(dev, mem);
...@@ -510,7 +547,10 @@ static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, mtk_drm_sys_suspend, ...@@ -510,7 +547,10 @@ static SIMPLE_DEV_PM_OPS(mtk_drm_pm_ops, mtk_drm_sys_suspend,
mtk_drm_sys_resume); mtk_drm_sys_resume);
static const struct of_device_id mtk_drm_of_ids[] = { static const struct of_device_id mtk_drm_of_ids[] = {
{ .compatible = "mediatek,mt8173-mmsys", }, { .compatible = "mediatek,mt2701-mmsys",
.data = &mt2701_mmsys_driver_data},
{ .compatible = "mediatek,mt8173-mmsys",
.data = &mt8173_mmsys_driver_data},
{ } { }
}; };
......
...@@ -28,6 +28,14 @@ struct drm_fb_helper; ...@@ -28,6 +28,14 @@ struct drm_fb_helper;
struct drm_property; struct drm_property;
struct regmap; struct regmap;
struct mtk_mmsys_driver_data {
const enum mtk_ddp_comp_id *main_path;
unsigned int main_len;
const enum mtk_ddp_comp_id *ext_path;
unsigned int ext_len;
bool shadow_register;
};
struct mtk_drm_private { struct mtk_drm_private {
struct drm_device *drm; struct drm_device *drm;
struct device *dma_dev; struct device *dma_dev;
...@@ -39,6 +47,7 @@ struct mtk_drm_private { ...@@ -39,6 +47,7 @@ struct mtk_drm_private {
void __iomem *config_regs; void __iomem *config_regs;
struct device_node *comp_node[DDP_COMPONENT_ID_MAX]; struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX]; struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX];
const struct mtk_mmsys_driver_data *data;
struct { struct {
struct drm_atomic_state *state; struct drm_atomic_state *state;
......
This diff is collapsed.
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/phy/phy.h> #include <linux/phy/phy.h>
...@@ -87,6 +88,9 @@ ...@@ -87,6 +88,9 @@
#define MIPITX_DSI_PLL_CON2 0x58 #define MIPITX_DSI_PLL_CON2 0x58
#define MIPITX_DSI_PLL_TOP 0x64
#define RG_DSI_MPPLL_PRESERVE (0xff << 8)
#define MIPITX_DSI_PLL_PWR 0x68 #define MIPITX_DSI_PLL_PWR 0x68
#define RG_DSI_MPPLL_SDM_PWR_ON BIT(0) #define RG_DSI_MPPLL_SDM_PWR_ON BIT(0)
#define RG_DSI_MPPLL_SDM_ISO_EN BIT(1) #define RG_DSI_MPPLL_SDM_ISO_EN BIT(1)
...@@ -123,10 +127,15 @@ ...@@ -123,10 +127,15 @@
#define SW_LNT2_HSTX_PRE_OE BIT(24) #define SW_LNT2_HSTX_PRE_OE BIT(24)
#define SW_LNT2_HSTX_OE BIT(25) #define SW_LNT2_HSTX_OE BIT(25)
struct mtk_mipitx_data {
const u32 mppll_preserve;
};
struct mtk_mipi_tx { struct mtk_mipi_tx {
struct device *dev; struct device *dev;
void __iomem *regs; void __iomem *regs;
unsigned int data_rate; u32 data_rate;
const struct mtk_mipitx_data *driver_data;
struct clk_hw pll_hw; struct clk_hw pll_hw;
struct clk *pll; struct clk *pll;
}; };
...@@ -163,7 +172,7 @@ static void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, ...@@ -163,7 +172,7 @@ static void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
{ {
struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw); struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
unsigned int txdiv, txdiv0, txdiv1; u8 txdiv, txdiv0, txdiv1;
u64 pcw; u64 pcw;
dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate); dev_dbg(mipi_tx->dev, "prepare: %u Hz\n", mipi_tx->data_rate);
...@@ -243,6 +252,10 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw) ...@@ -243,6 +252,10 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1, mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
RG_DSI_MPPLL_SDM_SSC_EN); RG_DSI_MPPLL_SDM_SSC_EN);
mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
RG_DSI_MPPLL_PRESERVE,
mipi_tx->driver_data->mppll_preserve);
return 0; return 0;
} }
...@@ -255,6 +268,9 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) ...@@ -255,6 +268,9 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0, mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
RG_DSI_MPPLL_PLL_EN); RG_DSI_MPPLL_PLL_EN);
mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
RG_DSI_MPPLL_PRESERVE, 0);
mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR, mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
RG_DSI_MPPLL_SDM_ISO_EN | RG_DSI_MPPLL_SDM_ISO_EN |
RG_DSI_MPPLL_SDM_PWR_ON, RG_DSI_MPPLL_SDM_PWR_ON,
...@@ -310,7 +326,7 @@ static const struct clk_ops mtk_mipi_tx_pll_ops = { ...@@ -310,7 +326,7 @@ static const struct clk_ops mtk_mipi_tx_pll_ops = {
static int mtk_mipi_tx_power_on_signal(struct phy *phy) static int mtk_mipi_tx_power_on_signal(struct phy *phy)
{ {
struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
unsigned int reg; u32 reg;
for (reg = MIPITX_DSI_CLOCK_LANE; for (reg = MIPITX_DSI_CLOCK_LANE;
reg <= MIPITX_DSI_DATA_LANE3; reg += 4) reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
...@@ -341,7 +357,7 @@ static int mtk_mipi_tx_power_on(struct phy *phy) ...@@ -341,7 +357,7 @@ static int mtk_mipi_tx_power_on(struct phy *phy)
static void mtk_mipi_tx_power_off_signal(struct phy *phy) static void mtk_mipi_tx_power_off_signal(struct phy *phy)
{ {
struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy); struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
unsigned int reg; u32 reg;
mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON, mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON,
RG_DSI_PAD_TIE_LOW_EN); RG_DSI_PAD_TIE_LOW_EN);
...@@ -391,6 +407,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev) ...@@ -391,6 +407,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
if (!mipi_tx) if (!mipi_tx)
return -ENOMEM; return -ENOMEM;
mipi_tx->driver_data = of_device_get_match_data(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mipi_tx->regs = devm_ioremap_resource(dev, mem); mipi_tx->regs = devm_ioremap_resource(dev, mem);
if (IS_ERR(mipi_tx->regs)) { if (IS_ERR(mipi_tx->regs)) {
...@@ -448,8 +465,19 @@ static int mtk_mipi_tx_remove(struct platform_device *pdev) ...@@ -448,8 +465,19 @@ static int mtk_mipi_tx_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct mtk_mipitx_data mt2701_mipitx_data = {
.mppll_preserve = (3 << 8)
};
static const struct mtk_mipitx_data mt8173_mipitx_data = {
.mppll_preserve = (0 << 8)
};
static const struct of_device_id mtk_mipi_tx_match[] = { static const struct of_device_id mtk_mipi_tx_match[] = {
{ .compatible = "mediatek,mt8173-mipi-tx", }, { .compatible = "mediatek,mt2701-mipi-tx",
.data = &mt2701_mipitx_data },
{ .compatible = "mediatek,mt8173-mipi-tx",
.data = &mt8173_mipitx_data },
{}, {},
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment