fbdev changes for 3.14
This is a rather boring pull request. There is one new fb driver, OpenCores VGA/LCD, but other than that it's just minor cleanups and fixes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJS4kg5AAoJEPo9qoy8lh71ng0P/jmi0rDF5+0D+L3EjE1tLN9M +0DhoUdkSXweSRLk0TxF4vkHmlStykTEbBkdKGqFa6yKvq+V7wFtgv2lchraZmJv TsTiZ60J6JnA0xbHurt+GntWRgzIGWIHF9QBk/hxn1QB3oIscR2I6K9z+YVKStXH ywyBOmvfyghDkPG8taqXuDCtWFKYMwuoUP+YfqvVT1Ey4J+pEJ8EpBM9nvLJmvuW ZrARDqkntoQZOzfW52HVis0hzrQLi8bJQp5BEu+yd2Q3sSOXV7kV8HOCkhiGwHCE zEtPM5KavmHRECoZtCtNTRvf+e0byKibuAnKSvnuwdfxRurvh4T3I7YUf3VsnIoL +obxad3737zvIY0yDx3PIU/dbCtv63sy+6Gl/E7HAn9Q0t1fGml1Y0XC8Ohy6rR5 b9WmSGcF0nxPBxHeyjJLXJMxiv8iclvBLhZc5CUeKYB+teLEGorRpMsuElPmizOh elMus/f6NHxbaJoS6FJPTMm3QfdjqG3SLGAOpNkZgFtCsNGaqyexVQViEV/PgEJI Qe67KeuUGdJhvko7ct19u1d/ZHs19LXnUmtLsD/xbs6YcUCQZ106B9ZP+YRc+ie0 9QDcfI+WEc82xL18L3bge+xYc45jdPhCOn6zwAKIYqNq5ITkjdt0jHLv5dtfPkbI Hv/P2Peuc6u3KSDFyrwe =RmAl -----END PGP SIGNATURE----- Merge tag 'fbdev-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux Pull fbdev changes from Tomi Valkeinen: "This is a rather boring pull request. There is one new fb driver, OpenCores VGA/LCD, but other than that it's just minor cleanups and fixes" * tag 'fbdev-3.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (51 commits) i810: delete useless variable video: add OpenCores VGA/LCD framebuffer driver video/logo: Remove MIPS-specific include section tgafb: potential NULL dereference in init video: mmp: Using plain integer as NULL pointer video: mmp: delete a stray mutex_unlock() video: amba-clcd: Make CLCD driver available on more platforms video: Replace local macro with PCI standard macro fbmem: really support wildcard video=options for all fbdev drivers video: vgacon: Don't build on arm64 video: mx3fb: Allow blocking during framebuffer allocation fbcon: Fix memory leak in fbcon_exit(). fbcon: trivial optimization for fbcon_exit video: pxa168fb: Cleanup pxa168fb.h file video: pxa: Cleanup video-pxafb.h header video: msm: Cleanup video-msm_fb.h header video: ep93xx: Cleanup video-ep93xx.h header video: mxsfb: fix broken videomode selection video: mxsfb: convert pr_debug()/dev_dbg() to pr_err()/dev_err() for error messages video: vmlfb: remove unnecessary pci_set_drvdata() ...
This commit is contained in:
Коммит
b788769e06
|
@ -312,7 +312,8 @@ config FB_PM2_FIFO_DISCONNECT
|
|||
|
||||
config FB_ARMCLCD
|
||||
tristate "ARM PrimeCell PL110 support"
|
||||
depends on FB && ARM && ARM_AMBA
|
||||
depends on ARM || ARM64 || COMPILE_TEST
|
||||
depends on FB && ARM_AMBA
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
|
@ -979,6 +980,22 @@ config FB_PVR2
|
|||
(<file:drivers/video/pvr2fb.c>). Please see the file
|
||||
<file:Documentation/fb/pvr2fb.txt>.
|
||||
|
||||
config FB_OPENCORES
|
||||
tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
|
||||
depends on FB
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
help
|
||||
This enables support for the OpenCores VGA/LCD core.
|
||||
|
||||
The OpenCores VGA/LCD core is typically used together with
|
||||
softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor
|
||||
systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs.
|
||||
|
||||
The source code and specification for the core is available at
|
||||
<http://opencores.org/project,vga_lcd>
|
||||
|
||||
config FB_S1D13XXX
|
||||
tristate "Epson S1D13XXX framebuffer support"
|
||||
depends on FB
|
||||
|
|
|
@ -150,6 +150,7 @@ obj-$(CONFIG_FB_NUC900) += nuc900fb.o
|
|||
obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
|
||||
obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
|
||||
obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
|
||||
obj-$(CONFIG_FB_OPENCORES) += ocfb.o
|
||||
|
||||
# Platform or fallback drivers go here
|
||||
obj-$(CONFIG_FB_UVESA) += uvesafb.o
|
||||
|
|
|
@ -589,7 +589,6 @@ static void asiliantfb_remove(struct pci_dev *dp)
|
|||
fb_dealloc_cmap(&p->cmap);
|
||||
iounmap(p->screen_base);
|
||||
release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
|
||||
pci_set_drvdata(dp, NULL);
|
||||
framebuffer_release(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ config VGA_CONSOLE
|
|||
bool "VGA text console" if EXPERT || !X86
|
||||
depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && \
|
||||
!SUPERH && !BLACKFIN && !AVR32 && !MN10300 && !CRIS && \
|
||||
(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER)
|
||||
(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \
|
||||
!ARM64
|
||||
default y
|
||||
help
|
||||
Saying Y here will allow you to use Linux in text mode through a
|
||||
|
|
|
@ -3547,8 +3547,10 @@ static void fbcon_exit(void)
|
|||
"no"));
|
||||
|
||||
for (j = first_fb_vc; j <= last_fb_vc; j++) {
|
||||
if (con2fb_map[j] == i)
|
||||
if (con2fb_map[j] == i) {
|
||||
mapped = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mapped) {
|
||||
|
@ -3561,6 +3563,7 @@ static void fbcon_exit(void)
|
|||
|
||||
fbcon_del_cursor_timer(info);
|
||||
kfree(ops->cursor_src);
|
||||
kfree(ops->cursor_state.mask);
|
||||
kfree(info->fbcon_par);
|
||||
info->fbcon_par = NULL;
|
||||
}
|
||||
|
|
|
@ -1930,6 +1930,9 @@ int fb_get_options(const char *name, char **option)
|
|||
options = opt + name_len + 1;
|
||||
}
|
||||
}
|
||||
/* No match, pass global option */
|
||||
if (!options && option && fb_mode_option)
|
||||
options = kstrdup(fb_mode_option, GFP_KERNEL);
|
||||
if (options && !strncmp(options, "off", 3))
|
||||
retval = 1;
|
||||
|
||||
|
|
|
@ -2011,9 +2011,7 @@ static int i810fb_init_pci(struct pci_dev *dev,
|
|||
struct fb_info *info;
|
||||
struct i810fb_par *par = NULL;
|
||||
struct fb_videomode mode;
|
||||
int i, err = -1, vfreq, hfreq, pixclock;
|
||||
|
||||
i = 0;
|
||||
int err = -1, vfreq, hfreq, pixclock;
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct i810fb_par), &dev->dev);
|
||||
if (!info)
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
#include <asm/setup.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MIPS
|
||||
#include <asm/bootinfo.h>
|
||||
#endif
|
||||
|
||||
static bool nologo;
|
||||
module_param(nologo, bool, 0);
|
||||
MODULE_PARM_DESC(nologo, "Disables startup logo");
|
||||
|
|
|
@ -30,7 +30,7 @@ static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
|
|||
{
|
||||
if (path && overlay_id < path->overlay_num)
|
||||
return &path->overlays[overlay_id];
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int path_check_status(struct mmp_path *path)
|
||||
|
@ -173,7 +173,7 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info)
|
|||
+ sizeof(struct mmp_overlay) * info->overlay_num;
|
||||
path = kzalloc(size, GFP_KERNEL);
|
||||
if (!path)
|
||||
goto failed;
|
||||
return NULL;
|
||||
|
||||
/* path set */
|
||||
mutex_init(&path->access_ok);
|
||||
|
@ -219,11 +219,6 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info)
|
|||
|
||||
mutex_unlock(&disp_lock);
|
||||
return path;
|
||||
|
||||
failed:
|
||||
kfree(path);
|
||||
mutex_unlock(&disp_lock);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mmp_register_path);
|
||||
|
||||
|
|
|
@ -1263,7 +1263,7 @@ static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,
|
|||
|
||||
fbi->screen_base = dma_alloc_writecombine(fbi->device,
|
||||
mem_len,
|
||||
&addr, GFP_DMA);
|
||||
&addr, GFP_DMA | GFP_KERNEL);
|
||||
|
||||
if (!fbi->screen_base) {
|
||||
dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <linux/fb.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <video/of_display_timing.h>
|
||||
#include <video/of_videomode.h>
|
||||
#include <video/videomode.h>
|
||||
|
||||
#define REG_SET 4
|
||||
|
@ -297,7 +298,7 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
pr_debug("Unsupported colour depth: %u\n", var->bits_per_pixel);
|
||||
pr_err("Unsupported colour depth: %u\n", var->bits_per_pixel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -426,7 +427,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
|
|||
ctrl |= CTRL_SET_WORD_LENGTH(3);
|
||||
switch (host->ld_intf_width) {
|
||||
case STMLCDIF_8BIT:
|
||||
dev_dbg(&host->pdev->dev,
|
||||
dev_err(&host->pdev->dev,
|
||||
"Unsupported LCD bus width mapping\n");
|
||||
return -EINVAL;
|
||||
case STMLCDIF_16BIT:
|
||||
|
@ -439,7 +440,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)
|
|||
writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&host->pdev->dev, "Unhandled color depth of %u\n",
|
||||
dev_err(&host->pdev->dev, "Unhandled color depth of %u\n",
|
||||
fb_info->var.bits_per_pixel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -589,7 +590,8 @@ static struct fb_ops mxsfb_ops = {
|
|||
.fb_imageblit = cfb_imageblit,
|
||||
};
|
||||
|
||||
static int mxsfb_restore_mode(struct mxsfb_info *host)
|
||||
static int mxsfb_restore_mode(struct mxsfb_info *host,
|
||||
struct fb_videomode *vmode)
|
||||
{
|
||||
struct fb_info *fb_info = &host->fb_info;
|
||||
unsigned line_count;
|
||||
|
@ -597,7 +599,6 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
|
|||
unsigned long pa, fbsize;
|
||||
int bits_per_pixel, ofs;
|
||||
u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl;
|
||||
struct fb_videomode vmode;
|
||||
|
||||
/* Only restore the mode when the controller is running */
|
||||
ctrl = readl(host->base + LCDC_CTRL);
|
||||
|
@ -611,8 +612,8 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
|
|||
|
||||
transfer_count = readl(host->base + host->devdata->transfer_count);
|
||||
|
||||
vmode.xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
|
||||
vmode.yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count);
|
||||
vmode->xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count);
|
||||
vmode->yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count);
|
||||
|
||||
switch (CTRL_GET_WORD_LENGTH(ctrl)) {
|
||||
case 0:
|
||||
|
@ -628,40 +629,39 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
|
|||
|
||||
fb_info->var.bits_per_pixel = bits_per_pixel;
|
||||
|
||||
vmode.pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U);
|
||||
vmode.hsync_len = get_hsync_pulse_width(host, vdctrl2);
|
||||
vmode.left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode.hsync_len;
|
||||
vmode.right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - vmode.hsync_len -
|
||||
vmode.left_margin - vmode.xres;
|
||||
vmode.vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0);
|
||||
vmode->pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U);
|
||||
vmode->hsync_len = get_hsync_pulse_width(host, vdctrl2);
|
||||
vmode->left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode->hsync_len;
|
||||
vmode->right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) -
|
||||
vmode->hsync_len - vmode->left_margin - vmode->xres;
|
||||
vmode->vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0);
|
||||
period = readl(host->base + LCDC_VDCTRL1);
|
||||
vmode.upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode.vsync_len;
|
||||
vmode.lower_margin = period - vmode.vsync_len - vmode.upper_margin - vmode.yres;
|
||||
vmode->upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode->vsync_len;
|
||||
vmode->lower_margin = period - vmode->vsync_len -
|
||||
vmode->upper_margin - vmode->yres;
|
||||
|
||||
vmode.vmode = FB_VMODE_NONINTERLACED;
|
||||
vmode->vmode = FB_VMODE_NONINTERLACED;
|
||||
|
||||
vmode.sync = 0;
|
||||
vmode->sync = 0;
|
||||
if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH)
|
||||
vmode.sync |= FB_SYNC_HOR_HIGH_ACT;
|
||||
vmode->sync |= FB_SYNC_HOR_HIGH_ACT;
|
||||
if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH)
|
||||
vmode.sync |= FB_SYNC_VERT_HIGH_ACT;
|
||||
vmode->sync |= FB_SYNC_VERT_HIGH_ACT;
|
||||
|
||||
pr_debug("Reconstructed video mode:\n");
|
||||
pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n",
|
||||
vmode.xres, vmode.yres,
|
||||
vmode.hsync_len, vmode.left_margin, vmode.right_margin,
|
||||
vmode.vsync_len, vmode.upper_margin, vmode.lower_margin);
|
||||
pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode.pixclock));
|
||||
|
||||
fb_add_videomode(&vmode, &fb_info->modelist);
|
||||
vmode->xres, vmode->yres, vmode->hsync_len, vmode->left_margin,
|
||||
vmode->right_margin, vmode->vsync_len, vmode->upper_margin,
|
||||
vmode->lower_margin);
|
||||
pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode->pixclock));
|
||||
|
||||
host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl);
|
||||
host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4);
|
||||
|
||||
fb_info->fix.line_length = vmode.xres * (bits_per_pixel >> 3);
|
||||
fb_info->fix.line_length = vmode->xres * (bits_per_pixel >> 3);
|
||||
|
||||
pa = readl(host->base + host->devdata->cur_buf);
|
||||
fbsize = fb_info->fix.line_length * vmode.yres;
|
||||
fbsize = fb_info->fix.line_length * vmode->yres;
|
||||
if (pa < fb_info->fix.smem_start)
|
||||
return -EINVAL;
|
||||
if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len)
|
||||
|
@ -681,18 +681,17 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
|
||||
static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
|
||||
struct fb_videomode *vmode)
|
||||
{
|
||||
struct fb_info *fb_info = &host->fb_info;
|
||||
struct fb_var_screeninfo *var = &fb_info->var;
|
||||
struct device *dev = &host->pdev->dev;
|
||||
struct device_node *np = host->pdev->dev.of_node;
|
||||
struct device_node *display_np;
|
||||
struct device_node *timings_np;
|
||||
struct display_timings *timings;
|
||||
struct videomode vm;
|
||||
u32 width;
|
||||
int i;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
display_np = of_parse_phandle(np, "display", 0);
|
||||
if (!display_np) {
|
||||
|
@ -732,54 +731,35 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
|
|||
goto put_display_node;
|
||||
}
|
||||
|
||||
timings = of_get_display_timings(display_np);
|
||||
if (!timings) {
|
||||
dev_err(dev, "failed to get display timings\n");
|
||||
ret = -ENOENT;
|
||||
ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to get videomode from DT\n");
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
timings_np = of_find_node_by_name(display_np,
|
||||
"display-timings");
|
||||
if (!timings_np) {
|
||||
dev_err(dev, "failed to find display-timings node\n");
|
||||
ret = -ENOENT;
|
||||
ret = fb_videomode_from_videomode(&vm, vmode);
|
||||
if (ret < 0)
|
||||
goto put_display_node;
|
||||
}
|
||||
|
||||
for (i = 0; i < of_get_child_count(timings_np); i++) {
|
||||
struct videomode vm;
|
||||
struct fb_videomode fb_vm;
|
||||
if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
|
||||
host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
|
||||
if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
|
||||
host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
|
||||
|
||||
ret = videomode_from_timings(timings, &vm, i);
|
||||
if (ret < 0)
|
||||
goto put_timings_node;
|
||||
ret = fb_videomode_from_videomode(&vm, &fb_vm);
|
||||
if (ret < 0)
|
||||
goto put_timings_node;
|
||||
|
||||
if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
|
||||
host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
|
||||
if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
|
||||
host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
|
||||
fb_add_videomode(&fb_vm, &fb_info->modelist);
|
||||
}
|
||||
|
||||
put_timings_node:
|
||||
of_node_put(timings_np);
|
||||
put_display_node:
|
||||
of_node_put(display_np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mxsfb_init_fbinfo(struct mxsfb_info *host)
|
||||
static int mxsfb_init_fbinfo(struct mxsfb_info *host,
|
||||
struct fb_videomode *vmode)
|
||||
{
|
||||
int ret;
|
||||
struct fb_info *fb_info = &host->fb_info;
|
||||
struct fb_var_screeninfo *var = &fb_info->var;
|
||||
dma_addr_t fb_phys;
|
||||
void *fb_virt;
|
||||
unsigned fb_size;
|
||||
int ret;
|
||||
|
||||
fb_info->fbops = &mxsfb_ops;
|
||||
fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
|
||||
|
@ -789,7 +769,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
|
|||
fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
|
||||
fb_info->fix.accel = FB_ACCEL_NONE;
|
||||
|
||||
ret = mxsfb_init_fbinfo_dt(host);
|
||||
ret = mxsfb_init_fbinfo_dt(host, vmode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -810,7 +790,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
|
|||
fb_info->screen_base = fb_virt;
|
||||
fb_info->screen_size = fb_info->fix.smem_len = fb_size;
|
||||
|
||||
if (mxsfb_restore_mode(host))
|
||||
if (mxsfb_restore_mode(host, vmode))
|
||||
memset(fb_virt, 0, fb_size);
|
||||
|
||||
return 0;
|
||||
|
@ -850,7 +830,7 @@ static int mxsfb_probe(struct platform_device *pdev)
|
|||
struct resource *res;
|
||||
struct mxsfb_info *host;
|
||||
struct fb_info *fb_info;
|
||||
struct fb_modelist *modelist;
|
||||
struct fb_videomode *mode;
|
||||
int ret;
|
||||
|
||||
if (of_id)
|
||||
|
@ -862,6 +842,11 @@ static int mxsfb_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mode = devm_kzalloc(&pdev->dev, sizeof(struct fb_videomode),
|
||||
GFP_KERNEL);
|
||||
if (mode == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
host = to_imxfb_host(fb_info);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
@ -893,15 +878,11 @@ static int mxsfb_probe(struct platform_device *pdev)
|
|||
goto fb_release;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&fb_info->modelist);
|
||||
|
||||
ret = mxsfb_init_fbinfo(host);
|
||||
ret = mxsfb_init_fbinfo(host, mode);
|
||||
if (ret != 0)
|
||||
goto fb_release;
|
||||
|
||||
modelist = list_first_entry(&fb_info->modelist,
|
||||
struct fb_modelist, list);
|
||||
fb_videomode_to_var(&fb_info->var, &modelist->mode);
|
||||
fb_videomode_to_var(&fb_info->var, mode);
|
||||
|
||||
/* init the color fields */
|
||||
mxsfb_check_var(&fb_info->var, fb_info);
|
||||
|
@ -927,7 +908,6 @@ static int mxsfb_probe(struct platform_device *pdev)
|
|||
fb_destroy:
|
||||
if (host->enabled)
|
||||
clk_disable_unprepare(host->clk);
|
||||
fb_destroy_modelist(&fb_info->modelist);
|
||||
fb_release:
|
||||
framebuffer_release(fb_info);
|
||||
|
||||
|
|
|
@ -1461,7 +1461,6 @@ static void nvidiafb_remove(struct pci_dev *pd)
|
|||
pci_release_regions(pd);
|
||||
kfree(info->pixmap.addr);
|
||||
framebuffer_release(info);
|
||||
pci_set_drvdata(pd, NULL);
|
||||
NVTRACE_LEAVE();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
* OpenCores VGA/LCD 2.0 core frame buffer driver
|
||||
*
|
||||
* Copyright (C) 2013 Stefan Kristiansson, stefan.kristiansson@saunalahti.fi
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* OCFB register defines */
|
||||
#define OCFB_CTRL 0x000
|
||||
#define OCFB_STAT 0x004
|
||||
#define OCFB_HTIM 0x008
|
||||
#define OCFB_VTIM 0x00c
|
||||
#define OCFB_HVLEN 0x010
|
||||
#define OCFB_VBARA 0x014
|
||||
#define OCFB_PALETTE 0x800
|
||||
|
||||
#define OCFB_CTRL_VEN 0x00000001 /* Video Enable */
|
||||
#define OCFB_CTRL_HIE 0x00000002 /* HSync Interrupt Enable */
|
||||
#define OCFB_CTRL_PC 0x00000800 /* 8-bit Pseudo Color Enable*/
|
||||
#define OCFB_CTRL_CD8 0x00000000 /* Color Depth 8 */
|
||||
#define OCFB_CTRL_CD16 0x00000200 /* Color Depth 16 */
|
||||
#define OCFB_CTRL_CD24 0x00000400 /* Color Depth 24 */
|
||||
#define OCFB_CTRL_CD32 0x00000600 /* Color Depth 32 */
|
||||
#define OCFB_CTRL_VBL1 0x00000000 /* Burst Length 1 */
|
||||
#define OCFB_CTRL_VBL2 0x00000080 /* Burst Length 2 */
|
||||
#define OCFB_CTRL_VBL4 0x00000100 /* Burst Length 4 */
|
||||
#define OCFB_CTRL_VBL8 0x00000180 /* Burst Length 8 */
|
||||
|
||||
#define PALETTE_SIZE 256
|
||||
|
||||
#define OCFB_NAME "OC VGA/LCD"
|
||||
|
||||
static char *mode_option;
|
||||
|
||||
static const struct fb_videomode default_mode = {
|
||||
/* 640x480 @ 60 Hz, 31.5 kHz hsync */
|
||||
NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
|
||||
0, FB_VMODE_NONINTERLACED
|
||||
};
|
||||
|
||||
struct ocfb_dev {
|
||||
struct fb_info info;
|
||||
void __iomem *regs;
|
||||
/* flag indicating whether the regs are little endian accessed */
|
||||
int little_endian;
|
||||
/* Physical and virtual addresses of framebuffer */
|
||||
phys_addr_t fb_phys;
|
||||
void __iomem *fb_virt;
|
||||
u32 pseudo_palette[PALETTE_SIZE];
|
||||
};
|
||||
|
||||
#ifndef MODULE
|
||||
static int __init ocfb_setup(char *options)
|
||||
{
|
||||
char *curr_opt;
|
||||
|
||||
if (!options || !*options)
|
||||
return 0;
|
||||
|
||||
while ((curr_opt = strsep(&options, ",")) != NULL) {
|
||||
if (!*curr_opt)
|
||||
continue;
|
||||
mode_option = curr_opt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline u32 ocfb_readreg(struct ocfb_dev *fbdev, loff_t offset)
|
||||
{
|
||||
if (fbdev->little_endian)
|
||||
return ioread32(fbdev->regs + offset);
|
||||
else
|
||||
return ioread32be(fbdev->regs + offset);
|
||||
}
|
||||
|
||||
static void ocfb_writereg(struct ocfb_dev *fbdev, loff_t offset, u32 data)
|
||||
{
|
||||
if (fbdev->little_endian)
|
||||
iowrite32(data, fbdev->regs + offset);
|
||||
else
|
||||
iowrite32be(data, fbdev->regs + offset);
|
||||
}
|
||||
|
||||
static int ocfb_setupfb(struct ocfb_dev *fbdev)
|
||||
{
|
||||
unsigned long bpp_config;
|
||||
struct fb_var_screeninfo *var = &fbdev->info.var;
|
||||
struct device *dev = fbdev->info.device;
|
||||
u32 hlen;
|
||||
u32 vlen;
|
||||
|
||||
/* Disable display */
|
||||
ocfb_writereg(fbdev, OCFB_CTRL, 0);
|
||||
|
||||
/* Register framebuffer address */
|
||||
fbdev->little_endian = 0;
|
||||
ocfb_writereg(fbdev, OCFB_VBARA, fbdev->fb_phys);
|
||||
|
||||
/* Detect endianess */
|
||||
if (ocfb_readreg(fbdev, OCFB_VBARA) != fbdev->fb_phys) {
|
||||
fbdev->little_endian = 1;
|
||||
ocfb_writereg(fbdev, OCFB_VBARA, fbdev->fb_phys);
|
||||
}
|
||||
|
||||
/* Horizontal timings */
|
||||
ocfb_writereg(fbdev, OCFB_HTIM, (var->hsync_len - 1) << 24 |
|
||||
(var->right_margin - 1) << 16 | (var->xres - 1));
|
||||
|
||||
/* Vertical timings */
|
||||
ocfb_writereg(fbdev, OCFB_VTIM, (var->vsync_len - 1) << 24 |
|
||||
(var->lower_margin - 1) << 16 | (var->yres - 1));
|
||||
|
||||
/* Total length of frame */
|
||||
hlen = var->left_margin + var->right_margin + var->hsync_len +
|
||||
var->xres;
|
||||
|
||||
vlen = var->upper_margin + var->lower_margin + var->vsync_len +
|
||||
var->yres;
|
||||
|
||||
ocfb_writereg(fbdev, OCFB_HVLEN, (hlen - 1) << 16 | (vlen - 1));
|
||||
|
||||
bpp_config = OCFB_CTRL_CD8;
|
||||
switch (var->bits_per_pixel) {
|
||||
case 8:
|
||||
if (!var->grayscale)
|
||||
bpp_config |= OCFB_CTRL_PC; /* enable palette */
|
||||
break;
|
||||
|
||||
case 16:
|
||||
bpp_config |= OCFB_CTRL_CD16;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
bpp_config |= OCFB_CTRL_CD24;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
bpp_config |= OCFB_CTRL_CD32;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(dev, "no bpp specified\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* maximum (8) VBL (video memory burst length) */
|
||||
bpp_config |= OCFB_CTRL_VBL8;
|
||||
|
||||
/* Enable output */
|
||||
ocfb_writereg(fbdev, OCFB_CTRL, (OCFB_CTRL_VEN | bpp_config));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ocfb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
unsigned blue, unsigned transp,
|
||||
struct fb_info *info)
|
||||
{
|
||||
struct ocfb_dev *fbdev = (struct ocfb_dev *)info->par;
|
||||
u32 color;
|
||||
|
||||
if (regno >= info->cmap.len) {
|
||||
dev_err(info->device, "regno >= cmap.len\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->var.grayscale) {
|
||||
/* grayscale = 0.30*R + 0.59*G + 0.11*B */
|
||||
red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
|
||||
}
|
||||
|
||||
red >>= (16 - info->var.red.length);
|
||||
green >>= (16 - info->var.green.length);
|
||||
blue >>= (16 - info->var.blue.length);
|
||||
transp >>= (16 - info->var.transp.length);
|
||||
|
||||
if (info->var.bits_per_pixel == 8 && !info->var.grayscale) {
|
||||
regno <<= 2;
|
||||
color = (red << 16) | (green << 8) | blue;
|
||||
ocfb_writereg(fbdev, OCFB_PALETTE + regno, color);
|
||||
} else {
|
||||
((u32 *)(info->pseudo_palette))[regno] =
|
||||
(red << info->var.red.offset) |
|
||||
(green << info->var.green.offset) |
|
||||
(blue << info->var.blue.offset) |
|
||||
(transp << info->var.transp.offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ocfb_init_fix(struct ocfb_dev *fbdev)
|
||||
{
|
||||
struct fb_var_screeninfo *var = &fbdev->info.var;
|
||||
struct fb_fix_screeninfo *fix = &fbdev->info.fix;
|
||||
|
||||
strcpy(fix->id, OCFB_NAME);
|
||||
|
||||
fix->line_length = var->xres * var->bits_per_pixel/8;
|
||||
fix->smem_len = fix->line_length * var->yres;
|
||||
fix->type = FB_TYPE_PACKED_PIXELS;
|
||||
|
||||
if (var->bits_per_pixel == 8 && !var->grayscale)
|
||||
fix->visual = FB_VISUAL_PSEUDOCOLOR;
|
||||
else
|
||||
fix->visual = FB_VISUAL_TRUECOLOR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ocfb_init_var(struct ocfb_dev *fbdev)
|
||||
{
|
||||
struct fb_var_screeninfo *var = &fbdev->info.var;
|
||||
|
||||
var->accel_flags = FB_ACCEL_NONE;
|
||||
var->activate = FB_ACTIVATE_NOW;
|
||||
var->xres_virtual = var->xres;
|
||||
var->yres_virtual = var->yres;
|
||||
|
||||
switch (var->bits_per_pixel) {
|
||||
case 8:
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->red.offset = 0;
|
||||
var->red.length = 8;
|
||||
var->green.offset = 0;
|
||||
var->green.length = 8;
|
||||
var->blue.offset = 0;
|
||||
var->blue.length = 8;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->red.offset = 11;
|
||||
var->red.length = 5;
|
||||
var->green.offset = 5;
|
||||
var->green.length = 6;
|
||||
var->blue.offset = 0;
|
||||
var->blue.length = 5;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->red.offset = 16;
|
||||
var->red.length = 8;
|
||||
var->green.offset = 8;
|
||||
var->green.length = 8;
|
||||
var->blue.offset = 0;
|
||||
var->blue.length = 8;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
var->transp.offset = 24;
|
||||
var->transp.length = 8;
|
||||
var->red.offset = 16;
|
||||
var->red.length = 8;
|
||||
var->green.offset = 8;
|
||||
var->green.length = 8;
|
||||
var->blue.offset = 0;
|
||||
var->blue.length = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops ocfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_setcolreg = ocfb_setcolreg,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
};
|
||||
|
||||
static int ocfb_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct ocfb_dev *fbdev;
|
||||
struct resource *res;
|
||||
int fbsize;
|
||||
|
||||
fbdev = devm_kzalloc(&pdev->dev, sizeof(*fbdev), GFP_KERNEL);
|
||||
if (!fbdev)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, fbdev);
|
||||
|
||||
fbdev->info.fbops = &ocfb_ops;
|
||||
fbdev->info.device = &pdev->dev;
|
||||
fbdev->info.par = fbdev;
|
||||
|
||||
/* Video mode setup */
|
||||
if (!fb_find_mode(&fbdev->info.var, &fbdev->info, mode_option,
|
||||
NULL, 0, &default_mode, 16)) {
|
||||
dev_err(&pdev->dev, "No valid video modes found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ocfb_init_var(fbdev);
|
||||
ocfb_init_fix(fbdev);
|
||||
|
||||
/* Request I/O resource */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "I/O resource request failed\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
res->flags &= ~IORESOURCE_CACHEABLE;
|
||||
fbdev->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(fbdev->regs))
|
||||
return PTR_ERR(fbdev->regs);
|
||||
|
||||
/* Allocate framebuffer memory */
|
||||
fbsize = fbdev->info.fix.smem_len;
|
||||
fbdev->fb_virt = dma_alloc_coherent(&pdev->dev, PAGE_ALIGN(fbsize),
|
||||
&fbdev->fb_phys, GFP_KERNEL);
|
||||
if (!fbdev->fb_virt) {
|
||||
dev_err(&pdev->dev,
|
||||
"Frame buffer memory allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
fbdev->info.fix.smem_start = fbdev->fb_phys;
|
||||
fbdev->info.screen_base = fbdev->fb_virt;
|
||||
fbdev->info.pseudo_palette = fbdev->pseudo_palette;
|
||||
|
||||
/* Clear framebuffer */
|
||||
memset_io(fbdev->fb_virt, 0, fbsize);
|
||||
|
||||
/* Setup and enable the framebuffer */
|
||||
ocfb_setupfb(fbdev);
|
||||
|
||||
if (fbdev->little_endian)
|
||||
fbdev->info.flags |= FBINFO_FOREIGN_ENDIAN;
|
||||
|
||||
/* Allocate color map */
|
||||
ret = fb_alloc_cmap(&fbdev->info.cmap, PALETTE_SIZE, 0);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Color map allocation failed\n");
|
||||
goto err_dma_free;
|
||||
}
|
||||
|
||||
/* Register framebuffer */
|
||||
ret = register_framebuffer(&fbdev->info);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Framebuffer registration failed\n");
|
||||
goto err_dealloc_cmap;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_dealloc_cmap:
|
||||
fb_dealloc_cmap(&fbdev->info.cmap);
|
||||
|
||||
err_dma_free:
|
||||
dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbsize), fbdev->fb_virt,
|
||||
fbdev->fb_phys);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ocfb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ocfb_dev *fbdev = platform_get_drvdata(pdev);
|
||||
|
||||
unregister_framebuffer(&fbdev->info);
|
||||
fb_dealloc_cmap(&fbdev->info.cmap);
|
||||
dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbdev->info.fix.smem_len),
|
||||
fbdev->fb_virt, fbdev->fb_phys);
|
||||
|
||||
/* Disable display */
|
||||
ocfb_writereg(fbdev, OCFB_CTRL, 0);
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id ocfb_match[] = {
|
||||
{ .compatible = "opencores,ocfb", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ocfb_match);
|
||||
|
||||
static struct platform_driver ocfb_driver = {
|
||||
.probe = ocfb_probe,
|
||||
.remove = ocfb_remove,
|
||||
.driver = {
|
||||
.name = "ocfb_fb",
|
||||
.of_match_table = ocfb_match,
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Init and exit routines
|
||||
*/
|
||||
static int __init ocfb_init(void)
|
||||
{
|
||||
#ifndef MODULE
|
||||
char *option = NULL;
|
||||
|
||||
if (fb_get_options("ocfb", &option))
|
||||
return -ENODEV;
|
||||
ocfb_setup(option);
|
||||
#endif
|
||||
return platform_driver_register(&ocfb_driver);
|
||||
}
|
||||
|
||||
static void __exit ocfb_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&ocfb_driver);
|
||||
}
|
||||
|
||||
module_init(ocfb_init);
|
||||
module_exit(ocfb_exit);
|
||||
|
||||
MODULE_AUTHOR("Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>");
|
||||
MODULE_DESCRIPTION("OpenCores VGA/LCD 2.0 frame buffer driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
module_param(mode_option, charp, 0);
|
||||
MODULE_PARM_DESC(mode_option, "Video mode ('<xres>x<yres>[-<bpp>][@refresh]')");
|
|
@ -346,28 +346,22 @@ static int acx565akm_get_actual_brightness(struct panel_drv_data *ddata)
|
|||
static int acx565akm_bl_update_status(struct backlight_device *dev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
|
||||
int r;
|
||||
int level;
|
||||
|
||||
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
|
||||
if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
|
||||
dev->props.power == FB_BLANK_UNBLANK)
|
||||
level = dev->props.brightness;
|
||||
else
|
||||
level = 0;
|
||||
|
||||
r = 0;
|
||||
if (ddata->has_bc)
|
||||
acx565akm_set_brightness(ddata, level);
|
||||
else
|
||||
r = -ENODEV;
|
||||
return -ENODEV;
|
||||
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acx565akm_bl_get_intensity(struct backlight_device *dev)
|
||||
|
@ -390,9 +384,33 @@ static int acx565akm_bl_get_intensity(struct backlight_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int acx565akm_bl_update_status_locked(struct backlight_device *dev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
r = acx565akm_bl_update_status(dev);
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int acx565akm_bl_get_intensity_locked(struct backlight_device *dev)
|
||||
{
|
||||
struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
r = acx565akm_bl_get_intensity(dev);
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct backlight_ops acx565akm_bl_ops = {
|
||||
.get_brightness = acx565akm_bl_get_intensity,
|
||||
.update_status = acx565akm_bl_update_status,
|
||||
.get_brightness = acx565akm_bl_get_intensity_locked,
|
||||
.update_status = acx565akm_bl_update_status_locked,
|
||||
};
|
||||
|
||||
/*--------------------Auto Brightness control via Sysfs---------------------*/
|
||||
|
@ -526,8 +544,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
|
|||
struct omap_dss_device *in = ddata->in;
|
||||
int r;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
|
||||
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
|
||||
|
||||
in->ops.sdi->set_timings(in, &ddata->videomode);
|
||||
|
@ -568,8 +584,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
|
|||
set_display_state(ddata, 1);
|
||||
set_cabc_mode(ddata, ddata->cabc_mode);
|
||||
|
||||
mutex_unlock(&ddata->mutex);
|
||||
|
||||
return acx565akm_bl_update_status(ddata->bl_dev);
|
||||
}
|
||||
|
||||
|
@ -616,7 +630,9 @@ static int acx565akm_enable(struct omap_dss_device *dssdev)
|
|||
if (omapdss_device_is_enabled(dssdev))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ddata->mutex);
|
||||
r = acx565akm_panel_power_on(dssdev);
|
||||
mutex_unlock(&ddata->mutex);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -149,6 +149,9 @@ static void apply_init_priv(void)
|
|||
|
||||
op = &dss_data.ovl_priv_data_array[i];
|
||||
|
||||
op->info.color_mode = OMAP_DSS_COLOR_RGB16;
|
||||
op->info.rotation_type = OMAP_DSS_ROT_DMA;
|
||||
|
||||
op->info.global_alpha = 255;
|
||||
|
||||
switch (i) {
|
||||
|
@ -629,7 +632,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
|
|||
struct mgr_priv_data *mp;
|
||||
int r;
|
||||
|
||||
DSSDBG("writing ovl %d regs", ovl->id);
|
||||
DSSDBG("writing ovl %d regs\n", ovl->id);
|
||||
|
||||
if (!op->enabled || !op->info_dirty)
|
||||
return;
|
||||
|
@ -664,7 +667,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
|
|||
struct ovl_priv_data *op = get_ovl_priv(ovl);
|
||||
struct mgr_priv_data *mp;
|
||||
|
||||
DSSDBG("writing ovl %d regs extra", ovl->id);
|
||||
DSSDBG("writing ovl %d regs extra\n", ovl->id);
|
||||
|
||||
if (!op->extra_info_dirty)
|
||||
return;
|
||||
|
@ -687,7 +690,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
|
|||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
struct omap_overlay *ovl;
|
||||
|
||||
DSSDBG("writing mgr %d regs", mgr->id);
|
||||
DSSDBG("writing mgr %d regs\n", mgr->id);
|
||||
|
||||
if (!mp->enabled)
|
||||
return;
|
||||
|
@ -713,7 +716,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)
|
|||
{
|
||||
struct mgr_priv_data *mp = get_mgr_priv(mgr);
|
||||
|
||||
DSSDBG("writing mgr %d regs extra", mgr->id);
|
||||
DSSDBG("writing mgr %d regs extra\n", mgr->id);
|
||||
|
||||
if (!mp->extra_info_dirty)
|
||||
return;
|
||||
|
|
|
@ -90,6 +90,8 @@ struct dispc_features {
|
|||
|
||||
/* revert to the OMAP4 mechanism of DISPC Smart Standby operation */
|
||||
bool mstandby_workaround:1;
|
||||
|
||||
bool set_max_preload:1;
|
||||
};
|
||||
|
||||
#define DISPC_MAX_NR_FIFOS 5
|
||||
|
@ -1200,7 +1202,17 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
|
|||
dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),
|
||||
FLD_VAL(high, hi_start, hi_end) |
|
||||
FLD_VAL(low, lo_start, lo_end));
|
||||
|
||||
/*
|
||||
* configure the preload to the pipeline's high threhold, if HT it's too
|
||||
* large for the preload field, set the threshold to the maximum value
|
||||
* that can be held by the preload register
|
||||
*/
|
||||
if (dss_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload &&
|
||||
plane != OMAP_DSS_WB)
|
||||
dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));
|
||||
}
|
||||
EXPORT_SYMBOL(dispc_ovl_set_fifo_threshold);
|
||||
|
||||
void dispc_enable_fifomerge(bool enable)
|
||||
{
|
||||
|
@ -1259,6 +1271,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
|
|||
*fifo_high = total_fifo_size - buf_unit;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);
|
||||
|
||||
static void dispc_ovl_set_fir(enum omap_plane plane,
|
||||
int hinc, int vinc,
|
||||
|
@ -1988,7 +2001,8 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
|
|||
*/
|
||||
static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
|
||||
const struct omap_video_timings *t, u16 pos_x,
|
||||
u16 width, u16 height, u16 out_width, u16 out_height)
|
||||
u16 width, u16 height, u16 out_width, u16 out_height,
|
||||
bool five_taps)
|
||||
{
|
||||
const int ds = DIV_ROUND_UP(height, out_height);
|
||||
unsigned long nonactive;
|
||||
|
@ -2008,6 +2022,10 @@ static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,
|
|||
if (blank <= limits[i])
|
||||
return -EINVAL;
|
||||
|
||||
/* FIXME add checks for 3-tap filter once the limitations are known */
|
||||
if (!five_taps)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Pixel data should be prepared before visible display point starts.
|
||||
* So, atleast DS-2 lines must have already been fetched by DISPC
|
||||
|
@ -2183,22 +2201,30 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
|
|||
do {
|
||||
in_height = DIV_ROUND_UP(height, *decim_y);
|
||||
in_width = DIV_ROUND_UP(width, *decim_x);
|
||||
*core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
|
||||
in_width, in_height, out_width, out_height, color_mode);
|
||||
|
||||
error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
|
||||
pos_x, in_width, in_height, out_width,
|
||||
out_height);
|
||||
*five_taps = in_height > out_height;
|
||||
|
||||
if (in_width > maxsinglelinewidth)
|
||||
if (in_height > out_height &&
|
||||
in_height < out_height * 2)
|
||||
*five_taps = false;
|
||||
if (!*five_taps)
|
||||
again:
|
||||
if (*five_taps)
|
||||
*core_clk = calc_core_clk_five_taps(pclk, mgr_timings,
|
||||
in_width, in_height, out_width,
|
||||
out_height, color_mode);
|
||||
else
|
||||
*core_clk = dispc.feat->calc_core_clk(pclk, in_width,
|
||||
in_height, out_width, out_height,
|
||||
mem_to_mem);
|
||||
|
||||
error = check_horiz_timing_omap3(pclk, lclk, mgr_timings,
|
||||
pos_x, in_width, in_height, out_width,
|
||||
out_height, *five_taps);
|
||||
if (error && *five_taps) {
|
||||
*five_taps = false;
|
||||
goto again;
|
||||
}
|
||||
|
||||
error = (error || in_width > maxsinglelinewidth * 2 ||
|
||||
(in_width > maxsinglelinewidth && *five_taps) ||
|
||||
!*core_clk || *core_clk > dispc_core_clk_rate());
|
||||
|
@ -2215,7 +2241,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
|
|||
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
|
||||
|
||||
if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width,
|
||||
height, out_width, out_height)){
|
||||
height, out_width, out_height, *five_taps)) {
|
||||
DSSERR("horizontal timing too tight\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -3211,6 +3237,8 @@ static void dispc_dump_regs(struct seq_file *s)
|
|||
DUMPREG(DISPC_CONTROL3);
|
||||
DUMPREG(DISPC_CONFIG3);
|
||||
}
|
||||
if (dss_has_feature(FEAT_MFLAG))
|
||||
DUMPREG(DISPC_GLOBAL_MFLAG_ATTRIBUTE);
|
||||
|
||||
#undef DUMPREG
|
||||
|
||||
|
@ -3285,6 +3313,8 @@ static void dispc_dump_regs(struct seq_file *s)
|
|||
DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
|
||||
if (dss_has_feature(FEAT_PRELOAD))
|
||||
DUMPREG(i, DISPC_OVL_PRELOAD);
|
||||
if (dss_has_feature(FEAT_MFLAG))
|
||||
DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
|
||||
}
|
||||
|
||||
#undef DISPC_REG
|
||||
|
@ -3520,6 +3550,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_24xx,
|
||||
.num_fifos = 3,
|
||||
.no_framedone_tv = true,
|
||||
.set_max_preload = false,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
|
||||
|
@ -3539,6 +3570,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_34xx,
|
||||
.num_fifos = 3,
|
||||
.no_framedone_tv = true,
|
||||
.set_max_preload = false,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
|
||||
|
@ -3558,6 +3590,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_34xx,
|
||||
.num_fifos = 3,
|
||||
.no_framedone_tv = true,
|
||||
.set_max_preload = false,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap44xx_dispc_feats __initconst = {
|
||||
|
@ -3577,6 +3610,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
|
|||
.calc_core_clk = calc_core_clk_44xx,
|
||||
.num_fifos = 5,
|
||||
.gfx_fifo_workaround = true,
|
||||
.set_max_preload = true,
|
||||
};
|
||||
|
||||
static const struct dispc_features omap54xx_dispc_feats __initconst = {
|
||||
|
@ -3597,6 +3631,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
|
|||
.num_fifos = 5,
|
||||
.gfx_fifo_workaround = true,
|
||||
.mstandby_workaround = true,
|
||||
.set_max_preload = true,
|
||||
};
|
||||
|
||||
static int __init dispc_init_features(struct platform_device *pdev)
|
||||
|
@ -3734,6 +3769,8 @@ static int dispc_runtime_suspend(struct device *dev)
|
|||
|
||||
static int dispc_runtime_resume(struct device *dev)
|
||||
{
|
||||
_omap_dispc_initial_config();
|
||||
|
||||
dispc_restore_context();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define DISPC_CONTROL3 0x0848
|
||||
#define DISPC_CONFIG3 0x084C
|
||||
#define DISPC_MSTANDBY_CTRL 0x0858
|
||||
#define DISPC_GLOBAL_MFLAG_ATTRIBUTE 0x085C
|
||||
|
||||
/* DISPC overlay registers */
|
||||
#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
|
||||
|
@ -100,6 +101,8 @@
|
|||
DISPC_FIR_COEF_V2_OFFSET(n, i))
|
||||
#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_PRELOAD_OFFSET(n))
|
||||
#define DISPC_OVL_MFLAG_THRESHOLD(n) (DISPC_OVL_BASE(n) + \
|
||||
DISPC_MFLAG_THRESHOLD_OFFSET(n))
|
||||
|
||||
/* DISPC up/downsampling FIR filter coefficient structure */
|
||||
struct dispc_coef {
|
||||
|
@ -894,4 +897,21 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane plane)
|
||||
{
|
||||
switch (plane) {
|
||||
case OMAP_DSS_GFX:
|
||||
return 0x0860;
|
||||
case OMAP_DSS_VIDEO1:
|
||||
return 0x0864;
|
||||
case OMAP_DSS_VIDEO2:
|
||||
return 0x0868;
|
||||
case OMAP_DSS_VIDEO3:
|
||||
return 0x086c;
|
||||
default:
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -277,7 +277,7 @@ static ssize_t display_wss_store(struct device *dev,
|
|||
return size;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL);
|
||||
static DEVICE_ATTR(display_name, S_IRUGO, display_name_show, NULL);
|
||||
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
|
||||
display_enabled_show, display_enabled_store);
|
||||
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
|
||||
|
@ -292,7 +292,7 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
|
|||
display_wss_show, display_wss_store);
|
||||
|
||||
static const struct attribute *display_sysfs_attrs[] = {
|
||||
&dev_attr_name.attr,
|
||||
&dev_attr_display_name.attr,
|
||||
&dev_attr_enabled.attr,
|
||||
&dev_attr_tear_elim.attr,
|
||||
&dev_attr_timings.attr,
|
||||
|
|
|
@ -117,7 +117,7 @@ struct dpi_clk_calc_ctx {
|
|||
/* outputs */
|
||||
|
||||
struct dsi_clock_info dsi_cinfo;
|
||||
struct dss_clock_info dss_cinfo;
|
||||
unsigned long long fck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
};
|
||||
|
||||
|
@ -184,12 +184,11 @@ static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint,
|
|||
dpi_calc_hsdiv_cb, ctx);
|
||||
}
|
||||
|
||||
static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data)
|
||||
static bool dpi_calc_dss_cb(unsigned long fck, void *data)
|
||||
{
|
||||
struct dpi_clk_calc_ctx *ctx = data;
|
||||
|
||||
ctx->dss_cinfo.fck = fck;
|
||||
ctx->dss_cinfo.fck_div = fckd;
|
||||
ctx->fck = fck;
|
||||
|
||||
return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
|
||||
dpi_calc_dispc_cb, ctx);
|
||||
|
@ -237,7 +236,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
|
|||
ctx->pck_min = 0;
|
||||
ctx->pck_max = pck + 1000 * i * i * i;
|
||||
|
||||
ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx);
|
||||
ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx);
|
||||
if (ok)
|
||||
return ok;
|
||||
}
|
||||
|
@ -286,13 +285,13 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
|
|||
if (!ok)
|
||||
return -EINVAL;
|
||||
|
||||
r = dss_set_clock_div(&ctx.dss_cinfo);
|
||||
r = dss_set_fck_rate(ctx.fck);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dpi.mgr_config.clock_info = ctx.dispc_cinfo;
|
||||
|
||||
*fck = ctx.dss_cinfo.fck;
|
||||
*fck = ctx.fck;
|
||||
*lck_div = ctx.dispc_cinfo.lck_div;
|
||||
*pck_div = ctx.dispc_cinfo.pck_div;
|
||||
|
||||
|
@ -495,7 +494,7 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
|
|||
if (!ok)
|
||||
return -EINVAL;
|
||||
|
||||
fck = ctx.dss_cinfo.fck;
|
||||
fck = ctx.fck;
|
||||
}
|
||||
|
||||
lck_div = ctx.dispc_cinfo.lck_div;
|
||||
|
@ -551,7 +550,8 @@ static int dpi_init_regulator(void)
|
|||
|
||||
vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi");
|
||||
if (IS_ERR(vdds_dsi)) {
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
return PTR_ERR(vdds_dsi);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,63 +47,73 @@
|
|||
|
||||
#define DSI_CATCH_MISSING_TE
|
||||
|
||||
struct dsi_reg { u16 idx; };
|
||||
struct dsi_reg { u16 module; u16 idx; };
|
||||
|
||||
#define DSI_REG(idx) ((const struct dsi_reg) { idx })
|
||||
#define DSI_REG(mod, idx) ((const struct dsi_reg) { mod, idx })
|
||||
|
||||
#define DSI_SZ_REGS SZ_1K
|
||||
/* DSI Protocol Engine */
|
||||
|
||||
#define DSI_REVISION DSI_REG(0x0000)
|
||||
#define DSI_SYSCONFIG DSI_REG(0x0010)
|
||||
#define DSI_SYSSTATUS DSI_REG(0x0014)
|
||||
#define DSI_IRQSTATUS DSI_REG(0x0018)
|
||||
#define DSI_IRQENABLE DSI_REG(0x001C)
|
||||
#define DSI_CTRL DSI_REG(0x0040)
|
||||
#define DSI_GNQ DSI_REG(0x0044)
|
||||
#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048)
|
||||
#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C)
|
||||
#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050)
|
||||
#define DSI_CLK_CTRL DSI_REG(0x0054)
|
||||
#define DSI_TIMING1 DSI_REG(0x0058)
|
||||
#define DSI_TIMING2 DSI_REG(0x005C)
|
||||
#define DSI_VM_TIMING1 DSI_REG(0x0060)
|
||||
#define DSI_VM_TIMING2 DSI_REG(0x0064)
|
||||
#define DSI_VM_TIMING3 DSI_REG(0x0068)
|
||||
#define DSI_CLK_TIMING DSI_REG(0x006C)
|
||||
#define DSI_TX_FIFO_VC_SIZE DSI_REG(0x0070)
|
||||
#define DSI_RX_FIFO_VC_SIZE DSI_REG(0x0074)
|
||||
#define DSI_COMPLEXIO_CFG2 DSI_REG(0x0078)
|
||||
#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(0x007C)
|
||||
#define DSI_VM_TIMING4 DSI_REG(0x0080)
|
||||
#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(0x0084)
|
||||
#define DSI_VM_TIMING5 DSI_REG(0x0088)
|
||||
#define DSI_VM_TIMING6 DSI_REG(0x008C)
|
||||
#define DSI_VM_TIMING7 DSI_REG(0x0090)
|
||||
#define DSI_STOPCLK_TIMING DSI_REG(0x0094)
|
||||
#define DSI_VC_CTRL(n) DSI_REG(0x0100 + (n * 0x20))
|
||||
#define DSI_VC_TE(n) DSI_REG(0x0104 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(0x0108 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(0x010C + (n * 0x20))
|
||||
#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(0x0110 + (n * 0x20))
|
||||
#define DSI_VC_IRQSTATUS(n) DSI_REG(0x0118 + (n * 0x20))
|
||||
#define DSI_VC_IRQENABLE(n) DSI_REG(0x011C + (n * 0x20))
|
||||
#define DSI_PROTO 0
|
||||
#define DSI_PROTO_SZ 0x200
|
||||
|
||||
#define DSI_REVISION DSI_REG(DSI_PROTO, 0x0000)
|
||||
#define DSI_SYSCONFIG DSI_REG(DSI_PROTO, 0x0010)
|
||||
#define DSI_SYSSTATUS DSI_REG(DSI_PROTO, 0x0014)
|
||||
#define DSI_IRQSTATUS DSI_REG(DSI_PROTO, 0x0018)
|
||||
#define DSI_IRQENABLE DSI_REG(DSI_PROTO, 0x001C)
|
||||
#define DSI_CTRL DSI_REG(DSI_PROTO, 0x0040)
|
||||
#define DSI_GNQ DSI_REG(DSI_PROTO, 0x0044)
|
||||
#define DSI_COMPLEXIO_CFG1 DSI_REG(DSI_PROTO, 0x0048)
|
||||
#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(DSI_PROTO, 0x004C)
|
||||
#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(DSI_PROTO, 0x0050)
|
||||
#define DSI_CLK_CTRL DSI_REG(DSI_PROTO, 0x0054)
|
||||
#define DSI_TIMING1 DSI_REG(DSI_PROTO, 0x0058)
|
||||
#define DSI_TIMING2 DSI_REG(DSI_PROTO, 0x005C)
|
||||
#define DSI_VM_TIMING1 DSI_REG(DSI_PROTO, 0x0060)
|
||||
#define DSI_VM_TIMING2 DSI_REG(DSI_PROTO, 0x0064)
|
||||
#define DSI_VM_TIMING3 DSI_REG(DSI_PROTO, 0x0068)
|
||||
#define DSI_CLK_TIMING DSI_REG(DSI_PROTO, 0x006C)
|
||||
#define DSI_TX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0070)
|
||||
#define DSI_RX_FIFO_VC_SIZE DSI_REG(DSI_PROTO, 0x0074)
|
||||
#define DSI_COMPLEXIO_CFG2 DSI_REG(DSI_PROTO, 0x0078)
|
||||
#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(DSI_PROTO, 0x007C)
|
||||
#define DSI_VM_TIMING4 DSI_REG(DSI_PROTO, 0x0080)
|
||||
#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(DSI_PROTO, 0x0084)
|
||||
#define DSI_VM_TIMING5 DSI_REG(DSI_PROTO, 0x0088)
|
||||
#define DSI_VM_TIMING6 DSI_REG(DSI_PROTO, 0x008C)
|
||||
#define DSI_VM_TIMING7 DSI_REG(DSI_PROTO, 0x0090)
|
||||
#define DSI_STOPCLK_TIMING DSI_REG(DSI_PROTO, 0x0094)
|
||||
#define DSI_VC_CTRL(n) DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
|
||||
#define DSI_VC_TE(n) DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
|
||||
#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
|
||||
#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
|
||||
#define DSI_VC_IRQSTATUS(n) DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
|
||||
#define DSI_VC_IRQENABLE(n) DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
|
||||
|
||||
/* DSIPHY_SCP */
|
||||
|
||||
#define DSI_DSIPHY_CFG0 DSI_REG(0x200 + 0x0000)
|
||||
#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004)
|
||||
#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008)
|
||||
#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014)
|
||||
#define DSI_DSIPHY_CFG10 DSI_REG(0x200 + 0x0028)
|
||||
#define DSI_PHY 1
|
||||
#define DSI_PHY_OFFSET 0x200
|
||||
#define DSI_PHY_SZ 0x40
|
||||
|
||||
#define DSI_DSIPHY_CFG0 DSI_REG(DSI_PHY, 0x0000)
|
||||
#define DSI_DSIPHY_CFG1 DSI_REG(DSI_PHY, 0x0004)
|
||||
#define DSI_DSIPHY_CFG2 DSI_REG(DSI_PHY, 0x0008)
|
||||
#define DSI_DSIPHY_CFG5 DSI_REG(DSI_PHY, 0x0014)
|
||||
#define DSI_DSIPHY_CFG10 DSI_REG(DSI_PHY, 0x0028)
|
||||
|
||||
/* DSI_PLL_CTRL_SCP */
|
||||
|
||||
#define DSI_PLL_CONTROL DSI_REG(0x300 + 0x0000)
|
||||
#define DSI_PLL_STATUS DSI_REG(0x300 + 0x0004)
|
||||
#define DSI_PLL_GO DSI_REG(0x300 + 0x0008)
|
||||
#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C)
|
||||
#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010)
|
||||
#define DSI_PLL 2
|
||||
#define DSI_PLL_OFFSET 0x300
|
||||
#define DSI_PLL_SZ 0x20
|
||||
|
||||
#define DSI_PLL_CONTROL DSI_REG(DSI_PLL, 0x0000)
|
||||
#define DSI_PLL_STATUS DSI_REG(DSI_PLL, 0x0004)
|
||||
#define DSI_PLL_GO DSI_REG(DSI_PLL, 0x0008)
|
||||
#define DSI_PLL_CONFIGURATION1 DSI_REG(DSI_PLL, 0x000C)
|
||||
#define DSI_PLL_CONFIGURATION2 DSI_REG(DSI_PLL, 0x0010)
|
||||
|
||||
#define REG_GET(dsidev, idx, start, end) \
|
||||
FLD_GET(dsi_read_reg(dsidev, idx), start, end)
|
||||
|
@ -277,7 +287,9 @@ struct dsi_clk_calc_ctx {
|
|||
|
||||
struct dsi_data {
|
||||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
void __iomem *proto_base;
|
||||
void __iomem *phy_base;
|
||||
void __iomem *pll_base;
|
||||
|
||||
int module_id;
|
||||
|
||||
|
@ -297,7 +309,8 @@ struct dsi_data {
|
|||
struct {
|
||||
enum dsi_vc_source source;
|
||||
struct omap_dss_device *dssdev;
|
||||
enum fifo_size fifo_size;
|
||||
enum fifo_size tx_fifo_size;
|
||||
enum fifo_size rx_fifo_size;
|
||||
int vc_id;
|
||||
} vc[4];
|
||||
|
||||
|
@ -413,16 +426,32 @@ static inline void dsi_write_reg(struct platform_device *dsidev,
|
|||
const struct dsi_reg idx, u32 val)
|
||||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
void __iomem *base;
|
||||
|
||||
__raw_writel(val, dsi->base + idx.idx);
|
||||
switch(idx.module) {
|
||||
case DSI_PROTO: base = dsi->proto_base; break;
|
||||
case DSI_PHY: base = dsi->phy_base; break;
|
||||
case DSI_PLL: base = dsi->pll_base; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
__raw_writel(val, base + idx.idx);
|
||||
}
|
||||
|
||||
static inline u32 dsi_read_reg(struct platform_device *dsidev,
|
||||
const struct dsi_reg idx)
|
||||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
void __iomem *base;
|
||||
|
||||
return __raw_readl(dsi->base + idx.idx);
|
||||
switch(idx.module) {
|
||||
case DSI_PROTO: base = dsi->proto_base; break;
|
||||
case DSI_PHY: base = dsi->phy_base; break;
|
||||
case DSI_PLL: base = dsi->pll_base; break;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
return __raw_readl(base + idx.idx);
|
||||
}
|
||||
|
||||
static void dsi_bus_lock(struct omap_dss_device *dssdev)
|
||||
|
@ -1129,7 +1158,8 @@ static int dsi_regulator_init(struct platform_device *dsidev)
|
|||
vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO");
|
||||
|
||||
if (IS_ERR(vdds_dsi)) {
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDS_DSI regulator\n");
|
||||
return PTR_ERR(vdds_dsi);
|
||||
}
|
||||
|
||||
|
@ -2427,14 +2457,14 @@ static void dsi_config_tx_fifo(struct platform_device *dsidev,
|
|||
int add = 0;
|
||||
int i;
|
||||
|
||||
dsi->vc[0].fifo_size = size1;
|
||||
dsi->vc[1].fifo_size = size2;
|
||||
dsi->vc[2].fifo_size = size3;
|
||||
dsi->vc[3].fifo_size = size4;
|
||||
dsi->vc[0].tx_fifo_size = size1;
|
||||
dsi->vc[1].tx_fifo_size = size2;
|
||||
dsi->vc[2].tx_fifo_size = size3;
|
||||
dsi->vc[3].tx_fifo_size = size4;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
u8 v;
|
||||
int size = dsi->vc[i].fifo_size;
|
||||
int size = dsi->vc[i].tx_fifo_size;
|
||||
|
||||
if (add + size > 4) {
|
||||
DSSERR("Illegal FIFO configuration\n");
|
||||
|
@ -2460,14 +2490,14 @@ static void dsi_config_rx_fifo(struct platform_device *dsidev,
|
|||
int add = 0;
|
||||
int i;
|
||||
|
||||
dsi->vc[0].fifo_size = size1;
|
||||
dsi->vc[1].fifo_size = size2;
|
||||
dsi->vc[2].fifo_size = size3;
|
||||
dsi->vc[3].fifo_size = size4;
|
||||
dsi->vc[0].rx_fifo_size = size1;
|
||||
dsi->vc[1].rx_fifo_size = size2;
|
||||
dsi->vc[2].rx_fifo_size = size3;
|
||||
dsi->vc[3].rx_fifo_size = size4;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
u8 v;
|
||||
int size = dsi->vc[i].fifo_size;
|
||||
int size = dsi->vc[i].rx_fifo_size;
|
||||
|
||||
if (add + size > 4) {
|
||||
DSSERR("Illegal FIFO configuration\n");
|
||||
|
@ -2920,7 +2950,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,
|
|||
DSSDBG("dsi_vc_send_long, %d bytes\n", len);
|
||||
|
||||
/* len + header */
|
||||
if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) {
|
||||
if (dsi->vc[channel].tx_fifo_size * 32 * 4 < len + 4) {
|
||||
DSSERR("unable to send long packet: packet too long.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -5345,8 +5375,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
|
|||
{
|
||||
u32 rev;
|
||||
int r, i;
|
||||
struct resource *dsi_mem;
|
||||
struct dsi_data *dsi;
|
||||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
|
||||
if (!dsi)
|
||||
|
@ -5376,16 +5407,64 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
|
|||
dsi->te_timer.function = dsi_te_timeout;
|
||||
dsi->te_timer.data = 0;
|
||||
#endif
|
||||
dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
|
||||
if (!dsi_mem) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto");
|
||||
if (!res) {
|
||||
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start;
|
||||
temp_res.end = temp_res.start + DSI_PROTO_SZ - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start,
|
||||
resource_size(dsi_mem));
|
||||
if (!dsi->base) {
|
||||
DSSERR("can't ioremap DSI\n");
|
||||
dsi->proto_base = devm_ioremap(&dsidev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!dsi->proto_base) {
|
||||
DSSERR("can't ioremap DSI protocol engine\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "phy");
|
||||
if (!res) {
|
||||
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start + DSI_PHY_OFFSET;
|
||||
temp_res.end = temp_res.start + DSI_PHY_SZ - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
dsi->phy_base = devm_ioremap(&dsidev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!dsi->proto_base) {
|
||||
DSSERR("can't ioremap DSI PHY\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "pll");
|
||||
if (!res) {
|
||||
res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
DSSERR("can't get IORESOURCE_MEM DSI\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
temp_res.start = res->start + DSI_PLL_OFFSET;
|
||||
temp_res.end = temp_res.start + DSI_PLL_SZ - 1;
|
||||
res = &temp_res;
|
||||
}
|
||||
|
||||
dsi->pll_base = devm_ioremap(&dsidev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!dsi->proto_base) {
|
||||
DSSERR("can't ioremap DSI PLL\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ static void dss_runtime_put(void);
|
|||
struct dss_features {
|
||||
u8 fck_div_max;
|
||||
u8 dss_fck_multiplier;
|
||||
const char *clk_name;
|
||||
const char *parent_clk_name;
|
||||
int (*dpi_select_source)(enum omap_channel channel);
|
||||
};
|
||||
|
||||
|
@ -75,13 +75,12 @@ static struct {
|
|||
struct platform_device *pdev;
|
||||
void __iomem *base;
|
||||
|
||||
struct clk *dpll4_m4_ck;
|
||||
struct clk *parent_clk;
|
||||
struct clk *dss_clk;
|
||||
unsigned long dss_clk_rate;
|
||||
|
||||
unsigned long cache_req_pck;
|
||||
unsigned long cache_prate;
|
||||
struct dss_clock_info cache_dss_cinfo;
|
||||
struct dispc_clock_info cache_dispc_cinfo;
|
||||
|
||||
enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI];
|
||||
|
@ -265,8 +264,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)
|
|||
|
||||
void dss_dump_clocks(struct seq_file *s)
|
||||
{
|
||||
unsigned long dpll4_ck_rate;
|
||||
unsigned long dpll4_m4_ck_rate;
|
||||
const char *fclk_name, *fclk_real_name;
|
||||
unsigned long fclk_rate;
|
||||
|
||||
|
@ -279,21 +276,9 @@ void dss_dump_clocks(struct seq_file *s)
|
|||
fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);
|
||||
fclk_rate = clk_get_rate(dss.dss_clk);
|
||||
|
||||
if (dss.dpll4_m4_ck) {
|
||||
dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
|
||||
|
||||
seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
|
||||
|
||||
seq_printf(s, "%s (%s) = %lu / %lu * %d = %lu\n",
|
||||
fclk_name, fclk_real_name, dpll4_ck_rate,
|
||||
dpll4_ck_rate / dpll4_m4_ck_rate,
|
||||
dss.feat->dss_fck_multiplier, fclk_rate);
|
||||
} else {
|
||||
seq_printf(s, "%s (%s) = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
fclk_rate);
|
||||
}
|
||||
seq_printf(s, "%s (%s) = %lu\n",
|
||||
fclk_name, fclk_real_name,
|
||||
fclk_rate);
|
||||
|
||||
dss_runtime_put();
|
||||
}
|
||||
|
@ -451,30 +436,8 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)
|
|||
}
|
||||
}
|
||||
|
||||
/* calculate clock rates using dividers in cinfo */
|
||||
int dss_calc_clock_rates(struct dss_clock_info *cinfo)
|
||||
{
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
|
||||
if (cinfo->fck_div > dss.feat->fck_div_max ||
|
||||
cinfo->fck_div == 0)
|
||||
return -EINVAL;
|
||||
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
|
||||
cinfo->fck = prate / cinfo->fck_div *
|
||||
dss.feat->dss_fck_multiplier;
|
||||
} else {
|
||||
if (cinfo->fck_div != 0)
|
||||
return -EINVAL;
|
||||
cinfo->fck = clk_get_rate(dss.dss_clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
|
||||
bool dss_div_calc(unsigned long pck, unsigned long fck_min,
|
||||
dss_div_calc_func func, void *data)
|
||||
{
|
||||
int fckd, fckd_start, fckd_stop;
|
||||
unsigned long fck;
|
||||
|
@ -483,22 +446,24 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
|
|||
unsigned long prate;
|
||||
unsigned m;
|
||||
|
||||
if (dss.dpll4_m4_ck == NULL) {
|
||||
/*
|
||||
* TODO: dss1_fclk can be changed on OMAP2, but the available
|
||||
* dividers are not continuous. We just use the pre-set rate for
|
||||
* now.
|
||||
*/
|
||||
fck = clk_get_rate(dss.dss_clk);
|
||||
fckd = 1;
|
||||
return func(fckd, fck, data);
|
||||
fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
|
||||
if (dss.parent_clk == NULL) {
|
||||
unsigned pckd;
|
||||
|
||||
pckd = fck_hw_max / pck;
|
||||
|
||||
fck = pck * pckd;
|
||||
|
||||
fck = clk_round_rate(dss.dss_clk, fck);
|
||||
|
||||
return func(fck, data);
|
||||
}
|
||||
|
||||
fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
fckd_hw_max = dss.feat->fck_div_max;
|
||||
|
||||
m = dss.feat->dss_fck_multiplier;
|
||||
prate = dss_get_dpll4_rate();
|
||||
prate = clk_get_rate(dss.parent_clk);
|
||||
|
||||
fck_min = fck_min ? fck_min : 1;
|
||||
|
||||
|
@ -508,50 +473,32 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
|
|||
for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
|
||||
fck = prate / fckd * m;
|
||||
|
||||
if (func(fckd, fck, data))
|
||||
if (func(fck, data))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int dss_set_clock_div(struct dss_clock_info *cinfo)
|
||||
int dss_set_fck_rate(unsigned long rate)
|
||||
{
|
||||
if (dss.dpll4_m4_ck) {
|
||||
unsigned long prate;
|
||||
int r;
|
||||
int r;
|
||||
|
||||
prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
DSSDBG("dpll4_m4 = %ld\n", prate);
|
||||
DSSDBG("set fck to %lu\n", rate);
|
||||
|
||||
r = clk_set_rate(dss.dpll4_m4_ck,
|
||||
DIV_ROUND_UP(prate, cinfo->fck_div));
|
||||
if (r)
|
||||
return r;
|
||||
} else {
|
||||
if (cinfo->fck_div != 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
r = clk_set_rate(dss.dss_clk, rate);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
|
||||
|
||||
WARN_ONCE(dss.dss_clk_rate != cinfo->fck,
|
||||
WARN_ONCE(dss.dss_clk_rate != rate,
|
||||
"clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
|
||||
cinfo->fck);
|
||||
|
||||
DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
|
||||
rate);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long dss_get_dpll4_rate(void)
|
||||
{
|
||||
if (dss.dpll4_m4_ck)
|
||||
return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long dss_get_dispc_clk_rate(void)
|
||||
{
|
||||
return dss.dss_clk_rate;
|
||||
|
@ -560,27 +507,23 @@ unsigned long dss_get_dispc_clk_rate(void)
|
|||
static int dss_setup_default_clock(void)
|
||||
{
|
||||
unsigned long max_dss_fck, prate;
|
||||
unsigned long fck;
|
||||
unsigned fck_div;
|
||||
struct dss_clock_info dss_cinfo = { 0 };
|
||||
int r;
|
||||
|
||||
if (dss.dpll4_m4_ck == NULL)
|
||||
return 0;
|
||||
|
||||
max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
|
||||
|
||||
prate = dss_get_dpll4_rate();
|
||||
if (dss.parent_clk == NULL) {
|
||||
fck = clk_round_rate(dss.dss_clk, max_dss_fck);
|
||||
} else {
|
||||
prate = clk_get_rate(dss.parent_clk);
|
||||
|
||||
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
|
||||
max_dss_fck);
|
||||
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
|
||||
max_dss_fck);
|
||||
fck = prate / fck_div * dss.feat->dss_fck_multiplier;
|
||||
}
|
||||
|
||||
dss_cinfo.fck_div = fck_div;
|
||||
|
||||
r = dss_calc_clock_rates(&dss_cinfo);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = dss_set_clock_div(&dss_cinfo);
|
||||
r = dss_set_fck_rate(fck);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -706,25 +649,25 @@ static int dss_get_clocks(void)
|
|||
|
||||
dss.dss_clk = clk;
|
||||
|
||||
if (dss.feat->clk_name) {
|
||||
clk = clk_get(NULL, dss.feat->clk_name);
|
||||
if (dss.feat->parent_clk_name) {
|
||||
clk = clk_get(NULL, dss.feat->parent_clk_name);
|
||||
if (IS_ERR(clk)) {
|
||||
DSSERR("Failed to get %s\n", dss.feat->clk_name);
|
||||
DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);
|
||||
return PTR_ERR(clk);
|
||||
}
|
||||
} else {
|
||||
clk = NULL;
|
||||
}
|
||||
|
||||
dss.dpll4_m4_ck = clk;
|
||||
dss.parent_clk = clk;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dss_put_clocks(void)
|
||||
{
|
||||
if (dss.dpll4_m4_ck)
|
||||
clk_put(dss.dpll4_m4_ck);
|
||||
if (dss.parent_clk)
|
||||
clk_put(dss.parent_clk);
|
||||
}
|
||||
|
||||
static int dss_runtime_get(void)
|
||||
|
@ -761,37 +704,41 @@ void dss_debug_dump_clocks(struct seq_file *s)
|
|||
#endif
|
||||
|
||||
static const struct dss_features omap24xx_dss_feats __initconst = {
|
||||
.fck_div_max = 16,
|
||||
/*
|
||||
* fck div max is really 16, but the divider range has gaps. The range
|
||||
* from 1 to 6 has no gaps, so let's use that as a max.
|
||||
*/
|
||||
.fck_div_max = 6,
|
||||
.dss_fck_multiplier = 2,
|
||||
.clk_name = NULL,
|
||||
.parent_clk_name = "core_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap34xx_dss_feats __initconst = {
|
||||
.fck_div_max = 16,
|
||||
.dss_fck_multiplier = 2,
|
||||
.clk_name = "dpll4_m4_ck",
|
||||
.parent_clk_name = "dpll4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap3630_dss_feats __initconst = {
|
||||
.fck_div_max = 32,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll4_m4_ck",
|
||||
.parent_clk_name = "dpll4_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap2_omap3,
|
||||
};
|
||||
|
||||
static const struct dss_features omap44xx_dss_feats __initconst = {
|
||||
.fck_div_max = 32,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll_per_m5x2_ck",
|
||||
.parent_clk_name = "dpll_per_x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap4,
|
||||
};
|
||||
|
||||
static const struct dss_features omap54xx_dss_feats __initconst = {
|
||||
.fck_div_max = 64,
|
||||
.dss_fck_multiplier = 1,
|
||||
.clk_name = "dpll_per_h12x2_ck",
|
||||
.parent_clk_name = "dpll_per_x2_ck",
|
||||
.dpi_select_source = &dss_dpi_select_source_omap5,
|
||||
};
|
||||
|
||||
|
|
|
@ -100,14 +100,6 @@ enum dss_writeback_channel {
|
|||
DSS_WB_LCD3_MGR = 7,
|
||||
};
|
||||
|
||||
struct dss_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long fck;
|
||||
|
||||
/* dividers */
|
||||
u16 fck_div;
|
||||
};
|
||||
|
||||
struct dispc_clock_info {
|
||||
/* rates that we get with dividers below */
|
||||
unsigned long lck;
|
||||
|
@ -250,12 +242,11 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);
|
|||
void dss_set_venc_output(enum omap_dss_venc_type type);
|
||||
void dss_set_dac_pwrdn_bgz(bool enable);
|
||||
|
||||
unsigned long dss_get_dpll4_rate(void);
|
||||
int dss_calc_clock_rates(struct dss_clock_info *cinfo);
|
||||
int dss_set_clock_div(struct dss_clock_info *cinfo);
|
||||
int dss_set_fck_rate(unsigned long rate);
|
||||
|
||||
typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data);
|
||||
bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data);
|
||||
typedef bool (*dss_div_calc_func)(unsigned long fck, void *data);
|
||||
bool dss_div_calc(unsigned long pck, unsigned long fck_min,
|
||||
dss_div_calc_func func, void *data);
|
||||
|
||||
/* SDI */
|
||||
int sdi_init_platform_driver(void) __init;
|
||||
|
|
|
@ -613,6 +613,7 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
|
|||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
FEAT_MFLAG,
|
||||
};
|
||||
|
||||
/* OMAP2 DSS Features */
|
||||
|
|
|
@ -64,6 +64,7 @@ enum dss_feat_id {
|
|||
FEAT_DSI_PLL_SELFREQDCO,
|
||||
FEAT_DSI_PLL_REFSEL,
|
||||
FEAT_DSI_PHY_DCC,
|
||||
FEAT_MFLAG,
|
||||
};
|
||||
|
||||
/* DSS register field id */
|
||||
|
|
|
@ -41,14 +41,14 @@
|
|||
#define HDMI_WP_VIDEO_SIZE 0x60
|
||||
#define HDMI_WP_VIDEO_TIMING_H 0x68
|
||||
#define HDMI_WP_VIDEO_TIMING_V 0x6C
|
||||
#define HDMI_WP_WP_CLK 0x70
|
||||
#define HDMI_WP_CLK 0x70
|
||||
#define HDMI_WP_AUDIO_CFG 0x80
|
||||
#define HDMI_WP_AUDIO_CFG2 0x84
|
||||
#define HDMI_WP_AUDIO_CTRL 0x88
|
||||
#define HDMI_WP_AUDIO_DATA 0x8C
|
||||
|
||||
/* HDMI WP IRQ flags */
|
||||
|
||||
#define HDMI_IRQ_CORE (1 << 0)
|
||||
#define HDMI_IRQ_OCP_TIMEOUT (1 << 4)
|
||||
#define HDMI_IRQ_AUDIO_FIFO_UNDERFLOW (1 << 8)
|
||||
#define HDMI_IRQ_AUDIO_FIFO_OVERFLOW (1 << 9)
|
||||
|
@ -378,15 +378,15 @@ static inline u32 hdmi_read_reg(void __iomem *base_addr, const u16 idx)
|
|||
FLD_GET(hdmi_read_reg(base, idx), start, end)
|
||||
|
||||
static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
|
||||
const u16 idx, int b2, int b1, u32 val)
|
||||
const u32 idx, int b2, int b1, u32 val)
|
||||
{
|
||||
u32 t = 0;
|
||||
while (val != REG_GET(base_addr, idx, b2, b1)) {
|
||||
udelay(1);
|
||||
u32 t = 0, v;
|
||||
while (val != (v = REG_GET(base_addr, idx, b2, b1))) {
|
||||
if (t++ > 10000)
|
||||
return !val;
|
||||
return v;
|
||||
udelay(1);
|
||||
}
|
||||
return val;
|
||||
return v;
|
||||
}
|
||||
|
||||
/* HDMI wrapper funcs */
|
||||
|
|
|
@ -95,7 +95,8 @@ static int hdmi_init_regulator(void)
|
|||
reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC");
|
||||
|
||||
if (IS_ERR(reg)) {
|
||||
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
|
||||
if (PTR_ERR(reg) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDA_HDMI_DAC regulator\n");
|
||||
return PTR_ERR(reg);
|
||||
}
|
||||
|
||||
|
@ -148,8 +149,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
dss_mgr_disable(mgr);
|
||||
|
||||
p = &hdmi.cfg.timings;
|
||||
|
||||
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
|
||||
|
@ -158,8 +157,6 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
|
|||
|
||||
hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
|
||||
|
||||
hdmi_wp_video_stop(&hdmi.wp);
|
||||
|
||||
/* config the PLL and PHY hdmi_set_pll_pwrfirst */
|
||||
r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
|
||||
if (r) {
|
||||
|
@ -218,14 +215,12 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
|
|||
static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct hdmi_cm cm;
|
||||
struct omap_dss_device *out = &hdmi.output;
|
||||
|
||||
cm = hdmi_get_code(timings);
|
||||
if (cm.code == -1)
|
||||
if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
|
@ -244,8 +239,17 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
|||
hdmi.cfg = *t;
|
||||
|
||||
dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
|
||||
} else {
|
||||
hdmi.cfg.timings = *timings;
|
||||
hdmi.cfg.cm.code = 0;
|
||||
hdmi.cfg.cm.mode = HDMI_DVI;
|
||||
|
||||
dispc_set_tv_pclk(timings->pixel_clock * 1000);
|
||||
}
|
||||
|
||||
DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
|
||||
"DVI" : "HDMI", hdmi.cfg.cm.code);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMICORE"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -125,12 +127,12 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
|
|||
|
||||
/* HDMI_CORE_DDC_STATUS_BUS_LOW */
|
||||
if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
|
||||
pr_err("I2C Bus Low?\n");
|
||||
DSSERR("I2C Bus Low?\n");
|
||||
return -EIO;
|
||||
}
|
||||
/* HDMI_CORE_DDC_STATUS_NO_ACK */
|
||||
if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
|
||||
pr_err("I2C No Ack\n");
|
||||
DSSERR("I2C No Ack\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -161,7 +163,7 @@ static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
|
|||
checksum += pedid[i];
|
||||
|
||||
if (checksum != 0) {
|
||||
pr_err("E-EDID checksum failed!!\n");
|
||||
DSSERR("E-EDID checksum failed!!\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -199,7 +201,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
|
|||
struct hdmi_core_infoframe_avi *avi_cfg,
|
||||
struct hdmi_core_packet_enable_repeat *repeat_cfg)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_init\n");
|
||||
DSSDBG("Enter hdmi_core_init\n");
|
||||
|
||||
/* video core */
|
||||
video_cfg->ip_bus_width = HDMI_INPUT_8BIT;
|
||||
|
@ -241,19 +243,19 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
|
|||
|
||||
static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_powerdown_disable\n");
|
||||
DSSDBG("Enter hdmi_core_powerdown_disable\n");
|
||||
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0);
|
||||
}
|
||||
|
||||
static void hdmi_core_swreset_release(struct hdmi_core_data *core)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_swreset_release\n");
|
||||
DSSDBG("Enter hdmi_core_swreset_release\n");
|
||||
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0);
|
||||
}
|
||||
|
||||
static void hdmi_core_swreset_assert(struct hdmi_core_data *core)
|
||||
{
|
||||
pr_debug("Enter hdmi_core_swreset_assert\n");
|
||||
DSSDBG("Enter hdmi_core_swreset_assert\n");
|
||||
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0);
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1006,7 @@ int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_core");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core");
|
||||
if (!res) {
|
||||
DSSDBG("can't get CORE mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
* map it to corresponding CEA or VESA index.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMI"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <video/omapdss.h>
|
||||
|
|
|
@ -124,7 +124,7 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_txphy");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
|
||||
if (!res) {
|
||||
DSSDBG("can't get PHY mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMIPLL"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -127,24 +129,24 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
|
|||
/* wait for bit change */
|
||||
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO,
|
||||
0, 0, 1) != 1) {
|
||||
pr_err("PLL GO bit not set\n");
|
||||
DSSERR("PLL GO bit not set\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Wait till the lock bit is set in PLL status */
|
||||
if (hdmi_wait_for_bit_change(pll->base,
|
||||
PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
|
||||
pr_err("cannot lock PLL\n");
|
||||
pr_err("CFG1 0x%x\n",
|
||||
DSSERR("cannot lock PLL\n");
|
||||
DSSERR("CFG1 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG1));
|
||||
pr_err("CFG2 0x%x\n",
|
||||
DSSERR("CFG2 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG2));
|
||||
pr_err("CFG4 0x%x\n",
|
||||
DSSERR("CFG4 0x%x\n",
|
||||
hdmi_read_reg(pll->base, PLLCTRL_CFG4));
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
pr_debug("PLL locked!\n");
|
||||
DSSDBG("PLL locked!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -157,7 +159,7 @@ static int hdmi_pll_reset(struct hdmi_pll_data *pll)
|
|||
/* READ 0x0 reset is in progress */
|
||||
if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
|
||||
!= 1) {
|
||||
pr_err("Failed to sysreset PLL\n");
|
||||
DSSERR("Failed to sysreset PLL\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -200,7 +202,7 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_pllctrl");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
|
||||
if (!res) {
|
||||
DSSDBG("can't get PLL mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMIWP"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -34,7 +36,7 @@ void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s)
|
|||
DUMPREG(HDMI_WP_VIDEO_SIZE);
|
||||
DUMPREG(HDMI_WP_VIDEO_TIMING_H);
|
||||
DUMPREG(HDMI_WP_VIDEO_TIMING_V);
|
||||
DUMPREG(HDMI_WP_WP_CLK);
|
||||
DUMPREG(HDMI_WP_CLK);
|
||||
DUMPREG(HDMI_WP_AUDIO_CFG);
|
||||
DUMPREG(HDMI_WP_AUDIO_CFG2);
|
||||
DUMPREG(HDMI_WP_AUDIO_CTRL);
|
||||
|
@ -76,7 +78,7 @@ int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val)
|
|||
/* Status of the power control of HDMI PHY */
|
||||
if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val)
|
||||
!= val) {
|
||||
pr_err("Failed to set PHY power mode to %d\n", val);
|
||||
DSSERR("Failed to set PHY power mode to %d\n", val);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -92,7 +94,7 @@ int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val)
|
|||
/* wait till PHY_PWR_STATUS is set */
|
||||
if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val)
|
||||
!= val) {
|
||||
pr_err("Failed to set PLL_PWR_STATUS\n");
|
||||
DSSERR("Failed to set PLL_PWR_STATUS\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
|
@ -129,7 +131,7 @@ void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
|
|||
{
|
||||
u32 r;
|
||||
bool vsync_pol, hsync_pol;
|
||||
pr_debug("Enter hdmi_wp_video_config_interface\n");
|
||||
DSSDBG("Enter hdmi_wp_video_config_interface\n");
|
||||
|
||||
vsync_pol = timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
hsync_pol = timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH;
|
||||
|
@ -148,7 +150,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
|
|||
u32 timing_h = 0;
|
||||
u32 timing_v = 0;
|
||||
|
||||
pr_debug("Enter hdmi_wp_video_config_timing\n");
|
||||
DSSDBG("Enter hdmi_wp_video_config_timing\n");
|
||||
|
||||
timing_h |= FLD_VAL(timings->hbp, 31, 20);
|
||||
timing_h |= FLD_VAL(timings->hfp, 19, 8);
|
||||
|
@ -164,7 +166,7 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
|
|||
void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
|
||||
struct omap_video_timings *timings, struct hdmi_config *param)
|
||||
{
|
||||
pr_debug("Enter hdmi_wp_video_init_format\n");
|
||||
DSSDBG("Enter hdmi_wp_video_init_format\n");
|
||||
|
||||
video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444;
|
||||
video_fmt->y_res = param->timings.y_res;
|
||||
|
@ -241,7 +243,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
|
|||
struct resource *res;
|
||||
struct resource temp_res;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_wp");
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wp");
|
||||
if (!res) {
|
||||
DSSDBG("can't get WP mem resource by name\n");
|
||||
/*
|
||||
|
|
|
@ -113,11 +113,6 @@ void dss_uninit_overlays(struct platform_device *pdev)
|
|||
int dss_ovl_simple_check(struct omap_overlay *ovl,
|
||||
const struct omap_overlay_info *info)
|
||||
{
|
||||
if (info->paddr == 0) {
|
||||
DSSERR("check_overlay: paddr cannot be 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
|
||||
if (info->out_width != 0 && info->width != info->out_width) {
|
||||
DSSERR("check_overlay: overlay %d doesn't support "
|
||||
|
|
|
@ -46,7 +46,7 @@ static struct {
|
|||
struct sdi_clk_calc_ctx {
|
||||
unsigned long pck_min, pck_max;
|
||||
|
||||
struct dss_clock_info dss_cinfo;
|
||||
unsigned long long fck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
};
|
||||
|
||||
|
@ -63,19 +63,18 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data)
|
||||
static bool dpi_calc_dss_cb(unsigned long fck, void *data)
|
||||
{
|
||||
struct sdi_clk_calc_ctx *ctx = data;
|
||||
|
||||
ctx->dss_cinfo.fck = fck;
|
||||
ctx->dss_cinfo.fck_div = fckd;
|
||||
ctx->fck = fck;
|
||||
|
||||
return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
|
||||
dpi_calc_dispc_cb, ctx);
|
||||
}
|
||||
|
||||
static int sdi_calc_clock_div(unsigned long pclk,
|
||||
struct dss_clock_info *dss_cinfo,
|
||||
unsigned long *fck,
|
||||
struct dispc_clock_info *dispc_cinfo)
|
||||
{
|
||||
int i;
|
||||
|
@ -98,9 +97,9 @@ static int sdi_calc_clock_div(unsigned long pclk,
|
|||
ctx.pck_min = 0;
|
||||
ctx.pck_max = pclk + 1000 * i * i * i;
|
||||
|
||||
ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx);
|
||||
ok = dss_div_calc(pclk, ctx.pck_min, dpi_calc_dss_cb, &ctx);
|
||||
if (ok) {
|
||||
*dss_cinfo = ctx.dss_cinfo;
|
||||
*fck = ctx.fck;
|
||||
*dispc_cinfo = ctx.dispc_cinfo;
|
||||
return 0;
|
||||
}
|
||||
|
@ -128,7 +127,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
{
|
||||
struct omap_dss_device *out = &sdi.output;
|
||||
struct omap_video_timings *t = &sdi.timings;
|
||||
struct dss_clock_info dss_cinfo;
|
||||
unsigned long fck;
|
||||
struct dispc_clock_info dispc_cinfo;
|
||||
unsigned long pck;
|
||||
int r;
|
||||
|
@ -150,13 +149,13 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
||||
t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
|
||||
|
||||
r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
|
||||
r = sdi_calc_clock_div(t->pixel_clock * 1000, &fck, &dispc_cinfo);
|
||||
if (r)
|
||||
goto err_calc_clock_div;
|
||||
|
||||
sdi.mgr_config.clock_info = dispc_cinfo;
|
||||
|
||||
pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
|
||||
pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000;
|
||||
|
||||
if (pck != t->pixel_clock) {
|
||||
DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
|
||||
|
@ -169,7 +168,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
|
|||
|
||||
dss_mgr_set_timings(out->manager, t);
|
||||
|
||||
r = dss_set_clock_div(&dss_cinfo);
|
||||
r = dss_set_fck_rate(fck);
|
||||
if (r)
|
||||
goto err_set_dss_clock_div;
|
||||
|
||||
|
@ -265,7 +264,8 @@ static int sdi_init_regulator(void)
|
|||
|
||||
vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi");
|
||||
if (IS_ERR(vdds_sdi)) {
|
||||
DSSERR("can't get VDDS_SDI regulator\n");
|
||||
if (PTR_ERR(vdds_sdi) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDS_SDI regulator\n");
|
||||
return PTR_ERR(vdds_sdi);
|
||||
}
|
||||
|
||||
|
|
|
@ -639,7 +639,8 @@ static int venc_init_regulator(void)
|
|||
vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");
|
||||
|
||||
if (IS_ERR(vdda_dac)) {
|
||||
DSSERR("can't get VDDA_DAC regulator\n");
|
||||
if (PTR_ERR(vdda_dac) != -EPROBE_DEFER)
|
||||
DSSERR("can't get VDDA_DAC regulator\n");
|
||||
return PTR_ERR(vdda_dac);
|
||||
}
|
||||
|
||||
|
|
|
@ -1833,6 +1833,16 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
|
|||
if (fbdev == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < fbdev->num_fbs; i++) {
|
||||
struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
|
||||
int j;
|
||||
|
||||
for (j = 0; j < ofbi->num_overlays; j++) {
|
||||
struct omap_overlay *ovl = ofbi->overlays[j];
|
||||
ovl->disable(ovl);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < fbdev->num_fbs; i++)
|
||||
unregister_framebuffer(fbdev->fbs[i]);
|
||||
|
||||
|
@ -2557,6 +2567,15 @@ static int omapfb_probe(struct platform_device *pdev)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (def_display) {
|
||||
u16 w, h;
|
||||
|
||||
def_display->driver->get_resolution(def_display, &w, &h);
|
||||
|
||||
dev_info(fbdev->dev, "using display '%s' mode %dx%d\n",
|
||||
def_display->name, w, h);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
|
|
|
@ -2128,7 +2128,6 @@ static void rivafb_remove(struct pci_dev *pd)
|
|||
pci_release_regions(pd);
|
||||
kfree(info->pixmap.addr);
|
||||
framebuffer_release(info);
|
||||
pci_set_drvdata(pd, NULL);
|
||||
NVTRACE_LEAVE();
|
||||
}
|
||||
|
||||
|
|
|
@ -1227,7 +1227,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
|
|||
/* Free the MERAM cache. */
|
||||
if (ch->cache) {
|
||||
sh_mobile_meram_cache_free(priv->meram_dev, ch->cache);
|
||||
ch->cache = 0;
|
||||
ch->cache = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,12 +32,6 @@
|
|||
|
||||
#include <video/tgafb.h>
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type)
|
||||
#else
|
||||
#define TGA_BUS_PCI(dev) 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TC
|
||||
#define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type)
|
||||
#else
|
||||
|
@ -236,7 +230,7 @@ tgafb_set_par(struct fb_info *info)
|
|||
};
|
||||
|
||||
struct tga_par *par = (struct tga_par *) info->par;
|
||||
int tga_bus_pci = TGA_BUS_PCI(par->dev);
|
||||
int tga_bus_pci = dev_is_pci(par->dev);
|
||||
int tga_bus_tc = TGA_BUS_TC(par->dev);
|
||||
u32 htimings, vtimings, pll_freq;
|
||||
u8 tga_type;
|
||||
|
@ -519,7 +513,7 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
|
|||
unsigned transp, struct fb_info *info)
|
||||
{
|
||||
struct tga_par *par = (struct tga_par *) info->par;
|
||||
int tga_bus_pci = TGA_BUS_PCI(par->dev);
|
||||
int tga_bus_pci = dev_is_pci(par->dev);
|
||||
int tga_bus_tc = TGA_BUS_TC(par->dev);
|
||||
|
||||
if (regno > 255)
|
||||
|
@ -1472,7 +1466,7 @@ static void
|
|||
tgafb_init_fix(struct fb_info *info)
|
||||
{
|
||||
struct tga_par *par = (struct tga_par *)info->par;
|
||||
int tga_bus_pci = TGA_BUS_PCI(par->dev);
|
||||
int tga_bus_pci = dev_is_pci(par->dev);
|
||||
int tga_bus_tc = TGA_BUS_TC(par->dev);
|
||||
u8 tga_type = par->tga_type;
|
||||
const char *tga_type_name = NULL;
|
||||
|
@ -1496,10 +1490,9 @@ tgafb_init_fix(struct fb_info *info)
|
|||
if (tga_bus_tc)
|
||||
tga_type_name = "Digital ZLX-E3";
|
||||
break;
|
||||
default:
|
||||
tga_type_name = "Unknown";
|
||||
break;
|
||||
}
|
||||
if (!tga_type_name)
|
||||
tga_type_name = "Unknown";
|
||||
|
||||
strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id));
|
||||
|
||||
|
@ -1560,7 +1553,7 @@ static int tgafb_register(struct device *dev)
|
|||
const struct fb_videomode *modedb_tga = NULL;
|
||||
resource_size_t bar0_start = 0, bar0_len = 0;
|
||||
const char *mode_option_tga = NULL;
|
||||
int tga_bus_pci = TGA_BUS_PCI(dev);
|
||||
int tga_bus_pci = dev_is_pci(dev);
|
||||
int tga_bus_tc = TGA_BUS_TC(dev);
|
||||
unsigned int modedbsize_tga = 0;
|
||||
void __iomem *mem_base;
|
||||
|
@ -1690,7 +1683,7 @@ static int tgafb_register(struct device *dev)
|
|||
static void tgafb_unregister(struct device *dev)
|
||||
{
|
||||
resource_size_t bar0_start = 0, bar0_len = 0;
|
||||
int tga_bus_pci = TGA_BUS_PCI(dev);
|
||||
int tga_bus_pci = dev_is_pci(dev);
|
||||
int tga_bus_tc = TGA_BUS_TC(dev);
|
||||
struct fb_info *info = NULL;
|
||||
struct tga_par *par;
|
||||
|
|
|
@ -383,7 +383,6 @@ static void vmlfb_disable_mmio(struct vml_par *par)
|
|||
static void vmlfb_release_devices(struct vml_par *par)
|
||||
{
|
||||
if (atomic_dec_and_test(&par->refcount)) {
|
||||
pci_set_drvdata(par->vdc, NULL);
|
||||
pci_disable_device(par->gpu);
|
||||
pci_disable_device(par->vdc);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
/*
|
||||
* arch/arm/mach-ep93xx/include/mach/fb.h
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARCH_EP93XXFB_H
|
||||
#define __ASM_ARCH_EP93XXFB_H
|
||||
#ifndef __VIDEO_EP93XX_H
|
||||
#define __VIDEO_EP93XX_H
|
||||
|
||||
struct platform_device;
|
||||
struct fb_videomode;
|
||||
|
@ -53,4 +49,4 @@ struct ep93xxfb_mach_info {
|
|||
void (*blank)(int blank_mode, struct fb_info *info);
|
||||
};
|
||||
|
||||
#endif /* __ASM_ARCH_EP93XXFB_H */
|
||||
#endif /* __VIDEO_EP93XX_H */
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* arch/arm/mach-msm/include/mach/msm_fb.h
|
||||
*
|
||||
/*
|
||||
* Internal shared definitions for various MSM framebuffer parts.
|
||||
*
|
||||
* Copyright (C) 2007 Google Incorporated
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* arch/arm/mach-pxa/include/mach/pxafb.h
|
||||
*
|
||||
* Support for the xscale frame buffer.
|
||||
*
|
||||
* Author: Jean-Frederic Clere
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/arch/arm/mach-mmp/include/mach/pxa168fb.h
|
||||
*
|
||||
* Copyright (C) 2009 Marvell International Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
Загрузка…
Ссылка в новой задаче