18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * linux/drivers/video/omap2/omapfb.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2008 Nokia Corporation
68c2ecf20Sopenharmony_ci * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Some code and ideas taken from drivers/video/omap/ driver
98c2ecf20Sopenharmony_ci * by Imre Deak.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#ifndef __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
138c2ecf20Sopenharmony_ci#define __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#ifdef CONFIG_FB_OMAP2_DEBUG_SUPPORT
168c2ecf20Sopenharmony_ci#define DEBUG
178c2ecf20Sopenharmony_ci#endif
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#include <linux/rwsem.h>
208c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#include <video/omapfb_dss.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#ifdef DEBUG
258c2ecf20Sopenharmony_ciextern bool omapfb_debug;
268c2ecf20Sopenharmony_ci#define DBG(format, ...) \
278c2ecf20Sopenharmony_ci	do { \
288c2ecf20Sopenharmony_ci		if (omapfb_debug) \
298c2ecf20Sopenharmony_ci			printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__); \
308c2ecf20Sopenharmony_ci	} while (0)
318c2ecf20Sopenharmony_ci#else
328c2ecf20Sopenharmony_ci#define DBG(format, ...)
338c2ecf20Sopenharmony_ci#endif
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#define FB2OFB(fb_info) ((struct omapfb_info *)(fb_info->par))
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/* max number of overlays to which a framebuffer data can be direct */
388c2ecf20Sopenharmony_ci#define OMAPFB_MAX_OVL_PER_FB 3
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistruct omapfb2_mem_region {
418c2ecf20Sopenharmony_ci	int             id;
428c2ecf20Sopenharmony_ci	unsigned long	attrs;
438c2ecf20Sopenharmony_ci	void		*token;
448c2ecf20Sopenharmony_ci	dma_addr_t	dma_handle;
458c2ecf20Sopenharmony_ci	u32		paddr;
468c2ecf20Sopenharmony_ci	void __iomem	*vaddr;
478c2ecf20Sopenharmony_ci	struct vrfb	vrfb;
488c2ecf20Sopenharmony_ci	unsigned long	size;
498c2ecf20Sopenharmony_ci	u8		type;		/* OMAPFB_PLANE_MEM_* */
508c2ecf20Sopenharmony_ci	bool		alloc;		/* allocated by the driver */
518c2ecf20Sopenharmony_ci	bool		map;		/* kernel mapped by the driver */
528c2ecf20Sopenharmony_ci	atomic_t	map_count;
538c2ecf20Sopenharmony_ci	struct rw_semaphore lock;
548c2ecf20Sopenharmony_ci	atomic_t	lock_count;
558c2ecf20Sopenharmony_ci};
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci/* appended to fb_info */
588c2ecf20Sopenharmony_cistruct omapfb_info {
598c2ecf20Sopenharmony_ci	int id;
608c2ecf20Sopenharmony_ci	struct omapfb2_mem_region *region;
618c2ecf20Sopenharmony_ci	int num_overlays;
628c2ecf20Sopenharmony_ci	struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
638c2ecf20Sopenharmony_ci	struct omapfb2_device *fbdev;
648c2ecf20Sopenharmony_ci	enum omap_dss_rotation_type rotation_type;
658c2ecf20Sopenharmony_ci	u8 rotation[OMAPFB_MAX_OVL_PER_FB];
668c2ecf20Sopenharmony_ci	bool mirror;
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistruct omapfb_display_data {
708c2ecf20Sopenharmony_ci	struct omapfb2_device *fbdev;
718c2ecf20Sopenharmony_ci	struct omap_dss_device *dssdev;
728c2ecf20Sopenharmony_ci	u8 bpp_override;
738c2ecf20Sopenharmony_ci	enum omapfb_update_mode update_mode;
748c2ecf20Sopenharmony_ci	bool auto_update_work_enabled;
758c2ecf20Sopenharmony_ci	struct delayed_work auto_update_work;
768c2ecf20Sopenharmony_ci};
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_cistruct omapfb2_device {
798c2ecf20Sopenharmony_ci	struct device *dev;
808c2ecf20Sopenharmony_ci	struct mutex  mtx;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	u32 pseudo_palette[17];
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	int state;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	unsigned num_fbs;
878c2ecf20Sopenharmony_ci	struct fb_info *fbs[10];
888c2ecf20Sopenharmony_ci	struct omapfb2_mem_region regions[10];
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	unsigned num_displays;
918c2ecf20Sopenharmony_ci	struct omapfb_display_data displays[10];
928c2ecf20Sopenharmony_ci	unsigned num_overlays;
938c2ecf20Sopenharmony_ci	struct omap_overlay *overlays[10];
948c2ecf20Sopenharmony_ci	unsigned num_managers;
958c2ecf20Sopenharmony_ci	struct omap_overlay_manager *managers[10];
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	struct workqueue_struct *auto_update_wq;
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistruct omapfb_colormode {
1018c2ecf20Sopenharmony_ci	enum omap_color_mode dssmode;
1028c2ecf20Sopenharmony_ci	u32 bits_per_pixel;
1038c2ecf20Sopenharmony_ci	u32 nonstd;
1048c2ecf20Sopenharmony_ci	struct fb_bitfield red;
1058c2ecf20Sopenharmony_ci	struct fb_bitfield green;
1068c2ecf20Sopenharmony_ci	struct fb_bitfield blue;
1078c2ecf20Sopenharmony_ci	struct fb_bitfield transp;
1088c2ecf20Sopenharmony_ci};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_civoid set_fb_fix(struct fb_info *fbi);
1118c2ecf20Sopenharmony_ciint check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var);
1128c2ecf20Sopenharmony_ciint omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type);
1138c2ecf20Sopenharmony_ciint omapfb_apply_changes(struct fb_info *fbi, int init);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ciint omapfb_create_sysfs(struct omapfb2_device *fbdev);
1168c2ecf20Sopenharmony_civoid omapfb_remove_sysfs(struct omapfb2_device *fbdev);
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ciint omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ciint dss_mode_to_fb_mode(enum omap_color_mode dssmode,
1218c2ecf20Sopenharmony_ci			struct fb_var_screeninfo *var);
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ciint omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
1248c2ecf20Sopenharmony_ci		u16 posx, u16 posy, u16 outw, u16 outh);
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_civoid omapfb_start_auto_update(struct omapfb2_device *fbdev,
1278c2ecf20Sopenharmony_ci		struct omap_dss_device *display);
1288c2ecf20Sopenharmony_civoid omapfb_stop_auto_update(struct omapfb2_device *fbdev,
1298c2ecf20Sopenharmony_ci		struct omap_dss_device *display);
1308c2ecf20Sopenharmony_ciint omapfb_get_update_mode(struct fb_info *fbi, enum omapfb_update_mode *mode);
1318c2ecf20Sopenharmony_ciint omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci/* find the display connected to this fb, if any */
1348c2ecf20Sopenharmony_cistatic inline struct omap_dss_device *fb2display(struct fb_info *fbi)
1358c2ecf20Sopenharmony_ci{
1368c2ecf20Sopenharmony_ci	struct omapfb_info *ofbi = FB2OFB(fbi);
1378c2ecf20Sopenharmony_ci	struct omap_overlay *ovl;
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	/* XXX: returns the display connected to first attached overlay */
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci	if (ofbi->num_overlays == 0)
1428c2ecf20Sopenharmony_ci		return NULL;
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	ovl = ofbi->overlays[0];
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	return ovl->get_device(ovl);
1478c2ecf20Sopenharmony_ci}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_cistatic inline struct omapfb_display_data *get_display_data(
1508c2ecf20Sopenharmony_ci		struct omapfb2_device *fbdev, struct omap_dss_device *dssdev)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	int i;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	for (i = 0; i < fbdev->num_displays; ++i)
1558c2ecf20Sopenharmony_ci		if (fbdev->displays[i].dssdev == dssdev)
1568c2ecf20Sopenharmony_ci			return &fbdev->displays[i];
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci	/* This should never happen */
1598c2ecf20Sopenharmony_ci	BUG();
1608c2ecf20Sopenharmony_ci	return NULL;
1618c2ecf20Sopenharmony_ci}
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistatic inline void omapfb_lock(struct omapfb2_device *fbdev)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	mutex_lock(&fbdev->mtx);
1668c2ecf20Sopenharmony_ci}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_cistatic inline void omapfb_unlock(struct omapfb2_device *fbdev)
1698c2ecf20Sopenharmony_ci{
1708c2ecf20Sopenharmony_ci	mutex_unlock(&fbdev->mtx);
1718c2ecf20Sopenharmony_ci}
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_cistatic inline int omapfb_overlay_enable(struct omap_overlay *ovl,
1748c2ecf20Sopenharmony_ci		int enable)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	if (enable)
1778c2ecf20Sopenharmony_ci		return ovl->enable(ovl);
1788c2ecf20Sopenharmony_ci	else
1798c2ecf20Sopenharmony_ci		return ovl->disable(ovl);
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic inline struct omapfb2_mem_region *
1838c2ecf20Sopenharmony_ciomapfb_get_mem_region(struct omapfb2_mem_region *rg)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	down_read_nested(&rg->lock, rg->id);
1868c2ecf20Sopenharmony_ci	atomic_inc(&rg->lock_count);
1878c2ecf20Sopenharmony_ci	return rg;
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistatic inline void omapfb_put_mem_region(struct omapfb2_mem_region *rg)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	atomic_dec(&rg->lock_count);
1938c2ecf20Sopenharmony_ci	up_read(&rg->lock);
1948c2ecf20Sopenharmony_ci}
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci#endif
197