Commit 0a0a3e4a authored by Andrey Filippov's avatar Andrey Filippov
Browse files

debugging histograms

parent dfe11ab2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -346,7 +346,7 @@ int initSequencers(int sensor_port)
    initFramePars(sensor_port);
    return 0;
}
/** Enable/disable sesnor channel (will not generate SoF/EoF pulses and interrupts if disabled). Used to turn off missing channels */
/** Enable/disable sensor channel (will not generate SoF/EoF pulses and interrupts if disabled). Used to turn off missing channels */
void enDisSensorChn(int sensor_port, ///< sensor_port sensor port number (0..3)
                    int en)          ///< enable channel
{
@@ -355,6 +355,7 @@ void enDisSensorChn(int sensor_port, ///< sensor_port sensor port number (0..3)
    sens_mode.chn_en_set = 1;
    x393_sens_mode(sens_mode,sensor_port);
    dev_dbg(g_devfp_ptr,"enDisSensorChn(%d,%d)\n", sensor_port, en);
    dev_info(g_devfp_ptr,"enDisSensorChn(%d,%d)\n", sensor_port, en);
}


+142 −44
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@
/**
 * \def MDF21(x) optional debug output 
 */

#define ELPHEL_INFO 1
#if ELPHEL_DEBUG
// only when commands are issued
  #define MDF21(x) { if (GLOBALPARS(G_DEBUG) & (1 <<21)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;} }
@@ -250,10 +250,34 @@ int histograms_init_hardware(void)
        hist_chn = chn + MAX_SENSORS *port;
        saxi_addr.page=(fpga_hist_phys >> PAGE_SHIFT)+ PARS_FRAMES * hist_chn;// table for 4 colors is exactly 1 page;
        set_x393_hist_saxi_addr (saxi_addr, hist_chn);       // Histogram DMA addresses (in 4096 byte pages)
#ifdef ELPHEL_INFO
    dev_info(g_dev_ptr, "histograms_init_hardware(): port=%d, chn=%d, fpga_hist_data=0x%08x, fpga_hist_phys=0x%08x, saxi_addr=0x%08x",
    		port, chn, (int)fpga_hist_data, (int) fpga_hist_phys, (int) saxi_addr.d32);
#endif

    }
    /*
    // debugging - fill memory to distinguish, invalidating caches
	dma_sync_single_for_cpu(NULL, fpga_hist_phys, pElphel_buf->histograms_size,    DMA_FROM_DEVICE); //
	*/
//    memset(fpga_hist_data, 0xa5, SENSOR_PORTS*MAX_SENSORS*PARS_FRAMES*4*256*4);
    __cpuc_flush_dcache_area(pElphel_buf->histograms_vaddr, pElphel_buf->histograms_size * PAGE_SIZE);
    outer_inv_range(fpga_hist_phys, fpga_hist_phys +  pElphel_buf->histograms_size * PAGE_SIZE); // END - EXCLUSIVE!, CHANGE ORDER (AFTER ____cpuc_flush_dcache_area
    memset(fpga_hist_data, 0xa5, pElphel_buf->histograms_size * PAGE_SIZE);
    __cpuc_flush_dcache_area(pElphel_buf->histograms_vaddr, pElphel_buf->histograms_size * PAGE_SIZE);
    outer_inv_range(fpga_hist_phys, fpga_hist_phys +  pElphel_buf->histograms_size * PAGE_SIZE); // END - EXCLUSIVE!, CHANGE ORDER (AFTER ____cpuc_flush_dcache_area

#ifdef ELPHEL_INFO
    dev_info(g_dev_ptr, "histograms_init_hardware(): set %d bytes of the histograms buffer to 0x%x",
    		(SENSOR_PORTS*MAX_SENSORS*PARS_FRAMES*4*256*4), 0xa5 );
