mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
lvds: add rk319x lvds
This commit is contained in:
@@ -12,6 +12,10 @@ config RK3026_LVDS
|
||||
bool "RK3026/RK3028A lvds transmitter support"
|
||||
default y
|
||||
|
||||
config RK319x_LVDS
|
||||
bool "RK319x lvds transmitter support"
|
||||
depends on ARCH_RK319X && RK_TRSM
|
||||
|
||||
config RK610_LVDS
|
||||
bool "RK610(Jetta) lvds transmitter support"
|
||||
depends on MFD_RK610 && RK_TRSM
|
||||
|
||||
@@ -5,6 +5,7 @@ obj-$(CONFIG_RK2928_LVDS) += rk2928_lvds.o
|
||||
obj-$(CONFIG_RK3026_LVDS) += rk3026_lvds.o
|
||||
obj-$(CONFIG_RK610_LVDS) += rk610_lcd.o
|
||||
obj-$(CONFIG_RK616_LVDS) += rk616_lvds.o
|
||||
obj-$(CONFIG_RK319x_LVDS) += rk319x_lvds.o
|
||||
obj-$(CONFIG_DP_ANX6345) += dp_anx6345.o
|
||||
obj-$(CONFIG_DP501) += dp501.o
|
||||
obj-$(CONFIG_RK32_DP) += rk32_dp.o rk32_dp_reg.o
|
||||
|
||||
247
drivers/video/rockchip/transmitter/rk319x_lvds.c
Executable file
247
drivers/video/rockchip/transmitter/rk319x_lvds.c
Executable file
@@ -0,0 +1,247 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/rk_fb.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/io.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
|
||||
#include "rk319x_lvds.h"
|
||||
|
||||
#define grf_readl(offset) readl_relaxed(RK30_GRF_BASE + offset)
|
||||
#define grf_writel(v,offset) do{ writel_relaxed(v, RK30_GRF_BASE + offset);dsb();} while (0)
|
||||
|
||||
#define lvds_readl(addr) readl_relaxed(addr)
|
||||
#define lvds_writel(v,addr) do{ writel_relaxed(v, addr);dsb();} while (0)
|
||||
|
||||
static struct early_suspend early_suspend;
|
||||
static char *virt_reg_addr;
|
||||
|
||||
void rk_dump_clock_info(void);
|
||||
void rk30_clk_dump_regs(void);
|
||||
|
||||
|
||||
static void rk319x_output_lvds(rk_screen *screen)
|
||||
{
|
||||
u32 val =0;
|
||||
|
||||
/*reset lvds*/
|
||||
//lvds_writel(0x0,virt_reg_addr+MIPIPHY_REGE0);
|
||||
//msleep(500);
|
||||
|
||||
val = 0;
|
||||
val |= LVDS_MODE(1); /*enable lvds mode*/
|
||||
val |= LVDS_SEL_LCDC(screen->lcdc_id); /* configure lvds source*/
|
||||
val |= LVDS_OUTPUT_FORMAT(screen->lvds_format); /*configure lvds_format*/
|
||||
val |= LVDS_MSBSEL(1);//LSB mode
|
||||
grf_writel(val,GRF_SOC_CON4);
|
||||
|
||||
|
||||
lvds_writel(0x7c,virt_reg_addr+MIPIPHY_REG0);//enable lvds lane
|
||||
lvds_writel(0x2,virt_reg_addr+MIPIPHY_REG3);//set lvds pll prediv fbdiv[8]
|
||||
lvds_writel(0x1c,virt_reg_addr+MIPIPHY_REG4);//set lvds pll fbdiv[7:0]
|
||||
lvds_writel(0x25,virt_reg_addr+MIPIPHY_REGE0);//lvds mode
|
||||
lvds_writel(0xa0,virt_reg_addr+MIPIPHY_REGE2);//timing
|
||||
lvds_writel(0xfc,virt_reg_addr+MIPIPHY_REGE7);//phase
|
||||
lvds_writel(0xf8,virt_reg_addr+MIPIPHY_REGEA);//power up lvds_pllpd
|
||||
|
||||
/* enable lvds*/
|
||||
val = 0;
|
||||
val |= LVDS_ENABLE(1);
|
||||
grf_writel(val,GRF_SOC_CON8);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void rk319x_output_lvttl(rk_screen *screen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void rk319x_output_disable(void)
|
||||
{
|
||||
u32 val =0;
|
||||
|
||||
val = 0;
|
||||
val |= LVDS_MODE(0);
|
||||
grf_writel(val,GRF_SOC_CON4);
|
||||
|
||||
val = 0;
|
||||
val |= LVDS_ENABLE(0);
|
||||
grf_writel(val,GRF_SOC_CON8);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int rk319x_lvds_set_param(rk_screen *screen,bool enable)
|
||||
{
|
||||
|
||||
if(OUT_ENABLE == enable){
|
||||
switch(screen->type){
|
||||
case SCREEN_LVDS:
|
||||
printk("%s>>>>LVDS Enable %d,power down LVDS\n",__func__,screen->type);
|
||||
rk319x_output_lvds(screen);
|
||||
break;
|
||||
case SCREEN_RGB:
|
||||
rk319x_output_lvttl(screen);
|
||||
break;
|
||||
default:
|
||||
printk("%s>>>>LVDS not support this screen type %d,power down LVDS\n",__func__,screen->type);
|
||||
rk319x_output_disable();
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
printk("%s>>>>LVDS %d,power down LVDS\n",__func__,screen->type);
|
||||
rk319x_output_disable();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lvds_early_suspend(struct early_suspend *handler)
|
||||
{
|
||||
rk_screen *screen = NULL;
|
||||
screen = rk_fb_get_prmry_screen();
|
||||
if(!screen)
|
||||
{
|
||||
printk(KERN_ERR,"the fb prmry screen is null!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rk319x_lvds_set_param(screen,OUT_DISABLE);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
static void lvds_late_resume(struct early_suspend *handler)
|
||||
{
|
||||
rk_screen *screen = NULL;
|
||||
screen = rk_fb_get_prmry_screen();
|
||||
if(!screen)
|
||||
{
|
||||
printk(KERN_ERR,"the fb prmry screen is null!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rk319x_lvds_set_param(screen,OUT_ENABLE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int init_clk()
|
||||
{
|
||||
int ret = 0;
|
||||
struct clk *refclk,*dsi_pclk,*dsi_pd,*mipiphy_dsi;
|
||||
|
||||
refclk = clk_get(NULL, "mipi_ref");
|
||||
if (unlikely(IS_ERR(refclk))) {
|
||||
ret = PTR_ERR(refclk);
|
||||
printk("%s %d \n",__func__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dsi_pclk = clk_get(NULL, "pclk_mipi_dsi");
|
||||
if (unlikely(IS_ERR(dsi_pclk))) {
|
||||
ret = PTR_ERR(dsi_pclk);
|
||||
printk("%s %d \n",__func__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mipiphy_dsi = clk_get(NULL, "pclk_mipiphy_dsi");
|
||||
if (unlikely(IS_ERR(mipiphy_dsi))) {
|
||||
ret = PTR_ERR(mipiphy_dsi);
|
||||
printk("%s %d \n",__func__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
dsi_pd = clk_get(NULL, "pd_mipi_dsi");
|
||||
if (unlikely(IS_ERR(dsi_pd))) {
|
||||
ret = PTR_ERR(dsi_pd);
|
||||
printk("%s %d \n",__func__,__LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
clk_enable(dsi_pd);
|
||||
clk_enable(dsi_pclk);
|
||||
clk_enable(mipiphy_dsi);
|
||||
clk_enable(refclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int rk319x_lvds_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
rk_screen *screen = NULL;
|
||||
|
||||
screen = rk_fb_get_prmry_screen();
|
||||
if(!screen)
|
||||
{
|
||||
dev_err(&pdev->dev,"the fb prmry screen is null!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = init_clk();
|
||||
if(ret < 0)
|
||||
return -1;
|
||||
|
||||
virt_reg_addr = ioremap(RK319X_MIPI_DSI_PHY_PHYS,RK319X_MIPI_DSI_PHY_SIZE);
|
||||
if(virt_reg_addr == NULL)
|
||||
return -1;
|
||||
|
||||
|
||||
rk319x_lvds_set_param(screen,OUT_ENABLE);
|
||||
|
||||
early_suspend.suspend = lvds_early_suspend,
|
||||
early_suspend.resume = lvds_late_resume,
|
||||
early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 20,
|
||||
register_early_suspend(&early_suspend);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int rk319x_lvds_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rk319x_lvds_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static struct platform_driver rk319x_lvds_driver = {
|
||||
.driver = {
|
||||
.name = "rk319x-lvds",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = rk319x_lvds_probe,
|
||||
.remove = rk319x_lvds_remove,
|
||||
.shutdown = rk319x_lvds_shutdown,
|
||||
};
|
||||
|
||||
static int __init rk319x_lvds_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk319x_lvds_driver);
|
||||
}
|
||||
fs_initcall(rk319x_lvds_init);
|
||||
static void __exit rk319x_lvds_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk319x_lvds_driver);
|
||||
}
|
||||
module_exit(rk319x_lvds_exit);
|
||||
|
||||
|
||||
|
||||
28
drivers/video/rockchip/transmitter/rk319x_lvds.h
Executable file
28
drivers/video/rockchip/transmitter/rk319x_lvds.h
Executable file
@@ -0,0 +1,28 @@
|
||||
#include<linux/rk_screen.h>
|
||||
|
||||
#define ENABLE 16
|
||||
|
||||
#define GRF_SOC_CON4 0x0070
|
||||
#define LVDS_SEL_LCDC(x) ((((x)&1)<<2)|(1<<(2+ENABLE)))
|
||||
#define LVDS_MODE(x) ((((x)&1)<<3)|(1<<(3+ENABLE)))
|
||||
#define LVDS_OUTPUT_FORMAT(x) ((((x)&3)<<4)|(3<<(4+ENABLE)))
|
||||
#define LVDS_MSBSEL(x) ((((x)&1)<<6)|(1<<(6+ENABLE)))
|
||||
|
||||
#define GRF_SOC_CON8 0x013c
|
||||
#define LVDS_ENABLE(x) ((((x)&1)<<7)|(1<<(7+ENABLE)))
|
||||
|
||||
#define MIPIPHY_REG0 0x0000
|
||||
#define MIPIPHY_REG3 0x000c
|
||||
#define MIPIPHY_REG4 0x0010
|
||||
#define MIPIPHY_REGE0 0x0380
|
||||
#define MIPIPHY_REGEA 0x03A8
|
||||
#define MIPIPHY_REGE2 0x0388
|
||||
#define MIPIPHY_REGE7 0x039C
|
||||
|
||||
|
||||
|
||||
enum{
|
||||
OUT_DISABLE=0,
|
||||
OUT_ENABLE,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user