diff options
Diffstat (limited to 'drivers/staging/msm/mddihosti.c')
| -rw-r--r-- | drivers/staging/msm/mddihosti.c | 2239 | 
1 files changed, 0 insertions, 2239 deletions
diff --git a/drivers/staging/msm/mddihosti.c b/drivers/staging/msm/mddihosti.c deleted file mode 100644 index f9d6e91e8d5..00000000000 --- a/drivers/staging/msm/mddihosti.c +++ /dev/null @@ -1,2239 +0,0 @@ -/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/mm.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/ioport.h> -#include <linux/device.h> -#include <linux/dma-mapping.h> - -#include "msm_fb_panel.h" -#include "mddihost.h" -#include "mddihosti.h" - -#define FEATURE_MDDI_UNDERRUN_RECOVERY -#ifndef FEATURE_MDDI_DISABLE_REVERSE -static void mddi_read_rev_packet(byte *data_ptr); -#endif - -struct timer_list mddi_host_timer; - -#define MDDI_DEFAULT_TIMER_LENGTH 5000	/* 5 seconds */ -uint32 mddi_rtd_frequency = 60000;	/* send RTD every 60 seconds */ -uint32 mddi_client_status_frequency = 60000;	/* get status pkt every 60 secs */ - -boolean mddi_vsync_detect_enabled = FALSE; -mddi_gpio_info_type mddi_gpio; - -uint32 mddi_host_core_version; -boolean mddi_debug_log_statistics = FALSE; -/* #define FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION */ -/* default to TRUE in case MDP does not vote */ -static boolean mddi_host_mdp_active_flag = TRUE; -static uint32 mddi_log_stats_counter; -uint32 mddi_log_stats_frequency = 4000; - -#define MDDI_DEFAULT_REV_PKT_SIZE            0x20 - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -static boolean mddi_rev_ptr_workaround = TRUE; -static uint32 mddi_reg_read_retry; -static uint32 mddi_reg_read_retry_max = 20; -static boolean mddi_enable_reg_read_retry = TRUE; -static boolean mddi_enable_reg_read_retry_once = FALSE; - -#define MDDI_MAX_REV_PKT_SIZE                0x60 - -#define MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE  0x60 - -#define MDDI_VIDEO_REV_PKT_SIZE              0x40 -#define MDDI_REV_BUFFER_SIZE  MDDI_MAX_REV_PKT_SIZE -static byte rev_packet_data[MDDI_MAX_REV_PKT_SIZE]; -#endif /* FEATURE_MDDI_DISABLE_REVERSE */ -/* leave these variables so graphics will compile */ - -#define MDDI_MAX_REV_DATA_SIZE  128 -/*lint -d__align(x) */ -boolean mddi_debug_clear_rev_data = TRUE; - -uint32 *mddi_reg_read_value_ptr; - -mddi_client_capability_type mddi_client_capability_pkt; -static boolean mddi_client_capability_request = FALSE; - -#ifndef FEATURE_MDDI_DISABLE_REVERSE - -#define MAX_MDDI_REV_HANDLERS 2 -#define INVALID_PKT_TYPE 0xFFFF - -typedef struct { -	mddi_rev_handler_type handler;	/* ISR to be executed */ -	uint16 pkt_type; -} mddi_rev_pkt_handler_type; -static mddi_rev_pkt_handler_type mddi_rev_pkt_handler[MAX_MDDI_REV_HANDLERS] = -    { {NULL, INVALID_PKT_TYPE}, {NULL, INVALID_PKT_TYPE} }; - -static boolean mddi_rev_encap_user_request = FALSE; -static mddi_linked_list_notify_type mddi_rev_user; - -spinlock_t mddi_host_spin_lock; -extern uint32 mdp_in_processing; -#endif - -typedef enum { -	MDDI_REV_IDLE -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	    , MDDI_REV_REG_READ_ISSUED, -	MDDI_REV_REG_READ_SENT, -	MDDI_REV_ENCAP_ISSUED, -	MDDI_REV_STATUS_REQ_ISSUED, -	MDDI_REV_CLIENT_CAP_ISSUED -#endif -} mddi_rev_link_state_type; - -typedef enum { -	MDDI_LINK_DISABLED, -	MDDI_LINK_HIBERNATING, -	MDDI_LINK_ACTIVATING, -	MDDI_LINK_ACTIVE -} mddi_host_link_state_type; - -typedef struct { -	uint32 count; -	uint32 in_count; -	uint32 disp_req_count; -	uint32 state_change_count; -	uint32 ll_done_count; -	uint32 rev_avail_count; -	uint32 error_count; -	uint32 rev_encap_count; -	uint32 llist_ptr_write_1; -	uint32 llist_ptr_write_2; -} mddi_host_int_type; - -typedef struct { -	uint32 fwd_crc_count; -	uint32 rev_crc_count; -	uint32 pri_underflow; -	uint32 sec_underflow; -	uint32 rev_overflow; -	uint32 pri_overwrite; -	uint32 sec_overwrite; -	uint32 rev_overwrite; -	uint32 dma_failure; -	uint32 rtd_failure; -	uint32 reg_read_failure; -#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY -	uint32 pri_underrun_detected; -#endif -} mddi_host_stat_type; - -typedef struct { -	uint32 rtd_cnt; -	uint32 rev_enc_cnt; -	uint32 vid_cnt; -	uint32 reg_acc_cnt; -	uint32 cli_stat_cnt; -	uint32 cli_cap_cnt; -	uint32 reg_read_cnt; -	uint32 link_active_cnt; -	uint32 link_hibernate_cnt; -	uint32 vsync_response_cnt; -	uint32 fwd_crc_cnt; -	uint32 rev_crc_cnt; -} mddi_log_params_struct_type; - -typedef struct { -	uint32 rtd_value; -	uint32 rtd_counter; -	uint32 client_status_cnt; -	boolean rev_ptr_written; -	uint8 *rev_ptr_start; -	uint8 *rev_ptr_curr; -	uint32 mddi_rev_ptr_write_val; -	dma_addr_t rev_data_dma_addr; -	uint16 rev_pkt_size; -	mddi_rev_link_state_type rev_state; -	mddi_host_link_state_type link_state; -	mddi_host_driver_state_type driver_state; -	boolean disable_hibernation; -	uint32 saved_int_reg; -	uint32 saved_int_en; -	mddi_linked_list_type *llist_ptr; -	dma_addr_t llist_dma_addr; -	mddi_linked_list_type *llist_dma_ptr; -	uint32 *rev_data_buf; -	struct completion mddi_llist_avail_comp; -	boolean mddi_waiting_for_llist_avail; -	mddi_host_int_type int_type; -	mddi_host_stat_type stats; -	mddi_log_params_struct_type log_parms; -	mddi_llist_info_type llist_info; -	mddi_linked_list_notify_type llist_notify[MDDI_MAX_NUM_LLIST_ITEMS]; -} mddi_host_cntl_type; - -static mddi_host_type mddi_curr_host = MDDI_HOST_PRIM; -static mddi_host_cntl_type mhctl[MDDI_NUM_HOST_CORES]; -mddi_linked_list_type *llist_extern[MDDI_NUM_HOST_CORES]; -mddi_linked_list_type *llist_dma_extern[MDDI_NUM_HOST_CORES]; -mddi_linked_list_notify_type *llist_extern_notify[MDDI_NUM_HOST_CORES]; -static mddi_log_params_struct_type prev_parms[MDDI_NUM_HOST_CORES]; - -extern uint32 mdp_total_vdopkts; - -static boolean mddi_host_io_clock_on = FALSE; -static boolean mddi_host_hclk_on = FALSE; - -int int_mddi_pri_flag = FALSE; -int int_mddi_ext_flag = FALSE; - -static void mddi_report_errors(uint32 int_reg) -{ -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	if (int_reg & MDDI_INT_PRI_UNDERFLOW) { -		pmhctl->stats.pri_underflow++; -		MDDI_MSG_ERR("!!! MDDI Primary Underflow !!!\n"); -	} -	if (int_reg & MDDI_INT_SEC_UNDERFLOW) { -		pmhctl->stats.sec_underflow++; -		MDDI_MSG_ERR("!!! MDDI Secondary Underflow !!!\n"); -	} -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	if (int_reg & MDDI_INT_REV_OVERFLOW) { -		pmhctl->stats.rev_overflow++; -		MDDI_MSG_ERR("!!! MDDI Reverse Overflow !!!\n"); -		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -		mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val); - -	} -	if (int_reg & MDDI_INT_CRC_ERROR) -		MDDI_MSG_ERR("!!! MDDI Reverse CRC Error !!!\n"); -#endif -	if (int_reg & MDDI_INT_PRI_OVERWRITE) { -		pmhctl->stats.pri_overwrite++; -		MDDI_MSG_ERR("!!! MDDI Primary Overwrite !!!\n"); -	} -	if (int_reg & MDDI_INT_SEC_OVERWRITE) { -		pmhctl->stats.sec_overwrite++; -		MDDI_MSG_ERR("!!! MDDI Secondary Overwrite !!!\n"); -	} -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	if (int_reg & MDDI_INT_REV_OVERWRITE) { -		pmhctl->stats.rev_overwrite++; -		/* This will show up normally and is not a problem */ -		MDDI_MSG_DEBUG("MDDI Reverse Overwrite!\n"); -	} -	if (int_reg & MDDI_INT_RTD_FAILURE) { -		mddi_host_reg_outm(INTEN, MDDI_INT_RTD_FAILURE, 0); -		pmhctl->stats.rtd_failure++; -		MDDI_MSG_ERR("!!! MDDI RTD Failure !!!\n"); -	} -#endif -	if (int_reg & MDDI_INT_DMA_FAILURE) { -		pmhctl->stats.dma_failure++; -		MDDI_MSG_ERR("!!! MDDI DMA Abort !!!\n"); -	} -} - -static void mddi_host_enable_io_clock(void) -{ -	if (!MDDI_HOST_IS_IO_CLOCK_ON) -		MDDI_HOST_ENABLE_IO_CLOCK; -} - -static void mddi_host_enable_hclk(void) -{ - -	if (!MDDI_HOST_IS_HCLK_ON) -		MDDI_HOST_ENABLE_HCLK; -} - -static void mddi_host_disable_io_clock(void) -{ -#ifndef FEATURE_MDDI_HOST_IO_CLOCK_CONTROL_DISABLE -	if (MDDI_HOST_IS_IO_CLOCK_ON) -		MDDI_HOST_DISABLE_IO_CLOCK; -#endif -} - -static void mddi_host_disable_hclk(void) -{ -#ifndef FEATURE_MDDI_HOST_HCLK_CONTROL_DISABLE -	if (MDDI_HOST_IS_HCLK_ON) -		MDDI_HOST_DISABLE_HCLK; -#endif -} - -static void mddi_vote_to_sleep(mddi_host_type host_idx, boolean sleep) -{ -	uint16 vote_mask; - -	if (host_idx == MDDI_HOST_PRIM) -		vote_mask = 0x01; -	else -		vote_mask = 0x02; -} - -static void mddi_report_state_change(uint32 int_reg) -{ -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	if ((pmhctl->saved_int_reg & MDDI_INT_IN_HIBERNATION) && -	    (pmhctl->saved_int_reg & MDDI_INT_LINK_ACTIVE)) { -		/* recover from condition where the io_clock was turned off by the -		   clock driver during a transition to hibernation. The io_clock -		   disable is to prevent MDP/MDDI underruns when changing ARM -		   clock speeds. In the process of halting the ARM, the hclk -		   divider needs to be set to 1. When it is set to 1, there is -		   a small time (usecs) when hclk is off or slow, and this can -		   cause an underrun. To prevent the underrun, clock driver turns -		   off the MDDI io_clock before making the change. */ -		mddi_host_reg_out(CMD, MDDI_CMD_POWERUP); -	} - -	if (int_reg & MDDI_INT_LINK_ACTIVE) { -		pmhctl->link_state = MDDI_LINK_ACTIVE; -		pmhctl->log_parms.link_active_cnt++; -		pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL); -		MDDI_MSG_DEBUG("!!! MDDI Active RTD:0x%x!!!\n", -			       pmhctl->rtd_value); -		/* now interrupt on hibernation */ -		mddi_host_reg_outm(INTEN, -				   (MDDI_INT_IN_HIBERNATION | -				    MDDI_INT_LINK_ACTIVE), -				   MDDI_INT_IN_HIBERNATION); - -#ifdef DEBUG_MDDIHOSTI -		/* if gpio interrupt is enabled, start polling at fastest -		 * registered rate -		 */ -		if (mddi_gpio.polling_enabled) { -			timer_reg(&mddi_gpio_poll_timer, -		mddi_gpio_poll_timer_cb, 0, mddi_gpio.polling_interval, 0); -		} -#endif -#ifndef FEATURE_MDDI_DISABLE_REVERSE -		if (mddi_rev_ptr_workaround) { -			/* HW CR: need to reset reverse register stuff */ -			pmhctl->rev_ptr_written = FALSE; -			pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -		} -#endif -		/* vote on sleep */ -		mddi_vote_to_sleep(host_idx, FALSE); - -		if (host_idx == MDDI_HOST_PRIM) { -			if (mddi_vsync_detect_enabled) { -				/* -				 * Indicate to client specific code that vsync -				 * was enabled, but we did not detect a client -				 * intiated wakeup. The client specific -				 * handler can either reassert vsync detection, -				 * or treat this as a valid vsync. -				 */ -				mddi_client_lcd_vsync_detected(FALSE); -				pmhctl->log_parms.vsync_response_cnt++; -			} -		} -	} -	if (int_reg & MDDI_INT_IN_HIBERNATION) { -		pmhctl->link_state = MDDI_LINK_HIBERNATING; -		pmhctl->log_parms.link_hibernate_cnt++; -		MDDI_MSG_DEBUG("!!! MDDI Hibernating !!!\n"); -		/* now interrupt on link_active */ -#ifdef FEATURE_MDDI_DISABLE_REVERSE -		mddi_host_reg_outm(INTEN, -				   (MDDI_INT_MDDI_IN | -				    MDDI_INT_IN_HIBERNATION | -				    MDDI_INT_LINK_ACTIVE), -				   MDDI_INT_LINK_ACTIVE); -#else -		mddi_host_reg_outm(INTEN, -				   (MDDI_INT_MDDI_IN | -				    MDDI_INT_IN_HIBERNATION | -				    MDDI_INT_LINK_ACTIVE), -				   (MDDI_INT_MDDI_IN | MDDI_INT_LINK_ACTIVE)); - -		pmhctl->rtd_counter = mddi_rtd_frequency; - -		if (pmhctl->rev_state != MDDI_REV_IDLE) { -			/* a rev_encap will not wake up the link, so we do that here */ -			pmhctl->link_state = MDDI_LINK_ACTIVATING; -			mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); -		} -#endif - -		if (pmhctl->disable_hibernation) { -			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE); -			mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); -			pmhctl->link_state = MDDI_LINK_ACTIVATING; -		} -#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY -		if ((pmhctl->llist_info.transmitting_start_idx != -		     UNASSIGNED_INDEX) -		    && -		    ((pmhctl-> -		      saved_int_reg & (MDDI_INT_PRI_LINK_LIST_DONE | -				       MDDI_INT_PRI_PTR_READ)) == -		     MDDI_INT_PRI_PTR_READ)) { -			mddi_linked_list_type *llist_dma; -			llist_dma = pmhctl->llist_dma_ptr; -			/* -			 * All indications are that we have not received a -			 * linked list done interrupt, due to an underrun -			 * condition. Recovery attempt is to send again. -			 */ -			dma_coherent_pre_ops(); -			/* Write to primary pointer register again */ -			mddi_host_reg_out(PRI_PTR, -					  &llist_dma[pmhctl->llist_info. -						     transmitting_start_idx]); -			pmhctl->stats.pri_underrun_detected++; -		} -#endif - -		/* vote on sleep */ -		if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { -			mddi_vote_to_sleep(host_idx, TRUE); -		} - -#ifdef DEBUG_MDDIHOSTI -		/* need to stop polling timer */ -		if (mddi_gpio.polling_enabled) { -			(void) timer_clr(&mddi_gpio_poll_timer, T_NONE); -		} -#endif -	} -} - -void mddi_host_timer_service(unsigned long data) -{ -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	unsigned long flags; -#endif -	mddi_host_type host_idx; -	mddi_host_cntl_type *pmhctl; - -	unsigned long time_ms = MDDI_DEFAULT_TIMER_LENGTH; -	init_timer(&mddi_host_timer); -	mddi_host_timer.function = mddi_host_timer_service; -	mddi_host_timer.data = 0; - -	mddi_host_timer.expires = jiffies + ((time_ms * HZ) / 1000); -	add_timer(&mddi_host_timer); - -	for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES; -	     host_idx++) { -		pmhctl = &(mhctl[host_idx]); -		mddi_log_stats_counter += (uint32) time_ms; -#ifndef FEATURE_MDDI_DISABLE_REVERSE -		pmhctl->rtd_counter += (uint32) time_ms; -		pmhctl->client_status_cnt += (uint32) time_ms; - -		if (host_idx == MDDI_HOST_PRIM) { -			if (pmhctl->client_status_cnt >= -			    mddi_client_status_frequency) { -				if ((pmhctl->link_state == -				     MDDI_LINK_HIBERNATING) -				    && (pmhctl->client_status_cnt > -					mddi_client_status_frequency)) { -					/* -					 * special case where we are hibernating -					 * and mddi_host_isr is not firing, so -					 * kick the link so that the status can -					 * be retrieved -					 */ - -					/* need to wake up link before issuing -					 * rev encap command -					 */ -					MDDI_MSG_INFO("wake up link!\n"); -					spin_lock_irqsave(&mddi_host_spin_lock, -							  flags); -					mddi_host_enable_hclk(); -					mddi_host_enable_io_clock(); -					pmhctl->link_state = -					    MDDI_LINK_ACTIVATING; -					mddi_host_reg_out(CMD, -							  MDDI_CMD_LINK_ACTIVE); -					spin_unlock_irqrestore -					    (&mddi_host_spin_lock, flags); -				} else -				    if ((pmhctl->link_state == MDDI_LINK_ACTIVE) -					&& pmhctl->disable_hibernation) { -					/* -					 * special case where we have disabled -					 * hibernation and mddi_host_isr -					 * is not firing, so enable interrupt -					 * for no pkts pending, which will -					 * generate an interrupt -					 */ -					MDDI_MSG_INFO("kick isr!\n"); -					spin_lock_irqsave(&mddi_host_spin_lock, -							  flags); -					mddi_host_enable_hclk(); -					mddi_host_reg_outm(INTEN, -							   MDDI_INT_NO_CMD_PKTS_PEND, -							   MDDI_INT_NO_CMD_PKTS_PEND); -					spin_unlock_irqrestore -					    (&mddi_host_spin_lock, flags); -				} -			} -		} -#endif /* #ifndef FEATURE_MDDI_DISABLE_REVERSE */ -	} - -	/* Check if logging is turned on */ -	for (host_idx = MDDI_HOST_PRIM; host_idx < MDDI_NUM_HOST_CORES; -	     host_idx++) { -		mddi_log_params_struct_type *prev_ptr = &(prev_parms[host_idx]); -		pmhctl = &(mhctl[host_idx]); - -		if (mddi_debug_log_statistics) { - -			/* get video pkt count from MDP, since MDDI sw cannot know this */ -			pmhctl->log_parms.vid_cnt = mdp_total_vdopkts; - -			if (mddi_log_stats_counter >= mddi_log_stats_frequency) { -				/* mddi_log_stats_counter = 0; */ -				if (mddi_debug_log_statistics) { -					MDDI_MSG_NOTICE -					    ("MDDI Statistics since last report:\n"); -					MDDI_MSG_NOTICE("  Packets sent:\n"); -					MDDI_MSG_NOTICE -					    ("    %d RTD packet(s)\n", -					     pmhctl->log_parms.rtd_cnt - -					     prev_ptr->rtd_cnt); -					if (prev_ptr->rtd_cnt != -					    pmhctl->log_parms.rtd_cnt) { -						unsigned long flags; -						spin_lock_irqsave -						    (&mddi_host_spin_lock, -						     flags); -						mddi_host_enable_hclk(); -						pmhctl->rtd_value = -						    mddi_host_reg_in(RTD_VAL); -						spin_unlock_irqrestore -						    (&mddi_host_spin_lock, -						     flags); -						MDDI_MSG_NOTICE -						    ("      RTD value=%d\n", -						     pmhctl->rtd_value); -					} -					MDDI_MSG_NOTICE -					    ("    %d VIDEO packets\n", -					     pmhctl->log_parms.vid_cnt - -					     prev_ptr->vid_cnt); -					MDDI_MSG_NOTICE -					    ("    %d Register Access packets\n", -					     pmhctl->log_parms.reg_acc_cnt - -					     prev_ptr->reg_acc_cnt); -					MDDI_MSG_NOTICE -					    ("    %d Reverse Encapsulation packet(s)\n", -					     pmhctl->log_parms.rev_enc_cnt - -					     prev_ptr->rev_enc_cnt); -					if (prev_ptr->rev_enc_cnt != -					    pmhctl->log_parms.rev_enc_cnt) { -						/* report # of reverse CRC errors */ -						MDDI_MSG_NOTICE -						    ("      %d reverse CRC errors detected\n", -						     pmhctl->log_parms. -						     rev_crc_cnt - -						     prev_ptr->rev_crc_cnt); -					} -					MDDI_MSG_NOTICE -					    ("  Packets received:\n"); -					MDDI_MSG_NOTICE -					    ("    %d Client Status packets", -					     pmhctl->log_parms.cli_stat_cnt - -					     prev_ptr->cli_stat_cnt); -					if (prev_ptr->cli_stat_cnt != -					    pmhctl->log_parms.cli_stat_cnt) { -						MDDI_MSG_NOTICE -						    ("      %d forward CRC errors reported\n", -						     pmhctl->log_parms. -						     fwd_crc_cnt - -						     prev_ptr->fwd_crc_cnt); -					} -					MDDI_MSG_NOTICE -					    ("    %d Register Access Read packets\n", -					     pmhctl->log_parms.reg_read_cnt - -					     prev_ptr->reg_read_cnt); - -					if (pmhctl->link_state == -					    MDDI_LINK_ACTIVE) { -						MDDI_MSG_NOTICE -						    ("  Current Link Status: Active\n"); -					} else -					    if ((pmhctl->link_state == -						 MDDI_LINK_HIBERNATING) -						|| (pmhctl->link_state == -						    MDDI_LINK_ACTIVATING)) { -						MDDI_MSG_NOTICE -						    ("  Current Link Status: Hibernation\n"); -					} else { -						MDDI_MSG_NOTICE -						    ("  Current Link Status: Inactive\n"); -					} -					MDDI_MSG_NOTICE -					    ("    Active state entered %d times\n", -					     pmhctl->log_parms.link_active_cnt - -					     prev_ptr->link_active_cnt); -					MDDI_MSG_NOTICE -					    ("    Hibernation state entered %d times\n", -					     pmhctl->log_parms. -					     link_hibernate_cnt - -					     prev_ptr->link_hibernate_cnt); -				} -			} -			prev_parms[host_idx] = pmhctl->log_parms; -		} -	} -	if (mddi_log_stats_counter >= mddi_log_stats_frequency) -		mddi_log_stats_counter = 0; - -	return; -}				/* mddi_host_timer_cb */ - -static void mddi_process_link_list_done(void) -{ -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	/* normal forward linked list packet(s) were sent */ -	if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) { -		MDDI_MSG_ERR("**** getting LL done, but no list ****\n"); -	} else { -		uint16 idx; - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -		if (pmhctl->rev_state == MDDI_REV_REG_READ_ISSUED) { -			/* special case where a register read packet was sent */ -			pmhctl->rev_state = MDDI_REV_REG_READ_SENT; -			if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) { -				MDDI_MSG_ERR -				    ("**** getting LL done, but no list ****\n"); -			} -		} -#endif -		for (idx = pmhctl->llist_info.transmitting_start_idx;;) { -			uint16 next_idx = pmhctl->llist_notify[idx].next_idx; -			/* with reg read we don't release the waiting tcb until after -			 * the reverse encapsulation has completed. -			 */ -			if (idx != pmhctl->llist_info.reg_read_idx) { -				/* notify task that may be waiting on this completion */ -				if (pmhctl->llist_notify[idx].waiting) { -					complete(& -						 (pmhctl->llist_notify[idx]. -						  done_comp)); -				} -				if (pmhctl->llist_notify[idx].done_cb != NULL) { -					(*(pmhctl->llist_notify[idx].done_cb)) -					    (); -				} - -				pmhctl->llist_notify[idx].in_use = FALSE; -				pmhctl->llist_notify[idx].waiting = FALSE; -				pmhctl->llist_notify[idx].done_cb = NULL; -				if (idx < MDDI_NUM_DYNAMIC_LLIST_ITEMS) { -					/* static LLIST items are configured only once */ -					pmhctl->llist_notify[idx].next_idx = -					    UNASSIGNED_INDEX; -				} -				/* -				 * currently, all linked list packets are -				 * register access, so we can increment the -				 * counter for that packet type here. -				 */ -				pmhctl->log_parms.reg_acc_cnt++; -			} -			if (idx == pmhctl->llist_info.transmitting_end_idx) -				break; -			idx = next_idx; -			if (idx == UNASSIGNED_INDEX) -				MDDI_MSG_CRIT("MDDI linked list corruption!\n"); -		} - -		pmhctl->llist_info.transmitting_start_idx = UNASSIGNED_INDEX; -		pmhctl->llist_info.transmitting_end_idx = UNASSIGNED_INDEX; - -		if (pmhctl->mddi_waiting_for_llist_avail) { -			if (! -			    (pmhctl-> -			     llist_notify[pmhctl->llist_info.next_free_idx]. -			     in_use)) { -				pmhctl->mddi_waiting_for_llist_avail = FALSE; -				complete(&(pmhctl->mddi_llist_avail_comp)); -			} -		} -	} - -	/* Turn off MDDI_INT_PRI_LINK_LIST_DONE interrupt */ -	mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, 0); - -} - -static void mddi_queue_forward_linked_list(void) -{ -	uint16 first_pkt_index; -	mddi_linked_list_type *llist_dma; -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); -	llist_dma = pmhctl->llist_dma_ptr; - -	first_pkt_index = UNASSIGNED_INDEX; - -	if (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) { -#ifndef FEATURE_MDDI_DISABLE_REVERSE -		if (pmhctl->llist_info.reg_read_waiting) { -			if (pmhctl->rev_state == MDDI_REV_IDLE) { -				/* -				 * we have a register read to send and -				 * can send it now -				 */ -				pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED; -				mddi_reg_read_retry = 0; -				first_pkt_index = -				    pmhctl->llist_info.waiting_start_idx; -				pmhctl->llist_info.reg_read_waiting = FALSE; -			} -		} else -#endif -		{ -			/* -			 * not register read to worry about, go ahead and write -			 * anything that may be on the waiting list. -			 */ -			first_pkt_index = pmhctl->llist_info.waiting_start_idx; -		} -	} - -	if (first_pkt_index != UNASSIGNED_INDEX) { -		pmhctl->llist_info.transmitting_start_idx = -		    pmhctl->llist_info.waiting_start_idx; -		pmhctl->llist_info.transmitting_end_idx = -		    pmhctl->llist_info.waiting_end_idx; -		pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX; -		pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX; - -		/* write to the primary pointer register */ -		MDDI_MSG_DEBUG("MDDI writing primary ptr with idx=%d\n", -			       first_pkt_index); - -		pmhctl->int_type.llist_ptr_write_2++; - -		dma_coherent_pre_ops(); -		mddi_host_reg_out(PRI_PTR, &llist_dma[first_pkt_index]); - -		/* enable interrupt when complete */ -		mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, -				   MDDI_INT_PRI_LINK_LIST_DONE); - -	} - -} - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -static void mddi_read_rev_packet(byte *data_ptr) -{ -	uint16 i, length; -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	uint8 *rev_ptr_overflow = -	    (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE); - -	/* first determine the length and handle invalid lengths */ -	length = *pmhctl->rev_ptr_curr++; -	if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) -		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -	length |= ((*pmhctl->rev_ptr_curr++) << 8); -	if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) -		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -	if (length > (pmhctl->rev_pkt_size - 2)) { -		MDDI_MSG_ERR("Invalid rev pkt length %d\n", length); -		/* rev_pkt_size should always be <= rev_ptr_size so limit to packet size */ -		length = pmhctl->rev_pkt_size - 2; -	} - -	/* If the data pointer is NULL, just increment the pmhctl->rev_ptr_curr. -	 * Loop around if necessary. Don't bother reading the data. -	 */ -	if (data_ptr == NULL) { -		pmhctl->rev_ptr_curr += length; -		if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) -			pmhctl->rev_ptr_curr -= MDDI_REV_BUFFER_SIZE; -		return; -	} - -	data_ptr[0] = length & 0x0ff; -	data_ptr[1] = length >> 8; -	data_ptr += 2; -	/* copy the data to data_ptr byte-at-a-time */ -	for (i = 0; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow); -	     i++) -		*data_ptr++ = *pmhctl->rev_ptr_curr++; -	if (pmhctl->rev_ptr_curr >= rev_ptr_overflow) -		pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -	for (; (i < length) && (pmhctl->rev_ptr_curr < rev_ptr_overflow); i++) -		*data_ptr++ = *pmhctl->rev_ptr_curr++; -} - -static void mddi_process_rev_packets(void) -{ -	uint32 rev_packet_count; -	word i; -	uint32 crc_errors; -	boolean mddi_reg_read_successful = FALSE; -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	pmhctl->log_parms.rev_enc_cnt++; -	if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) && -	    (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED) && -	    (pmhctl->rev_state != MDDI_REV_CLIENT_CAP_ISSUED)) { -		MDDI_MSG_ERR("Wrong state %d for reverse int\n", -			     pmhctl->rev_state); -	} -	/* Turn off MDDI_INT_REV_AVAIL interrupt */ -	mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL, 0); - -	/* Clear rev data avail int */ -	mddi_host_reg_out(INT, MDDI_INT_REV_DATA_AVAIL); - -	/* Get Number of packets */ -	rev_packet_count = mddi_host_reg_in(REV_PKT_CNT); - -#ifndef T_MSM7500 -	/* Clear out rev packet counter */ -	mddi_host_reg_out(REV_PKT_CNT, 0x0000); -#endif - -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) -	if ((pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) && -	    (rev_packet_count > 0) && -	    (mddi_host_core_version == 0x28 || -	     mddi_host_core_version == 0x30)) { - -		uint32 int_reg; -		uint32 max_count = 0; - -		mddi_host_reg_out(REV_PTR, pmhctl->mddi_rev_ptr_write_val); -		int_reg = mddi_host_reg_in(INT); -		while ((int_reg & 0x100000) == 0) { -			udelay(3); -			int_reg = mddi_host_reg_in(INT); -			if (++max_count > 100) -				break; -		} -	} -#endif - -	/* Get CRC error count */ -	crc_errors = mddi_host_reg_in(REV_CRC_ERR); -	if (crc_errors != 0) { -		pmhctl->log_parms.rev_crc_cnt += crc_errors; -		pmhctl->stats.rev_crc_count += crc_errors; -		MDDI_MSG_ERR("!!! MDDI %d Reverse CRC Error(s) !!!\n", -			     crc_errors); -#ifndef T_MSM7500 -		/* Clear CRC error count */ -		mddi_host_reg_out(REV_CRC_ERR, 0x0000); -#endif -		/* also issue an RTD to attempt recovery */ -		pmhctl->rtd_counter = mddi_rtd_frequency; -	} - -	pmhctl->rtd_value = mddi_host_reg_in(RTD_VAL); - -	MDDI_MSG_DEBUG("MDDI rev pkt cnt=%d, ptr=0x%x, RTD:0x%x\n", -		       rev_packet_count, -		       pmhctl->rev_ptr_curr - pmhctl->rev_ptr_start, -		       pmhctl->rtd_value); - -	if (rev_packet_count >= 1) { -		mddi_invalidate_cache_lines((uint32 *) pmhctl->rev_ptr_start, -					    MDDI_REV_BUFFER_SIZE); -	} -	/* order the reads */ -	dma_coherent_post_ops(); -	for (i = 0; i < rev_packet_count; i++) { -		mddi_rev_packet_type *rev_pkt_ptr; - -		mddi_read_rev_packet(rev_packet_data); - -		rev_pkt_ptr = (mddi_rev_packet_type *) rev_packet_data; - -		if (rev_pkt_ptr->packet_length > pmhctl->rev_pkt_size) { -			MDDI_MSG_ERR("!!!invalid packet size: %d\n", -				     rev_pkt_ptr->packet_length); -		} - -		MDDI_MSG_DEBUG("MDDI rev pkt 0x%x size 0x%x\n", -			       rev_pkt_ptr->packet_type, -			       rev_pkt_ptr->packet_length); - -		/* Do whatever you want to do with the data based on the packet type */ -		switch (rev_pkt_ptr->packet_type) { -		case 66:	/* Client Capability */ -			{ -				mddi_client_capability_type -				    *client_capability_pkt_ptr; - -				client_capability_pkt_ptr = -				    (mddi_client_capability_type *) -				    rev_packet_data; -				MDDI_MSG_NOTICE -				    ("Client Capability: Week=%d, Year=%d\n", -				     client_capability_pkt_ptr-> -				     Week_of_Manufacture, -				     client_capability_pkt_ptr-> -				     Year_of_Manufacture); -				memcpy((void *)&mddi_client_capability_pkt, -				       (void *)rev_packet_data, -				       sizeof(mddi_client_capability_type)); -				pmhctl->log_parms.cli_cap_cnt++; -			} -			break; - -		case 70:	/* Display Status */ -			{ -				mddi_client_status_type *client_status_pkt_ptr; - -				client_status_pkt_ptr = -				    (mddi_client_status_type *) rev_packet_data; -				if ((client_status_pkt_ptr->crc_error_count != -				     0) -				    || (client_status_pkt_ptr-> -					reverse_link_request != 0)) { -					MDDI_MSG_ERR -					    ("Client Status: RevReq=%d, CrcErr=%d\n", -					     client_status_pkt_ptr-> -					     reverse_link_request, -					     client_status_pkt_ptr-> -					     crc_error_count); -				} else { -					MDDI_MSG_DEBUG -					    ("Client Status: RevReq=%d, CrcErr=%d\n", -					     client_status_pkt_ptr-> -					     reverse_link_request, -					     client_status_pkt_ptr-> -					     crc_error_count); -				} -				pmhctl->log_parms.fwd_crc_cnt += -				    client_status_pkt_ptr->crc_error_count; -				pmhctl->stats.fwd_crc_count += -				    client_status_pkt_ptr->crc_error_count; -				pmhctl->log_parms.cli_stat_cnt++; -			} -			break; - -		case 146:	/* register access packet */ -			{ -				mddi_register_access_packet_type -				    * regacc_pkt_ptr; - -				regacc_pkt_ptr = -				    (mddi_register_access_packet_type *) -				    rev_packet_data; - -				MDDI_MSG_DEBUG -				    ("Reg Acc parse reg=0x%x, value=0x%x\n", -				     regacc_pkt_ptr->register_address, -				     regacc_pkt_ptr->register_data_list); - -				/* Copy register value to location passed in */ -				if (mddi_reg_read_value_ptr) { -#if defined(T_MSM6280) && !defined(T_MSM7200) -					/* only least significant 16 bits are valid with 6280 */ -					*mddi_reg_read_value_ptr = -					    regacc_pkt_ptr-> -					    register_data_list & 0x0000ffff; -#else -					*mddi_reg_read_value_ptr = -					    regacc_pkt_ptr->register_data_list; -#endif -					mddi_reg_read_successful = TRUE; -					mddi_reg_read_value_ptr = NULL; -				} - -#ifdef DEBUG_MDDIHOSTI -				if ((mddi_gpio.polling_enabled) && -				    (regacc_pkt_ptr->register_address == -				     mddi_gpio.polling_reg)) { -					/* -					 * ToDo: need to call Linux GPIO call -					 * here... -					 */ -					 mddi_client_lcd_gpio_poll( -					 regacc_pkt_ptr->register_data_list); -				} -#endif -				pmhctl->log_parms.reg_read_cnt++; -			} -			break; - -		default:	/* any other packet */ -			{ -				uint16 hdlr; - -				for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; -				     hdlr++) { -					if (mddi_rev_pkt_handler[hdlr]. -					    pkt_type == -					    rev_pkt_ptr->packet_type) { -						(* -						 (mddi_rev_pkt_handler[hdlr]. -						  handler)) (rev_pkt_ptr); -					/* pmhctl->rev_state = MDDI_REV_IDLE; */ -						break; -					} -				} -				if (hdlr >= MAX_MDDI_REV_HANDLERS) -					MDDI_MSG_ERR("MDDI unknown rev pkt\n"); -			} -			break; -		} -	} -	if ((pmhctl->rev_ptr_curr + pmhctl->rev_pkt_size) >= -	    (pmhctl->rev_ptr_start + MDDI_REV_BUFFER_SIZE)) { -		pmhctl->rev_ptr_written = FALSE; -	} - -	if (pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) { -		pmhctl->rev_state = MDDI_REV_IDLE; -		if (mddi_rev_user.waiting) { -			mddi_rev_user.waiting = FALSE; -			complete(&(mddi_rev_user.done_comp)); -		} else if (pmhctl->llist_info.reg_read_idx == UNASSIGNED_INDEX) { -			MDDI_MSG_ERR -			    ("Reverse Encap state, but no reg read in progress\n"); -		} else { -			if ((!mddi_reg_read_successful) && -			    (mddi_reg_read_retry < mddi_reg_read_retry_max) && -			    (mddi_enable_reg_read_retry)) { -				/* -				 * There is a race condition that can happen -				 * where the reverse encapsulation message is -				 * sent out by the MDDI host before the register -				 * read packet is sent. As a work-around for -				 * that problem we issue the reverse -				 * encapsulation one more time before giving up. -				 */ -				if (mddi_enable_reg_read_retry_once) -					mddi_reg_read_retry = -					    mddi_reg_read_retry_max; -				pmhctl->rev_state = MDDI_REV_REG_READ_SENT; -				pmhctl->stats.reg_read_failure++; -			} else { -				uint16 reg_read_idx = -				    pmhctl->llist_info.reg_read_idx; - -				mddi_reg_read_retry = 0; -				if (pmhctl->llist_notify[reg_read_idx].waiting) { -					complete(& -						 (pmhctl-> -						  llist_notify[reg_read_idx]. -						  done_comp)); -				} -				pmhctl->llist_info.reg_read_idx = -				    UNASSIGNED_INDEX; -				if (pmhctl->llist_notify[reg_read_idx]. -				    done_cb != NULL) { -					(* -					 (pmhctl->llist_notify[reg_read_idx]. -					  done_cb)) (); -				} -				pmhctl->llist_notify[reg_read_idx].next_idx = -				    UNASSIGNED_INDEX; -				pmhctl->llist_notify[reg_read_idx].in_use = -				    FALSE; -				pmhctl->llist_notify[reg_read_idx].waiting = -				    FALSE; -				pmhctl->llist_notify[reg_read_idx].done_cb = -				    NULL; -				if (!mddi_reg_read_successful) -					pmhctl->stats.reg_read_failure++; -			} -		} -	} else if (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED) { -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) -		if (mddi_host_core_version == 0x28 || -		    mddi_host_core_version == 0x30) { -			mddi_host_reg_out(FIFO_ALLOC, 0x00); -			pmhctl->rev_ptr_written = TRUE; -			mddi_host_reg_out(REV_PTR, -				pmhctl->mddi_rev_ptr_write_val); -			pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -			mddi_host_reg_out(CMD, 0xC00); -		} -#endif - -		if (mddi_rev_user.waiting) { -			mddi_rev_user.waiting = FALSE; -			complete(&(mddi_rev_user.done_comp)); -		} -		pmhctl->rev_state = MDDI_REV_IDLE; -	} else { -		pmhctl->rev_state = MDDI_REV_IDLE; -	} - -	/* pmhctl->rev_state = MDDI_REV_IDLE; */ - -	/* Re-enable interrupt */ -	mddi_host_reg_outm(INTEN, MDDI_INT_REV_DATA_AVAIL, -			   MDDI_INT_REV_DATA_AVAIL); - -} - -static void mddi_issue_reverse_encapsulation(void) -{ -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); -	/* Only issue a reverse encapsulation packet if: -	 * 1) another reverse is not in progress (MDDI_REV_IDLE). -	 * 2) a register read has been sent (MDDI_REV_REG_READ_SENT). -	 * 3) forward is not in progress, because of a hw bug in client that -	 *    causes forward crc errors on packet immediately after rev encap. -	 */ -	if (((pmhctl->rev_state == MDDI_REV_IDLE) || -	     (pmhctl->rev_state == MDDI_REV_REG_READ_SENT)) && -	    (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) && -	    (!mdp_in_processing)) { -		uint32 mddi_command = MDDI_CMD_SEND_REV_ENCAP; - -		if ((pmhctl->rev_state == MDDI_REV_REG_READ_SENT) || -		    (mddi_rev_encap_user_request == TRUE)) { -			mddi_host_enable_io_clock(); -			if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { -				/* need to wake up link before issuing rev encap command */ -				MDDI_MSG_DEBUG("wake up link!\n"); -				pmhctl->link_state = MDDI_LINK_ACTIVATING; -				mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); -			} else { -				if (pmhctl->rtd_counter >= mddi_rtd_frequency) { -					MDDI_MSG_DEBUG -					    ("mddi sending RTD command!\n"); -					mddi_host_reg_out(CMD, -							  MDDI_CMD_SEND_RTD); -					pmhctl->rtd_counter = 0; -					pmhctl->log_parms.rtd_cnt++; -				} -				if (pmhctl->rev_state != MDDI_REV_REG_READ_SENT) { -					/* this is generic reverse request by user, so -					 * reset the waiting flag. */ -					mddi_rev_encap_user_request = FALSE; -				} -				/* link is active so send reverse encap to get register read results */ -				pmhctl->rev_state = MDDI_REV_ENCAP_ISSUED; -				mddi_command = MDDI_CMD_SEND_REV_ENCAP; -				MDDI_MSG_DEBUG("sending rev encap!\n"); -			} -		} else -		    if ((pmhctl->client_status_cnt >= -			 mddi_client_status_frequency) -			|| mddi_client_capability_request) { -			mddi_host_enable_io_clock(); -			if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { -				/* only wake up the link if it client status is overdue */ -				if ((pmhctl->client_status_cnt >= -				     (mddi_client_status_frequency * 2)) -				    || mddi_client_capability_request) { -					/* need to wake up link before issuing rev encap command */ -					MDDI_MSG_DEBUG("wake up link!\n"); -					pmhctl->link_state = -					    MDDI_LINK_ACTIVATING; -					mddi_host_reg_out(CMD, -							  MDDI_CMD_LINK_ACTIVE); -				} -			} else { -				if (pmhctl->rtd_counter >= mddi_rtd_frequency) { -					MDDI_MSG_DEBUG -					    ("mddi sending RTD command!\n"); -					mddi_host_reg_out(CMD, -							  MDDI_CMD_SEND_RTD); -					pmhctl->rtd_counter = 0; -					pmhctl->log_parms.rtd_cnt++; -				} -				/* periodically get client status */ -				MDDI_MSG_DEBUG -				    ("mddi sending rev enc! (get status)\n"); -				if (mddi_client_capability_request) { -					pmhctl->rev_state = -					    MDDI_REV_CLIENT_CAP_ISSUED; -					mddi_command = MDDI_CMD_GET_CLIENT_CAP; -					mddi_client_capability_request = FALSE; -				} else { -					pmhctl->rev_state = -					    MDDI_REV_STATUS_REQ_ISSUED; -					pmhctl->client_status_cnt = 0; -					mddi_command = -					    MDDI_CMD_GET_CLIENT_STATUS; -				} -			} -		} -		if ((pmhctl->rev_state == MDDI_REV_ENCAP_ISSUED) || -		    (pmhctl->rev_state == MDDI_REV_STATUS_REQ_ISSUED) || -		    (pmhctl->rev_state == MDDI_REV_CLIENT_CAP_ISSUED)) { -			pmhctl->int_type.rev_encap_count++; -#if defined(T_MSM6280) && !defined(T_MSM7200) -			mddi_rev_pointer_written = TRUE; -			mddi_host_reg_out(REV_PTR, mddi_rev_ptr_write_val); -			mddi_rev_ptr_curr = mddi_rev_ptr_start; -			/* force new rev ptr command */ -			mddi_host_reg_out(CMD, 0xC00); -#else -			if (!pmhctl->rev_ptr_written) { -				MDDI_MSG_DEBUG("writing reverse pointer!\n"); -				pmhctl->rev_ptr_written = TRUE; -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) -				if ((pmhctl->rev_state == -				     MDDI_REV_CLIENT_CAP_ISSUED) && -				    (mddi_host_core_version == 0x28 || -				     mddi_host_core_version == 0x30)) { -					pmhctl->rev_ptr_written = FALSE; -					mddi_host_reg_out(FIFO_ALLOC, 0x02); -				} else -					mddi_host_reg_out(REV_PTR, -						  pmhctl-> -						  mddi_rev_ptr_write_val); -#else -				mddi_host_reg_out(REV_PTR, -						  pmhctl-> -						  mddi_rev_ptr_write_val); -#endif -			} -#endif -			if (mddi_debug_clear_rev_data) { -				uint16 i; -				for (i = 0; i < MDDI_MAX_REV_DATA_SIZE / 4; i++) -					pmhctl->rev_data_buf[i] = 0xdddddddd; -				/* clean cache */ -				mddi_flush_cache_lines(pmhctl->rev_data_buf, -						       MDDI_MAX_REV_DATA_SIZE); -			} - -			/* send reverse encapsulation to get needed data */ -			mddi_host_reg_out(CMD, mddi_command); -		} -	} - -} - -static void mddi_process_client_initiated_wakeup(void) -{ -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	/* Disable MDDI_INT Interrupt, we detect client initiated wakeup one -	 * time for each entry into hibernation */ -	mddi_host_reg_outm(INTEN, MDDI_INT_MDDI_IN, 0); - -	if (host_idx == MDDI_HOST_PRIM) { -		if (mddi_vsync_detect_enabled) { -			mddi_host_enable_io_clock(); -#ifndef MDDI_HOST_DISP_LISTEN -			/* issue command to bring up link */ -			/* need to do this to clear the vsync condition */ -			if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { -				pmhctl->link_state = MDDI_LINK_ACTIVATING; -				mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); -			} -#endif -			/* -			 * Indicate to client specific code that vsync was -			 * enabled, and we did not detect a client initiated -			 * wakeup. The client specific handler can clear the -			 * condition if necessary to prevent subsequent -			 * client initiated wakeups. -			 */ -			mddi_client_lcd_vsync_detected(TRUE); -			pmhctl->log_parms.vsync_response_cnt++; -			MDDI_MSG_NOTICE("MDDI_INT_IN condition\n"); - -		} -	} - -	if (mddi_gpio.polling_enabled) { -		mddi_host_enable_io_clock(); -		/* check interrupt status now */ -		(void)mddi_queue_register_read_int(mddi_gpio.polling_reg, -						   &mddi_gpio.polling_val); -	} -} -#endif /* FEATURE_MDDI_DISABLE_REVERSE */ - -static void mddi_host_isr(void) -{ -	uint32 int_reg, int_en; -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	uint32 status_reg; -#endif -	mddi_host_type host_idx = mddi_curr_host; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	if (!MDDI_HOST_IS_HCLK_ON) { -		MDDI_HOST_ENABLE_HCLK; -		MDDI_MSG_DEBUG("HCLK disabled, but isr is firing\n"); -	} -	int_reg = mddi_host_reg_in(INT); -	int_en = mddi_host_reg_in(INTEN); -	pmhctl->saved_int_reg = int_reg; -	pmhctl->saved_int_en = int_en; -	int_reg = int_reg & int_en; -	pmhctl->int_type.count++; - - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	status_reg = mddi_host_reg_in(STAT); - -	if ((int_reg & MDDI_INT_MDDI_IN) || -	    ((int_en & MDDI_INT_MDDI_IN) && -	     ((int_reg == 0) || (status_reg & MDDI_STAT_CLIENT_WAKEUP_REQ)))) { -		/* -		 * The MDDI_IN condition will clear itself, and so it is -		 * possible that MDDI_IN was the reason for the isr firing, -		 * even though the interrupt register does not have the -		 * MDDI_IN bit set. To check if this was the case we need to -		 * look at the status register bit that signifies a client -		 * initiated wakeup. If the status register bit is set, as well -		 * as the MDDI_IN interrupt enabled, then we treat this as a -		 * client initiated wakeup. -		 */ -		if (int_reg & MDDI_INT_MDDI_IN) -			pmhctl->int_type.in_count++; -		mddi_process_client_initiated_wakeup(); -	} -#endif - -	if (int_reg & MDDI_INT_LINK_STATE_CHANGES) { -		pmhctl->int_type.state_change_count++; -		mddi_report_state_change(int_reg); -	} - -	if (int_reg & MDDI_INT_PRI_LINK_LIST_DONE) { -		pmhctl->int_type.ll_done_count++; -		mddi_process_link_list_done(); -	} -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	if (int_reg & MDDI_INT_REV_DATA_AVAIL) { -		pmhctl->int_type.rev_avail_count++; -		mddi_process_rev_packets(); -	} -#endif - -	if (int_reg & MDDI_INT_ERROR_CONDITIONS) { -		pmhctl->int_type.error_count++; -		mddi_report_errors(int_reg); - -		mddi_host_reg_out(INT, int_reg & MDDI_INT_ERROR_CONDITIONS); -	} -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	mddi_issue_reverse_encapsulation(); - -	if ((pmhctl->rev_state != MDDI_REV_ENCAP_ISSUED) && -	    (pmhctl->rev_state != MDDI_REV_STATUS_REQ_ISSUED)) -#endif -		/* don't want simultaneous reverse and forward with Eagle */ -		mddi_queue_forward_linked_list(); - -	if (int_reg & MDDI_INT_NO_CMD_PKTS_PEND) { -		/* this interrupt is used to kick the isr when hibernation is disabled */ -		mddi_host_reg_outm(INTEN, MDDI_INT_NO_CMD_PKTS_PEND, 0); -	} - -	if ((!mddi_host_mdp_active_flag) && -	    (!mddi_vsync_detect_enabled) && -	    (pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) && -	    (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) && -	    (pmhctl->rev_state == MDDI_REV_IDLE)) { -		if (pmhctl->link_state == MDDI_LINK_HIBERNATING) { -			mddi_host_disable_io_clock(); -			mddi_host_disable_hclk(); -		} -#ifdef FEATURE_MDDI_HOST_ENABLE_EARLY_HIBERNATION -		else if ((pmhctl->link_state == MDDI_LINK_ACTIVE) && -			 (!pmhctl->disable_hibernation)) { -			mddi_host_reg_out(CMD, MDDI_CMD_POWERDOWN); -		} -#endif -	} -} - -static void mddi_host_isr_primary(void) -{ -	mddi_curr_host = MDDI_HOST_PRIM; -	mddi_host_isr(); -} - -irqreturn_t mddi_pmdh_isr_proxy(int irq, void *ptr) -{ -	mddi_host_isr_primary(); -	return IRQ_HANDLED; -} - -static void mddi_host_isr_external(void) -{ -	mddi_curr_host = MDDI_HOST_EXT; -	mddi_host_isr(); -	mddi_curr_host = MDDI_HOST_PRIM; -} - -irqreturn_t mddi_emdh_isr_proxy(int irq, void *ptr) -{ -	mddi_host_isr_external(); -	return IRQ_HANDLED; -} - -static void mddi_host_initialize_registers(mddi_host_type host_idx) -{ -	uint32 pad_reg_val; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	if (pmhctl->driver_state == MDDI_DRIVER_ENABLED) -		return; - -	/* turn on HCLK to MDDI host core */ -	mddi_host_enable_hclk(); - -	/* MDDI Reset command */ -	mddi_host_reg_out(CMD, MDDI_CMD_RESET); - -	/* Version register (= 0x01) */ -	mddi_host_reg_out(VERSION, 0x0001); - -	/* Bytes per subframe register */ -	mddi_host_reg_out(BPS, MDDI_HOST_BYTES_PER_SUBFRAME); - -	/* Subframes per media frames register (= 0x03) */ -	mddi_host_reg_out(SPM, 0x0003); - -	/* Turn Around 1 register (= 0x05) */ -	mddi_host_reg_out(TA1_LEN, 0x0005); - -	/* Turn Around 2 register (= 0x0C) */ -	mddi_host_reg_out(TA2_LEN, MDDI_HOST_TA2_LEN); - -	/* Drive hi register (= 0x96) */ -	mddi_host_reg_out(DRIVE_HI, 0x0096); - -	/* Drive lo register (= 0x32) */ -	mddi_host_reg_out(DRIVE_LO, 0x0032); - -	/* Display wakeup count register (= 0x3c) */ -	mddi_host_reg_out(DISP_WAKE, 0x003c); - -	/* Reverse Rate Divisor register (= 0x2) */ -	mddi_host_reg_out(REV_RATE_DIV, MDDI_HOST_REV_RATE_DIV); - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	/* Reverse Pointer Size */ -	mddi_host_reg_out(REV_SIZE, MDDI_REV_BUFFER_SIZE); - -	/* Rev Encap Size */ -	mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size); -#endif - -	/* Periodic Rev Encap */ -	/* don't send periodically */ -	mddi_host_reg_out(CMD, MDDI_CMD_PERIODIC_REV_ENCAP); - -	pad_reg_val = mddi_host_reg_in(PAD_CTL); -	if (pad_reg_val == 0) { -		/* If we are turning on band gap, need to wait 5us before turning -		 * on the rest of the PAD */ -		mddi_host_reg_out(PAD_CTL, 0x08000); -		udelay(5); -	} -#ifdef T_MSM7200 -	/* Recommendation from PAD hw team */ -	mddi_host_reg_out(PAD_CTL, 0xa850a); -#else -	/* Recommendation from PAD hw team */ -	mddi_host_reg_out(PAD_CTL, 0xa850f); -#endif - -#if defined(CONFIG_FB_MSM_MDP31) || defined(CONFIG_FB_MSM_MDP40) -	mddi_host_reg_out(PAD_IO_CTL, 0x00320000); -	mddi_host_reg_out(PAD_CAL, 0x00220020); -#endif - -	mddi_host_core_version = mddi_host_reg_inm(CORE_VER, 0xffff); - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	if (mddi_host_core_version >= 8) -		mddi_rev_ptr_workaround = FALSE; -	pmhctl->rev_ptr_curr = pmhctl->rev_ptr_start; -#endif - -	if ((mddi_host_core_version > 8) && (mddi_host_core_version < 0x19)) -		mddi_host_reg_out(TEST, 0x2); - -	/* Need an even number for counts */ -	mddi_host_reg_out(DRIVER_START_CNT, 0x60006); - -#ifndef T_MSM7500 -	/* Setup defaults for MDP related register */ -	mddi_host_reg_out(MDP_VID_FMT_DES, 0x5666); -	mddi_host_reg_out(MDP_VID_PIX_ATTR, 0x00C3); -	mddi_host_reg_out(MDP_VID_CLIENTID, 0); -#endif - -	/* automatically hibernate after 1 empty subframe */ -	if (pmhctl->disable_hibernation) -		mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE); -	else -		mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1); - -	/* Bring up link if display (client) requests it */ -#ifdef MDDI_HOST_DISP_LISTEN -	mddi_host_reg_out(CMD, MDDI_CMD_DISP_LISTEN); -#else -	mddi_host_reg_out(CMD, MDDI_CMD_DISP_IGNORE); -#endif - -} - -void mddi_host_configure_interrupts(mddi_host_type host_idx, boolean enable) -{ -	unsigned long flags; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	spin_lock_irqsave(&mddi_host_spin_lock, flags); - -	/* turn on HCLK to MDDI host core if it has been disabled */ -	mddi_host_enable_hclk(); -	/* Clear MDDI Interrupt enable reg */ -	mddi_host_reg_out(INTEN, 0); - -	spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -	if (enable) { -		pmhctl->driver_state = MDDI_DRIVER_ENABLED; - -		if (host_idx == MDDI_HOST_PRIM) { -			if (request_irq -			    (INT_MDDI_PRI, mddi_pmdh_isr_proxy, IRQF_DISABLED, -			     "PMDH", 0) != 0) -				printk(KERN_ERR -				       "a mddi: unable to request_irq\n"); -			else -				int_mddi_pri_flag = TRUE; -		} else { -			if (request_irq -			    (INT_MDDI_EXT, mddi_emdh_isr_proxy, IRQF_DISABLED, -			     "EMDH", 0) != 0) -				printk(KERN_ERR -				       "b mddi: unable to request_irq\n"); -			else -				int_mddi_ext_flag = TRUE; -		} - -		/* Set MDDI Interrupt enable reg -- Enable Reverse data avail */ -#ifdef FEATURE_MDDI_DISABLE_REVERSE -		mddi_host_reg_out(INTEN, -				  MDDI_INT_ERROR_CONDITIONS | -				  MDDI_INT_LINK_STATE_CHANGES); -#else -		/* Reverse Pointer register */ -		pmhctl->rev_ptr_written = FALSE; - -		mddi_host_reg_out(INTEN, -				  MDDI_INT_REV_DATA_AVAIL | -				  MDDI_INT_ERROR_CONDITIONS | -				  MDDI_INT_LINK_STATE_CHANGES); -		pmhctl->rtd_counter = mddi_rtd_frequency; -		pmhctl->client_status_cnt = 0; -#endif -	} else { -		if (pmhctl->driver_state == MDDI_DRIVER_ENABLED) -			pmhctl->driver_state = MDDI_DRIVER_DISABLED; -	} - -} - -static void mddi_host_powerup(mddi_host_type host_idx) -{ -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	if (pmhctl->link_state != MDDI_LINK_DISABLED) -		return; - -	/* enable IO_CLK and hclk to MDDI host core */ -	mddi_host_enable_io_clock(); - -	mddi_host_initialize_registers(host_idx); -	mddi_host_configure_interrupts(host_idx, TRUE); - -	pmhctl->link_state = MDDI_LINK_ACTIVATING; - -	/* Link activate command */ -	mddi_host_reg_out(CMD, MDDI_CMD_LINK_ACTIVE); - -#ifdef CLKRGM_MDDI_IO_CLOCK_IN_MHZ -	MDDI_MSG_NOTICE("MDDI Host: Activating Link %d Mbps\n", -			CLKRGM_MDDI_IO_CLOCK_IN_MHZ * 2); -#else -	MDDI_MSG_NOTICE("MDDI Host: Activating Link\n"); -#endif - -	/* Initialize the timer */ -	if (host_idx == MDDI_HOST_PRIM) -		mddi_host_timer_service(0); -} - -void mddi_host_init(mddi_host_type host_idx) -/* Write out the MDDI configuration registers */ -{ -	static boolean initialized = FALSE; -	mddi_host_cntl_type *pmhctl; - -	if (host_idx >= MDDI_NUM_HOST_CORES) { -		MDDI_MSG_ERR("Invalid host core index\n"); -		return; -	} - -	if (!initialized) { -		uint16 idx; -		mddi_host_type host; -		for (host = MDDI_HOST_PRIM; host < MDDI_NUM_HOST_CORES; host++) { -			pmhctl = &(mhctl[host]); -			initialized = TRUE; - -			pmhctl->llist_ptr = -			    dma_alloc_coherent(NULL, MDDI_LLIST_POOL_SIZE, -					       &(pmhctl->llist_dma_addr), -					       GFP_KERNEL); -			pmhctl->llist_dma_ptr = -			    (mddi_linked_list_type *) (void *)pmhctl-> -			    llist_dma_addr; -#ifdef FEATURE_MDDI_DISABLE_REVERSE -			pmhctl->rev_data_buf = NULL; -			if (pmhctl->llist_ptr == NULL) -#else -			mddi_rev_user.waiting = FALSE; -			init_completion(&(mddi_rev_user.done_comp)); -			pmhctl->rev_data_buf = -			    dma_alloc_coherent(NULL, MDDI_MAX_REV_DATA_SIZE, -					       &(pmhctl->rev_data_dma_addr), -					       GFP_KERNEL); -			if ((pmhctl->llist_ptr == NULL) -			    || (pmhctl->rev_data_buf == NULL)) -#endif -			{ -				MDDI_MSG_CRIT -				    ("unable to alloc non-cached memory\n"); -			} -			llist_extern[host] = pmhctl->llist_ptr; -			llist_dma_extern[host] = pmhctl->llist_dma_ptr; -			llist_extern_notify[host] = pmhctl->llist_notify; - -			for (idx = 0; idx < UNASSIGNED_INDEX; idx++) { -				init_completion(& -						(pmhctl->llist_notify[idx]. -						 done_comp)); -			} -			init_completion(&(pmhctl->mddi_llist_avail_comp)); -			spin_lock_init(&mddi_host_spin_lock); -			pmhctl->mddi_waiting_for_llist_avail = FALSE; -			pmhctl->mddi_rev_ptr_write_val = -			    (uint32) (void *)(pmhctl->rev_data_dma_addr); -			pmhctl->rev_ptr_start = (void *)pmhctl->rev_data_buf; - -			pmhctl->rev_pkt_size = MDDI_DEFAULT_REV_PKT_SIZE; -			pmhctl->rev_state = MDDI_REV_IDLE; -#ifdef IMAGE_MODEM_PROC -			/* assume hibernation state is last state from APPS proc, so that -			 * we don't reinitialize the host core */ -			pmhctl->link_state = MDDI_LINK_HIBERNATING; -#else -			pmhctl->link_state = MDDI_LINK_DISABLED; -#endif -			pmhctl->driver_state = MDDI_DRIVER_DISABLED; -			pmhctl->disable_hibernation = FALSE; - -			/* initialize llist variables */ -			pmhctl->llist_info.transmitting_start_idx = -			    UNASSIGNED_INDEX; -			pmhctl->llist_info.transmitting_end_idx = -			    UNASSIGNED_INDEX; -			pmhctl->llist_info.waiting_start_idx = UNASSIGNED_INDEX; -			pmhctl->llist_info.waiting_end_idx = UNASSIGNED_INDEX; -			pmhctl->llist_info.reg_read_idx = UNASSIGNED_INDEX; -			pmhctl->llist_info.next_free_idx = -			    MDDI_FIRST_DYNAMIC_LLIST_IDX; -			pmhctl->llist_info.reg_read_waiting = FALSE; - -			mddi_vsync_detect_enabled = FALSE; -			mddi_gpio.polling_enabled = FALSE; - -			pmhctl->int_type.count = 0; -			pmhctl->int_type.in_count = 0; -			pmhctl->int_type.disp_req_count = 0; -			pmhctl->int_type.state_change_count = 0; -			pmhctl->int_type.ll_done_count = 0; -			pmhctl->int_type.rev_avail_count = 0; -			pmhctl->int_type.error_count = 0; -			pmhctl->int_type.rev_encap_count = 0; -			pmhctl->int_type.llist_ptr_write_1 = 0; -			pmhctl->int_type.llist_ptr_write_2 = 0; - -			pmhctl->stats.fwd_crc_count = 0; -			pmhctl->stats.rev_crc_count = 0; -			pmhctl->stats.pri_underflow = 0; -			pmhctl->stats.sec_underflow = 0; -			pmhctl->stats.rev_overflow = 0; -			pmhctl->stats.pri_overwrite = 0; -			pmhctl->stats.sec_overwrite = 0; -			pmhctl->stats.rev_overwrite = 0; -			pmhctl->stats.dma_failure = 0; -			pmhctl->stats.rtd_failure = 0; -			pmhctl->stats.reg_read_failure = 0; -#ifdef FEATURE_MDDI_UNDERRUN_RECOVERY -			pmhctl->stats.pri_underrun_detected = 0; -#endif - -			pmhctl->log_parms.rtd_cnt = 0; -			pmhctl->log_parms.rev_enc_cnt = 0; -			pmhctl->log_parms.vid_cnt = 0; -			pmhctl->log_parms.reg_acc_cnt = 0; -			pmhctl->log_parms.cli_stat_cnt = 0; -			pmhctl->log_parms.cli_cap_cnt = 0; -			pmhctl->log_parms.reg_read_cnt = 0; -			pmhctl->log_parms.link_active_cnt = 0; -			pmhctl->log_parms.link_hibernate_cnt = 0; -			pmhctl->log_parms.fwd_crc_cnt = 0; -			pmhctl->log_parms.rev_crc_cnt = 0; -			pmhctl->log_parms.vsync_response_cnt = 0; - -			prev_parms[host_idx] = pmhctl->log_parms; -			mddi_client_capability_pkt.packet_length = 0; -		} - -#ifndef T_MSM7500 -		/* tell clock driver we are user of this PLL */ -		MDDI_HOST_ENABLE_IO_CLOCK; -#endif -	} - -	mddi_host_powerup(host_idx); -	pmhctl = &(mhctl[host_idx]); -} - -#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT -static uint32 mddi_client_id; - -uint32 mddi_get_client_id(void) -{ - -#ifndef FEATURE_MDDI_DISABLE_REVERSE -	mddi_host_type host_idx = MDDI_HOST_PRIM; -	static boolean client_detection_try = FALSE; -	mddi_host_cntl_type *pmhctl; -	unsigned long flags; -	uint16 saved_rev_pkt_size; - -	if (!client_detection_try) { -		/* Toshiba display requires larger drive_lo value */ -		mddi_host_reg_out(DRIVE_LO, 0x0050); - -		pmhctl = &(mhctl[MDDI_HOST_PRIM]); - -		saved_rev_pkt_size = pmhctl->rev_pkt_size; - -		/* Increase Rev Encap Size */ -		pmhctl->rev_pkt_size = MDDI_CLIENT_CAPABILITY_REV_PKT_SIZE; -		mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size); - -		/* disable hibernation temporarily */ -		if (!pmhctl->disable_hibernation) -			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE); - -		mddi_rev_user.waiting = TRUE; -		INIT_COMPLETION(mddi_rev_user.done_comp); - -		spin_lock_irqsave(&mddi_host_spin_lock, flags); - -		/* turn on clock(s), if they have been disabled */ -		mddi_host_enable_hclk(); -		mddi_host_enable_io_clock(); - -		mddi_client_capability_request = TRUE; - -		if (pmhctl->rev_state == MDDI_REV_IDLE) { -			/* attempt to send the reverse encapsulation now */ -			mddi_issue_reverse_encapsulation(); -		} -		spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -		wait_for_completion_killable(&(mddi_rev_user.done_comp)); - -		/* Set Rev Encap Size back to its original value */ -		pmhctl->rev_pkt_size = saved_rev_pkt_size; -		mddi_host_reg_out(REV_ENCAP_SZ, pmhctl->rev_pkt_size); - -		/* reenable auto-hibernate */ -		if (!pmhctl->disable_hibernation) -			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1); - -		mddi_host_reg_out(DRIVE_LO, 0x0032); -		client_detection_try = TRUE; - -		mddi_client_id = (mddi_client_capability_pkt.Mfr_Name<<16) | -				mddi_client_capability_pkt.Product_Code; - -		if (!mddi_client_id) -			mddi_disable(1); -	} - -#if 0 -	switch (mddi_client_capability_pkt.Mfr_Name) { -	case 0x4474: -		if ((mddi_client_capability_pkt.Product_Code != 0x8960) && -		    (target == DISPLAY_1)) { -			ret = PRISM_WVGA; -		} -		break; - -	case 0xD263: -		if (target == DISPLAY_1) -			ret = TOSHIBA_VGA_PRIM; -		else if (target == DISPLAY_2) -			ret = TOSHIBA_QCIF_SECD; -		break; - -	case 0: -		if (mddi_client_capability_pkt.Product_Code == 0x8835) { -			if (target == DISPLAY_1) -				ret = SHARP_QVGA_PRIM; -			else if (target == DISPLAY_2) -				ret = SHARP_128x128_SECD; -		} -		break; - -	default: -		break; -	} - -	if ((!client_detection_try) && (ret != TOSHIBA_VGA_PRIM) -	    && (ret != TOSHIBA_QCIF_SECD)) { -		/* Not a Toshiba display, so change drive_lo back to default value */ -		mddi_host_reg_out(DRIVE_LO, 0x0032); -	} -#endif - -#endif - -	return mddi_client_id; -} -#endif - -void mddi_host_powerdown(mddi_host_type host_idx) -{ -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	if (host_idx >= MDDI_NUM_HOST_CORES) { -		MDDI_MSG_ERR("Invalid host core index\n"); -		return; -	} - -	if (pmhctl->driver_state == MDDI_DRIVER_RESET) { -		return; -	} - -	if (host_idx == MDDI_HOST_PRIM) { -		/* disable timer */ -		del_timer(&mddi_host_timer); -	} - -	mddi_host_configure_interrupts(host_idx, FALSE); - -	/* turn on HCLK to MDDI host core if it has been disabled */ -	mddi_host_enable_hclk(); - -	/* MDDI Reset command */ -	mddi_host_reg_out(CMD, MDDI_CMD_RESET); - -	/* Pad Control Register */ -	mddi_host_reg_out(PAD_CTL, 0x0); - -	/* disable IO_CLK and hclk to MDDI host core */ -	mddi_host_disable_io_clock(); -	mddi_host_disable_hclk(); - -	pmhctl->link_state = MDDI_LINK_DISABLED; -	pmhctl->driver_state = MDDI_DRIVER_RESET; - -	MDDI_MSG_NOTICE("MDDI Host: Disabling Link\n"); - -} - -uint16 mddi_get_next_free_llist_item(mddi_host_type host_idx, boolean wait) -{ -	unsigned long flags; -	uint16 ret_idx; -	boolean forced_wait = FALSE; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	ret_idx = pmhctl->llist_info.next_free_idx; - -	pmhctl->llist_info.next_free_idx++; -	if (pmhctl->llist_info.next_free_idx >= MDDI_NUM_DYNAMIC_LLIST_ITEMS) -		pmhctl->llist_info.next_free_idx = MDDI_FIRST_DYNAMIC_LLIST_IDX; -	spin_lock_irqsave(&mddi_host_spin_lock, flags); -	if (pmhctl->llist_notify[ret_idx].in_use) { -		if (!wait) { -			pmhctl->llist_info.next_free_idx = ret_idx; -			ret_idx = UNASSIGNED_INDEX; -		} else { -			forced_wait = TRUE; -			INIT_COMPLETION(pmhctl->mddi_llist_avail_comp); -		} -	} -	spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -	if (forced_wait) { -		wait_for_completion_killable(& -						  (pmhctl-> -						   mddi_llist_avail_comp)); -		MDDI_MSG_ERR("task waiting on mddi llist item\n"); -	} - -	if (ret_idx != UNASSIGNED_INDEX) { -		pmhctl->llist_notify[ret_idx].waiting = FALSE; -		pmhctl->llist_notify[ret_idx].done_cb = NULL; -		pmhctl->llist_notify[ret_idx].in_use = TRUE; -		pmhctl->llist_notify[ret_idx].next_idx = UNASSIGNED_INDEX; -	} - -	return ret_idx; -} - -uint16 mddi_get_reg_read_llist_item(mddi_host_type host_idx, boolean wait) -{ -#ifdef FEATURE_MDDI_DISABLE_REVERSE -	MDDI_MSG_CRIT("No reverse link available\n"); -	(void)wait; -	return FALSE; -#else -	unsigned long flags; -	uint16 ret_idx; -	boolean error = FALSE; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	spin_lock_irqsave(&mddi_host_spin_lock, flags); -	if (pmhctl->llist_info.reg_read_idx != UNASSIGNED_INDEX) { -		/* need to block here or is this an error condition? */ -		error = TRUE; -		ret_idx = UNASSIGNED_INDEX; -	} -	spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -	if (!error) { -		ret_idx = pmhctl->llist_info.reg_read_idx = -		    mddi_get_next_free_llist_item(host_idx, wait); -		/* clear the reg_read_waiting flag */ -		pmhctl->llist_info.reg_read_waiting = FALSE; -	} - -	if (error) -		MDDI_MSG_ERR("***** Reg read still in progress! ****\n"); -	return ret_idx; -#endif - -} - -void mddi_queue_forward_packets(uint16 first_llist_idx, -				uint16 last_llist_idx, -				boolean wait, -				mddi_llist_done_cb_type llist_done_cb, -				mddi_host_type host_idx) -{ -	unsigned long flags; -	mddi_linked_list_type *llist; -	mddi_linked_list_type *llist_dma; -	mddi_host_cntl_type *pmhctl = &(mhctl[host_idx]); - -	if ((first_llist_idx >= UNASSIGNED_INDEX) || -	    (last_llist_idx >= UNASSIGNED_INDEX)) { -		MDDI_MSG_ERR("MDDI queueing invalid linked list\n"); -		return; -	} - -	if (pmhctl->link_state == MDDI_LINK_DISABLED) -		MDDI_MSG_CRIT("MDDI host powered down!\n"); - -	llist = pmhctl->llist_ptr; -	llist_dma = pmhctl->llist_dma_ptr; - -	/* clean cache so MDDI host can read data */ -	memory_barrier(); - -	pmhctl->llist_notify[last_llist_idx].waiting = wait; -	if (wait) -		INIT_COMPLETION(pmhctl->llist_notify[last_llist_idx].done_comp); -	pmhctl->llist_notify[last_llist_idx].done_cb = llist_done_cb; - -	spin_lock_irqsave(&mddi_host_spin_lock, flags); - -	if ((pmhctl->llist_info.transmitting_start_idx == UNASSIGNED_INDEX) && -	    (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) && -	    (pmhctl->rev_state == MDDI_REV_IDLE)) { -		/* no packets are currently transmitting */ -#ifndef FEATURE_MDDI_DISABLE_REVERSE -		if (first_llist_idx == pmhctl->llist_info.reg_read_idx) { -			/* This is the special case where the packet is a register read. */ -			pmhctl->rev_state = MDDI_REV_REG_READ_ISSUED; -			mddi_reg_read_retry = 0; -			/* mddi_rev_reg_read_attempt = 1; */ -		} -#endif -		/* assign transmitting index values */ -		pmhctl->llist_info.transmitting_start_idx = first_llist_idx; -		pmhctl->llist_info.transmitting_end_idx = last_llist_idx; - -		/* turn on clock(s), if they have been disabled */ -		mddi_host_enable_hclk(); -		mddi_host_enable_io_clock(); -		pmhctl->int_type.llist_ptr_write_1++; -		/* Write to primary pointer register */ -		dma_coherent_pre_ops(); -		mddi_host_reg_out(PRI_PTR, &llist_dma[first_llist_idx]); - -		/* enable interrupt when complete */ -		mddi_host_reg_outm(INTEN, MDDI_INT_PRI_LINK_LIST_DONE, -				   MDDI_INT_PRI_LINK_LIST_DONE); - -	} else if (pmhctl->llist_info.waiting_start_idx == UNASSIGNED_INDEX) { -#ifndef FEATURE_MDDI_DISABLE_REVERSE -		if (first_llist_idx == pmhctl->llist_info.reg_read_idx) { -			/* -			 * we have a register read to send but need to wait -			 * for current reverse activity to end or there are -			 * packets currently transmitting -			 */ -			/* mddi_rev_reg_read_attempt = 0; */ -			pmhctl->llist_info.reg_read_waiting = TRUE; -		} -#endif - -		/* assign waiting index values */ -		pmhctl->llist_info.waiting_start_idx = first_llist_idx; -		pmhctl->llist_info.waiting_end_idx = last_llist_idx; -	} else { -		uint16 prev_end_idx = pmhctl->llist_info.waiting_end_idx; -#ifndef FEATURE_MDDI_DISABLE_REVERSE -		if (first_llist_idx == pmhctl->llist_info.reg_read_idx) { -			/* -			 * we have a register read to send but need to wait -			 * for current reverse activity to end or there are -			 * packets currently transmitting -			 */ -			/* mddi_rev_reg_read_attempt = 0; */ -			pmhctl->llist_info.reg_read_waiting = TRUE; -		} -#endif - -		llist = pmhctl->llist_ptr; - -		/* clear end flag in previous last packet */ -		llist[prev_end_idx].link_controller_flags = 0; -		pmhctl->llist_notify[prev_end_idx].next_idx = first_llist_idx; - -		/* set the next_packet_pointer of the previous last packet */ -		llist[prev_end_idx].next_packet_pointer = -		    (void *)(&llist_dma[first_llist_idx]); - -		/* clean cache so MDDI host can read data */ -		memory_barrier(); - -		/* assign new waiting last index value */ -		pmhctl->llist_info.waiting_end_idx = last_llist_idx; -	} - -	spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -} - -void mddi_host_write_pix_attr_reg(uint32 value) -{ -	(void)value; -} - -void mddi_queue_reverse_encapsulation(boolean wait) -{ -#ifdef FEATURE_MDDI_DISABLE_REVERSE -	MDDI_MSG_CRIT("No reverse link available\n"); -	(void)wait; -#else -	unsigned long flags; -	boolean error = FALSE; -	mddi_host_type host_idx = MDDI_HOST_PRIM; -	mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]); - -	spin_lock_irqsave(&mddi_host_spin_lock, flags); - -	/* turn on clock(s), if they have been disabled */ -	mddi_host_enable_hclk(); -	mddi_host_enable_io_clock(); - -	if (wait) { -		if (!mddi_rev_user.waiting) { -			mddi_rev_user.waiting = TRUE; -			INIT_COMPLETION(mddi_rev_user.done_comp); -		} else -			error = TRUE; -	} -	mddi_rev_encap_user_request = TRUE; - -	if (pmhctl->rev_state == MDDI_REV_IDLE) { -		/* attempt to send the reverse encapsulation now */ -		mddi_host_type orig_host_idx = mddi_curr_host; -		mddi_curr_host = host_idx; -		mddi_issue_reverse_encapsulation(); -		mddi_curr_host = orig_host_idx; -	} -	spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -	if (error) { -		MDDI_MSG_ERR("Reverse Encap request already in progress\n"); -	} else if (wait) -		wait_for_completion_killable(&(mddi_rev_user.done_comp)); -#endif -} - -/* ISR to be executed */ -boolean mddi_set_rev_handler(mddi_rev_handler_type handler, uint16 pkt_type) -{ -#ifdef FEATURE_MDDI_DISABLE_REVERSE -	MDDI_MSG_CRIT("No reverse link available\n"); -	(void)handler; -	(void)pkt_type; -	return (FALSE); -#else -	unsigned long flags; -	uint16 hdlr; -	boolean handler_set = FALSE; -	boolean overwrite = FALSE; -	mddi_host_type host_idx = MDDI_HOST_PRIM; -	mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]); - -	/* Disable interrupts */ -	spin_lock_irqsave(&mddi_host_spin_lock, flags); - -	for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) { -		if (mddi_rev_pkt_handler[hdlr].pkt_type == pkt_type) { -			mddi_rev_pkt_handler[hdlr].handler = handler; -			if (handler == NULL) { -				/* clearing handler from table */ -				mddi_rev_pkt_handler[hdlr].pkt_type = -				    INVALID_PKT_TYPE; -				handler_set = TRUE; -				if (pkt_type == 0x10) {	/* video stream packet */ -					/* ensure HCLK on to MDDI host core before register write */ -					mddi_host_enable_hclk(); -					/* No longer getting video, so reset rev encap size to default */ -					pmhctl->rev_pkt_size = -					    MDDI_DEFAULT_REV_PKT_SIZE; -					mddi_host_reg_out(REV_ENCAP_SZ, -							  pmhctl->rev_pkt_size); -				} -			} else { -				/* already a handler for this packet */ -				overwrite = TRUE; -			} -			break; -		} -	} -	if ((hdlr >= MAX_MDDI_REV_HANDLERS) && (handler != NULL)) { -		/* assigning new handler */ -		for (hdlr = 0; hdlr < MAX_MDDI_REV_HANDLERS; hdlr++) { -			if (mddi_rev_pkt_handler[hdlr].pkt_type == -			    INVALID_PKT_TYPE) { -				if ((pkt_type == 0x10) &&	/* video stream packet */ -				    (pmhctl->rev_pkt_size < -				     MDDI_VIDEO_REV_PKT_SIZE)) { -					/* ensure HCLK on to MDDI host core before register write */ -					mddi_host_enable_hclk(); -					/* Increase Rev Encap Size */ -					pmhctl->rev_pkt_size = -					    MDDI_VIDEO_REV_PKT_SIZE; -					mddi_host_reg_out(REV_ENCAP_SZ, -							  pmhctl->rev_pkt_size); -				} -				mddi_rev_pkt_handler[hdlr].handler = handler; -				mddi_rev_pkt_handler[hdlr].pkt_type = pkt_type; -				handler_set = TRUE; -				break; -			} -		} -	} - -	/* Restore interrupts */ -	spin_unlock_irqrestore(&mddi_host_spin_lock, flags); - -	if (overwrite) -		MDDI_MSG_ERR("Overwriting previous rev packet handler\n"); - -	return handler_set; - -#endif -}				/* mddi_set_rev_handler */ - -void mddi_host_disable_hibernation(boolean disable) -{ -	mddi_host_type host_idx = MDDI_HOST_PRIM; -	mddi_host_cntl_type *pmhctl = &(mhctl[MDDI_HOST_PRIM]); - -	if (disable) { -		pmhctl->disable_hibernation = TRUE; -		/* hibernation will be turned off by isr next time it is entered */ -	} else { -		if (pmhctl->disable_hibernation) { -			unsigned long flags; -			spin_lock_irqsave(&mddi_host_spin_lock, flags); -			if (!MDDI_HOST_IS_HCLK_ON) -				MDDI_HOST_ENABLE_HCLK; -			mddi_host_reg_out(CMD, MDDI_CMD_HIBERNATE | 1); -			spin_unlock_irqrestore(&mddi_host_spin_lock, flags); -			pmhctl->disable_hibernation = FALSE; -		} -	} -} - -void mddi_mhctl_remove(mddi_host_type host_idx) -{ -	mddi_host_cntl_type *pmhctl; - -	pmhctl = &(mhctl[host_idx]); - -	dma_free_coherent(NULL, MDDI_LLIST_POOL_SIZE, (void *)pmhctl->llist_ptr, -			  pmhctl->llist_dma_addr); - -	dma_free_coherent(NULL, MDDI_MAX_REV_DATA_SIZE, -			  (void *)pmhctl->rev_data_buf, -			  pmhctl->rev_data_dma_addr); -}  | 