#endif
    /* Circbuf - noithing like that
    // Hand all data to device
    dma_sync_single_for_device(NULL, fpga_hist_phys, SENSOR_PORTS*MAX_SENSORS*PARS_FRAMES*4*256*4, DMA_FROM_DEVICE);

   */
#ifdef ELPHEL_INFO
    dev_info(g_dev_ptr, "histograms_init_hardware()");
#endif
    histograms_dma_ctrl(2);
    return 0;
}
@@ -263,11 +287,25 @@ void histograms_dma_ctrl(int mode) ///< 0 - reset, 1 - disable, 2 - enable
{
    x393_hist_saxi_mode_t saxi_mode;
    saxi_mode.d32=    0;
    saxi_mode.cache=  3;
    saxi_mode.confirm=1;
    saxi_mode.cache=  3; // 0; // 3;
    saxi_mode.confirm=0; // 1; in simulator it was 0
    saxi_mode.nrst=   (mode)?  1:0;
    saxi_mode.en=     (mode>1)?1:0;
    set_x393_hist_saxi_mode(saxi_mode);
    /*
    if (saxi_mode.en){ // just testing
//        dma_sync_single_for_device(NULL, fpga_hist_phys, SENSOR_PORTS*MAX_SENSORS*PARS_FRAMES*4*256*4, DMA_FROM_DEVICE);
        dma_sync_single_for_device(NULL, fpga_hist_phys, pElphel_buf->histograms_size, DMA_FROM_DEVICE);
//
    } else {
    	dma_sync_single_for_cpu(NULL, fpga_hist_phys, pElphel_buf->histograms_size,    DMA_FROM_DEVICE);
    }
    */

#ifdef ELPHEL_INFO
    dev_info(g_dev_ptr, "histograms_dma_ctrl(), mode = %d, saxi_mode= 0x%x",mode, (int) saxi_mode.d32);
#endif

}


@@ -291,19 +329,21 @@ void init_histograms(int chn_mask) ///< combined subchannels and ports Save mask
            GLOBALPARS(p, G_HIST_LAST_INDEX + s) =0xffffffff; // mark as invalid
            GLOBALPARS(p, G_SUBCHANNELS) &= ~(1 << s);
        }
        dev_dbg(g_dev_ptr, "Sensor %d channel %d index = %d", p,  s,  histograms_map[p][s]);
    }
    dev_dbg(g_dev_ptr, "Histograms structures, channel mask = 0x%x, numHistChn = 0x%x",chn_mask, numHistChn);

#ifdef ELPHEL_INFO
    dev_info(g_dev_ptr, "Histograms structures, channel mask = 0x%x, numHistChn = 0x%x",chn_mask, numHistChn);
#endif
    //G_SUBCHANNELS
    sz = numHistChn * HISTOGRAM_CACHE_NUMBER * sizeof(struct histogram_stuct_t);
    pages = ((sz -1) >> PAGE_SHIFT)+1;
    // Uses pre-allocated memory
//    if (sz & (PAGE_SIZE-1)) pages++;
    // When device == NULL, dma_alloc_coherent just allocates notmal memory, page aligned, CMA if available
//    histograms = (struct  histogram_stuct_t* [HISTOGRAM_CACHE_NUMBER]) dma_alloc_coherent(NULL,(sz * PAGE_SIZE),&histograms_phys,GFP_KERNEL);
//    histograms = (struct  histogram_stuct_t[HISTOGRAM_CACHE_NUMBER] * ) dma_alloc_coherent(NULL,(sz * PAGE_SIZE),&histograms_phys,GFP_KERNEL);
//    histograms = (struct  histogram_stuct_t[HISTOGRAM_CACHE_NUMBER]) *  dma_alloc_coherent(NULL,(sz * PAGE_SIZE),&histograms_phys,GFP_KERNEL);


