diff options
Diffstat (limited to 'recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83')
6 files changed, 0 insertions, 896 deletions
diff --git a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/Kconfig b/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/Kconfig deleted file mode 100644 index 1d8f37f..0000000 --- a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config DRM_I2C_SN65DSI83 - bool "SN65DSI83 mipi dsi to lvds bridge" - depends on OF - select DRM_MIPI_DSI - default y - help - Support for the sn65dsi83 MIPI DSI to LVDS bridge diff --git a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/Makefile b/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/Makefile deleted file mode 100644 index dee7f49..0000000 --- a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -sn65dsi83-objs := sn65dsi83_drv.o sn65dsi83_brg.o -obj-$(CONFIG_DRM_I2C_SN65DSI83) := sn65dsi83.o diff --git a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_brg.c b/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_brg.c deleted file mode 100644 index f4a7713..0000000 --- a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_brg.c +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2018 CopuLab Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * 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 <linux/i2c.h> -#include <linux/device.h> -#include <linux/gpio/consumer.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/of_graph.h> -#include <linux/slab.h> - -#include <drm/drmP.h> -#include <drm/drm_atomic.h> -#include <drm/drm_atomic_helper.h> -#include <drm/drm_edid.h> -#include <drm/drm_mipi_dsi.h> -#include <drm/drm_connector.h> -#include <video/mipi_display.h> -#include <video/of_videomode.h> -#include <video/videomode.h> - -#include "sn65dsi83_brg.h" - -/* Register addresses */ - -#define SN65DSI83_SOFT_RESET 0x09 -#define SN65DSI83_CORE_PLL 0x0A - #define LVDS_CLK_RANGE_SHIFT 1 - #define HS_CLK_SRC_SHIFT 0 - -#define SN65DSI83_PLL_DIV 0x0B - #define DSI_CLK_DIV_SHIFT 3 - -#define SN65DSI83_PLL_EN 0x0D -#define SN65DSI83_DSI_CFG 0x10 - #define CHA_DSI_LANES_SHIFT 3 - -#define SN65DSI83_DSI_EQ 0x11 -#define SN65DSI83_CHA_DSI_CLK_RNG 0x12 -#define SN65DSI83_CHB_DSI_CLK_RNG 0x13 -#define SN65DSI83_LVDS_MODE 0x18 - #define DE_NEG_POLARITY_SHIFT 7 - #define HS_NEG_POLARITY_SHIFT 6 - #define VS_NEG_POLARITY_SHIFT 5 - #define LVDS_LINK_CFG_SHIFT 4 - #define CHA_24BPP_MODE_SHIFT 3 - #define CHA_24BPP_FMT1_SHIFT 1 - -#define SN65DSI83_LVDS_SIGN 0x19 -#define SN65DSI83_LVDS_TERM 0x1A -#define SN65DSI83_LVDS_CM_ADJ 0x1B -#define SN65DSI83_CHA_LINE_LEN_LO 0x20 -#define SN65DSI83_CHA_LINE_LEN_HI 0x21 -#define SN65DSI83_CHB_LINE_LEN_LO 0x22 -#define SN65DSI83_CHB_LINE_LEN_HI 0x23 -#define SN65DSI83_CHA_VERT_LINES_LO 0x24 -#define SN65DSI83_CHA_VERT_LINES_HI 0x25 -#define SN65DSI83_CHB_VERT_LINES_LO 0x26 -#define SN65DSI83_CHB_VERT_LINES_HI 0x27 -#define SN65DSI83_CHA_SYNC_DELAY_LO 0x28 -#define SN65DSI83_CHA_SYNC_DELAY_HI 0x29 -#define SN65DSI83_CHB_SYNC_DELAY_LO 0x2A -#define SN65DSI83_CHB_SYNC_DELAY_HI 0x2B -#define SN65DSI83_CHA_HSYNC_WIDTH_LO 0x2C -#define SN65DSI83_CHA_HSYNC_WIDTH_HI 0x2D -#define SN65DSI83_CHB_HSYNC_WIDTH_LO 0x2E -#define SN65DSI83_CHB_HSYNC_WIDTH_HI 0x2F -#define SN65DSI83_CHA_VSYNC_WIDTH_LO 0x30 -#define SN65DSI83_CHA_VSYNC_WIDTH_HI 0x31 -#define SN65DSI83_CHB_VSYNC_WIDTH_LO 0x32 -#define SN65DSI83_CHB_VSYNC_WIDTH_HI 0x33 -#define SN65DSI83_CHA_HORZ_BACKPORCH 0x34 -#define SN65DSI83_CHB_HORZ_BACKPORCH 0x35 -#define SN65DSI83_CHA_VERT_BACKPORCH 0x36 -#define SN65DSI83_CHB_VERT_BACKPORCH 0x37 -#define SN65DSI83_CHA_HORZ_FRONTPORCH 0x38 -#define SN65DSI83_CHB_HORZ_FRONTPORCH 0x39 -#define SN65DSI83_CHA_VERT_FRONTPORCH 0x3A -#define SN65DSI83_CHB_VERT_FRONTPORCH 0x3B -#define SN65DSI83_CHA_ERR 0xE5 -#define SN65DSI83_TEST_PATTERN 0x3C -#define SN65DSI83_REG_3D 0x3D -#define SN65DSI83_REG_3E 0x3E - -static int sn65dsi83_brg_power_on(struct sn65dsi83_brg *brg) -{ - dev_info(&brg->client->dev,"%s\n",__func__); - gpiod_set_value_cansleep(brg->gpio_enable, 1); - /* Wait for 1ms for the internal voltage regulator to stabilize */ - msleep(1); - - return 0; -} - -static void sn65dsi83_brg_power_off(struct sn65dsi83_brg *brg) -{ - dev_info(&brg->client->dev,"%s\n",__func__); - gpiod_set_value_cansleep(brg->gpio_enable, 0); - /* - * The EN pin must be held low for at least 10 ms - * before being asserted high - */ - msleep(10); -} - -static int sn65dsi83_write(struct i2c_client *client, u8 reg, u8 val) -{ - int ret; - - ret = i2c_smbus_write_byte_data(client, reg, val); - - if (ret) - dev_err(&client->dev, "failed to write at 0x%02x", reg); - - dev_dbg(&client->dev, "%s: write reg 0x%02x data 0x%02x", __func__, reg, val); - - return ret; -} -#define SN65DSI83_WRITE(reg,val) sn65dsi83_write(client, (reg) , (val)) - -static int sn65dsi83_read(struct i2c_client *client, u8 reg) -{ - int ret; - - dev_info(&client->dev, "client 0x%p", client); - ret = i2c_smbus_read_byte_data(client, reg); - - if (ret < 0) { - dev_err(&client->dev, "failed reading at 0x%02x", reg); - return ret; - } - - dev_dbg(&client->dev, "%s: read reg 0x%02x data 0x%02x", __func__, reg, ret); - - return ret; -} -#define SN65DSI83_READ(reg) sn65dsi83_read(client, (reg)) - -static int sn65dsi83_brg_start_stream(struct sn65dsi83_brg *brg) -{ - int regval; - struct i2c_client *client = I2C_CLIENT(brg); - - dev_info(&client->dev,"%s\n",__func__); - /* Set the PLL_EN bit (CSR 0x0D.0) */ - SN65DSI83_WRITE(SN65DSI83_PLL_EN, 0x1); - /* Wait for the PLL_LOCK bit to be set (CSR 0x0A.7) */ - msleep(200); - - /* Perform SW reset to apply changes */ - SN65DSI83_WRITE(SN65DSI83_SOFT_RESET, 0x01); - - /* Read CHA Error register */ - regval = SN65DSI83_READ(SN65DSI83_CHA_ERR); - dev_info(&client->dev, "CHA (0x%02x) = 0x%02x", - SN65DSI83_CHA_ERR, regval); - - return 0; -} - -static void sn65dsi83_brg_stop_stream(struct sn65dsi83_brg *brg) -{ - struct i2c_client *client = I2C_CLIENT(brg); - dev_info(&client->dev,"%s\n",__func__); - /* Clear the PLL_EN bit (CSR 0x0D.0) */ - SN65DSI83_WRITE(SN65DSI83_PLL_EN, 0x00); -} - -static int sn65dsi83_calk_clk_range(int min_regval, int max_regval, - unsigned long min_clk, unsigned long inc, - unsigned long target_clk) -{ - int regval = min_regval; - unsigned long clk = min_clk; - - while (regval <= max_regval) { - if ((clk <= target_clk) && (target_clk < (clk + inc))) - return regval; - - regval++; - clk += inc; - } - - return -1; -} - -#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X)) -static int sn65dsi83_calk_div(int min_regval, int max_regval, int min_div, - int inc, unsigned long source_clk, - unsigned long target_clk) -{ - int regval = min_regval; - int div = min_div; - unsigned long curr_delta; - unsigned long prev_delta = ABS(DIV_ROUND_UP(source_clk, div) - - target_clk); - - while (regval <= max_regval) { - curr_delta = ABS(DIV_ROUND_UP(source_clk, div) - target_clk); - if (curr_delta > prev_delta) - return --regval; - - regval++; - div += inc; - } - - return -1; -} - -static int sn65dsi83_brg_configure(struct sn65dsi83_brg *brg) -{ - int regval = 0; - struct i2c_client *client = I2C_CLIENT(brg); - struct videomode *vm = VM(brg); - - u32 dsi_clk = (((PIXCLK * BPP(brg)) / DSI_LANES(brg)) >> 1); - - dev_info(&client->dev, "DSI clock [ %u ] Hz\n",dsi_clk); - dev_info(&client->dev, "GeoMetry [ %d x %d ] Hz\n",HACTIVE,VACTIVE); - - /* Reset PLL_EN and SOFT_RESET registers */ - SN65DSI83_WRITE(SN65DSI83_SOFT_RESET,0x00); - SN65DSI83_WRITE(SN65DSI83_PLL_EN,0x00); - - /* LVDS clock setup */ - if ((25000000 <= PIXCLK) && (PIXCLK < 37500000)) - regval = 0; - else - regval = sn65dsi83_calk_clk_range(0x01, 0x05, 37500000, 25000000, - PIXCLK); - - if (regval < 0) { - dev_err(&client->dev, "failed to configure LVDS clock"); - return -EINVAL; - } - - regval = (regval << LVDS_CLK_RANGE_SHIFT); - regval |= (1 << HS_CLK_SRC_SHIFT); /* Use DSI clock */ - SN65DSI83_WRITE(SN65DSI83_CORE_PLL,regval); - - /* DSI clock range */ - regval = sn65dsi83_calk_clk_range(0x08, 0x64, 40000000, 5000000, dsi_clk); - if (regval < 0) { - dev_err(&client->dev, "failed to configure DSI clock range\n"); - return -EINVAL; - } - SN65DSI83_WRITE(SN65DSI83_CHA_DSI_CLK_RNG,regval); - - /* DSI clock divider */ - regval = sn65dsi83_calk_div(0x0, 0x18, 1, 1, dsi_clk, PIXCLK); - if (regval < 0) { - dev_err(&client->dev, "failed to calculate DSI clock divider"); - return -EINVAL; - } - - regval = regval << DSI_CLK_DIV_SHIFT; - SN65DSI83_WRITE(SN65DSI83_PLL_DIV,regval); - - /* Configure DSI_LANES */ - regval = SN65DSI83_READ(SN65DSI83_DSI_CFG); - regval &= ~(3 << CHA_DSI_LANES_SHIFT); - regval |= ((4 - DSI_LANES(brg)) << CHA_DSI_LANES_SHIFT); - SN65DSI83_WRITE(SN65DSI83_DSI_CFG,regval); - - /* CHA_DSI_DATA_EQ - No Equalization */ - /* CHA_DSI_CLK_EQ - No Equalization */ - SN65DSI83_WRITE(SN65DSI83_DSI_EQ,0x00); - - /* Video formats */ - regval = 0; - if (FLAGS & DISPLAY_FLAGS_HSYNC_LOW) - regval |= (1 << HS_NEG_POLARITY_SHIFT); - - if (FLAGS & DISPLAY_FLAGS_VSYNC_LOW) - regval |= (1 << VS_NEG_POLARITY_SHIFT); - - if (FLAGS & DISPLAY_FLAGS_DE_LOW) - regval |= (1 << DE_NEG_POLARITY_SHIFT); - - if (BPP(brg) == 24) - regval |= (1 << CHA_24BPP_MODE_SHIFT); - - if (FORMAT(brg) == 1) - regval |= (1 << CHA_24BPP_FMT1_SHIFT); - - regval |= (1 << LVDS_LINK_CFG_SHIFT); - SN65DSI83_WRITE(SN65DSI83_LVDS_MODE,regval); - - /* Voltage and pins */ - SN65DSI83_WRITE(SN65DSI83_LVDS_SIGN,0x00); - SN65DSI83_WRITE(SN65DSI83_LVDS_TERM,0x03); - SN65DSI83_WRITE(SN65DSI83_LVDS_CM_ADJ,0x00); - - /* Configure sync delay to minimal allowed value */ - SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_LO,0x21); - SN65DSI83_WRITE(SN65DSI83_CHA_SYNC_DELAY_HI,0x00); - - /* Geometry */ - SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_LO,LOW(HACTIVE)); - SN65DSI83_WRITE(SN65DSI83_CHA_LINE_LEN_HI,HIGH(HACTIVE)); - - SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_LO,LOW(VACTIVE)); - SN65DSI83_WRITE(SN65DSI83_CHA_VERT_LINES_HI,HIGH(VACTIVE)); - - SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_LO,LOW(HPW)); - SN65DSI83_WRITE(SN65DSI83_CHA_HSYNC_WIDTH_HI,HIGH(HPW)); - - SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_LO,LOW(VPW)); - SN65DSI83_WRITE(SN65DSI83_CHA_VSYNC_WIDTH_HI,HIGH(VPW)); - - SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_BACKPORCH,LOW(HBP)); - SN65DSI83_WRITE(SN65DSI83_CHA_VERT_BACKPORCH,LOW(VBP)); - - SN65DSI83_WRITE(SN65DSI83_CHA_HORZ_FRONTPORCH,LOW(HFP)); - SN65DSI83_WRITE(SN65DSI83_CHA_VERT_FRONTPORCH,LOW(VFP)); - - SN65DSI83_WRITE(SN65DSI83_TEST_PATTERN,0x00); - SN65DSI83_WRITE(SN65DSI83_REG_3D,0x00); - SN65DSI83_WRITE(SN65DSI83_REG_3E,0x00); - - /* mute channel B */ - SN65DSI83_WRITE(SN65DSI83_CHB_DSI_CLK_RNG, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_LINE_LEN_LO, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_LINE_LEN_HI, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_VERT_LINES_LO, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_VERT_LINES_HI, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_SYNC_DELAY_LO, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_SYNC_DELAY_HI, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_HSYNC_WIDTH_LO, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_HSYNC_WIDTH_HI, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_VSYNC_WIDTH_LO, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_VSYNC_WIDTH_HI, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_HORZ_BACKPORCH, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_VERT_BACKPORCH, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_HORZ_FRONTPORCH, 0x00); - SN65DSI83_WRITE(SN65DSI83_CHB_VERT_FRONTPORCH, 0x00); - return 0; -} - -static int sn65dsi83_brg_setup(struct sn65dsi83_brg *brg) -{ - struct i2c_client *client = I2C_CLIENT(brg); - dev_info(&client->dev,"%s\n",__func__); - sn65dsi83_brg_power_on(brg); - return sn65dsi83_brg_configure(brg); -} - -static int sn65dsi83_brg_reset(struct sn65dsi83_brg *brg) -{ - /* Soft Reset reg value at power on should be 0x00 */ - struct i2c_client *client = I2C_CLIENT(brg); - int ret = SN65DSI83_READ(SN65DSI83_SOFT_RESET); - dev_info(&client->dev,"%s\n",__func__); - if (ret != 0x00) { - dev_err(&client->dev,"Failed to reset the device"); - return -ENODEV; - } - return 0; -} - -static struct sn65dsi83_brg_funcs brg_func = { - .power_on = sn65dsi83_brg_power_on, - .power_off = sn65dsi83_brg_power_off, - .setup = sn65dsi83_brg_setup, - .reset = sn65dsi83_brg_reset, - .start_stream = sn65dsi83_brg_start_stream, - .stop_stream = sn65dsi83_brg_stop_stream, -}; - -static struct sn65dsi83_brg brg = { - .funcs = &brg_func, -}; - -struct sn65dsi83_brg *sn65dsi83_brg_get(void) { - return &brg; -} diff --git a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_brg.h b/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_brg.h deleted file mode 100644 index 9f23df8..0000000 --- a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_brg.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _SN65DSI83_BRG_H__ -#define _SN65DSI83_BRG_H__ - -#include <linux/i2c.h> -#include <linux/gpio/consumer.h> -#include <video/videomode.h> - -struct sn65dsi83_brg; -struct sn65dsi83_brg_funcs { - int (*power_on)(struct sn65dsi83_brg *sn65dsi8383_brg); - void (*power_off)(struct sn65dsi83_brg *sn65dsi8383_brg); - int (*reset)(struct sn65dsi83_brg *sn65dsi8383_brg); - int (*setup)(struct sn65dsi83_brg *sn65dsi8383_brg); - int (*start_stream)(struct sn65dsi83_brg *sn65dsi8383_brg); - void (*stop_stream)(struct sn65dsi83_brg *sn65dsi8383_brg); -}; - -struct sn65dsi83_brg { - struct i2c_client *client; - struct gpio_desc *gpio_enable; - /* Bridge Panel Parameters */ - struct videomode vm; - u32 width_mm; - u32 height_mm; - u32 format; - u32 bpp; - - u8 num_dsi_lanes; - struct sn65dsi83_brg_funcs *funcs; -}; -struct sn65dsi83_brg *sn65dsi83_brg_get(void); - -#define I2C_DEVICE(A) &(A)->client->dev -#define I2C_CLIENT(A) (A)->client -#define VM(A) &(A)->vm -#define BPP(A) (A)->bpp -#define FORMAT(A) (A)->format -#define DSI_LANES(A) (A)->num_dsi_lanes - -/* The caller has to have a vm structure defined */ -#define PIXCLK vm->pixelclock -#define HACTIVE vm->hactive -#define HFP vm->hfront_porch -#define HBP vm->hback_porch -#define HPW vm->hsync_len -#define VACTIVE vm->vactive -#define VFP vm->vfront_porch -#define VBP vm->vback_porch -#define VPW vm->vsync_len -#define FLAGS vm->flags - -#define HIGH(A) (((A) >> 8) & 0xFF) -#define LOW(A) ((A) & 0xFF) - -#endif /* _SN65DSI83_BRG_H__ */ diff --git a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_drv.c b/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_drv.c deleted file mode 100644 index d3459cf..0000000 --- a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_drv.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Licensed under the GPL-2. - */ - -#include <linux/device.h> -#include <linux/gpio/consumer.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/of_graph.h> -#include <linux/slab.h> - -#include <drm/drmP.h> -#include <drm/drm_atomic.h> -#include <drm/drm_atomic_helper.h> -#include <drm/drm_edid.h> -#include <drm/drm_mipi_dsi.h> -#include <drm/drm_connector.h> -#include <drm/drm_crtc_helper.h> -#include <video/mipi_display.h> -#include <video/of_videomode.h> -#include <video/videomode.h> - -#include "sn65dsi83_timing.h" -#include "sn65dsi83_brg.h" - -struct sn65dsi83 { - u8 channel_id; - enum drm_connector_status status; - bool powered; - struct drm_display_mode curr_mode; - struct drm_bridge bridge; - struct drm_connector connector; - struct device_node *host_node; - struct mipi_dsi_device *dsi; - struct sn65dsi83_brg *brg; -}; - -static int sn65dsi83_attach_dsi(struct sn65dsi83 *sn65dsi83); -#define DRM_DEVICE(A) A->dev->dev -/* Connector funcs */ -static struct sn65dsi83 *connector_to_sn65dsi83(struct drm_connector *connector) -{ - return container_of(connector, struct sn65dsi83, connector); -} - -static int sn65dsi83_connector_get_modes(struct drm_connector *connector) -{ - struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector); - struct sn65dsi83_brg *brg = sn65dsi83->brg; - struct device *dev = connector->dev->dev; - struct drm_display_mode *mode; - u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24; - u32 *bus_flags = &connector->display_info.bus_flags; - int ret; - - dev_info(dev, "%s\n",__func__); - mode = drm_mode_create(connector->dev); - if (!mode) { - DRM_DEV_ERROR(dev, "Failed to create display mode!\n"); - return 0; - } - - drm_display_mode_from_videomode(&brg->vm, mode); - mode->width_mm = brg->width_mm; - mode->height_mm = brg->height_mm; - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; - - drm_mode_probed_add(connector, mode); - drm_mode_connector_list_update(connector); - - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - - if (brg->vm.flags & DISPLAY_FLAGS_DE_HIGH) - *bus_flags |= DRM_BUS_FLAG_DE_HIGH; - if (brg->vm.flags & DISPLAY_FLAGS_DE_LOW) - *bus_flags |= DRM_BUS_FLAG_DE_LOW; - if (brg->vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) - *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE; - if (brg->vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) - *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE; - - ret = drm_display_info_set_bus_formats(&connector->display_info, - &bus_format, 1); - if (ret) - return ret; - - return 1; -} - -static enum drm_mode_status -sn65dsi83_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector); - struct device *dev = connector->dev->dev; - if (mode->clock > ( sn65dsi83->brg->vm.pixelclock / 1000 )) - return MODE_CLOCK_HIGH; - - dev_info(dev, "%s: mode: %d*%d@%d is valid\n",__func__, - mode->hdisplay,mode->vdisplay,mode->clock); - return MODE_OK; -} - -static struct drm_connector_helper_funcs sn65dsi83_connector_helper_funcs = { - .get_modes = sn65dsi83_connector_get_modes, - .mode_valid = sn65dsi83_connector_mode_valid, -}; - -static enum drm_connector_status -sn65dsi83_connector_detect(struct drm_connector *connector, bool force) -{ - struct sn65dsi83 *sn65dsi83 = connector_to_sn65dsi83(connector); - struct device *dev = connector->dev->dev; - enum drm_connector_status status; - dev_info(dev, "%s\n",__func__); - - status = connector_status_connected; - sn65dsi83->status = status; - return status; -} - -int drm_helper_probe_single_connector_modes(struct drm_connector *connector, - uint32_t maxX, uint32_t maxY); - -static struct drm_connector_funcs sn65dsi83_connector_funcs = { - .dpms = drm_helper_connector_dpms, - .fill_modes = drm_helper_probe_single_connector_modes, - .detect = sn65dsi83_connector_detect, - .destroy = drm_connector_cleanup, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -/* Bridge funcs */ -static struct sn65dsi83 *bridge_to_sn65dsi83(struct drm_bridge *bridge) -{ - return container_of(bridge, struct sn65dsi83, bridge); -} - -static void sn65dsi83_bridge_enable(struct drm_bridge *bridge) -{ - struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge); - dev_info(DRM_DEVICE(bridge),"%s\n",__func__); - sn65dsi83->brg->funcs->setup(sn65dsi83->brg); - sn65dsi83->brg->funcs->start_stream(sn65dsi83->brg); -} - -static void sn65dsi83_bridge_disable(struct drm_bridge *bridge) -{ - struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge); - dev_info(DRM_DEVICE(bridge),"%s\n",__func__); - sn65dsi83->brg->funcs->stop_stream(sn65dsi83->brg); - sn65dsi83->brg->funcs->power_off(sn65dsi83->brg); -} - -static void sn65dsi83_bridge_mode_set(struct drm_bridge *bridge, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) -{ - struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge); - dev_info(DRM_DEVICE(bridge), "%s: mode: %d*%d@%d\n",__func__, - mode->hdisplay,mode->vdisplay,mode->clock); - drm_mode_copy(&sn65dsi83->curr_mode, adj_mode); -} - -static int sn65dsi83_bridge_attach(struct drm_bridge *bridge) -{ - struct sn65dsi83 *sn65dsi83 = bridge_to_sn65dsi83(bridge); - int ret; - - dev_info(DRM_DEVICE(bridge),"%s\n",__func__); - if (!bridge->encoder) { - DRM_ERROR("Parent encoder object not found"); - return -ENODEV; - } - - sn65dsi83->connector.polled = DRM_CONNECTOR_POLL_CONNECT; - - ret = drm_connector_init(bridge->dev, &sn65dsi83->connector, - &sn65dsi83_connector_funcs, - DRM_MODE_CONNECTOR_DSI); - if (ret) { - DRM_ERROR("Failed to initialize connector with drm\n"); - return ret; - } - drm_connector_helper_add(&sn65dsi83->connector, - &sn65dsi83_connector_helper_funcs); - drm_mode_connector_attach_encoder(&sn65dsi83->connector, bridge->encoder); - - ret = sn65dsi83_attach_dsi(sn65dsi83); - - return ret; -} - -static struct drm_bridge_funcs sn65dsi83_bridge_funcs = { - .enable = sn65dsi83_bridge_enable, - .disable = sn65dsi83_bridge_disable, - .mode_set = sn65dsi83_bridge_mode_set, - .attach = sn65dsi83_bridge_attach, -}; - -static int sn65dsi83_parse_dt(struct device_node *np, - struct sn65dsi83 *sn65dsi83) -{ - struct device *dev = &sn65dsi83->brg->client->dev; - u32 num_lanes = 2, bpp = 24, format = 2, width = 149, height = 93; - struct device_node *endpoint; - - endpoint = of_graph_get_next_endpoint(np, NULL); - if (!endpoint) - return -ENODEV; - - sn65dsi83->host_node = of_graph_get_remote_port_parent(endpoint); - if (!sn65dsi83->host_node) { - of_node_put(endpoint); - return -ENODEV; - } - - of_property_read_u32(np, "ti,dsi-lanes", &num_lanes); - of_property_read_u32(np, "ti,lvds-format", &format); - of_property_read_u32(np, "ti,lvds-bpp", &bpp); - of_property_read_u32(np, "ti,width-mm", &width); - of_property_read_u32(np, "ti,height-mm", &height); - - if (num_lanes < 1 || num_lanes > 4) { - dev_err(dev, "Invalid dsi-lanes: %d\n", num_lanes); - return -EINVAL; - } - sn65dsi83->brg->num_dsi_lanes = num_lanes; - - sn65dsi83->brg->gpio_enable = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(sn65dsi83->brg->gpio_enable)) { - dev_err(dev, "failed to parse enable gpio"); - return PTR_ERR(sn65dsi83->brg->gpio_enable); - } - - sn65dsi83->brg->format = format; - sn65dsi83->brg->bpp = bpp; - - sn65dsi83->brg->width_mm = width; - sn65dsi83->brg->height_mm = height; - - /* Read default timing if there is not device tree node for */ - if ((of_get_videomode(np, &sn65dsi83->brg->vm, 0)) < 0) - videomode_from_timing(&panel_default_timing, &sn65dsi83->brg->vm); - - of_node_put(endpoint); - of_node_put(sn65dsi83->host_node); - - return 0; -} - -static int sn65dsi83_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct sn65dsi83 *sn65dsi83; - struct device *dev = &i2c->dev; - int ret; - - dev_info(dev,"%s\n",__func__); - if (!dev->of_node) - return -EINVAL; - - sn65dsi83 = devm_kzalloc(dev, sizeof(*sn65dsi83), GFP_KERNEL); - if (!sn65dsi83) - return -ENOMEM; - - /* Initialize it before DT parser */ - sn65dsi83->brg = sn65dsi83_brg_get(); - sn65dsi83->brg->client = i2c; - - sn65dsi83->powered = false; - sn65dsi83->status = connector_status_disconnected; - - i2c_set_clientdata(i2c, sn65dsi83); - - ret = sn65dsi83_parse_dt(dev->of_node, sn65dsi83); - if (ret) - return ret; - - sn65dsi83->brg->funcs->power_off(sn65dsi83->brg); - sn65dsi83->brg->funcs->power_on(sn65dsi83->brg); - ret = sn65dsi83->brg->funcs->reset(sn65dsi83->brg); - if (ret != 0x00) { - dev_err(dev, "Failed to reset the device"); - return -ENODEV; - } - sn65dsi83->brg->funcs->power_off(sn65dsi83->brg); - - - sn65dsi83->bridge.funcs = &sn65dsi83_bridge_funcs; - sn65dsi83->bridge.of_node = dev->of_node; - - ret = drm_bridge_add(&sn65dsi83->bridge); - if (ret) { - dev_err(dev, "failed to add sn65dsi83 bridge\n"); - } - - return ret; -} - -static int sn65dsi83_attach_dsi(struct sn65dsi83 *sn65dsi83) -{ - struct device *dev = &sn65dsi83->brg->client->dev; - struct mipi_dsi_host *host; - struct mipi_dsi_device *dsi; - int ret = 0; - const struct mipi_dsi_device_info info = { .type = "sn65dsi83", - .channel = 0, - .node = NULL, - }; - - dev_info(dev, "%s\n",__func__); - host = of_find_mipi_dsi_host_by_node(sn65dsi83->host_node); - if (!host) { - dev_err(dev, "failed to find dsi host\n"); - return -EPROBE_DEFER; - } - - dsi = mipi_dsi_device_register_full(host, &info); - if (IS_ERR(dsi)) { - dev_err(dev, "failed to create dsi device\n"); - ret = PTR_ERR(dsi); - return -ENODEV; - } - - sn65dsi83->dsi = dsi; - - dsi->lanes = sn65dsi83->brg->num_dsi_lanes; - dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; - - ret = mipi_dsi_attach(dsi); - if (ret < 0) { - dev_err(dev, "failed to attach dsi to host\n"); - mipi_dsi_device_unregister(dsi); - } - - return ret; -} - -static void sn65dsi83_detach_dsi(struct sn65dsi83 *sn65dsi83) -{ - struct device *dev = &sn65dsi83->brg->client->dev; - dev_info(dev, "%s\n",__func__); - mipi_dsi_detach(sn65dsi83->dsi); - mipi_dsi_device_unregister(sn65dsi83->dsi); -} - -static int sn65dsi83_remove(struct i2c_client *i2c) -{ - struct sn65dsi83 *sn65dsi83 = i2c_get_clientdata(i2c); - struct device *dev = &sn65dsi83->brg->client->dev; - dev_info(dev, "%s\n",__func__); - - sn65dsi83_detach_dsi(sn65dsi83); - drm_bridge_remove(&sn65dsi83->bridge); - - return 0; -} - -static const struct i2c_device_id sn65dsi83_i2c_ids[] = { - { "sn65dsi83", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sn65dsi83_i2c_ids); - -static const struct of_device_id sn65dsi83_of_ids[] = { - { .compatible = "ti,sn65dsi83" }, - { } -}; -MODULE_DEVICE_TABLE(of, sn65dsi83_of_ids); - -static struct mipi_dsi_driver sn65dsi83_dsi_driver = { - .driver.name = "sn65dsi83", -}; - -static struct i2c_driver sn65dsi83_driver = { - .driver = { - .name = "sn65dsi83", - .of_match_table = sn65dsi83_of_ids, - }, - .id_table = sn65dsi83_i2c_ids, - .probe = sn65dsi83_probe, - .remove = sn65dsi83_remove, -}; - -static int __init sn65dsi83_init(void) -{ - if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) - mipi_dsi_driver_register(&sn65dsi83_dsi_driver); - - return i2c_add_driver(&sn65dsi83_driver); -} -module_init(sn65dsi83_init); - -static void __exit sn65dsi83_exit(void) -{ - i2c_del_driver(&sn65dsi83_driver); - - if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) - mipi_dsi_driver_unregister(&sn65dsi83_dsi_driver); -} -module_exit(sn65dsi83_exit); - -MODULE_AUTHOR("CompuLab <compulab@compula.co.il>"); -MODULE_DESCRIPTION("SN65DSI bridge driver"); -MODULE_LICENSE("GPL"); diff --git a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_timing.h b/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_timing.h deleted file mode 100644 index e9bb663..0000000 --- a/recipes-kernel/linux/rvphone/cl-imx8/sn65dsi83/sn65dsi83_timing.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __SN65DSI83_TIMING_H__ -#define __SN65DSI83_TIMING_H__ - -/* Default Video Parameters */ -#define PIXCLK_INIT 62500000 - -#define HACTIVE_INIT 1280 -#define HPW_INIT 2 -#define HBP_INIT 6 -#define HFP_INIT 5 - -#define VACTIVE_INIT 800 -#define VPW_INIT 1 -#define VBP_INIT 2 -#define VFP_INIT 3 - -static const struct display_timing panel_default_timing = { - .pixelclock = { PIXCLK_INIT, PIXCLK_INIT, PIXCLK_INIT }, - .hactive = { HACTIVE_INIT, HACTIVE_INIT, HACTIVE_INIT }, - .hfront_porch = { HFP_INIT, HFP_INIT, HFP_INIT }, - .hsync_len = { HPW_INIT, HPW_INIT, HPW_INIT }, - .hback_porch = { HBP_INIT, HBP_INIT, HBP_INIT }, - .vactive = { VACTIVE_INIT, VACTIVE_INIT, VACTIVE_INIT }, - .vfront_porch = { VFP_INIT, VFP_INIT, VFP_INIT }, - .vsync_len = { VPW_INIT, VPW_INIT, VPW_INIT }, - .vback_porch = { VBP_INIT, VBP_INIT, VBP_INIT }, - .flags = DISPLAY_FLAGS_HSYNC_LOW | - DISPLAY_FLAGS_VSYNC_LOW | - DISPLAY_FLAGS_DE_LOW | - DISPLAY_FLAGS_PIXDATA_NEGEDGE, -}; - -#endif /* __SN65DSI83_TIMING_H__ */ |