Commit 39bf0bff authored by Dave Airlie's avatar Dave Airlie

Merge branch 'mediatek-drm-next-4.13' of...

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

This include new color format support and some fixups.

* 'mediatek-drm-next-4.13' of https://github.com/ckhu-mediatek/linux.git-tags:
  drm/mediatek: separate color module to fixup error memory reallocation
  drm/mediatek: check for memory allocation failure
  drm/mediatek: re-phrase DRM_INFO error message
  drm/mediatek: use platform_register_drivers
  drm/mediatek: Support UYVY and YUYV format for overlay
parents 00fc2c26 5ac5895a
mediatek-drm-y := mtk_disp_ovl.o \ mediatek-drm-y := mtk_disp_color.o \
mtk_disp_ovl.o \
mtk_disp_rdma.o \ mtk_disp_rdma.o \
mtk_drm_crtc.o \ mtk_drm_crtc.o \
mtk_drm_ddp.o \ mtk_drm_ddp.o \
......
/*
* Copyright (c) 2017 MediaTek Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <drm/drmP.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"
#define DISP_COLOR_CFG_MAIN 0x0400
#define DISP_COLOR_START_MT2701 0x0f00
#define DISP_COLOR_START_MT8173 0x0c00
#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 COLOR_BYPASS_ALL BIT(7)
#define COLOR_SEQ_SEL BIT(13)
struct mtk_disp_color_data {
unsigned int color_offset;
};
/**
* struct mtk_disp_color - DISP_COLOR driver structure
* @ddp_comp - structure containing type enum and hardware resources
* @crtc - associated crtc to report irq events to
*/
struct mtk_disp_color {
struct mtk_ddp_comp ddp_comp;
struct drm_crtc *crtc;
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);
}
static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc)
{
struct mtk_disp_color *color = comp_to_color(comp);
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)
{
struct mtk_disp_color *color = comp_to_color(comp);
writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
comp->regs + DISP_COLOR_CFG_MAIN);
writel(0x1, comp->regs + DISP_COLOR_START(color));
}
static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = {
.config = mtk_color_config,
.start = mtk_color_start,
};
static int mtk_disp_color_bind(struct device *dev, struct device *master,
void *data)
{
struct mtk_disp_color *priv = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
int ret;
ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
if (ret < 0) {
dev_err(dev, "Failed to register component %s: %d\n",
dev->of_node->full_name, ret);
return ret;
}
return 0;
}
static void mtk_disp_color_unbind(struct device *dev, struct device *master,
void *data)
{
struct mtk_disp_color *priv = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
mtk_ddp_comp_unregister(drm_dev, &priv->ddp_comp);
}
static const struct component_ops mtk_disp_color_component_ops = {
.bind = mtk_disp_color_bind,
.unbind = mtk_disp_color_unbind,
};
static int mtk_disp_color_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mtk_disp_color *priv;
int comp_id;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR);
if (comp_id < 0) {
dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
return comp_id;
}
ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
&mtk_disp_color_funcs);
if (ret) {
dev_err(dev, "Failed to initialize component: %d\n", ret);
return ret;
}
priv->data = of_device_get_match_data(dev);
platform_set_drvdata(pdev, priv);
ret = component_add(dev, &mtk_disp_color_component_ops);
if (ret)
dev_err(dev, "Failed to add component: %d\n", ret);
return ret;
}
static int mtk_disp_color_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &mtk_disp_color_component_ops);
return 0;
}
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},
{},
};
MODULE_DEVICE_TABLE(of, mtk_disp_color_driver_dt_match);
struct platform_driver mtk_disp_color_driver = {
.probe = mtk_disp_color_probe,
.remove = mtk_disp_color_remove,
.driver = {
.name = "mediatek-disp-color",
.owner = THIS_MODULE,
.of_match_table = mtk_disp_color_driver_dt_match,
},
};
...@@ -42,9 +42,12 @@ ...@@ -42,9 +42,12 @@
#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_MTX_YUV_TO_RGB (6 << 16)
#define OVL_CON_CLRFMT_RGB (1 << 12) #define OVL_CON_CLRFMT_RGB (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_UYVY (4 << 12)
#define OVL_CON_CLRFMT_YUYV (5 << 12)
#define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ #define OVL_CON_CLRFMT_RGB565(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
0 : OVL_CON_CLRFMT_RGB) 0 : OVL_CON_CLRFMT_RGB)
#define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \ #define OVL_CON_CLRFMT_RGB888(ovl) ((ovl)->data->fmt_rgb565_is_0 ? \
...@@ -176,6 +179,10 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt) ...@@ -176,6 +179,10 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
case DRM_FORMAT_XBGR8888: case DRM_FORMAT_XBGR8888:
case DRM_FORMAT_ABGR8888: case DRM_FORMAT_ABGR8888:
return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP; return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_UYVY:
return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
case DRM_FORMAT_YUYV:
return OVL_CON_CLRFMT_YUYV | OVL_CON_MTX_YUV_TO_RGB;
} }
} }
......
...@@ -559,6 +559,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, ...@@ -559,6 +559,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr, mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
sizeof(*mtk_crtc->ddp_comp), sizeof(*mtk_crtc->ddp_comp),
GFP_KERNEL); GFP_KERNEL);
if (!mtk_crtc->ddp_comp)
return -ENOMEM;
mtk_crtc->mutex = mtk_disp_mutex_get(priv->mutex_dev, pipe); mtk_crtc->mutex = mtk_disp_mutex_get(priv->mutex_dev, pipe);
if (IS_ERR(mtk_crtc->mutex)) { if (IS_ERR(mtk_crtc->mutex)) {
......
...@@ -38,13 +38,6 @@ ...@@ -38,13 +38,6 @@
#define DISP_REG_UFO_START 0x0000 #define DISP_REG_UFO_START 0x0000
#define DISP_COLOR_CFG_MAIN 0x0400
#define DISP_COLOR_START_MT2701 0x0f00
#define DISP_COLOR_START_MT8173 0x0c00
#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
...@@ -55,9 +48,6 @@ ...@@ -55,9 +48,6 @@
#define LUT_10BIT_MASK 0x03ff #define LUT_10BIT_MASK 0x03ff
#define COLOR_BYPASS_ALL BIT(7)
#define COLOR_SEQ_SEL BIT(13)
#define OD_RELAYMODE BIT(0) #define OD_RELAYMODE BIT(0)
#define UFO_BYPASS BIT(2) #define UFO_BYPASS BIT(2)
...@@ -82,20 +72,6 @@ ...@@ -82,20 +72,6 @@
#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)
{ {
...@@ -119,25 +95,6 @@ void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc, ...@@ -119,25 +95,6 @@ void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
} }
} }
static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc)
{
struct mtk_disp_color *color = comp_to_color(comp);
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)
{
struct mtk_disp_color *color = comp_to_color(comp);
writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
comp->regs + DISP_COLOR_CFG_MAIN);
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,
unsigned int h, unsigned int vrefresh, unsigned int h, unsigned int vrefresh,
unsigned int bpc) unsigned int bpc)
...@@ -229,11 +186,6 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = { ...@@ -229,11 +186,6 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
.stop = mtk_gamma_stop, .stop = mtk_gamma_stop,
}; };
static const struct mtk_ddp_comp_funcs ddp_color = {
.config = mtk_color_config,
.start = mtk_color_start,
};
static const struct mtk_ddp_comp_funcs ddp_od = { static const struct mtk_ddp_comp_funcs ddp_od = {
.config = mtk_od_config, .config = mtk_od_config,
.start = mtk_od_start, .start = mtk_od_start,
...@@ -268,8 +220,8 @@ struct mtk_ddp_comp_match { ...@@ -268,8 +220,8 @@ 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_BLS] = { MTK_DISP_BLS, 0, NULL },
[DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, &ddp_color }, [DDP_COMPONENT_COLOR0] = { MTK_DISP_COLOR, 0, NULL },
[DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, &ddp_color }, [DDP_COMPONENT_COLOR1] = { MTK_DISP_COLOR, 1, NULL },
[DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL }, [DDP_COMPONENT_DPI0] = { MTK_DPI, 0, NULL },
[DDP_COMPONENT_DSI0] = { MTK_DSI, 0, NULL }, [DDP_COMPONENT_DSI0] = { MTK_DSI, 0, NULL },
[DDP_COMPONENT_DSI1] = { MTK_DSI, 1, NULL }, [DDP_COMPONENT_DSI1] = { MTK_DSI, 1, NULL },
...@@ -286,22 +238,6 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = { ...@@ -286,22 +238,6 @@ 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)
{ {
...@@ -324,23 +260,11 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, ...@@ -324,23 +260,11 @@ 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; 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;
......
...@@ -439,11 +439,12 @@ static int mtk_drm_probe(struct platform_device *pdev) ...@@ -439,11 +439,12 @@ static int mtk_drm_probe(struct platform_device *pdev)
private->comp_node[comp_id] = of_node_get(node); private->comp_node[comp_id] = of_node_get(node);
/* /*
* Currently only the OVL, RDMA, DSI, and DPI blocks have * Currently only the COLOR, OVL, RDMA, DSI, and DPI blocks have
* separate component platform drivers and initialize their own * separate component platform drivers and initialize their own
* DDP component structure. The others are initialized here. * DDP component structure. The others are initialized here.
*/ */
if (comp_type == MTK_DISP_OVL || if (comp_type == MTK_DISP_COLOR ||
comp_type == MTK_DISP_OVL ||
comp_type == MTK_DISP_RDMA || comp_type == MTK_DISP_RDMA ||
comp_type == MTK_DSI || comp_type == MTK_DSI ||
comp_type == MTK_DPI) { comp_type == MTK_DPI) {
...@@ -566,6 +567,7 @@ static struct platform_driver mtk_drm_platform_driver = { ...@@ -566,6 +567,7 @@ static struct platform_driver mtk_drm_platform_driver = {
static struct platform_driver * const mtk_drm_drivers[] = { static struct platform_driver * const mtk_drm_drivers[] = {
&mtk_ddp_driver, &mtk_ddp_driver,
&mtk_disp_color_driver,
&mtk_disp_ovl_driver, &mtk_disp_ovl_driver,
&mtk_disp_rdma_driver, &mtk_disp_rdma_driver,
&mtk_dpi_driver, &mtk_dpi_driver,
...@@ -576,33 +578,14 @@ static struct platform_driver * const mtk_drm_drivers[] = { ...@@ -576,33 +578,14 @@ static struct platform_driver * const mtk_drm_drivers[] = {
static int __init mtk_drm_init(void) static int __init mtk_drm_init(void)
{ {
int ret; return platform_register_drivers(mtk_drm_drivers,
int i; ARRAY_SIZE(mtk_drm_drivers));
for (i = 0; i < ARRAY_SIZE(mtk_drm_drivers); i++) {
ret = platform_driver_register(mtk_drm_drivers[i]);
if (ret < 0) {
pr_err("Failed to register %s driver: %d\n",
mtk_drm_drivers[i]->driver.name, ret);
goto err;
}
}
return 0;
err:
while (--i >= 0)
platform_driver_unregister(mtk_drm_drivers[i]);
return ret;
} }
static void __exit mtk_drm_exit(void) static void __exit mtk_drm_exit(void)
{ {
int i; platform_unregister_drivers(mtk_drm_drivers,
ARRAY_SIZE(mtk_drm_drivers));
for (i = ARRAY_SIZE(mtk_drm_drivers) - 1; i >= 0; i--)
platform_driver_unregister(mtk_drm_drivers[i]);
} }
module_init(mtk_drm_init); module_init(mtk_drm_init);
......
...@@ -59,6 +59,7 @@ struct mtk_drm_private { ...@@ -59,6 +59,7 @@ struct mtk_drm_private {
}; };
extern struct platform_driver mtk_ddp_driver; extern struct platform_driver mtk_ddp_driver;
extern struct platform_driver mtk_disp_color_driver;
extern struct platform_driver mtk_disp_ovl_driver; extern struct platform_driver mtk_disp_ovl_driver;
extern struct platform_driver mtk_disp_rdma_driver; extern struct platform_driver mtk_disp_rdma_driver;
extern struct platform_driver mtk_dpi_driver; extern struct platform_driver mtk_dpi_driver;
......
...@@ -28,6 +28,8 @@ static const u32 formats[] = { ...@@ -28,6 +28,8 @@ static const u32 formats[] = {
DRM_FORMAT_XRGB8888, DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888,
DRM_FORMAT_RGB565, DRM_FORMAT_RGB565,
DRM_FORMAT_UYVY,
DRM_FORMAT_YUYV,
}; };
static void mtk_plane_reset(struct drm_plane *plane) static void mtk_plane_reset(struct drm_plane *plane)
......
...@@ -930,7 +930,7 @@ static u32 mtk_dsi_recv_cnt(u8 type, u8 *read_data) ...@@ -930,7 +930,7 @@ static u32 mtk_dsi_recv_cnt(u8 type, u8 *read_data)
DRM_INFO("type is 0x02, try again\n"); DRM_INFO("type is 0x02, try again\n");
break; break;
default: default:
DRM_INFO("type(0x%x) cannot be non-recognite\n", type); DRM_INFO("type(0x%x) not recognized\n", type);
break; break;
} }
......
...@@ -1778,33 +1778,14 @@ static struct platform_driver * const mtk_hdmi_drivers[] = { ...@@ -1778,33 +1778,14 @@ static struct platform_driver * const mtk_hdmi_drivers[] = {
static int __init mtk_hdmitx_init(void) static int __init mtk_hdmitx_init(void)
{ {
int ret; return platform_register_drivers(mtk_hdmi_drivers,
int i; ARRAY_SIZE(mtk_hdmi_drivers));
for (i = 0; i < ARRAY_SIZE(mtk_hdmi_drivers); i++) {
ret = platform_driver_register(mtk_hdmi_drivers[i]);
if (ret < 0) {
pr_err("Failed to register %s driver: %d\n",
mtk_hdmi_drivers[i]->driver.name, ret);
goto err;
}
}
return 0;
err:
while (--i >= 0)
platform_driver_unregister(mtk_hdmi_drivers[i]);
return ret;
} }
static void __exit mtk_hdmitx_exit(void) static void __exit mtk_hdmitx_exit(void)
{ {
int i; platform_unregister_drivers(mtk_hdmi_drivers,
ARRAY_SIZE(mtk_hdmi_drivers));
for (i = ARRAY_SIZE(mtk_hdmi_drivers) - 1; i >= 0; i--)
platform_driver_unregister(mtk_hdmi_drivers[i]);
} }
module_init(mtk_hdmitx_init); module_init(mtk_hdmitx_init);
......
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