Release 4.7 drivers/staging/sm750fb/sm750_hw.c
  
  
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/console.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#include <linux/platform_device.h>
#include <linux/screen_info.h>
#include <linux/sizes.h>
#include "sm750.h"
#include "ddk750.h"
#include "sm750_accel.h"
int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
{
	int ret;
	ret = 0;
	sm750_dev->vidreg_start  = pci_resource_start(pdev, 1);
	sm750_dev->vidreg_size = SZ_2M;
	pr_info("mmio phyAddr = %lx\n", sm750_dev->vidreg_start);
	/* reserve the vidreg space of smi adaptor
         * if you do this, u need to add release region code
         * in lynxfb_remove, or memory will not be mapped again
         * successfully
         * */
	ret = pci_request_region(pdev, 1, "sm750fb");
	if (ret) {
		pr_err("Can not request PCI regions.\n");
		goto exit;
	}
	/* now map mmio and vidmem*/
	sm750_dev->pvReg = ioremap_nocache(sm750_dev->vidreg_start,
					   sm750_dev->vidreg_size);
	if (!sm750_dev->pvReg) {
		pr_err("mmio failed\n");
		ret = -EFAULT;
		goto exit;
	} else {
		pr_info("mmio virtual addr = %p\n", sm750_dev->pvReg);
	}
	sm750_dev->accel.dprBase = sm750_dev->pvReg + DE_BASE_ADDR_TYPE1;
	sm750_dev->accel.dpPortBase = sm750_dev->pvReg + DE_PORT_ADDR_TYPE1;
	ddk750_set_mmio(sm750_dev->pvReg, sm750_dev->devid, sm750_dev->revid);
	sm750_dev->vidmem_start = pci_resource_start(pdev, 0);
	/* don't use pdev_resource[x].end - resource[x].start to
         * calculate the resource size,its only the maximum available
         * size but not the actual size,use
         * @ddk750_getVMSize function can be safe.
         * */
	sm750_dev->vidmem_size = ddk750_getVMSize();
	pr_info("video memory phyAddr = %lx, size = %u bytes\n",
		sm750_dev->vidmem_start, sm750_dev->vidmem_size);
	/* reserve the vidmem space of smi adaptor */
	sm750_dev->pvMem = ioremap_wc(sm750_dev->vidmem_start,
				      sm750_dev->vidmem_size);
	if (!sm750_dev->pvMem) {
		pr_err("Map video memory failed\n");
		ret = -EFAULT;
		goto exit;
	} else {
		pr_info("video memory vaddr = %p\n", sm750_dev->pvMem);
	}
exit:
	return ret;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 215 | 86.00% | 2 | 25.00% | 
| mike rapoport | mike rapoport | 30 | 12.00% | 4 | 50.00% | 
| anatoly stepanov | anatoly stepanov | 4 | 1.60% | 1 | 12.50% | 
| luis r. rodriguez | luis r. rodriguez | 1 | 0.40% | 1 | 12.50% | 
 | Total | 250 | 100.00% | 8 | 100.00% | 
int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
{
	struct init_status *parm;
	parm = &sm750_dev->initParm;
	if (parm->chip_clk == 0)
		parm->chip_clk = (getChipType() == SM750LE) ?
						DEFAULT_SM750LE_CHIP_CLOCK :
						DEFAULT_SM750_CHIP_CLOCK;
	if (parm->mem_clk == 0)
		parm->mem_clk = parm->chip_clk;
	if (parm->master_clk == 0)
		parm->master_clk = parm->chip_clk/3;
	ddk750_initHw((initchip_param_t *)&sm750_dev->initParm);
	/* for sm718,open pci burst */
	if (sm750_dev->devid == 0x718) {
		POKE32(SYSTEM_CTRL,
		       PEEK32(SYSTEM_CTRL) | SYSTEM_CTRL_PCI_BURST);
	}
	if (getChipType() != SM750LE) {
		unsigned int val;
		/* does user need CRT ?*/
		if (sm750_dev->nocrt) {
			POKE32(MISC_CTRL,
			       PEEK32(MISC_CTRL) | MISC_CTRL_DAC_POWER_OFF);
			/* shut off dpms */
			val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK;
			val |= SYSTEM_CTRL_DPMS_VPHN;
			POKE32(SYSTEM_CTRL, val);
		} else {
			POKE32(MISC_CTRL,
			       PEEK32(MISC_CTRL) & ~MISC_CTRL_DAC_POWER_OFF);
			/* turn on dpms */
			val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK;
			val |= SYSTEM_CTRL_DPMS_VPHP;
			POKE32(SYSTEM_CTRL, val);
		}
		val = PEEK32(PANEL_DISPLAY_CTRL) &
			~(PANEL_DISPLAY_CTRL_DUAL_DISPLAY |
			  PANEL_DISPLAY_CTRL_DOUBLE_PIXEL);
		switch (sm750_dev->pnltype) {
		case sm750_24TFT:
			break;
		case sm750_doubleTFT:
			val |= PANEL_DISPLAY_CTRL_DOUBLE_PIXEL;
			break;
		case sm750_dualTFT:
			val |= PANEL_DISPLAY_CTRL_DUAL_DISPLAY;
			break;
		}
		POKE32(PANEL_DISPLAY_CTRL, val);
	} else {
		/* for 750LE ,no DVI chip initialization makes Monitor no signal */
		/* Set up GPIO for software I2C to program DVI chip in the
                   Xilinx SP605 board, in order to have video signal.
                 */
		sm750_sw_i2c_init(0, 1);
		/* Customer may NOT use CH7301 DVI chip, which has to be
                initialized differently.
                */
		if (sm750_sw_i2c_read_reg(0xec, 0x4a) == 0x95) {
		/* The following register values for CH7301 are from
                   Chrontel app note and our experiment.
                */
			pr_info("yes,CH7301 DVI chip found\n");
			sm750_sw_i2c_write_reg(0xec, 0x1d, 0x16);
			sm750_sw_i2c_write_reg(0xec, 0x21, 0x9);
			sm750_sw_i2c_write_reg(0xec, 0x49, 0xC0);
			pr_info("okay,CH7301 DVI chip setup done\n");
		}
	}
	/* init 2d engine */
	if (!sm750_dev->accel_off)
		hw_sm750_initAccel(sm750_dev);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 259 | 75.73% | 1 | 7.14% | 
| mike rapoport | mike rapoport | 80 | 23.39% | 10 | 71.43% | 
| janani ravichandran | janani ravichandran | 1 | 0.29% | 1 | 7.14% | 
| anatoly stepanov | anatoly stepanov | 1 | 0.29% | 1 | 7.14% | 
| matej vasek | matej vasek | 1 | 0.29% | 1 | 7.14% | 
 | Total | 342 | 100.00% | 14 | 100.00% | 
int hw_sm750_output_setMode(struct lynxfb_output *output,
									struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix)
{
	int ret;
	disp_output_t dispSet;
	int channel;
	ret = 0;
	dispSet = 0;
	channel = *output->channel;
	if (getChipType() != SM750LE) {
		if (channel == sm750_primary) {
			pr_info("primary channel\n");
			if (output->paths & sm750_panel)
				dispSet |= do_LCD1_PRI;
			if (output->paths & sm750_crt)
				dispSet |= do_CRT_PRI;
		} else {
			pr_info("secondary channel\n");
			if (output->paths & sm750_panel)
				dispSet |= do_LCD1_SEC;
			if (output->paths & sm750_crt)
				dispSet |= do_CRT_SEC;
		}
		ddk750_setLogicalDispOut(dispSet);
	} else {
		/* just open DISPLAY_CONTROL_750LE register bit 3:0*/
		u32 reg;
		reg = PEEK32(DISPLAY_CONTROL_750LE);
		reg |= 0xf;
		POKE32(DISPLAY_CONTROL_750LE, reg);
	}
	pr_info("ddk setlogicdispout done\n");
	return ret;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 159 | 99.38% | 1 | 50.00% | 
| juston li | juston li | 1 | 0.62% | 1 | 50.00% | 
 | Total | 160 | 100.00% | 2 | 100.00% | 
int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, struct fb_var_screeninfo *var)
{
	struct sm750_dev *sm750_dev;
	struct lynxfb_par *par = container_of(crtc, struct lynxfb_par, crtc);
	sm750_dev = par->dev;
	switch (var->bits_per_pixel) {
	case 8:
	case 16:
		break;
	case 32:
		if (sm750_dev->revid == SM750LE_REVISION_ID) {
			pr_debug("750le do not support 32bpp\n");
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 73 | 83.91% | 1 | 33.33% | 
| mike rapoport | mike rapoport | 14 | 16.09% | 2 | 66.67% | 
 | Total | 87 | 100.00% | 3 | 100.00% | 
/*
        set the controller's mode for @crtc charged with @var and @fix parameters
*/
int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
								struct fb_var_screeninfo *var,
								struct fb_fix_screeninfo *fix)
{
	int ret, fmt;
	u32 reg;
	mode_parameter_t modparm;
	clock_type_t clock;
	struct sm750_dev *sm750_dev;
	struct lynxfb_par *par;
	ret = 0;
	par = container_of(crtc, struct lynxfb_par, crtc);
	sm750_dev = par->dev;
	if (!sm750_dev->accel_off) {
		/* set 2d engine pixel format according to mode bpp */
		switch (var->bits_per_pixel) {
		case 8:
			fmt = 0;
			break;
		case 16:
			fmt = 1;
			break;
		case 32:
		default:
			fmt = 2;
			break;
		}
		hw_set2dformat(&sm750_dev->accel, fmt);
	}
	/* set timing */
	modparm.pixel_clock = ps_to_hz(var->pixclock);
	modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? POS:NEG;
	modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? POS:NEG;
	modparm.clock_phase_polarity = (var->sync & FB_SYNC_COMP_HIGH_ACT) ? POS:NEG;
	modparm.horizontal_display_end = var->xres;
	modparm.horizontal_sync_width = var->hsync_len;
	modparm.horizontal_sync_start = var->xres + var->right_margin;
	modparm.horizontal_total = var->xres + var->left_margin + var->right_margin + var->hsync_len;
	modparm.vertical_display_end = var->yres;
	modparm.vertical_sync_height = var->vsync_len;
	modparm.vertical_sync_start = var->yres + var->lower_margin;
	modparm.vertical_total = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
	/* choose pll */
	if (crtc->channel != sm750_secondary)
		clock = PRIMARY_PLL;
	else
		clock = SECONDARY_PLL;
	pr_debug("Request pixel clock = %lu\n", modparm.pixel_clock);
	ret = ddk750_setModeTiming(&modparm, clock);
	if (ret) {
		pr_err("Set mode timing failed\n");
		goto exit;
	}
	if (crtc->channel != sm750_secondary) {
		/* set pitch, offset ,width,start address ,etc... */
		POKE32(PANEL_FB_ADDRESS,
		       crtc->oScreen & PANEL_FB_ADDRESS_ADDRESS_MASK);
		reg = var->xres * (var->bits_per_pixel >> 3);
		/* crtc->channel is not equal to par->index on numeric,be aware of that */
		reg = ALIGN(reg, crtc->line_pad);
		reg = (reg << PANEL_FB_WIDTH_WIDTH_SHIFT) &
		       PANEL_FB_WIDTH_WIDTH_MASK;
		reg |= (fix->line_length & PANEL_FB_WIDTH_OFFSET_MASK);
		POKE32(PANEL_FB_WIDTH, reg);
		reg = ((var->xres - 1) << PANEL_WINDOW_WIDTH_WIDTH_SHIFT) &
		       PANEL_WINDOW_WIDTH_WIDTH_MASK;
		reg |= (var->xoffset & PANEL_WINDOW_WIDTH_X_MASK);
		POKE32(PANEL_WINDOW_WIDTH, reg);
		reg = ((var->yres_virtual - 1) <<
		       PANEL_WINDOW_HEIGHT_HEIGHT_SHIFT);
		reg &= PANEL_WINDOW_HEIGHT_HEIGHT_MASK;
		reg |= (var->yoffset & PANEL_WINDOW_HEIGHT_Y_MASK);
		POKE32(PANEL_WINDOW_HEIGHT, reg);
		POKE32(PANEL_PLANE_TL, 0);
		reg = ((var->yres - 1) << PANEL_PLANE_BR_BOTTOM_SHIFT) &
		       PANEL_PLANE_BR_BOTTOM_MASK;
		reg |= ((var->xres - 1) & PANEL_PLANE_BR_RIGHT_MASK);
		POKE32(PANEL_PLANE_BR, reg);
		/* set pixel format */
		reg = PEEK32(PANEL_DISPLAY_CTRL);
		POKE32(PANEL_DISPLAY_CTRL, reg | (var->bits_per_pixel >> 4));
	} else {
		/* not implemented now */
		POKE32(CRT_FB_ADDRESS, crtc->oScreen);
		reg = var->xres * (var->bits_per_pixel >> 3);
		/* crtc->channel is not equal to par->index on numeric,be aware of that */
		reg = ALIGN(reg, crtc->line_pad) << CRT_FB_WIDTH_WIDTH_SHIFT;
		reg &= CRT_FB_WIDTH_WIDTH_MASK;
		reg |= (fix->line_length & CRT_FB_WIDTH_OFFSET_MASK);
		POKE32(CRT_FB_WIDTH, reg);
		/* SET PIXEL FORMAT */
		reg = PEEK32(CRT_DISPLAY_CTRL);
		reg |= ((var->bits_per_pixel >> 4) &
			CRT_DISPLAY_CTRL_FORMAT_MASK);
		POKE32(CRT_DISPLAY_CTRL, reg);
	}
exit:
	return ret;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 501 | 79.27% | 1 | 8.33% | 
| mike rapoport | mike rapoport | 131 | 20.73% | 11 | 91.67% | 
 | Total | 632 | 100.00% | 12 | 100.00% | 
int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index,
								ushort red, ushort green, ushort blue)
{
	static unsigned int add[] = {PANEL_PALETTE_RAM, CRT_PALETTE_RAM};
	POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 65 | 100.00% | 1 | 100.00% | 
 | Total | 65 | 100.00% | 1 | 100.00% | 
int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank)
{
	int dpms, crtdb;
	switch (blank) {
	case FB_BLANK_UNBLANK:
		dpms = CRT_DISPLAY_CTRL_DPMS_0;
		crtdb = 0;
		break;
	case FB_BLANK_NORMAL:
		dpms = CRT_DISPLAY_CTRL_DPMS_0;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	case FB_BLANK_VSYNC_SUSPEND:
		dpms = CRT_DISPLAY_CTRL_DPMS_2;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	case FB_BLANK_HSYNC_SUSPEND:
		dpms = CRT_DISPLAY_CTRL_DPMS_1;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	case FB_BLANK_POWERDOWN:
		dpms = CRT_DISPLAY_CTRL_DPMS_3;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	default:
		return -EINVAL;
	}
	if (output->paths & sm750_crt) {
		unsigned int val;
		val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_DPMS_MASK;
		POKE32(CRT_DISPLAY_CTRL, val | dpms);
		val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK;
		POKE32(CRT_DISPLAY_CTRL, val | crtdb);
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 110 | 76.39% | 1 | 25.00% | 
| mike rapoport | mike rapoport | 29 | 20.14% | 2 | 50.00% | 
| greg kroah-hartman | greg kroah-hartman | 5 | 3.47% | 1 | 25.00% | 
 | Total | 144 | 100.00% | 4 | 100.00% | 
int hw_sm750_setBLANK(struct lynxfb_output *output, int blank)
{
	unsigned int dpms, pps, crtdb;
	dpms = pps = crtdb = 0;
	switch (blank) {
	case FB_BLANK_UNBLANK:
		pr_debug("flag = FB_BLANK_UNBLANK\n");
		dpms = SYSTEM_CTRL_DPMS_VPHP;
		pps = PANEL_DISPLAY_CTRL_DATA;
		break;
	case FB_BLANK_NORMAL:
		pr_debug("flag = FB_BLANK_NORMAL\n");
		dpms = SYSTEM_CTRL_DPMS_VPHP;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	case FB_BLANK_VSYNC_SUSPEND:
		dpms = SYSTEM_CTRL_DPMS_VNHP;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	case FB_BLANK_HSYNC_SUSPEND:
		dpms = SYSTEM_CTRL_DPMS_VPHN;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	case FB_BLANK_POWERDOWN:
		dpms = SYSTEM_CTRL_DPMS_VNHN;
		crtdb = CRT_DISPLAY_CTRL_BLANK;
		break;
	}
	if (output->paths & sm750_crt) {
		unsigned int val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK;
		POKE32(SYSTEM_CTRL, val | dpms);
		val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK;
		POKE32(CRT_DISPLAY_CTRL, val | crtdb);
	}
	if (output->paths & sm750_panel) {
		unsigned int val = PEEK32(PANEL_DISPLAY_CTRL);
		val &= ~PANEL_DISPLAY_CTRL_DATA;
		val |= pps;
		POKE32(PANEL_DISPLAY_CTRL, val);
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 143 | 74.09% | 1 | 16.67% | 
| mike rapoport | mike rapoport | 48 | 24.87% | 4 | 66.67% | 
| juston li | juston li | 2 | 1.04% | 1 | 16.67% | 
 | Total | 193 | 100.00% | 6 | 100.00% | 
void hw_sm750_initAccel(struct sm750_dev *sm750_dev)
{
	u32 reg;
	enable2DEngine(1);
	if (getChipType() == SM750LE) {
		reg = PEEK32(DE_STATE1);
		reg |= DE_STATE1_DE_ABORT;
		POKE32(DE_STATE1, reg);
		reg = PEEK32(DE_STATE1);
		reg &= ~DE_STATE1_DE_ABORT;
		POKE32(DE_STATE1, reg);
	} else {
		/* engine reset */
		reg = PEEK32(SYSTEM_CTRL);
		reg |= SYSTEM_CTRL_DE_ABORT;
		POKE32(SYSTEM_CTRL, reg);
		reg = PEEK32(SYSTEM_CTRL);
		reg &= ~SYSTEM_CTRL_DE_ABORT;
		POKE32(SYSTEM_CTRL, reg);
	}
	/* call 2d init */
	sm750_dev->accel.de_init(&sm750_dev->accel);
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 104 | 88.14% | 1 | 20.00% | 
| mike rapoport | mike rapoport | 14 | 11.86% | 4 | 80.00% | 
 | Total | 118 | 100.00% | 5 | 100.00% | 
int hw_sm750le_deWait(void)
{
	int i = 0x10000000;
	unsigned int mask = DE_STATE2_DE_STATUS_BUSY | DE_STATE2_DE_FIFO_EMPTY |
		DE_STATE2_DE_MEM_FIFO_EMPTY;
	while (i--) {
		unsigned int val = PEEK32(DE_STATE2);
		if ((val & mask) ==
		    (DE_STATE2_DE_FIFO_EMPTY | DE_STATE2_DE_MEM_FIFO_EMPTY))
			return 0;
	}
	/* timeout error */
	return -1;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 41 | 68.33% | 1 | 25.00% | 
| mike rapoport | mike rapoport | 16 | 26.67% | 2 | 50.00% | 
| supriya karanth | supriya karanth | 3 | 5.00% | 1 | 25.00% | 
 | Total | 60 | 100.00% | 4 | 100.00% | 
int hw_sm750_deWait(void)
{
	int i = 0x10000000;
	unsigned int mask = SYSTEM_CTRL_DE_STATUS_BUSY |
		SYSTEM_CTRL_DE_FIFO_EMPTY |
		SYSTEM_CTRL_DE_MEM_FIFO_EMPTY;
	while (i--) {
		unsigned int val = PEEK32(SYSTEM_CTRL);
		if ((val & mask) ==
		    (SYSTEM_CTRL_DE_FIFO_EMPTY | SYSTEM_CTRL_DE_MEM_FIFO_EMPTY))
			return 0;
	}
	/* timeout error */
	return -1;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 41 | 68.33% | 1 | 25.00% | 
| mike rapoport | mike rapoport | 16 | 26.67% | 2 | 50.00% | 
| supriya karanth | supriya karanth | 3 | 5.00% | 1 | 25.00% | 
 | Total | 60 | 100.00% | 4 | 100.00% | 
int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
	const struct fb_var_screeninfo *var,
	const struct fb_info *info)
{
	uint32_t total;
	/* check params */
	if ((var->xoffset + var->xres > var->xres_virtual) ||
	    (var->yoffset + var->yres > var->yres_virtual)) {
		return -EINVAL;
	}
	total = var->yoffset * info->fix.line_length +
		((var->xoffset * var->bits_per_pixel) >> 3);
	total += crtc->oScreen;
	if (crtc->channel == sm750_primary) {
		POKE32(PANEL_FB_ADDRESS,
		       PEEK32(PANEL_FB_ADDRESS) |
		       (total & PANEL_FB_ADDRESS_ADDRESS_MASK));
	} else {
		POKE32(CRT_FB_ADDRESS,
		       PEEK32(CRT_FB_ADDRESS) |
		       (total & CRT_FB_ADDRESS_ADDRESS_MASK));
	}
	return 0;
}
Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 131 | 92.25% | 1 | 25.00% | 
| mike rapoport | mike rapoport | 10 | 7.04% | 2 | 50.00% | 
| juston li | juston li | 1 | 0.70% | 1 | 25.00% | 
 | Total | 142 | 100.00% | 4 | 100.00% | 
Overall Contributors
 | Person | Tokens | Prop | Commits | CommitProp | 
| sudip mukherjee | sudip mukherjee | 1908 | 82.17% | 2 | 5.00% | 
| mike rapoport | mike rapoport | 391 | 16.84% | 29 | 72.50% | 
| supriya karanth | supriya karanth | 6 | 0.26% | 1 | 2.50% | 
| anatoly stepanov | anatoly stepanov | 5 | 0.22% | 2 | 5.00% | 
| greg kroah-hartman | greg kroah-hartman | 5 | 0.22% | 1 | 2.50% | 
| juston li | juston li | 4 | 0.17% | 2 | 5.00% | 
| janani ravichandran | janani ravichandran | 1 | 0.04% | 1 | 2.50% | 
| matej vasek | matej vasek | 1 | 0.04% | 1 | 2.50% | 
| luis r. rodriguez | luis r. rodriguez | 1 | 0.04% | 1 | 2.50% | 
 | Total | 2322 | 100.00% | 40 | 100.00% | 
  
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.