//    histograms = dma_alloc_coherent(NULL,(pages * PAGE_SIZE),&histograms_phys,GFP_KERNEL); // OK
//    dev_warn(g_dev_ptr, "dma_alloc_coherent(NULL, 0x%x, 0x%x,GFP_KERNEL)",pages * PAGE_SIZE, (int) histograms_phys);
// This code is spin-locked above to prevent simultaneous allocation from several php instances, so  GFP_KERNEL may not be used
@@ -319,6 +359,9 @@ void init_histograms(int chn_mask) ///< combined subchannels and ports Save mask
    local_ irq_save(flags);
#endif
    dev_dbg(g_dev_ptr, "Histograms structures, channel mask = 0x%x",chn_mask);
#ifdef ELPHEL_INFO
    dev_info(g_dev_ptr, "Histograms structures, channel mask = 0x%x",chn_mask);
#endif
    for (s=0; s<numHistChn; s++) {
        for (i=0; i < HISTOGRAM_CACHE_NUMBER; i++) {
            histograms[s][i].frame=0xffffffff;
@@ -329,7 +372,9 @@ void init_histograms(int chn_mask) ///< combined subchannels and ports Save mask
    local_ irq_restore(flags);
#endif
    dev_dbg(g_dev_ptr, "Histograms structures initialized");

#ifdef ELPHEL_INFO
    dev_info(g_dev_ptr, "Histograms structures initialized");
#endif
}
/** Get histogram index for sensor port/channel, skipping unused ones */
int get_hist_index (int sensor_port,     ///< sensor port number (0..3)
@@ -359,10 +404,13 @@ int set_histograms (int sensor_port, ///< sensor port number (0..3)
{
    const int hist_frames_available = PARS_FRAMES - 3; // ?
    int i, color_start, hist_indx, hist_frame, hist_frame_index;
    unsigned long thisFrameNumber=getThisFrameNumber(sensor_port);
    unsigned long thisFrameNumber; // =getThisFrameNumber(sensor_port);
	hist_indx=get_hist_index(sensor_port,sensor_chn); // channel/subchannel combination, removed unused
    if (gammaHash || framep) { // adding possibility to copy absolute histogram FPGA buffer
    	thisFrameNumber=getThisFrameNumber(sensor_port);
		dev_dbg(g_dev_ptr, "Setting histograms for frame=%ld(0x%lx), thisFrameNumber=%ld (0x%lx), needed=0x%x\n",
				frame,frame,thisFrameNumber,thisFrameNumber, needed);
    hist_indx=get_hist_index(sensor_port,sensor_chn); // channel/subchannel combination, removed unused
//		hist_indx=get_hist_index(sensor_port,sensor_chn); // channel/subchannel combination, removed unused
		if (hist_indx <0 ) return -EINVAL;
		if (frame >= thisFrameNumber) {
			dev_dbg(g_dev_ptr, "frame=%ld(0x%lx) >= thisFrameNumber=%ld (0x%lx) (not yet available)\n",frame,frame,thisFrameNumber,thisFrameNumber);
@@ -390,7 +438,17 @@ int set_histograms (int sensor_port, ///< sensor port number (0..3)
		} else {
			needed &= ~histograms[hist_indx][hist_frame_index].valid; // remove those that are already available from the request
		}
	    hist_frame=(frame + (GLOBALPARS(sensor_port, G_HIST_SHIFT))) & PARS_FRAMES_MASK; // TODO: Verify
    } else {
//	    hist_frame=(frame + (GLOBALPARS(sensor_port, G_HIST_SHIFT))) & PARS_FRAMES_MASK; // TODO: Verify
	    hist_frame= frame & PARS_FRAMES_MASK;
	    hist_frame_index = hist_frame & (HISTOGRAM_CACHE_NUMBER-1); // 0..7
		dev_dbg(g_dev_ptr, "frame = 0x%x, histograms[%d][%d].frame = 0x%lx, hist_frame_index=0x%x\n",
				(int) frame, hist_indx, hist_frame_index, histograms[hist_indx][hist_frame_index].frame, hist_frame_index);
    }
    dev_dbg(g_dev_ptr, "needed=0x%x\n", needed);
// #define L2_INVAL_SIZE             (32 * 1024)
// #define L2_INVAL_SIZE             (256*sizeof(u32))

    // TODO: handle valid and needed for multichannel?
    if (!(needed & 0xf)) // nothing to do with FPGA
@@ -398,16 +456,29 @@ int set_histograms (int sensor_port, ///< sensor port number (0..3)
    // Copying received data to histograms structure, maybe later we can skip that step and use data in place
    //  hist_frame=(frame-1) & PARS_FRAMES_MASK; // TODO: Verify
//    hist_frame=frame & PARS_FRAMES_MASK; // TODO: Verify
    hist_frame=(frame + (GLOBALPARS(sensor_port, G_HIST_SHIFT))) & PARS_FRAMES_MASK; // TODO: Verify

///    __cpuc_flush_dcache_area(pElphel_buf->histograms_vaddr, pElphel_buf->histograms_size);
///    outer_inv_range(fpga_hist_phys, fpga_hist_phys +  pElphel_buf->histograms_size * PAGE_SIZE); // END - EXCLUSIVE!, CHANGE ORDER (AFTER ____cpuc_flush_dcache_area


    for (i=0; i<4; i++) if (needed & ( 1 << i )) {
        u32 phys_addr= fpga_hist_phys + PAGE_SIZE*(hist_frame + PARS_FRAMES * (sensor_chn + MAX_SENSORS *sensor_port)) + i*256*sizeof(u32); // start of selected color
        u32 * dma_data = &fpga_hist_data[sensor_port][sensor_chn][hist_frame][i][0];
        // invalidate both caches
        outer_inv_range(phys_addr, phys_addr + (256*sizeof(u32) - 1));
        __cpuc_flush_dcache_area(dma_data, 256*sizeof(u32));
//        outer_inv_range(phys_addr, phys_addr + (256*sizeof(u32) - 1));
///        __cpuc_flush_dcache_area(dma_data, 256*sizeof(u32));
///        outer_inv_range(phys_addr, phys_addr + (256*sizeof(u32))); // END - EXCLUSIVE!, CHANGE ORDER (AFTER ____cpuc_flush_dcache_area
        // trying to invalidate all histogram memory
////        __cpuc_flush_dcache_area(pElphel_buf->histograms_vaddr, pElphel_buf->histograms_size * PAGE_SIZE);
      __cpuc_flush_dcache_area(dma_data, 256*sizeof(u32)); // even 8x does not work !!!
////        outer_inv_range(fpga_hist_phys, fpga_hist_phys +  pElphel_buf->histograms_size * PAGE_SIZE); // END - EXCLUSIVE!, CHANGE ORDER (AFTER ____cpuc_flush_dcache_area
        // this is OK
        outer_inv_range(phys_addr, phys_addr + (256*sizeof(u32))); // END - EXCLUSIVE!, CHANGE ORDER (AFTER ____cpuc_flush_dcache_area
        color_start= i<<8 ;
        memcpy(&histograms[hist_indx][hist_frame_index].hist[256*i],
                dma_data, 256*sizeof(u32));
///        __cpuc_flush_dcache_area(&histograms[hist_indx][hist_frame_index].hist[256*i], 256*sizeof(u32)); // even 8x does not work !!!
        __cpuc_flush_dcache_area(&histograms[hist_indx][hist_frame_index].hist[256*i], 256*sizeof(u32)); // even 8x does not work !!!
        memcpy(&histograms[hist_indx][hist_frame_index].hist[256*i], dma_data, 256*sizeof(u32));
        __cpuc_flush_dcache_area(&histograms[hist_indx][hist_frame_index].hist[256*i], 256*sizeof(u32)); // even 8x does not work !!!
        // old in 353:  fpga_hist_read_nice (color_start, 256, (unsigned long *) &histograms[GLOBALPARS(G_HIST_LAST_INDEX)].hist[color_start]);
        histograms[hist_indx][hist_frame_index].valid |= 1 << i;
        dev_dbg(g_dev_ptr, "histograms[%d][%d].valid=0x%lx\n",
@@ -663,7 +734,7 @@ loff_t histograms_lseek (struct file * file,
                         loff_t offset,
                         int orig)
{
    int p,s,index;
    int p,s,index,i;
    struct histograms_pd * privData = (struct histograms_pd *) file->private_data;
    unsigned long reqAddr,reqFrame;

@@ -750,7 +821,28 @@ loff_t histograms_lseek (struct file * file,
                    break; // just in case
                case SEEK_END:
                    if (offset < 0) {
                        return -EINVAL;
                    	index = (offset >> 4)  & 1; // histogram accommodates only half of 16 frames
                        p = (offset >> 2)  & 3;
                        s = (offset >> 0)  & 3;
                        if (get_hist_index(p,s) < 0)
                            return -ENXIO; // invalid port/channel combination
                        privData->port =       p;
                        privData->subchannel = s;
                        for (i = 0; i < HISTOGRAM_CACHE_NUMBER; i++) {
                        	set_histograms(
                        			p,                                    // int sensor_port
									s,                                    // int sensor_chn
									i + (index * HISTOGRAM_CACHE_NUMBER), // unsigned long frame
									0xff,                                 // int needed,
									0,                                    // unsigned long * gammaHash,
									0);                                   // unsigned long * framep
                        }

                        file->f_pos= index; // HISTOGRAMS_FILE_SIZE;
                        dev_dbg(g_dev_ptr, "DEBUG FPGA: index=%d, sensor=%d, channel = %d, file->f_pos = 0x%x\n",
                        		index, p, s, (int) file->f_pos);
                        return file->f_pos;
//                        return -EINVAL;
                    } else {
                        if (offset < LSEEK_HIST_NEEDED) {
                            //#define      LSEEK_HIST_SET_CHN   0x30 ///< ..2F Select channel to wait for (4*port+subchannel)
@@ -777,6 +869,12 @@ loff_t histograms_lseek (struct file * file,
                            case  LSEEK_HIST_WAIT_C: // set histogram waiting for the C (actually R, G2, B) histograms to become available - implies G1 too
                                privData-> wait_mode=1;
                                break;
                            case  LSEEK_HIST_DIS: // Disable histograms DMA engine, hand buffer to CPU
                            	histograms_dma_ctrl(1); //< 0 - reset, 1 - disable, 2 - enable
                                break;
                            case  LSEEK_HIST_EN: // Disable histograms DMA engine, hand buffer to CPU
                            	histograms_dma_ctrl(2); //< 0 - reset, 1 - disable, 2 - enable
                                break;
                            default:
                                switch (offset & ~0x1f) {
                                case  LSEEK_DAEMON_HIST_Y: // wait for daemon enabled and histograms Y ready
+4 −0
Original line number Diff line number Diff line
@@ -1555,6 +1555,10 @@ struct p_names_t {
#define      LSEEK_HIST_REQ_EN    0x2a ///< enable histogram request when reading histogram (safer, but may be not desirable in HDR mode) - default after opening
#define      LSEEK_HIST_REQ_DIS   0x2b ///< disable histogram request when reading histogram - will read latest available relying it is available
#define      LSEEK_HIST_SET_CHN   0x30 ///< ..3F Select channel to wait for (4*port+subchannel)

#define      LSEEK_HIST_DIS       0x40 ///< Disable histograms DMA
#define      LSEEK_HIST_EN        0x41 ///< Enable  histograms DMA

#define      LSEEK_HIST_NEEDED    0x10000 ///< set histogram "needed" mask - 0x10000..0x1ffff
//#define      LSEEK_HIST_WAIT_AE   0x2a ///< wait for autoexposure enabled