/* SPDX-License-Identifier: GPL-2.0 */ #ifndef LYNXDRV_H_ #define LYNXDRV_H_ #define FB_ACCEL_SMI 0xab #define MHZ(x) ((x) * 1000000) #define DEFAULT_SM750_CHIP_CLOCK 290 #define DEFAULT_SM750LE_CHIP_CLOCK 333 #ifndef SM750LE_REVISION_ID #define SM750LE_REVISION_ID ((unsigned char)0xfe) #endif enum sm750_pnltype { sm750_24TFT = 0, /* 24bit tft */ sm750_dualTFT = 2, /* dual 18 bit tft */ sm750_doubleTFT = 1, /* 36 bit double pixel tft */ }; /* vga channel is not concerned */ enum sm750_dataflow { sm750_simul_pri, /* primary => all head */ sm750_simul_sec, /* secondary => all head */ sm750_dual_normal, /* primary => panel head and secondary => crt */ sm750_dual_swap, /* primary => crt head and secondary => panel */ }; enum sm750_channel { sm750_primary = 0, /* enum value equal to the register filed data */ sm750_secondary = 1, }; enum sm750_path { sm750_panel = 1, sm750_crt = 2, sm750_pnc = 3, /* panel and crt */ }; struct init_status { ushort powerMode; /* below three clocks are in unit of MHZ*/ ushort chip_clk; ushort mem_clk; ushort master_clk; ushort setAllEngOff; ushort resetMemory; }; struct lynx_accel { /* base virtual address of DPR registers */ volatile unsigned char __iomem *dprBase; /* base virtual address of de data port */ volatile unsigned char __iomem *dpPortBase; /* function pointers */ void (*de_init)(struct lynx_accel *accel); int (*de_wait)(void);/* see if hardware ready to work */ int (*de_fillrect)(struct lynx_accel *accel, u32 base, u32 pitch, u32 bpp, u32 x, u32 y, u32 width, u32 height, u32 color, u32 rop); int (*de_copyarea)(struct lynx_accel *accel, u32 s_base, u32 s_pitch, u32 sx, u32 sy, u32 d_base, u32 d_pitch, u32 bpp, u32 dx, u32 dy, u32 width, u32 height, u32 rop2); int (*de_imageblit)(struct lynx_accel *accel, const char *p_srcbuf, u32 src_delta, u32 start_bit, u32 d_base, u32 d_pitch, u32 byte_per_pixel, u32 dx, u32 dy, u32 width, u32 height, u32 f_color, u32 b_color, u32 rop2); }; struct sm750_dev { /* common members */ u16 devid; u8 revid; struct pci_dev *pdev; struct fb_info *fbinfo[2]; struct lynx_accel accel; int accel_off; int fb_count; int mtrr_off; struct{ int vram; } mtrr; /* all smi graphic adaptor got below attributes */ unsigned long vidmem_start; unsigned long vidreg_start; __u32 vidmem_size; __u32 vidreg_size; void __iomem *pvReg; unsigned char __iomem *pvMem; /* locks*/ spinlock_t slock; struct init_status initParm; enum sm750_pnltype pnltype; enum sm750_dataflow dataflow; int nocrt; /* * 0: no hardware cursor * 1: primary crtc hw cursor enabled, * 2: secondary crtc hw cursor enabled * 3: both ctrc hw cursor enabled */ int hwCursor; }; struct lynx_cursor { /* cursor width ,height and size */ int w; int h; int size; /* hardware limitation */ int max_w; int max_h; /* base virtual address and offset of cursor image */ char __iomem *vstart; int offset; /* mmio addr of hw cursor */ volatile char __iomem *mmio; }; struct lynxfb_crtc { unsigned char __iomem *v_cursor; /* virtual address of cursor */ unsigned char __iomem *v_screen; /* virtual address of on_screen */ int o_cursor; /* cursor address offset in vidmem */ int o_screen; /* onscreen address offset in vidmem */ int channel;/* which channel this crtc stands for*/ resource_size_t vidmem_size;/* this view's video memory max size */ /* below attributes belong to info->fix, their value depends on specific adaptor*/ u16 line_pad;/* padding information:0,1,2,4,8,16,... */ u16 xpanstep; u16 ypanstep; u16 ywrapstep; void *priv; /* cursor information */ struct lynx_cursor cursor; }; struct lynxfb_output { int dpms; int paths; /* * which paths(s) this output stands for,for sm750: * paths=1:means output for panel paths * paths=2:means output for crt paths * paths=3:means output for both panel and crt paths */ int *channel; /* * which channel these outputs linked with,for sm750: * *channel=0 means primary channel * *channel=1 means secondary channel * output->channel ==> &crtc->channel */ void *priv; int (*proc_setBLANK)(struct lynxfb_output *output, int blank); }; struct lynxfb_par { /* either 0 or 1 for dual head adaptor,0 is the older one registered */ int index; unsigned int pseudo_palette[256]; struct lynxfb_crtc crtc; struct lynxfb_output output; struct fb_info *info; struct sm750_dev *dev; }; static inline unsigned long ps_to_hz(unsigned int psvalue) { unsigned long long numerator = 1000 * 1000 * 1000 * 1000ULL; /* 10^12 / picosecond period gives frequency in Hz */ do_div(numerator, psvalue); return (unsigned long)numerator; } int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev); int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev); void hw_sm750_initAccel(struct sm750_dev *sm750_dev); int hw_sm750_deWait(void); int hw_sm750le_deWait(void); int hw_sm750_output_setMode(struct lynxfb_output *output, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix); int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, struct fb_var_screeninfo *var); int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix); int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index, ushort red, ushort green, ushort blue); int hw_sm750_setBLANK(struct lynxfb_output *output, int blank); int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank); int hw_sm750_pan_display(struct lynxfb_crtc *crtc, const struct fb_var_screeninfo *var, const struct fb_info *info); #endif