pinctrl-names = "default";
pinctrl-0 = <&i2c2_pins>;
status = "okay";
+
+ seeed_plane_i2c@45 {
+ compatible = "seeed_panel";
+ reg = <0x45>;
+
+ port {
+ panel_dsi_port: endpoint {
+ remote-endpoint = <&dsi_out_port>;
+ };
+ };
+ };
+
};
&i2c3 {
};
&hdmi {
- status = "okay";
+ status = "okay";//okay
pinctrl-names = "default";
pinctrl-0 = <&inno_hdmi_pins>;
reg = <1>;
remote-endpoint = <&hdmi_in_lcdc>;
};
+
+ dc_out_dpi2: endpoint@2 {
+ reg = <2>;
+ remote-endpoint = <&mipi_in>;
+ };
};
};
};
};
+&encoder {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ mipi_in: endpoint {
+ remote-endpoint = <&dc_out_dpi2>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ mipi_out: endpoint {
+ remote-endpoint = <&dsi_in_port>;
+ };
+ };
+ };
+};
+
+&mipi_dsi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mipitx_pins>;
+ status = "okay";
+};
+
&co_process {
status = "okay";
};
<&clkvout JH7110_U0_DC8200_CLK_PIX1>,
<&clkvout JH7110_U0_DC8200_CLK_AXI>,
<&clkvout JH7110_U0_DC8200_CLK_CORE>,
- <&clkvout JH7110_U0_DC8200_CLK_AHB>;
+ <&clkvout JH7110_U0_DC8200_CLK_AHB>,
+ <&clkgen JH7110_VOUT_TOP_CLK_VOUT_AXI>,
+ <&clkgen JH7110_DOM_VOUT_TOP_LCD_CLK>;
clock-names = "noc_cpu","noc_cfg0","noc_gpu","noc_vdec","noc_venc",
"noc_disp","noc_isp","noc_stg","vout_src",
"top_vout_axi","ahb1","top_vout_ahb",
"top_vout_hdmiTX0","i2stx","pix_clk","vout_pix1",
- "axi_clk","core_clk","vout_ahb";
+ "axi_clk","core_clk","vout_ahb",
+ "vout_top_axi","vout_top_lcd";
resets = <&rstgen RSTN_U0_DOM_VOUT_TOP_SRC>,
<&rstgen RSTN_U0_DC8200_AXI>,
"rst_noc_disp","rst_noc_isp","rst_noc_stg","rst_noc_ddrc";
};
+ encoder: display-encoder {
+ compatible = "verisilicon,dsi-encoder";
+ status = "disabled";
+ };
+
mipi_dphy: mipi-dphy@295e0000{
compatible = "starfive,jh7100-mipi-dphy-tx";
reg = <0x0 0x295e0000 0x0 0x10000>;
mipi_dsi: mipi@295d0000 {
compatible = "cdns,dsi";
reg = <0x0 0x295d0000 0x0 0x10000>;
+ interrupts = <98>;
reg-names = "dsi";
clocks = <&clkvout JH7110_U0_CDNS_DSITX_CLK_SYS>,
<&clkvout JH7110_U0_CDNS_DSITX_CLK_APB>,
status = "disabled";
port {
- dsi_out_port: endpoint {
- /*remote-endpoint = <&panel_dsi_port>;*/
+ dsi_out_port: endpoint@0 {
+ remote-endpoint = <&panel_dsi_port>;
+ };
+ dsi_in_port: endpoint@1 {
+ remote-endpoint = <&mipi_out>;
};
};
};
};
+ mipitx_pins: mipitx-pins {
+ mipitx-1-pins {
+ sf,pins = <PAD_GPIO36>;
+ sf,pinmux = <PAD_GPIO36_FUNC_SEL 1>;
+ sf,pin-ioconfig = <IO(GPIO_IE(0))>;
+ };
+ mipitx-2-pins {
+ sf,pins = <PAD_GPIO37>;
+ sf,pinmux = <PAD_GPIO37_FUNC_SEL 1>;
+ sf,pin-ioconfig = <IO(GPIO_IE(0))>;
+ };
+ mipitx-3-pins {
+ sf,pins = <PAD_GPIO38>;
+ sf,pinmux = <PAD_GPIO38_FUNC_SEL 1>;
+ sf,pin-ioconfig = <IO(GPIO_IE(0))>;
+ };
+ mipitx-4-pins {
+ sf,pins = <PAD_GPIO39>;
+ sf,pinmux = <PAD_GPIO39_FUNC_SEL 1>;
+ sf,pin-ioconfig = <IO(GPIO_IE(0))>;
+ };
+ mipitx-5-pins {
+ sf,pins = <PAD_GPIO40>;
+ sf,pinmux = <PAD_GPIO40_FUNC_SEL 1>;
+ sf,pin-ioconfig = <IO(GPIO_IE(0))>;
+ };
+ };
+
pcie0_perst_default: pcie0_perst_default {
perst-pins {
sf,pins = <PAD_GPIO26>;
CONFIG_SENSORS_SFCTEMP=y
CONFIG_WATCHDOG=y
CONFIG_STARFIVE_WATCHDOG=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_STF7110=y
# CONFIG_MEDIA_CEC_SUPPORT is not set
CONFIG_MEDIA_SUPPORT=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIN_SENSOR_OV4689=y
CONFIG_DRM=y
CONFIG_DRM_VERISILICON=y
-CONFIG_STARFIVE_INNO_HDMI=y
+CONFIG_STARFIVE_DSI=y
# CONFIG_DRM_IMG_NULLDISP is not set
CONFIG_DRM_LEGACY=y
CONFIG_FB=y
CONFIG_SIFIVE_L2_FLUSH_START=0x40000000
CONFIG_SIFIVE_L2_FLUSH_SIZE=0x400000000
CONFIG_PWM=y
+CONFIG_PHY_M31_DPHY_RX0=y
CONFIG_RAS=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
# CONFIG_FTRACE is not set
# CONFIG_RUNTIME_TESTING_MENU is not set
CONFIG_MEMTEST=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_STF7110=y
for the Innosilicon HDMI driver. If you want to enable
HDMI on RK3036 based SoC, you should select this option.
config STARFIVE_DSI
- bool "DSI"
+ bool "Starfive MIPI DSI Select"
+ depends on DRM_VERISILICON
+ select DRM_MIPI_DSI
+ select GENERIC_PHY
+ select GENERIC_PHY_MIPI_DPHY
help
- enable dsi, you should select this option.
+ This selects support for starfive SoC specific extensions
+ for the Synopsys DesignWare MIPI driver. If you want to
+ enable MIPI DSI on VIC7110 based SoC, you should
+ select this option.
source "drivers/gpu/drm/verisilicon/adv7511/Kconfig"
2、evb板子当前与hdmi冲突的gpio有\r
i2c0 i2c1 i2c2 i2c3 sdio1 tdm\r
调试hdmi的时候建议在jh7100-common.dtsi文件\r
+将这些模块的pin的结点进行注释或者将node disabled\r
+\r
+\r
+\r
+build drm mipi-dsi need to config:\r
+# CONFIG_DRM_I2C_ADV7511_CEC is not set\r
+CONFIG_DRM_VERISILICON=y\r
+#CONFIG_DRM_I2C_ADV7513 is not set\r
+CONFIG_DRM_LEGACY=y\r
+CONFIG_STARFIVE_DSI=y\r
+CONFIG_PHY_M31_DPHY_RX0=y\r
+#STARFIVE_INNO_HDMI is not set\r
+# CONFIG_DRM_VGEM is not set\r
+# CONFIG_DRM_VKMS is not set\r
+\r
+notes:\r
+1.\r
+测试mipi-dsi时,在编译前需要打开的dts节点有:\r
+jh7110.dtsi: \r
+dc8200, encoder: display-encoder, mipi_dphy, mipi_dsi, mipi_panel\r
+\r
+jh7100-common.dtsi:\r
+&i2c2\r
+\r
+\r
+2.\r
+evb板子当前与mipi-dsi冲突的gpio有:\r
+i2c0, i2c3, hdmi(inno), hdmi_output(rgb), sdio1(mmc1)\r
+\r
+调试mipi-dsi的时候建议在jh7100-common.dtsi文件\r
将这些模块的pin的结点进行注释或者将node disabled
\ No newline at end of file
#include <linux/phy/phy-mipi-dphy.h>
#include "vs_drv.h"
+//#include <soc/starfive/jh7110_pmic.h>//20220520 pmic support
+//#include"vs_clock.h"
//sysrst registers
#define SRST_ASSERT0 0x00
#define DSI_NULL_FRAME_OVERHEAD 6
#define DSI_EOT_PKT_SIZE 4
+#if 1 //7110 fw
+#define ARRAY_SIZE_DSI(x) (sizeof(x) / sizeof((x)[0]))
+#define TEST_CTRL(x) (x)
+#endif
+
struct cdns_dsi_output {
struct mipi_dsi_device *dev;
struct drm_panel *panel;
//clk op func----------//
static int cdns_dsi_clock_enable(struct cdns_dsi *dsi, struct device *dev)
{
+ //dev_info(dev,"==cdns_dsi_clock_enable begin\n");
int ret;
/*clk_prepare_enable(dsi->sys_clk);*/
ret = clk_prepare_enable(dsi->dsi_sys_clk);
dev_err(dev, "failed to prepare/enable dpi_clk\n");
return ret;
}
-
+
+ //dev_info(dev,"==cdns_dsi_clock_enable successful\n");
return ret;
}
//rst op func--------//
static int cdns_dsi_resets_deassert(struct cdns_dsi *dsi, struct device *dev)
{
+ //dev_info(dev,"==cdns_dsi_resets_deassert begin\n");
int ret;
ret = reset_control_deassert(dsi->sys_rst);
dev_err(dev, "failed to deassert sys_rst\n");
return ret;
}
- ret = reset_control_deassert(dsi->txbytehs_rst);
- if (ret < 0) {
- dev_err(dev, "failed to deassert txbytehs_rst\n");
- return ret;
- }
+ //ret = reset_control_deassert(dsi->txbytehs_rst);
+ //if (ret < 0) {
+ // dev_err(dev, "failed to deassert txbytehs_rst\n");
+ // return ret;
+ //}
ret = reset_control_deassert(dsi->apb_rst);
if (ret < 0) {
dev_err(dev, "failed to deassert apb_rst\n");
dev_err(dev, "failed to deassert rxesc_rst\n");
return ret;
}
-
+ //dev_info(dev,"==cdns_dsi_resets_deassert successful\n");
return ret;
}
static int cdns_dsi_resets_assert(struct cdns_dsi *dsi, struct device *dev)
{
+ //dev_info(dev,"==cdns_dsi_resets_assert begin\n");
int ret;
ret = reset_control_assert(dsi->sys_rst);
dev_err(dev, "failed to assert sys_rst\n");
return ret;
}
- ret = reset_control_assert(dsi->txbytehs_rst);
- if (ret < 0) {
- dev_err(dev, "failed to assert txbytehs_rst\n");
- return ret;
- }
+ //ret = reset_control_assert(dsi->txbytehs_rst);
+ //if (ret < 0) {
+ // dev_err(dev, "failed to assert txbytehs_rst\n");
+ // return ret;
+ //}
ret = reset_control_assert(dsi->apb_rst);
if (ret < 0) {
dev_err(dev, "failed to assert apb_rst\n");
dev_err(dev, "failed to assert dpi_rst\n");
return ret;
}
-
+ //dev_info(dev,"==cdns_dsi_resets_assert successful\n");
return ret;
}
//get clock func
-static int cdns_dsi_get_clock(struct platform_device *pdev, struct cdns_dsi *dsi)
+static int cdns_dsi_get_clock(struct device *dev, struct cdns_dsi *dsi)
{
+ //dev_info(dev,"==cdns_dsi_get_clock begin\n");
int ret;
- dsi->dsi_sys_clk = devm_clk_get(&pdev->dev, "sys");
- if (IS_ERR(dsi->dsi_sys_clk))
+ dsi->dsi_sys_clk = devm_clk_get(dev, "sys");
+ if (IS_ERR(dsi->dsi_sys_clk)){
+ dev_err(dev, "failed to get dsi_sys_clk\n");
return PTR_ERR(dsi->dsi_sys_clk);
- dsi->apb_clk = devm_clk_get(&pdev->dev, "apb");
- if (IS_ERR(dsi->apb_clk))
+ }
+
+ dsi->apb_clk = devm_clk_get(dev, "apb");
+ if (IS_ERR(dsi->apb_clk)){
+ dev_err(dev, "failed to get apb_clk\n");
return PTR_ERR(dsi->apb_clk);
- dsi->txesc_clk = devm_clk_get(&pdev->dev, "txesc");
- if (IS_ERR(dsi->txesc_clk))
+ }
+
+ dsi->txesc_clk = devm_clk_get(dev, "txesc");
+ if (IS_ERR(dsi->txesc_clk)){
+ dev_err(dev, "failed to get txesc_clk\n");
return PTR_ERR(dsi->txesc_clk);
- dsi->dpi_clk = devm_clk_get(&pdev->dev, "dpi");
- if (IS_ERR(dsi->dpi_clk))
+ }
+
+ dsi->dpi_clk = devm_clk_get(dev, "dpi");
+ if (IS_ERR(dsi->dpi_clk)){
+ dev_err(dev, "failed to get dpi_clk\n");
return PTR_ERR(dsi->dpi_clk);
+ }
+ //dev_info(dev,"==cdns_dsi_get_clock successful\n");
return ret;
}
//get reset func
-static int cdns_dsi_get_reset(struct platform_device *pdev, struct cdns_dsi *dsi)
+static int cdns_dsi_get_reset(struct device *dev, struct cdns_dsi *dsi)
{
+ //dev_info(dev,"==cdns_dsi_get_reset begin\n");
int ret;
- dsi->dpi_rst = reset_control_get_exclusive(&pdev->dev, "dsi_dpi");
- if (IS_ERR(dsi->dpi_rst))
+ dsi->dpi_rst = reset_control_get_exclusive(dev, "dsi_dpi");
+ if (IS_ERR(dsi->dpi_rst)){
+ dev_err(dev, "failed to get dpi_rst\n");
return PTR_ERR(dsi->dpi_rst);
- dsi->apb_rst = reset_control_get_exclusive(&pdev->dev, "dsi_apb");
- if (IS_ERR(dsi->apb_rst))
+ }
+
+ dsi->apb_rst = reset_control_get_exclusive(dev, "dsi_apb");
+ if (IS_ERR(dsi->apb_rst)){
+ dev_err(dev, "failed to get apb_rst\n");
return PTR_ERR(dsi->apb_rst);
- dsi->rxesc_rst = reset_control_get_exclusive(&pdev->dev, "dsi_rxesc");
- if (IS_ERR(dsi->rxesc_rst))
+ }
+
+ dsi->rxesc_rst = reset_control_get_exclusive(dev, "dsi_rxesc");
+ if (IS_ERR(dsi->rxesc_rst)){
+ dev_err(dev, "failed to get rxesc_rst\n");
return PTR_ERR(dsi->rxesc_rst);
- dsi->sys_rst = reset_control_get_exclusive(&pdev->dev, "dsi_sys");
- if (IS_ERR(dsi->sys_rst))
+ }
+
+ dsi->sys_rst = reset_control_get_exclusive(dev, "dsi_sys");
+ if (IS_ERR(dsi->sys_rst)){
+ dev_err(dev, "failed to get sys_rst\n");
return PTR_ERR(dsi->sys_rst);
- dsi->txbytehs_rst = reset_control_get_exclusive(&pdev->dev, "dsi_txbytehs");
- if (IS_ERR(dsi->txbytehs_rst))
+ }
+
+ dsi->txbytehs_rst = reset_control_get_exclusive(dev, "dsi_txbytehs");
+ if (IS_ERR(dsi->txbytehs_rst)){
+ dev_err(dev, "failed to get txbytehs_rst\n");
return PTR_ERR(dsi->txbytehs_rst);
- dsi->txesc_rst = reset_control_get_exclusive(&pdev->dev, "dsi_txesc");
- if (IS_ERR(dsi->txesc_rst))
+ }
+
+ dsi->txesc_rst = reset_control_get_exclusive(dev, "dsi_txesc");
+ if (IS_ERR(dsi->txesc_rst)){
+ dev_err(dev, "failed to get txesc_rst\n");
return PTR_ERR(dsi->txesc_rst);
+ }
+ //dev_info(dev,"==cdns_dsi_get_reset successful\n");
return ret;
}
dsi_cfg->hfp = dpi_to_dsi_timing(mode_to_dpi_hfp(mode, mode_valid_check),
bpp, DSI_HFP_FRAME_OVERHEAD);
//dpi to dsi transfer can not match , reconfig those parms
+ #if 0
if (mode->hdisplay == 800) {
dsi_cfg->hsa = 16; //30-14
dsi_cfg->hbp = 73; //85-12
dsi_cfg->hfp = 146; //152-6
}
+ #endif
+ #if 1
+ if (mode->hdisplay == 800) {
+ dsi_cfg->hsa = 5; //19-14
+ dsi_cfg->hbp = 5; //17-12
+ dsi_cfg->hfp = 102; //108-6
+ }
+ #endif
return 0;
}
+#if 1//original
static int cdns_dsi_adjust_phy_config(struct cdns_dsi *dsi,
struct cdns_dsi_cfg *dsi_cfg,
struct phy_configure_opts_mipi_dphy *phy_cfg,
return 0;
}
-
+#endif
+#if 1 //original
static int cdns_dsi_check_conf(struct cdns_dsi *dsi,
const struct drm_display_mode *mode,
struct cdns_dsi_cfg *dsi_cfg,
return 0;
}
+#endif
static int cdns_dsi_bridge_attach(struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags)
struct cdns_dsi *dsi = input_to_dsi(input);
struct cdns_dsi_output *output = &dsi->output;
+ dev_info(dsi->base.dev, "===>cdns_dsi_bridge_attach begin\n");
if (!drm_core_check_feature(bridge->dev, DRIVER_ATOMIC)) {
dev_err(dsi->base.dev,
"cdns-dsi driver is only compatible with DRM devices supporting atomic updates");
return -EOPNOTSUPP;
}
-
+ dev_info(dsi->base.dev, "===>cdns_dsi_bridge_attach end\n");
return drm_bridge_attach(bridge->encoder, output->bridge, bridge,
flags);
}
if ((mode->hdisplay * bpp) % 32)
return MODE_H_ILLEGAL;
- ret = cdns_dsi_check_conf(dsi, mode, &dsi_cfg, true);
- if (ret)
- return MODE_BAD;
+ ret = cdns_dsi_check_conf(dsi, mode, &dsi_cfg, true); //original
+ //if (ret)
+ // return MODE_BAD;
return MODE_OK;
}
+#if 1 //20220602
+static inline void sys_delay(int cycles)
+{
+ int i = 0;
+
+ while (i++ < cycles);
+}
+int sys_mipi_dsi_set_ppi_txbyte_hs(int enable, struct cdns_dsi *dsi)
+//int sys_mipi_dsi_set_ppi_txbyte_hs(int enable)
+{
+ static int status = 0;
+ int ret;
+ if (!enable && status) {
+ status = 0;
+ //_ASSERT_RESET_RSTGEN_RSTN_U0_CDNS_DSITX_RSTN_TXBYTEHS_;
+ ret = reset_control_assert(dsi->txbytehs_rst);
+ if (ret < 0) {
+ dev_err(dsi->base.dev, "failed to assert txbytehs_rst\n");
+ return ret;
+ }
+ dev_info(dsi->base.dev, "STOP dsi ppi_txbyte_hs\n");
+ } else if (enable && !status) {
+ status = 1;
+ //_CLEAR_RESET_RSTGEN_RSTN_U0_CDNS_DSITX_RSTN_TXBYTEHS_;
+ ret = reset_control_deassert(dsi->txbytehs_rst);
+ if (ret < 0) {
+ dev_err(dsi->base.dev, "failed to deassert txbytehs_rst\n");
+ return ret;
+ }
+
+ dev_info(dsi->base.dev, "START dsi ppi_txbyte_hs\n");
+ }
+
+ dev_info(dsi->base.dev, "sys_mipi_dsi_set_ppi_txbyte_hs\n");
+ sys_delay(100);
+ return 0;
+}
+#endif
+
static void cdns_dsi_bridge_disable(struct drm_bridge *bridge)
{
struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge);
val = readl(dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id);
writel(val, dsi->regs + MCTL_MAIN_EN);
pm_runtime_put(dsi->base.dev);
+ sys_mipi_dsi_set_ppi_txbyte_hs(0, dsi);//20220609
phy_power_off(dsi->dphy);
phy_exit(dsi->dphy);
}
+#if 0 //original
static void release_txbyte_rst(void)
{
void __iomem *regs = ioremap(0x12250000, 0x10000);
} while (temp != 0x1);
//udelay(1);
}
+#endif
static void cdns_dsi_hs_init(struct cdns_dsi *dsi)
{
struct cdns_dsi_output *output = &dsi->output;
- u32 dpi_fifo_int = 0;
-
+ //u32 dpi_fifo_int = 0;
+ int ret;
/*
* Power all internal DPHY blocks down and maintain their reset line
* asserted before changing the DPHY config.
phy_set_mode(dsi->dphy, PHY_MODE_MIPI_DPHY);
phy_configure(dsi->dphy, &output->phy_opts);
phy_power_on(dsi->dphy);
- release_txbyte_rst();
+ //release_txbyte_rst();//20220602 disabled
+ #if 1
+
+ //ret = sys_mipi_dsi_set_ppi_txbyte_hs(1);
+ ret = sys_mipi_dsi_set_ppi_txbyte_hs(1, dsi);
+ #endif
writel(PLL_LOCKED, dsi->regs + MCTL_MAIN_STS_CLR);
writel(DPHY_CMN_PSO | DPHY_ALL_D_PDN | DPHY_C_PDN | DPHY_CMN_PDN,
DPHY_D_RSTB(output->dev->lanes) | DPHY_C_RSTB,
dsi->regs + MCTL_DPHY_CFG0);
+//20220602 disabled
+/*
dpi_fifo_int = readl(dsi->regs + DPI_IRQ_CLR);
if (dpi_fifo_int)
writel(1, dsi->regs + DPI_IRQ_CLR);
+*/
}
static void cdns_dsi_init_link(struct cdns_dsi *dsi)
if (dsi->link_initialized)
return;
- val = 0;
+ //val = 0;//original
+ val = WAIT_BURST_TIME(0xf);
for (i = 1; i < output->dev->lanes; i++)
val |= DATA_LANE_EN(i);
ulpout = DIV_ROUND_UP(NSEC_PER_MSEC, sysclk_period);
writel(CLK_LANE_ULPOUT_TIME(ulpout) | DATA_LANE_ULPOUT_TIME(ulpout),
dsi->regs + MCTL_ULPOUT_TIME);
+ //dev_info(dsi->base.dev, "sysclk_period = %ldns, ulpout: 0x%08x\n", sysclk_period, ulpout);
writel(LINK_EN, dsi->regs + MCTL_MAIN_DATA_CTL);
writel(val, dsi->regs + MCTL_MAIN_EN);
dsi->link_initialized = true;
+
}
static void cdns_dsi_bridge_enable(struct drm_bridge *bridge)
struct cdns_dsi_cfg dsi_cfg;
u32 tmp, reg_wakeup;
int nlanes;
+ int vrefresh;
+ u32 div;
if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0))
return;
mode = &bridge->encoder->crtc->state->adjusted_mode;
nlanes = output->dev->lanes;
- WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false));
+ //WARN_ON_ONCE(cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false));//original //7110 mode illegal,need confirm //cannot disable
+ cdns_dsi_check_conf(dsi, mode, &dsi_cfg, false);
cdns_dsi_hs_init(dsi);
cdns_dsi_init_link(dsi);
+#if 0
+ dev_info(dsi->base.dev, "DSI HSA: %d, HBP: %d, HFP: %d, HACT: %d, HTOTAL: %d\n",
+ dsi_cfg.hsa, dsi_cfg.hbp, dsi_cfg.hfp, dsi_cfg.hact, dsi_cfg.htotal);
+#endif
+
+#if 1
+ dsi_cfg.htotal=2544;//7110,0 while testing, must
+ //dev_info(dsi->base.dev, "change HTOTAL: %d\n",dsi_cfg.htotal);
+#endif
+
writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa),
dsi->regs + VID_HSIZE1);
writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact),
dsi->regs + VID_HSIZE2);
+#if 0
+ dev_info(dsi->base.dev, "DPI HSA: %d, HBP: %d, HFP: %d, HACT: %d, HTOTAL: %d\n",
+ mode->crtc_htotal - mode->crtc_hsync_end,
+ mode->crtc_hsync_end - mode->crtc_hsync_start,
+ mode->crtc_hsync_start - mode->crtc_hdisplay,
+ mode->crtc_hdisplay,
+ mode->crtc_htotal);
+ dev_info(dsi->base.dev, "DPI VSA: %d, VBP: %d, VFP: %d, VACT: %d, VTOTAL: %d\n",
+ mode->crtc_vtotal - mode->crtc_vsync_end,
+ mode->crtc_vsync_end - mode->crtc_vsync_start,
+ mode->crtc_vsync_start - mode->crtc_vdisplay-1,
+ mode->crtc_vdisplay,
+ mode->crtc_vtotal);
+#endif
+ #if 0//original
writel(VBP_LEN(mode->crtc_vtotal - mode->crtc_vsync_end - 1) |
VFP_LEN(mode->crtc_vsync_start - mode->crtc_vdisplay) |
VSA_LEN(mode->crtc_vsync_end - mode->crtc_vsync_start + 1),
dsi->regs + VID_VSIZE1);
+ #endif
+
+ #if 1//jh7110
+ writel(VBP_LEN(mode->crtc_vtotal - mode->crtc_vsync_end) |
+ VFP_LEN(mode->crtc_vsync_start - mode->crtc_vdisplay - 1) |
+ VSA_LEN(mode->crtc_vsync_end - mode->crtc_vsync_start),
+ dsi->regs + VID_VSIZE1);
+
+ #endif
writel(mode->crtc_vdisplay, dsi->regs + VID_VSIZE2);
-
tmp = dsi_cfg.htotal -
(dsi_cfg.hsa + DSI_BLANKING_FRAME_OVERHEAD +
DSI_HSA_FRAME_OVERHEAD);
tx_byte_period = DIV_ROUND_DOWN_ULL((u64)NSEC_PER_SEC * 8,
phy_cfg->hs_clk_rate);
reg_wakeup = (phy_cfg->hs_prepare + phy_cfg->hs_zero) / tx_byte_period;
+ //dev_info(dsi->base.dev, "tx_byte_period = %dns, reg_wakeup: 0x%08x\n", tx_byte_period, reg_wakeup);
writel(REG_WAKEUP_TIME(reg_wakeup) | REG_LINE_DURATION(tmp),
dsi->regs + VID_DPHY_TIME);
+#if 0//original
writel(0xafffb, dsi->regs + MCTL_DPHY_TIMEOUT1);
writel(0x3ffff, dsi->regs + MCTL_DPHY_TIMEOUT2);
writel(0x3ab05, dsi->regs + MCTL_ULPOUT_TIME);
+#endif
+
+#if 1 //7110
+ vrefresh = 49;//display_timing_vrefresh(dpi);
+ tmp = NSEC_PER_SEC / vrefresh;
+ tmp /= tx_byte_period;
+ for (div = 0; div <= CLK_DIV_MAX; div++) {
+ if (tmp <= HSTX_TIMEOUT_MAX)
+ break;
+
+ tmp >>= 1;
+ }
+
+ if (tmp > HSTX_TIMEOUT_MAX)
+ tmp = HSTX_TIMEOUT_MAX;
+
+ writel(CLK_DIV(div) | HSTX_TIMEOUT(tmp),
+ dsi->regs + MCTL_DPHY_TIMEOUT1);
+ //dev_info(dsi->base.dev, "vrefresh %dHz, HSTX_TIMEOUT %ld, div %d\n", vrefresh, tmp, div);
+
+ writel(LPRX_TIMEOUT(tmp), dsi->regs + MCTL_DPHY_TIMEOUT2);
+#endif
if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO) {
switch (output->dev->format) {
tmp = readl(dsi->regs + MCTL_MAIN_DATA_CTL);
tmp &= ~(IF_VID_SELECT_MASK | HOST_EOT_GEN | IF_VID_MODE);
- if (!(output->dev->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET))
+ if (!(output->dev->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)) //MIPI_DSI_MODE_EOT_PACKET" bit(9)
tmp |= HOST_EOT_GEN;
if (output->dev->mode_flags & MIPI_DSI_MODE_VIDEO)
* in a display pipeline.
*/
drm_bridge_add(&input->bridge);
-
return 0;
}
static UNIVERSAL_DEV_PM_OPS(cdns_dsi_pm_ops, cdns_dsi_suspend, cdns_dsi_resume,
NULL);
+#if 0
static int cdns_dsi_drm_remove(struct platform_device *pdev)
{
struct cdns_dsi *dsi = platform_get_drvdata(pdev);
return 0;
}
+#endif
static const struct of_device_id cdns_dsi_of_match[] = {
{ .compatible = "cdns,dsi" },
{ },
};
+#if 1
+static int cdns_check_register_access(struct cdns_dsi* dsi)
+{
+ const uint16_t CTRL_PATTERNS[] = {0x0000, 0xffff, 0xa5a5, 0x5a5a};
+ int i;
+ uint32_t rd_val;
+
+ for (i = 0; i < ARRAY_SIZE_DSI(CTRL_PATTERNS); i++) {
+ uint32_t temp = readl(dsi->regs + TEST_GENERIC);
+ temp &= ~0xffff;
+ temp |= TEST_CTRL(CTRL_PATTERNS[i]);
+ writel(temp, dsi->regs + TEST_GENERIC);
+
+ rd_val = readl(dsi->regs + TEST_GENERIC);
+ if (rd_val != temp) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
static int starfive_dsi_bind(struct device *dev, struct device *master, void *data)
{
struct cdns_dsi *dsi;
//struct drm_device *drm_dev = data;
//struct starfive_drm_private *private = drm_dev->dev_private;
int ret;
+ int irq;
u32 val;
dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
if (IS_ERR(dsi->regs))
return PTR_ERR(dsi->regs);
- ret = cdns_dsi_get_clock(pdev, dsi);//get clock res
- if (ret) {
- dev_err(&pdev->dev, "failed to get clock\n");
- return ret;
- }
- ret = cdns_dsi_get_reset(pdev, dsi);//get reset res
- if (ret) {
- dev_err(&pdev->dev, "failed to get reset\n");
- return ret;
- }
+ ret = cdns_dsi_get_clock(dev, dsi);//get clock res
- dsi->dphy = devm_phy_get(&pdev->dev, "dphy");
- if (IS_ERR(dsi->dphy))
- return PTR_ERR(dsi->dphy);
+ dev_info(dev, "dsi_sys_clk = %ld\n",clk_get_rate(dsi->dsi_sys_clk));
+
+ ret = cdns_dsi_get_reset(dev, dsi);//get reset res
ret = cdns_dsi_clock_enable(dsi, dev);
if (ret) {
- dev_err(&pdev->dev, "failed to enable clock\n");
+ dev_err(dev, "failed to enable clock\n");
return ret;
}
ret = cdns_dsi_resets_deassert(dsi, dev);
if (ret < 0) {
- dev_err(&pdev->dev, "failed to deassert reset\n");
+ dev_err(dev, "failed to deassert reset\n");
return ret;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0){
+ dev_err(dev, "---get irq error\n");
+ return irq;
+ }
+
+ dsi->dphy = devm_phy_get(&pdev->dev, "dphy");
+ if (IS_ERR(dsi->dphy))
+ return PTR_ERR(dsi->dphy);
+
val = readl(dsi->regs + ID_REG);
if (REV_VENDOR_ID(val) != 0xcad) {
goto err_disable_pclk;
}
+ ret = cdns_check_register_access(dsi);
+ if (ret) {
+ dev_err(dev, "error: r/w test generic reg failed\n");
+ goto ERROR;
+ }
+
val = readl(dsi->regs + IP_CONF);
dsi->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2);
dsi->rx_fifo_depth = RX_FIFO_DEPTH(val);
writel(0, dsi->regs + TVG_STS_CTL);
writel(0, dsi->regs + DPI_IRQ_EN);
+ ret = devm_request_irq(&pdev->dev, irq, cdns_dsi_interrupt, 0,
+ dev_name(&pdev->dev), dsi);
+ if (ret){
+ dev_err(dev, "---devm_request_irq error\n");
+ goto err_disable_pclk;
+ }
+
pm_runtime_enable(&pdev->dev);
dsi->base.dev = &pdev->dev;
dsi->base.ops = &cdns_dsi_ops;
goto err_disable_runtime_pm;
init_seeed_panel();
+ dev_err(dev, "====starfive_dsi_bind end\n");
return 0;
err_disable_runtime_pm:
err_disable_pclk:
//clk_disable_unprepare(dsi->dsi_p_clk);
+ERROR:
return ret;
}
int ret;
+#if 1
ret = cdns_dsi_resets_assert(dsi, dev);
if (ret < 0)
dev_err(dev, "failed to assert reset\n");
cdns_dsi_clock_disable(dsi);
+#endif
exit_seeed_panel();
mipi_dsi_host_unregister(&dsi->base);
}
static const struct drm_display_mode seeed_panel_modes[] = {
+ #if 0
{
.clock = 33000000 / 1000,
.hdisplay = 800,
.vsync_end = 480 + 135 + 5,
.vtotal = 480 + 135 + 5 + 5,
},
+ #endif
+ #if 1
+ {
+ .clock = 20144262 / 1000,
+ .hdisplay = 800,
+ .hsync_start = 800 + 10,
+ .hsync_end = 800 + 10 + 5,
+ .htotal = 800 + 10 + 5 + 5,
+ .vdisplay = 480,
+ .vsync_start = 480 + 4,
+ .vsync_end = 480 + 4 + 5,
+ .vtotal = 480 + 4 + 5 + 5,
+ },
+ #endif
};
static int seeed_panel_disable(struct drm_panel *panel)
return 0;
}
+int drv_config_dc_4_dsi(struct vs_dc *dc, struct device *dev)//for dc_dsi config //only for dc_init
+{
+ int ret;
+
+ dev_info(dev, "====> %s, %d.\n", __func__, __LINE__);
+ /*---------------------mux config------------*/
+ SET_U0_DSITX_DATA_MAPPING_DPI_DP_SEL(0);
+ //SET_U0_DSITX_DATA_MAPPING_DP_MODE(vout_sys->vout_dsitx.dp_color_mode);
+ SET_U1_DISPLAY_PANEL_MUX_PANEL_SEL(0);
+ //_ENABLE_CLOCK_CLK_DOM_VOUT_TOP_LCD_CLK_;
+ ret = clk_prepare_enable(dc->vout_top_lcd);
+ if (ret) {
+ dev_err(dev, "failed to prepare/enable vout_top_lcd\n");
+ return ret;
+ }
+ /*----------mux config------------*/
+ dev_info(dev, "====> %s, %d.\n", __func__, __LINE__);
+ return 0;
+}
int sys_dispctrl_init(void)
{
dev_err(dev, "failed to init vout clk reset: %d\n", ret);
return ret;
}
+ #ifdef CONFIG_STARFIVE_DSI
+ dc->vout_src = devm_clk_get(dev, "vout_src");
+ if (IS_ERR(dc->vout_src)){
+ dev_err(dev,"failed to get dc->vout_src\n");
+ return PTR_ERR(dc->vout_src);
+ }
+ dc->vout_top_lcd = devm_clk_get(dev, "vout_top_lcd");
+ if (IS_ERR(dc->vout_top_lcd)){
+ dev_err(dev,"failed to get dc->vout_top_lcd\n");
+ return PTR_ERR(dc->vout_top_lcd);
+ }
+ ret = drv_config_dc_4_dsi(dc,dev);
+ if (ret < 0) {
+ dev_err(dev, "failed to drv_config_dc_4_dsi: %d\n", ret);
+ return ret;
+ }
+ #endif
+ printk("====> %s, %d.\n", __func__, __LINE__);
ret = dc_hw_init(&dc->hw);
if (ret) {
struct vs_crtc_state *crtc_state = to_vs_crtc_state(crtc->state);
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
struct dc_hw_display display;
+ uint32_t vout_clock;
+ uint32_t div;
+ uint32_t div_new;
+ const uint32_t wanted_pxclk = mode->clock * 1000;
display.bus_format = crtc_state->output_fmt;
display.h_active = mode->hdisplay;
}
#endif
+#ifdef CONFIG_STARFIVE_DSI//7110 mipi
+ /*-----------------div freq clk sys_dispctrl_clk()----------*/
+ //const uint32_t wanted_pxclk = 20144262;//dpi->pixelclock;
+ //wanted_pxclk = mode->clock * 1000;
+ dev_info(dev, "wanted_pxclk = %d\n",wanted_pxclk);
+ //uint32_t vout_clock = 614400000;
+ vout_clock = clk_get_rate(dc->vout_src);
+ dev_info(dev, "vout_clock = %d\n", vout_clock);
+ div = _GET_CLOCK_DIVIDE_STATUS_CLK_DC8200_PIX0_;
+ div_new = vout_clock / wanted_pxclk;
+ if (div != div_new) {
+ div = div_new;
+ _DIVIDE_CLOCK_CLK_DC8200_PIX0_(div);
+ _SWITCH_CLOCK_CLK_U0_DC8200_CLK_PIX0_SOURCE_CLK_DC8200_PIX0_;
+ }
+ /*-----------------div freq clk sys_dispctrl_clk()----------*/
+#endif
+
if (crtc_state->encoder_type == DRM_MODE_ENCODER_DSI)
dc_hw_set_out(&dc->hw, OUT_DPI, display.id);
else
struct reset_control *rstn_dc8200_ahb;
//dc8200 rst
+//7110 mp
+struct clk *vout_top_axi;//20220530 for vout_clock
+struct clk *vout_top_lcd;//7110 mp
+//7110 mp
};
extern struct platform_driver dc_platform_driver;
+//20220530
+//extern struct platform_driver simple_encoder_driver;
+extern struct platform_driver starfive_dsi_platform_driver;
+extern int init_seeed_panel(void);
+extern void exit_seeed_panel(void);
+
#endif /* __VS_DC_H__ */
else
dc_set_clear(hw, DC_DISPLAY_PANEL_START, 0, BIT(1) | BIT(2));
+#ifdef CONFIG_STARFIVE_DSI
+ dc_write(hw, DC_DISPLAY_H + offset, hw->display[id].h_active |
+ (hw->display[id].h_total << 16));
+
+ dc_write(hw, DC_DISPLAY_H_SYNC + offset,
+ hw->display[id].h_sync_start |
+ (hw->display[id].h_sync_end << 15) |
+ BIT(31) |
+ BIT(30));
+
+ dc_write(hw, DC_DISPLAY_V + offset, hw->display[id].v_active |
+ (hw->display[id].v_total << 16));
+
+ dc_write(hw, DC_DISPLAY_V_SYNC + offset,
+ hw->display[id].v_sync_start |
+ (hw->display[id].v_sync_end << 15) |
+ (hw->display[id].v_sync_polarity ? 0 : BIT(31)) |
+ BIT(30));
+
+#else
dc_write(hw, DC_DISPLAY_H + offset, hw->display[id].h_active |
(hw->display[id].h_total << 16));
dc_write(hw, DC_DISPLAY_H_SYNC + offset,
(hw->display[id].v_sync_end << 15) |
(hw->display[id].v_sync_polarity ? 0 : BIT(31)) |
BIT(30));
+#endif
if (hw->info->pipe_sync) {
switch (display->sync_mode) {
&starfive_dsi_platform_driver,
#endif
/* encoder */
- //&simple_encoder_driver,
+ &simple_encoder_driver,
//&starfive_encoder_driver,
#ifdef CONFIG_VERISILICON_VIRTUAL_DISPLAY
static int encoder_bind(struct device *dev, struct device *master, void *data)
{
+
struct drm_device *drm_dev = data;
struct simple_encoder *simple = dev_get_drvdata(dev);
struct drm_encoder *encoder;
struct drm_bridge *bridge;
+ struct drm_panel *tmp_panel;//20220530
int ret;
encoder = &simple->encoder;
/* Encoder. */
+
ret = drm_encoder_init(drm_dev, encoder, &encoder_funcs,
simple->priv->encoder_type, NULL);
if (ret)
drm_of_find_possible_crtcs(drm_dev, dev->of_node);
/* output port is port1*/
- ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL, &bridge);
- if (ret)
- goto err;
+#ifdef CONFIG_STARFIVE_DSI
+ ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0,&tmp_panel, &bridge);
+ if (ret){
+ printk("==no panel, %d\n",ret);
+ //dev_err_probe(dev, ret, "endpoint returns %d\n", ret);
+ goto err;
+ }
+ if (tmp_panel)
+ dev_err(dev, "found panel on endpoint\n");
+#else
+ ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1, NULL, &bridge);
+ if (ret)
+ goto err;
+#endif
#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE
ret = drm_bridge_attach(encoder, bridge, NULL, 0);
#else
--- /dev/null
+/* SPDX-License-Identifier: GPL-2.0 */\r
+/*\r
+ * Copyright (C) 2022 StarFive Technology Co., Ltd. \r
+ */\r
+\r
+#ifndef __7110_M31_DPHY_H__\r
+#define __7110_M31_DPHY_H__\r
+\r
+#define AON_POWER_READY_N_WIDTH 0x1U\r
+#define AON_POWER_READY_N_SHIFT 0x0U\r
+#define AON_POWER_READY_N_MASK 0x1U\r
+#define CFG_CKLANE_SET_WIDTH 0x5U\r
+#define CFG_CKLANE_SET_SHIFT 0x1U\r
+#define CFG_CKLANE_SET_MASK 0x3EU\r
+#define CFG_DATABUS16_SEL_WIDTH 0x1U\r
+#define CFG_DATABUS16_SEL_SHIFT 0x6U\r
+#define CFG_DATABUS16_SEL_MASK 0x40U\r
+#define CFG_DPDN_SWAP_WIDTH 0x5U\r
+#define CFG_DPDN_SWAP_SHIFT 0x7U\r
+#define CFG_DPDN_SWAP_MASK 0xF80U\r
+#define CFG_L0_SWAP_SEL_WIDTH 0x3U\r
+#define CFG_L0_SWAP_SEL_SHIFT 0xCU\r
+#define CFG_L0_SWAP_SEL_MASK 0x7000U\r
+#define CFG_L1_SWAP_SEL_WIDTH 0x3U\r
+#define CFG_L1_SWAP_SEL_SHIFT 0xFU\r
+#define CFG_L1_SWAP_SEL_MASK 0x38000U\r
+#define CFG_L2_SWAP_SEL_WIDTH 0x3U\r
+#define CFG_L2_SWAP_SEL_SHIFT 0x12U\r
+#define CFG_L2_SWAP_SEL_MASK 0x1C0000U\r
+#define CFG_L3_SWAP_SEL_WIDTH 0x3U\r
+#define CFG_L3_SWAP_SEL_SHIFT 0x15U\r
+#define CFG_L3_SWAP_SEL_MASK 0xE00000U\r
+#define CFG_L4_SWAP_SEL_WIDTH 0x3U\r
+#define CFG_L4_SWAP_SEL_SHIFT 0x18U\r
+#define CFG_L4_SWAP_SEL_MASK 0x7000000U\r
+#define MPOSV_31_0__WIDTH 0x20U\r
+#define MPOSV_31_0__SHIFT 0x0U\r
+#define MPOSV_31_0__MASK 0xFFFFFFFFU\r
+#define MPOSV_46_32__WIDTH 0xFU\r
+#define MPOSV_46_32__SHIFT 0x0U\r
+#define MPOSV_46_32__MASK 0x7FFFU\r
+#define RGS_CDTX_PLL_FM_CPLT_WIDTH 0x1U\r
+#define RGS_CDTX_PLL_FM_CPLT_SHIFT 0xFU\r
+#define RGS_CDTX_PLL_FM_CPLT_MASK 0x8000U\r
+#define RGS_CDTX_PLL_FM_OVER_WIDTH 0x1U\r
+#define RGS_CDTX_PLL_FM_OVER_SHIFT 0x10U\r
+#define RGS_CDTX_PLL_FM_OVER_MASK 0x10000U\r
+#define RGS_CDTX_PLL_FM_UNDER_WIDTH 0x1U\r
+#define RGS_CDTX_PLL_FM_UNDER_SHIFT 0x11U\r
+#define RGS_CDTX_PLL_FM_UNDER_MASK 0x20000U\r
+#define RGS_CDTX_PLL_UNLOCK_WIDTH 0x1U\r
+#define RGS_CDTX_PLL_UNLOCK_SHIFT 0x12U\r
+#define RGS_CDTX_PLL_UNLOCK_MASK 0x40000U\r
+#define RG_CDTX_L0N_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L0N_HSTX_RES_SHIFT 0x13U\r
+#define RG_CDTX_L0N_HSTX_RES_MASK 0xF80000U\r
+#define RG_CDTX_L0P_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L0P_HSTX_RES_SHIFT 0x18U\r
+#define RG_CDTX_L0P_HSTX_RES_MASK 0x1F000000U\r
+\r
+#define RG_CDTX_L1N_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L1N_HSTX_RES_SHIFT 0x0U\r
+#define RG_CDTX_L1N_HSTX_RES_MASK 0x1FU\r
+#define RG_CDTX_L1P_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L1P_HSTX_RES_SHIFT 0x5U\r
+#define RG_CDTX_L1P_HSTX_RES_MASK 0x3E0U\r
+#define RG_CDTX_L2N_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L2N_HSTX_RES_SHIFT 0xAU\r
+#define RG_CDTX_L2N_HSTX_RES_MASK 0x7C00U\r
+#define RG_CDTX_L2P_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L2P_HSTX_RES_SHIFT 0xFU\r
+#define RG_CDTX_L2P_HSTX_RES_MASK 0xF8000U\r
+#define RG_CDTX_L3N_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L3N_HSTX_RES_SHIFT 0x14U\r
+#define RG_CDTX_L3N_HSTX_RES_MASK 0x1F00000U\r
+#define RG_CDTX_L3P_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L3P_HSTX_RES_SHIFT 0x19U\r
+#define RG_CDTX_L3P_HSTX_RES_MASK 0x3E000000U\r
+\r
+#define RG_CDTX_L4N_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L4N_HSTX_RES_SHIFT 0x0U\r
+#define RG_CDTX_L4N_HSTX_RES_MASK 0x1FU\r
+#define RG_CDTX_L4P_HSTX_RES_WIDTH 0x5U\r
+#define RG_CDTX_L4P_HSTX_RES_SHIFT 0x5U\r
+#define RG_CDTX_L4P_HSTX_RES_MASK 0x3E0U\r
+\r
+#define RG_CDTX_PLL_FBK_FRA_WIDTH 0x18U\r
+#define RG_CDTX_PLL_FBK_FRA_SHIFT 0x0U\r
+#define RG_CDTX_PLL_FBK_FRA_MASK 0xFFFFFFU\r
+\r
+#define RG_CDTX_PLL_FBK_INT_WIDTH 0x9U\r
+#define RG_CDTX_PLL_FBK_INT_SHIFT 0x0U\r
+#define RG_CDTX_PLL_FBK_INT_MASK 0x1FFU\r
+#define RG_CDTX_PLL_FM_EN_WIDTH 0x1U\r
+#define RG_CDTX_PLL_FM_EN_SHIFT 0x9U\r
+#define RG_CDTX_PLL_FM_EN_MASK 0x200U\r
+#define RG_CDTX_PLL_LDO_STB_X2_EN_WIDTH 0x1U\r
+#define RG_CDTX_PLL_LDO_STB_X2_EN_SHIFT 0xAU\r
+#define RG_CDTX_PLL_LDO_STB_X2_EN_MASK 0x400U\r
+#define RG_CDTX_PLL_PRE_DIV_WIDTH 0x2U\r
+#define RG_CDTX_PLL_PRE_DIV_SHIFT 0xBU\r
+#define RG_CDTX_PLL_PRE_DIV_MASK 0x1800U\r
+#define RG_CDTX_PLL_SSC_DELTA_WIDTH 0x12U\r
+#define RG_CDTX_PLL_SSC_DELTA_SHIFT 0xDU\r
+#define RG_CDTX_PLL_SSC_DELTA_MASK 0x7FFFE000U\r
+\r
+#define RG_CDTX_PLL_SSC_DELTA_INIT_WIDTH 0x12U\r
+#define RG_CDTX_PLL_SSC_DELTA_INIT_SHIFT 0x0U\r
+#define RG_CDTX_PLL_SSC_DELTA_INIT_MASK 0x3FFFFU\r
+#define RG_CDTX_PLL_SSC_EN_WIDTH 0x1U\r
+#define RG_CDTX_PLL_SSC_EN_SHIFT 0x12U\r
+#define RG_CDTX_PLL_SSC_EN_MASK 0x40000U\r
+#define RG_CDTX_PLL_SSC_PRD_WIDTH 0xAU\r
+#define RG_CDTX_PLL_SSC_PRD_SHIFT 0x13U\r
+#define RG_CDTX_PLL_SSC_PRD_MASK 0x1FF80000U\r
+\r
+#define RG_CLANE_HS_CLK_POST_TIME_WIDTH 0x8U\r
+#define RG_CLANE_HS_CLK_POST_TIME_SHIFT 0x0U\r
+#define RG_CLANE_HS_CLK_POST_TIME_MASK 0xFFU\r
+#define RG_CLANE_HS_CLK_PRE_TIME_WIDTH 0x8U\r
+#define RG_CLANE_HS_CLK_PRE_TIME_SHIFT 0x8U\r
+#define RG_CLANE_HS_CLK_PRE_TIME_MASK 0xFF00U\r
+#define RG_CLANE_HS_PRE_TIME_WIDTH 0x8U\r
+#define RG_CLANE_HS_PRE_TIME_SHIFT 0x10U\r
+#define RG_CLANE_HS_PRE_TIME_MASK 0xFF0000U\r
+#define RG_CLANE_HS_TRAIL_TIME_WIDTH 0x8U\r
+#define RG_CLANE_HS_TRAIL_TIME_SHIFT 0x18U\r
+#define RG_CLANE_HS_TRAIL_TIME_MASK 0xFF000000U\r
+\r
+#define RG_CLANE_HS_ZERO_TIME_WIDTH 0x8U\r
+#define RG_CLANE_HS_ZERO_TIME_SHIFT 0x0U\r
+#define RG_CLANE_HS_ZERO_TIME_MASK 0xFFU\r
+#define RG_DLANE_HS_PRE_TIME_WIDTH 0x8U\r
+#define RG_DLANE_HS_PRE_TIME_SHIFT 0x8U\r
+#define RG_DLANE_HS_PRE_TIME_MASK 0xFF00U\r
+#define RG_DLANE_HS_TRAIL_TIME_WIDTH 0x8U\r
+#define RG_DLANE_HS_TRAIL_TIME_SHIFT 0x10U\r
+#define RG_DLANE_HS_TRAIL_TIME_MASK 0xFF0000U\r
+#define RG_DLANE_HS_ZERO_TIME_WIDTH 0x8U\r
+#define RG_DLANE_HS_ZERO_TIME_SHIFT 0x18U\r
+#define RG_DLANE_HS_ZERO_TIME_MASK 0xFF000000U\r
+\r
+#define RG_EXTD_CYCLE_SEL_WIDTH 0x3U\r
+#define RG_EXTD_CYCLE_SEL_SHIFT 0x0U\r
+#define RG_EXTD_CYCLE_SEL_MASK 0x7U\r
+\r
+#define SCFG_C_HS_PRE_ZERO_TIME_WIDTH 0x20U\r
+#define SCFG_C_HS_PRE_ZERO_TIME_SHIFT 0x0U\r
+#define SCFG_C_HS_PRE_ZERO_TIME_MASK 0xFFFFFFFFU\r
+\r
+#define SCFG_DPHY_SRC_SEL_WIDTH 0x1U\r
+#define SCFG_DPHY_SRC_SEL_SHIFT 0x0U\r
+#define SCFG_DPHY_SRC_SEL_MASK 0x1U\r
+#define SCFG_DSI_TXREADY_ESC_SEL_WIDTH 0x2U\r
+#define SCFG_DSI_TXREADY_ESC_SEL_SHIFT 0x1U\r
+#define SCFG_DSI_TXREADY_ESC_SEL_MASK 0x6U\r
+#define SCFG_PPI_C_READY_SEL_WIDTH 0x2U\r
+#define SCFG_PPI_C_READY_SEL_SHIFT 0x3U\r
+#define SCFG_PPI_C_READY_SEL_MASK 0x18U\r
+#define VCONTROL_WIDTH 0x5U\r
+#define VCONTROL_SHIFT 0x5U\r
+#define VCONTROL_MASK 0x3E0U\r
+\r
+#define XCFGI_DW00_WIDTH 0x20U\r
+#define XCFGI_DW00_SHIFT 0x0U\r
+#define XCFGI_DW00_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW01_WIDTH 0x20U\r
+#define XCFGI_DW01_SHIFT 0x0U\r
+#define XCFGI_DW01_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW02_WIDTH 0x20U\r
+#define XCFGI_DW02_SHIFT 0x0U\r
+#define XCFGI_DW02_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW03_WIDTH 0x20U\r
+#define XCFGI_DW03_SHIFT 0x0U\r
+#define XCFGI_DW03_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW04_WIDTH 0x20U\r
+#define XCFGI_DW04_SHIFT 0x0U\r
+#define XCFGI_DW04_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW05_WIDTH 0x20U\r
+#define XCFGI_DW05_SHIFT 0x0U\r
+#define XCFGI_DW05_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW06_WIDTH 0x20U\r
+#define XCFGI_DW06_SHIFT 0x0U\r
+#define XCFGI_DW06_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW07_WIDTH 0x20U\r
+#define XCFGI_DW07_SHIFT 0x0U\r
+#define XCFGI_DW07_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW08_WIDTH 0x20U\r
+#define XCFGI_DW08_SHIFT 0x0U\r
+#define XCFGI_DW08_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW09_WIDTH 0x20U\r
+#define XCFGI_DW09_SHIFT 0x0U\r
+#define XCFGI_DW09_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW0A_WIDTH 0x20U\r
+#define XCFGI_DW0A_SHIFT 0x0U\r
+#define XCFGI_DW0A_MASK 0xFFFFFFFFU\r
+\r
+#define XCFGI_DW0B_WIDTH 0x20U\r
+#define XCFGI_DW0B_SHIFT 0x0U\r
+#define XCFGI_DW0B_MASK 0xFFFFFFFFU\r
+\r
+#define DBG1_MUX_DOUT_WIDTH 0x8U\r
+#define DBG1_MUX_DOUT_SHIFT 0x0U\r
+#define DBG1_MUX_DOUT_MASK 0xFFU\r
+#define DBG1_MUX_SEL_WIDTH 0x5U\r
+#define DBG1_MUX_SEL_SHIFT 0x8U\r
+#define DBG1_MUX_SEL_MASK 0x1F00U\r
+#define DBG2_MUX_DOUT_WIDTH 0x8U\r
+#define DBG2_MUX_DOUT_SHIFT 0xDU\r
+#define DBG2_MUX_DOUT_MASK 0x1FE000U\r
+#define DBG2_MUX_SEL_WIDTH 0x5U\r
+#define DBG2_MUX_SEL_SHIFT 0x15U\r
+#define DBG2_MUX_SEL_MASK 0x3E00000U\r
+#define REFCLK_IN_SEL_WIDTH 0x3U\r
+#define REFCLK_IN_SEL_SHIFT 0x1AU\r
+#define REFCLK_IN_SEL_MASK 0x1C000000U\r
+#define RESETB_WIDTH 0x1U\r
+#define RESETB_SHIFT 0x1DU\r
+#define RESETB_MASK 0x20000000U\r
+\r
+//aonsys con\r
+#define AON_GP_REG_WIDTH 0x20U\r
+#define AON_GP_REG_SHIFT 0x0U\r
+#define AON_GP_REG_MASK 0xFFFFFFFFU\r
+\r
+\r
+#define M31_DPHY_REFCLK_RESERVED 0\r
+#define M31_DPHY_REFCLK_12M 1\r
+#define M31_DPHY_REFCLK_19_2M 2\r
+#define M31_DPHY_REFCLK_25M 3\r
+#define M31_DPHY_REFCLK_26M 4\r
+#define M31_DPHY_REFCLK_27M 5\r
+#define M31_DPHY_REFCLK_38_4M 6\r
+#define M31_DPHY_REFCLK_52M 7\r
+#define M31_DPHY_REFCLK_BUTT 8\r
+\r
+#define DPHY_TX_PSW_EN_MASK (1<<30)\r
+\r
+struct m31_dphy_config {\r
+ int ref_clk;\r
+ unsigned long bitrate;\r
+ uint32_t pll_prev_div, pll_fbk_int, pll_fbk_fra, extd_cycle_sel;\r
+ uint32_t dlane_hs_pre_time, dlane_hs_zero_time, dlane_hs_trail_time;\r
+ uint32_t clane_hs_pre_time, clane_hs_zero_time, clane_hs_trail_time;\r
+ uint32_t clane_hs_clk_pre_time, clane_hs_clk_post_time;\r
+};\r
+\r
+#define M31_DPHY_REFCLK M31_DPHY_REFCLK_12M\r
+#define M31_DPHY_BITRATE_ALIGN 10000000\r
+\r
+\r
+\r
+static const struct m31_dphy_config m31_dphy_configs[] = {\r
+#if (M31_DPHY_REFCLK == M31_DPHY_REFCLK_25M)\r
+ //25000000,M31_DPHY_HS_RATE_80M,0x1,0x66,0x666666,0x4,0x0E,0x1D,0x15,0x05,0x2B,0x0D,0x0F,0x71, //comment unusual config for simplicity\r
+ {25000000, 100000000, 0x1, 0x80, 0x000000, 0x4, 0x10, 0x21, 0x17, 0x07, 0x35, 0x0F, 0x0F, 0x73,},\r
+ {25000000, 200000000, 0x1, 0x80, 0x000000, 0x3, 0x0C, 0x1B, 0x13, 0x07, 0x35, 0x0F, 0x07, 0x3F,},\r
+ {25000000, 300000000, 0x1, 0xC0, 0x000000, 0x3, 0x11, 0x25, 0x19, 0x0A, 0x50, 0x15, 0x07, 0x45,},\r
+ {25000000, 400000000, 0x1, 0x80, 0x000000, 0x2, 0x0A, 0x18, 0x11, 0x07, 0x35, 0x0F, 0x03, 0x25,},\r
+ {25000000, 500000000, 0x1, 0xA0, 0x000000, 0x2, 0x0C, 0x1D, 0x14, 0x09, 0x42, 0x12, 0x03, 0x28,},\r
+ {25000000, 600000000, 0x1, 0xC0, 0x000000, 0x2, 0x0E, 0x23, 0x17, 0x0A, 0x50, 0x15, 0x03, 0x2B,},\r
+ {25000000, 700000000, 0x1, 0x70, 0x000000, 0x1, 0x08, 0x14, 0x0F, 0x06, 0x2F, 0x0E, 0x01, 0x16,},\r
+ {25000000, 800000000, 0x1, 0x80, 0x000000, 0x1, 0x09, 0x17, 0x10, 0x07, 0x35, 0x0F, 0x01, 0x18,},\r
+ {25000000, 900000000, 0x1, 0x90, 0x000000, 0x1, 0x0A, 0x19, 0x12, 0x08, 0x3C, 0x10, 0x01, 0x19,},\r
+ {25000000, 1000000000, 0x1, 0xA0, 0x000000, 0x1, 0x0B, 0x1C, 0x13, 0x09, 0x42, 0x12, 0x01, 0x1B,},\r
+ {25000000, 1100000000, 0x1, 0xB0, 0x000000, 0x1, 0x0C, 0x1E, 0x15, 0x09, 0x4A, 0x14, 0x01, 0x1D,},\r
+ {25000000, 1200000000, 0x1, 0xC0, 0x000000, 0x1, 0x0E, 0x20, 0x16, 0x0A, 0x50, 0x15, 0x01, 0x1E,},\r
+ {25000000, 1300000000, 0x1, 0x68, 0x000000, 0x0, 0x07, 0x12, 0x0D, 0x05, 0x2C, 0x0D, 0x00, 0x0F,},\r
+ {25000000, 1400000000, 0x1, 0x70, 0x000000, 0x0, 0x07, 0x14, 0x0E, 0x06, 0x2F, 0x0E, 0x00, 0x10,},\r
+ {25000000, 1500000000, 0x1, 0x78, 0x000000, 0x0, 0x08, 0x14, 0x0F, 0x06, 0x32, 0x0E, 0x00, 0x11,},\r
+ {25000000, 1600000000, 0x1, 0x80, 0x000000, 0x0, 0x09, 0x15, 0x10, 0x07, 0x35, 0x0F, 0x00, 0x12,},\r
+ {25000000, 1700000000, 0x1, 0x88, 0x000000, 0x0, 0x09, 0x17, 0x10, 0x07, 0x39, 0x10, 0x00, 0x12,},\r
+ {25000000, 1800000000, 0x1, 0x90, 0x000000, 0x0, 0x0A, 0x18, 0x11, 0x08, 0x3C, 0x10, 0x00, 0x13,},\r
+ {25000000, 1900000000, 0x1, 0x98, 0x000000, 0x0, 0x0A, 0x1A, 0x12, 0x08, 0x3F, 0x11, 0x00, 0x14,},\r
+ {25000000, 2000000000, 0x1, 0xA0, 0x000000, 0x0, 0x0B, 0x1B, 0x13, 0x09, 0x42, 0x12, 0x00, 0x15,},\r
+ {25000000, 2100000000, 0x1, 0xA8, 0x000000, 0x0, 0x0B, 0x1C, 0x13, 0x09, 0x46, 0x13, 0x00, 0x15,},\r
+ {25000000, 2200000000, 0x1, 0xB0, 0x000000, 0x0, 0x0C, 0x1D, 0x14, 0x09, 0x4A, 0x14, 0x00, 0x16,},\r
+ {25000000, 2300000000, 0x1, 0xB8, 0x000000, 0x0, 0x0C, 0x1F, 0x15, 0x0A, 0x4C, 0x14, 0x00, 0x17,},\r
+ {25000000, 2400000000, 0x1, 0xC0, 0x000000, 0x0, 0x0D, 0x20, 0x16, 0x0A, 0x50, 0x15, 0x00, 0x18,},\r
+ {25000000, 2500000000, 0x1, 0xC8, 0x000000, 0x0, 0x0E, 0x21, 0x16, 0x0B, 0x53, 0x16, 0x00, 0x18,},\r
+#elif (M31_DPHY_REFCLK == M31_DPHY_REFCLK_12M)\r
+\r
+ {12000000, 180000000, 0x0, 0x78, 0x0 << 16 | 0x0<<8 | 0x0, 0x3, 0xb, 0x19, 0x12, 0x6, 0x30, 0xe, 0x7, 0x3e,},\r
+\r
+ {12000000, 500000000, 0x0, 0xa6, 0xaa << 16 | 0xaa << 8 | 0xaa, 0x2, 0xc, 0x1d, 0x14, 0x9, 0x42, 0x12, 0x3, 0x28,},\r
+ {12000000, 510000000, 0x0, 0xaa, 0x0 << 16 | 0x0 << 8 | 0x0, 0x2, 0xc, 0x1e, 0x14, 0x9, 0x44, 0x12, 0x3, 0x28,},\r
+\r
+ {12000000, 590000000, 0x0, 0xc4, 0xaa << 16 | 0xaa << 8 | 0xaa, 0x2, 0xe, 0x22, 0x17, 0xa, 0x4f, 0x15, 0x3, 0x2b,},\r
+\r
+ {12000000, 690000000, 0x0, 0x73, 0x0 << 16 | 0x0 << 8 | 0x0, 0x1, 0x8, 0x14, 0xe, 0x6, 0x2e, 0xd, 0x1, 0x16,},\r
+\r
+ {12000000, 720000000, 0x0, 0x78, 0x0<<16 | 0x0 << 8 | 0x0, 0x1, 0x8, 0x15, 0xf, 0x6, 0x30, 0xe, 0x1, 0x17,},\r
+\r
+ {12000000, 840000000, 0x0, 0x8c, 0x0 << 16 | 0x0<<8 | 0x0, 0x1, 0x9, 0x18, 0x11, 0x7, 0x38, 0x10, 0x1, 0x19,},\r
+\r
+#endif\r
+};\r
+\r
+static inline u32 sf_dphy_get_reg(void* io_addr, u32 shift, u32 mask)\r
+{\r
+ //void __iomem *io_addr = ioremap(addr, 0x10000);\r
+ u32 tmp;\r
+ tmp = readl(io_addr);\r
+ tmp = (tmp & mask) >> shift;\r
+ return tmp;\r
+}\r
+\r
+static inline void sf_dphy_set_reg(void* io_addr, u32 data, u32 shift, u32 mask)\r
+{\r
+ //void __iomem *io_addr = ioremap(addr, 0x10000);\r
+\r
+ u32 tmp;\r
+ tmp = readl(io_addr);\r
+ tmp &= ~mask;\r
+ tmp |= (data << shift) & mask;\r
+ writel(tmp, io_addr);\r
+}\r
+\r
+static inline void sf_dphy_assert_rst(void* io_addr, u32 addr_status, u32 mask)\r
+{\r
+ //void __iomem *io_addr = ioremap(addr, 0x4);\r
+\r
+ void __iomem *io_addr_status = ioremap(addr_status, 0x4);\r
+\r
+ u32 tmp;\r
+ tmp = readl(io_addr);\r
+ tmp |= mask;\r
+ writel(tmp,io_addr);\r
+ do{\r
+ tmp = readl(io_addr_status);\r
+ }while((tmp & mask)!=0);\r
+}\r
+\r
+static inline void sf_dphy_clear_rst (void* io_addr, u32 addr_status, u32 mask)\r
+{\r
+ //void __iomem *io_addr = ioremap(addr, 0x4);\r
+\r
+ void __iomem *io_addr_status = ioremap(addr_status, 0x4);\r
+\r
+ u32 tmp;\r
+ tmp = readl(io_addr);\r
+ tmp &= ~mask;\r
+ writel(tmp, io_addr);\r
+ do{\r
+ tmp = readl(io_addr_status);\r
+ }while((tmp & mask) != mask);\r
+}\r
+\r
+#endif /* __7110_M31_DPHY_H__ */\r
#include <linux/phy/phy-mipi-dphy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include<linux/reset.h>
+//#include <soc/starfive/jh7110_pmic.h>//20220602 pmic support
+#include <linux/regulator/consumer.h>
+#include "7110-m31-dphy.h"
//syscfg registers
#define SCFG_DSI_CSI_SEL 0x2c
void __iomem *topsys;
struct clk_bulk_data *clks;
+ //20220601 clk support
+ struct clk * txesc_clk;
+ struct reset_control *sys_rst;
+ struct reset_control *txbytehs_rst;
+ //20220601 clk support
+ void __iomem *aonsys;//7110 aonsys con
struct phy_configure_opts_mipi_dphy config;
u8 hsfreq;
+ struct regulator *mipitx_1p8;
+ struct regulator *mipitx_0p9;
+
struct phy *phy;
};
+static int sf_dphy_clkrst_get(struct device *dev, struct sf_dphy *dphy)
+{
+ //dev_info(dev,"===sf_dphy_clkrst_get begin\n");
+ int ret;
+
+ dphy->txesc_clk = devm_clk_get(dev, "dphy_txesc");
+ if (IS_ERR(dphy->txesc_clk)){
+ dev_err(dev, "===txesc_clk get error\n");
+ return PTR_ERR(dphy->txesc_clk);
+ }
+ dphy->sys_rst = reset_control_get_exclusive(dev, "dphy_sys");
+ if (IS_ERR(dphy->sys_rst)){
+ dev_err(dev, "===sys_rst get error\n");
+ return PTR_ERR(dphy->sys_rst);
+ }
+ //dphy->txbytehs_rst = reset_control_get_exclusive(dev,"dphy_txbytehs");
+ //if (IS_ERR(dphy->txbytehs_rst)){
+ // dev_err(dev,"===txbytehs_rst get error\n");
+ // return PTR_ERR(dphy->txbytehs_rst);
+ //}
+ //dev_info(dev,"===sf_dphy_clkrst_get begin\n");
+ return ret;
+}
+static int sf_dphy_clkrst_ena_deas(struct device *dev, struct sf_dphy *dphy)
+{
+ //dev_info(dev,"===sf_dphy_clkrst_ena_deas begin\n");
+ int ret;
+
+ ret = clk_prepare_enable(dphy->txesc_clk);
+ if (ret) {
+ dev_err(dev, "failed to prepare/enable txesc_clk\n");
+ return ret;
+ }
+ ret = reset_control_deassert(dphy->sys_rst);
+ if (ret < 0) {
+ dev_err(dev, "failed to deassert sys_rst\n");
+ return ret;
+ }
+ //ret = reset_control_deassert(dphy->txbytehs_rst);
+ //if (ret < 0) {
+ // dev_err(dev, "failed to deassert txbytehs_rst\n");
+ // return ret;
+ //}
+ //dev_info(dev,"===sf_dphy_clkrst_ena_deas successful\n");
+ return ret;
+}
+
+static int sf_dphy_clkrst_disa_assert(struct device *dev, struct sf_dphy *dphy)
+{
+ //dev_info(dev,"===sf_dphy_clkrst_disa_assert begin\n");
+ int ret;
+ ret = reset_control_assert(dphy->sys_rst);
+ if (ret < 0) {
+ dev_err(dev, "failed to assert sys_rst\n");
+ return ret;
+ }
+ //reset_control_assert(dphy->txbytehs_rst);
+ clk_disable_unprepare(dphy->txesc_clk);
+
+ //dev_info(dev,"===sf_dphy_clkrst_disa_assert successful\n");
+ return ret;
+}
+
+/*
+*static int sf_dphy_remove(struct platform_device *pdev)
+*{
+* struct sf_dphy *dphy = dev_get_drvdata(&pdev->dev);
+* reset_control_assert(dphy->sys_rst);
+* //reset_control_assert(dphy->txbytehs_rst);
+* clk_disable_unprepare(dphy->txesc_clk);
+* return 0;
+*}
+*/
+
+#if 0//original
static u32 top_sys_read32(struct sf_dphy *priv, u32 reg)
{
return ioread32(priv->topsys + reg);
}
static int sf_dphy_configure(struct phy *phy, union phy_configure_opts *opts)
-{
+{ //dev_info(dphy->dev,"--->sf_dphy_configure\n");
struct sf_dphy *dphy = phy_get_drvdata(phy);
uint32_t bit_rate = 800000000/1000000UL;//new mipi panel clock setting
+ //uint32_t bit_rate = 500000000/1000000UL;//7110 mipi panel clock setting
dphy_config(dphy, bit_rate);
mdelay(10);
polling_dphy_lock(dphy);
+ //dev_info(dphy->dev,"--->sf_dphy_configure\n");
return 0;
}
+#endif
-static int sf_dphy_power_on(struct phy *phy)
+static int is_pll_locked(struct sf_dphy *dphy)
{
- return 0;
+ //int tmp = GET_U0_MIPITX_DPHY_RGS_CDTX_PLL_UNLOCK;
+ int tmp = sf_dphy_get_reg(dphy->topsys + 0x8,
+ RGS_CDTX_PLL_UNLOCK_SHIFT, RGS_CDTX_PLL_UNLOCK_MASK);
+ return !tmp;
+}
+static void reset(int assert, struct sf_dphy *dphy)
+{
+ dev_info(dphy->dev, "1 SET_U0_MIPITX_DPHY_RESETB\n");
+ //SET_U0_MIPITX_DPHY_RESETB((!assert));
+ sf_dphy_set_reg(dphy->topsys + 0x64, (!assert), RESETB_SHIFT, RESETB_MASK);
+ dev_info(dphy->dev, "2 SET_U0_MIPITX_DPHY_RESETB\n");
+
+ if (!assert) {
+ while(!is_pll_locked(dphy));
+ dev_info(dphy->dev, "MIPI dphy-tx # PLL Locked\n");
+ }
}
-static int sf_dphy_power_off(struct phy *phy)
+static int sys_m31_dphy_tx_configure(struct phy *phy, union phy_configure_opts *opts)
{
+ //dev_info(dphy->dev,"---sys_m31_dphy_tx_configure begin\n");
+ struct sf_dphy *dphy;
+ uint32_t bitrate;
+ unsigned long alignment;
+ int i;
+ const struct m31_dphy_config *p;
+ const uint32_t AON_POWER_READY_N_active = 0;
+ dphy = phy_get_drvdata(phy);
+ bitrate = 500000000;
+
+ sf_dphy_set_reg(dphy->topsys + 0x8, 0x10,
+ RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
+ RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
+ RG_CDTX_L2N_HSTX_RES_SHIFT, RG_CDTX_L2N_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
+ RG_CDTX_L3N_HSTX_RES_SHIFT, RG_CDTX_L3N_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x10, 0x10,
+ RG_CDTX_L4N_HSTX_RES_SHIFT, RG_CDTX_L4N_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x8, 0x10,
+ RG_CDTX_L0P_HSTX_RES_SHIFT, RG_CDTX_L0P_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
+ RG_CDTX_L1P_HSTX_RES_SHIFT, RG_CDTX_L1P_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
+ RG_CDTX_L2P_HSTX_RES_SHIFT, RG_CDTX_L2P_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0xC, 0x10,
+ RG_CDTX_L3P_HSTX_RES_SHIFT, RG_CDTX_L3P_HSTX_RES_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x10, 0x10,
+ RG_CDTX_L4P_HSTX_RES_SHIFT, RG_CDTX_L4P_HSTX_RES_MASK);
+
+ dev_info(dphy->dev,"request dphy hs_rate %dMbps\n", bitrate/1000000);
+ //if (is_pll_locked()) {
+ if (is_pll_locked(dphy))
+ dev_info(dphy->dev, "Error: MIPI dphy-tx # PLL is not supposed to be LOCKED\n");
+ else
+ dev_info(dphy->dev, "MIPI dphy-tx # PLL is not LOCKED\n");
+
+ //unsigned long alignment = (bitrate <= M31_DPHY_HS_RATE_80M) ? M31_DPHY_HS_RATE_80M : M31_DPHY_BITRATE_ALIGN;
+ alignment = M31_DPHY_BITRATE_ALIGN;
+ if (bitrate % alignment) {
+ bitrate += alignment - (bitrate % alignment);
+ }
+
+ dev_info(dphy->dev, "want dphy hs_rate %dMbps\n", bitrate/1000000);
+
+ p = m31_dphy_configs;
+ for (i = 0; i < ARRAY_SIZE(m31_dphy_configs); i++, p++) {
+ if (p->bitrate == bitrate) {
+ dev_info(dphy->dev, "config dphy hs_rate %dMbps\n", bitrate/1000000);
+
+ //Clock source and lane setting
+ //SET_U0_MIPITX_DPHY_REFCLK_IN_SEL(M31_DPHY_REFCLK);
+ sf_dphy_set_reg(dphy->topsys + 0x64, M31_DPHY_REFCLK, REFCLK_IN_SEL_SHIFT, REFCLK_IN_SEL_MASK);
+ //const uint32_t AON_POWER_READY_N_active = 0;
+ dev_info(dphy->dev, "MIPI dphy-tx # AON_POWER_READY_N active(%d)\n", AON_POWER_READY_N_active);
+
+
+ sf_dphy_set_reg(dphy->topsys, AON_POWER_READY_N_active,
+ AON_POWER_READY_N_SHIFT, AON_POWER_READY_N_MASK);
+
+ sf_dphy_set_reg(dphy->topsys, 0x0,
+ CFG_L0_SWAP_SEL_SHIFT, CFG_L0_SWAP_SEL_MASK);//Lane setting
+ sf_dphy_set_reg(dphy->topsys, 0x1,
+ CFG_L1_SWAP_SEL_SHIFT, CFG_L1_SWAP_SEL_MASK);
+ sf_dphy_set_reg(dphy->topsys, 0x4,
+ CFG_L2_SWAP_SEL_SHIFT, CFG_L2_SWAP_SEL_MASK);
+ sf_dphy_set_reg(dphy->topsys, 0x2,
+ CFG_L3_SWAP_SEL_SHIFT, CFG_L3_SWAP_SEL_MASK);
+ sf_dphy_set_reg(dphy->topsys, 0x3,
+ CFG_L4_SWAP_SEL_SHIFT, CFG_L4_SWAP_SEL_MASK);
+ //PLL setting
+ sf_dphy_set_reg(dphy->topsys + 0x1c, 0x0,
+ RG_CDTX_PLL_SSC_EN_SHIFT, RG_CDTX_PLL_SSC_EN_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x18, 0x1,
+ RG_CDTX_PLL_LDO_STB_X2_EN_SHIFT, RG_CDTX_PLL_LDO_STB_X2_EN_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x18, 0x1,
+ RG_CDTX_PLL_FM_EN_SHIFT, RG_CDTX_PLL_FM_EN_MASK);
+
+ sf_dphy_set_reg(dphy->topsys + 0x18, p->pll_prev_div,
+ RG_CDTX_PLL_PRE_DIV_SHIFT, RG_CDTX_PLL_PRE_DIV_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x18, p->pll_fbk_int,
+ RG_CDTX_PLL_FBK_INT_SHIFT, RG_CDTX_PLL_FBK_INT_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x14, p->pll_fbk_fra,
+ RG_CDTX_PLL_FBK_FRA_SHIFT, RG_CDTX_PLL_FBK_FRA_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x28, p->extd_cycle_sel,
+ RG_EXTD_CYCLE_SEL_SHIFT, RG_EXTD_CYCLE_SEL_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_pre_time,
+ RG_DLANE_HS_PRE_TIME_SHIFT, RG_DLANE_HS_PRE_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_pre_time,
+ RG_DLANE_HS_PRE_TIME_SHIFT, RG_DLANE_HS_PRE_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_zero_time,
+ RG_DLANE_HS_ZERO_TIME_SHIFT, RG_DLANE_HS_ZERO_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x24, p->dlane_hs_trail_time,
+ RG_DLANE_HS_TRAIL_TIME_SHIFT, RG_DLANE_HS_TRAIL_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_pre_time,
+ RG_CLANE_HS_PRE_TIME_SHIFT, RG_CLANE_HS_PRE_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x24, p->clane_hs_zero_time,
+ RG_CLANE_HS_ZERO_TIME_SHIFT, RG_CLANE_HS_ZERO_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_trail_time,
+ RG_CLANE_HS_TRAIL_TIME_SHIFT, RG_CLANE_HS_TRAIL_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_clk_pre_time,
+ RG_CLANE_HS_CLK_PRE_TIME_SHIFT, RG_CLANE_HS_CLK_PRE_TIME_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x20, p->clane_hs_clk_post_time,
+ RG_CLANE_HS_CLK_POST_TIME_SHIFT, RG_CLANE_HS_CLK_POST_TIME_MASK);
+
+ break;
+ }
+ }
+
+ //dev_info(dphy->dev,"---sys_m31_dphy_tx_configure end\n");
+ return -ENOTSUPP;
+}
+
+static int sf_dphy_power_on(struct phy *phy)
+{ //dev_info(dphy->dev,"--->sf_dphy_power_on begin\n");
+
+ struct sf_dphy *dphy = phy_get_drvdata(phy);
+ int ret;
+
+ reset(0, dphy);
+ sf_dphy_set_reg(dphy->topsys + 0x30, 0,
+ SCFG_PPI_C_READY_SEL_SHIFT, SCFG_PPI_C_READY_SEL_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x30, 0,
+ SCFG_DSI_TXREADY_ESC_SEL_SHIFT, SCFG_DSI_TXREADY_ESC_SEL_MASK);
+ sf_dphy_set_reg(dphy->topsys + 0x2c, 0x30,
+ SCFG_C_HS_PRE_ZERO_TIME_SHIFT, SCFG_C_HS_PRE_ZERO_TIME_MASK);
+ //ret = sf_dphy_clkrst_init(&pdev->dev, dphy);//clk rst interface
+ ret = sf_dphy_clkrst_ena_deas(dphy->dev, dphy);//clk rst interface enable and deassert
+
+ //dev_info(dphy->dev,"--->sf_dphy_power_on end\n");
return 0;
}
-static int sf_dphy_init(struct phy *phy)
+static int sf_dphy_power_off(struct phy *phy)
{
+ //dev_info(dphy->dev,"--->sf_dphy_power_off begin\n");
struct sf_dphy *dphy = phy_get_drvdata(phy);
- dsi_csi2tx_sel(dphy, 0);
- dphy_clane_hs_txready_sel(dphy, 0x1);
+ sf_dphy_clkrst_disa_assert(dphy->dev, dphy);
+ reset(1, dphy);
+ //dev_info(dphy->dev,"--->sf_dphy_power_off end\n");
+ return 0;
+}
+static int sf_dphy_init(struct phy *phy)
+{
return 0;
}
}
static int sf_dphy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
-{
+{
+ struct sf_dphy *dphy = phy_get_drvdata(phy);
+
+ dev_info(dphy->dev, "--->sf_dphy_set_mode\n");
return 0;
}
.power_off = sf_dphy_power_off,
.init = sf_dphy_init,
.exit = sf_dphy_exit,
- .configure = sf_dphy_configure,
+ //.configure = sf_dphy_configure,
+ .configure = sys_m31_dphy_tx_configure,
.validate = sf_dphy_validate,
.set_mode = sf_dphy_set_mode,
.owner = THIS_MODULE,
MODULE_DEVICE_TABLE(of, sf_dphy_dt_ids);
static int sf_dphy_probe(struct platform_device *pdev)
-{
+{//dev_info(dphy->dev,"====sf_dphy_probe begin\n");
struct phy_provider *phy_provider;
struct sf_dphy *dphy;
struct resource *res;
int ret;
+ uint32_t temp;
+
+ dev_info(&pdev->dev, "sf_dphy_probe begin\n");
dphy = devm_kzalloc(&pdev->dev, sizeof(*dphy), GFP_KERNEL);
if (!dphy)
return -ENOMEM;
dev_set_drvdata(&pdev->dev, dphy);
- dev_info(&pdev->dev,"===> %s enter, %d \n", __func__, __LINE__);
+ dev_info(&pdev->dev, "===> %s enter, %d \n", __func__, __LINE__);
+
+ //dphy->topsys = ioremap(0x12260000, 0x10000);
+ //dphy->topsys = ioremap(0x295e0000, 0x10000);
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dphy->topsys = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dphy->topsys))
+ return PTR_ERR(dphy->topsys);
- dphy->topsys = ioremap(0x12260000, 0x10000);
dphy->phy = devm_phy_create(&pdev->dev, NULL, &sf_dphy_ops);
if (IS_ERR(dphy->phy)) {
}
phy_set_drvdata(dphy->phy, dphy);
+ //dont know need or not. will crash in starup
+ // this power switch control bit was added in ECO, check ECO item "aon psw_en" for detail
+ dev_info(dphy->dev, "control ECO\n");
+ dphy->aonsys = ioremap(0x17010000, 0x10000);
+ temp = 0;
+ //temp = GET_AON_GP_REG;
+ temp = sf_dphy_get_reg(dphy->aonsys, AON_GP_REG_SHIFT,AON_GP_REG_MASK);
+ dev_info(dphy->dev, "GET_AON_GP_REG\n");
+ /*
+ if (!(temp & DPHY_TX_PSW_EN_MASK)) {
+ temp |= DPHY_TX_PSW_EN_MASK;
+ SET_AON_GP_REG(temp);
+ }
+ */
+ if (!(temp & DPHY_TX_PSW_EN_MASK)) {
+ temp |= DPHY_TX_PSW_EN_MASK;
+ //SET_AON_GP_REG(temp);
+ sf_dphy_set_reg(dphy->aonsys, temp,AON_GP_REG_SHIFT,AON_GP_REG_MASK);
+ }
+ dev_info(dphy->dev, "control ECO\n");
+
+ //mipi_pmic setting
+ dphy->mipitx_1p8 = devm_regulator_get(&pdev->dev, "mipitx_1p8");
+ if (IS_ERR(dphy->mipitx_1p8))
+ return PTR_ERR(dphy->mipitx_1p8);
+
+ dphy->mipitx_0p9 = devm_regulator_get(&pdev->dev, "mipitx_0p9");
+ if (IS_ERR(dphy->mipitx_0p9))
+ return PTR_ERR(dphy->mipitx_0p9);
+
+ //pmic turn on
+ ret = regulator_enable(dphy->mipitx_0p9);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot enable mipitx_0p9 regulator\n");
+ //goto err_reg_0p9;
+ }
+ udelay(100);
+ ret = regulator_enable(dphy->mipitx_1p8);
+ if (ret) {
+ dev_err(&pdev->dev, "Cannot enable mipitx_1p8 regulator\n");
+ //goto err_reg_1p8;
+ }
+ udelay(100);
+ //mipi_pmic setting
+
+ //ret = sf_dphy_clkrst_init(&pdev->dev, dphy);//clk rst interface
+ ret = sf_dphy_clkrst_get(&pdev->dev, dphy);
+
phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+ dev_info(&pdev->dev, "sf_dphy_probe end\n");
+
return PTR_ERR_OR_ZERO(phy_provider);
}